1 /* path.h: path data structures
3 Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
13 #include <sys/ioctl.h>
17 enum executable_states
20 dont_care_if_executable,
21 not_executable = dont_care_if_executable,
22 dont_know_if_executable
29 suffix_info (const char *s, int addit = 0): name (s), addon (addit) {}
34 PC_SYM_FOLLOW = 0x0001,
35 PC_SYM_NOFOLLOW = 0x0002,
36 PC_SYM_IGNORE = 0x0004,
37 PC_SYM_CONTENTS = 0x0008,
39 PC_NULLEMPTY = 0x0020,
42 PC_NO_ACCESS_CHECK = 0x00800000,
43 PC_WRITABLE = 0x00400000
53 #define PC_NONULLEMPTY -1
55 #include "sys/mount.h"
60 PATH_SYMLINK = MOUNT_SYMLINK,
61 PATH_BINARY = MOUNT_BINARY,
62 PATH_EXEC = MOUNT_EXEC,
63 PATH_NOTEXEC = MOUNT_NOTEXEC,
64 PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
67 PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
68 PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
69 PATH_LNK = 0x01000000,
70 PATH_TEXT = 0x02000000,
71 PATH_HAS_SYMLINKS = 0x10000000,
72 PATH_SOCKET = 0x40000000
82 DWORD flags; /* Volume flags */
83 DWORD serial; /* Volume serial number */
84 unsigned is_remote_drive : 1;
85 unsigned has_buggy_open : 1;
87 unsigned has_acls : 1;
89 unsigned drive_type : 3;
95 flags () = serial () = 0;
96 is_remote_drive (false);
97 has_buggy_open (false);
103 inline DWORD& flags () {return status.flags;};
104 inline DWORD& serial () {return status.serial;};
106 IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
107 IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
108 IMPLEMENT_STATUS_FLAG (bool, is_fat)
109 IMPLEMENT_STATUS_FLAG (bool, has_ea)
110 IMPLEMENT_STATUS_FLAG (bool, has_acls)
111 IMPLEMENT_STATUS_FLAG (DWORD, drive_type)
113 bool update (const char *);
120 void add_ext_from_sym (symlink_info&);
129 bool isremote () {return fs.is_remote_drive ();}
130 int has_acls () const {return fs.has_acls (); }
131 int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
132 int hasgood_inode () const {return has_acls ();} // Not strictly correct
133 int has_buggy_open () const {return fs.has_buggy_open ();}
134 bool isencoded () {return path_flags & PATH_ENC;}
137 if (path_flags & PATH_BINARY)
139 if (path_flags & PATH_TEXT)
143 int issymlink () const {return path_flags & PATH_SYMLINK;}
144 int is_lnk_symlink () const {return path_flags & PATH_LNK;}
145 int isdevice () const {return dev.devn && dev.devn != FH_FS && dev.devn != FH_FIFO;}
146 int isfifo () const {return dev == FH_FIFO;}
147 int isspecial () const {return dev.devn && dev.devn != FH_FS;}
148 int is_auto_device () const {return isdevice () && !is_fs_special ();}
149 int is_fs_device () const {return isdevice () && is_fs_special ();}
150 int is_fs_special () const {return isspecial () && dev.isfs ();}
151 int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
152 int issocket () const {return dev.devn == FH_UNIX;}
153 int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
154 bool isro () const {return !!(path_flags & PATH_RO);}
155 bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
156 bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
157 int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
158 executable_states exec_state ()
160 extern int _check_for_executable;
161 if (path_flags & PATH_ALL_EXEC)
162 return is_executable;
163 if (path_flags & PATH_NOTEXEC)
164 return not_executable;
165 if (!_check_for_executable)
166 return dont_care_if_executable;
167 return dont_know_if_executable;
170 void set_binary () {path_flags |= PATH_BINARY;}
171 void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;}
172 void set_has_symlinks () {path_flags |= PATH_HAS_SYMLINKS;}
173 void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;}
175 void check (const char *src, unsigned opt = PC_SYM_FOLLOW,
176 const suffix_info *suffixes = NULL) __attribute__ ((regparm(3)));
178 path_conv (const device& in_dev): fileattr (INVALID_FILE_ATTRIBUTES),
179 path_flags (0), known_suffix (NULL), error (0), dev (in_dev)
181 strcpy (path, in_dev.native);
184 path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW,
185 const suffix_info *suffixes = NULL)
187 check (src, opt, suffixes);
190 path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW,
191 const suffix_info *suffixes = NULL)
193 check (src, opt | PC_NULLEMPTY, suffixes);
196 path_conv (): fileattr (INVALID_FILE_ATTRIBUTES), path_flags (0),
197 known_suffix (NULL), error (0), normalized_path (NULL)
201 void set_name (const char *win32, const char *posix);
202 inline char *get_win32 () { return path; }
203 PUNICODE_STRING get_nt_native_path (UNICODE_STRING &upath);
204 operator char *() {return path;}
205 operator const char *() {return path;}
206 operator DWORD &() {return fileattr;}
207 operator int () {return fileattr; }
208 char operator [](int i) const {return path[i];}
209 DWORD get_devn () {return dev.devn;}
210 short get_unitn () {return dev.minor;}
211 DWORD file_attributes () {return fileattr;}
212 void file_attributes (DWORD new_attr) {fileattr = new_attr;}
213 DWORD drive_type () {return fs.drive_type ();}
214 DWORD fs_flags () {return fs.flags ();}
215 bool fs_has_ea () {return fs.has_ea ();}
216 bool fs_is_fat () {return fs.is_fat ();}
217 void set_path (const char *p) {strcpy (path, p);}
218 DWORD volser () { return fs.serial (); }
219 void fillin (HANDLE h);
220 inline size_t size ()
222 return (sizeof (*this) - sizeof (path)) + strlen (path) + 1 + normalized_path_size;
225 unsigned __stdcall ndisk_links (DWORD);
226 char *normalized_path;
227 size_t normalized_path_size;
228 void set_normalized_path (const char *, bool) __attribute__ ((regparm (3)));
229 DWORD get_symlink_length () { return symlink_length; };
231 DWORD symlink_length;
232 char path[CYG_MAX_PATH];
236 #define SYMLINK_COOKIE "!<symlink>"
238 #define SYMLINK_EA_NAME ".CYGSYMLINK"
241 #define SOCKET_COOKIE "!<socket >"
243 /* The sizeof header written to a shortcut by Cygwin or U/WIN. */
244 #define SHORTCUT_HDR_SIZE 76
246 /* Maximum depth of symlinks (after which ELOOP is issued). */
247 #define MAX_LINK_DEPTH 10
248 int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
252 FE_NADA = 0, /* Nothing special */
253 FE_NNF = 1, /* Return NULL if not found */
254 FE_NATIVE = 2, /* Return native path in path_conv struct */
255 FE_CWD = 4 /* Search CWD for program */
257 const char * __stdcall find_exec (const char *name, path_conv& buf,
258 const char *winenv = "PATH=",
259 unsigned opt = FE_NADA,
260 const char **known_suffix = NULL)
261 __attribute__ ((regparm(3)));
263 /* Common macros for checking for invalid path names */
264 #define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
267 has_exec_chars (const char *buf, int len)
270 ((buf[0] == '#' && buf[1] == '!') ||
271 (buf[0] == ':' && buf[1] == '\n') ||
272 (buf[0] == 'M' && buf[1] == 'Z'));
275 int pathmatch (const char *path1, const char *path2) __attribute__ ((regparm (2)));
276 int pathnmatch (const char *path1, const char *path2, int len) __attribute__ ((regparm (2)));
278 bool fnunmunge (char *, const char *) __attribute__ ((regparm (2)));
280 int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
282 bool is_floppy (const char *);
284 /* FIXME: Move to own include file eventually */
286 #define MAX_ETC_FILES 2
291 static bool change_possible[MAX_ETC_FILES + 1];
292 static const char *fn[MAX_ETC_FILES + 1];
293 static FILETIME last_modified[MAX_ETC_FILES + 1];
294 static bool dir_changed (int);
295 static int init (int, const char *);
296 static bool file_changed (int);
297 static bool test_file_change (int);