]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* path.h: path data structures |
2 | ||
1fd5e000 CF |
3 | This file is part of Cygwin. |
4 | ||
5 | This software is a copyrighted work licensed under the terms of the | |
6 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
7 | details. */ | |
8 | ||
7ac61736 | 9 | #include "devices.h" |
58298328 | 10 | #include "mount.h" |
fafbf755 | 11 | #include "cygheap_malloc.h" |
2d355410 | 12 | #include "nfs.h" |
7ac61736 | 13 | |
c1023ee3 | 14 | #include <sys/mount.h> |
7ac61736 CF |
15 | #include <sys/ioctl.h> |
16 | #include <fcntl.h> | |
6ae28c22 | 17 | #include <alloca.h> |
7ac61736 | 18 | |
c3a46349 | 19 | extern inline bool |
f3810c72 CV |
20 | has_attribute (DWORD attributes, DWORD attribs_to_test) |
21 | { | |
22 | return attributes != INVALID_FILE_ATTRIBUTES | |
23 | && (attributes & attribs_to_test); | |
24 | } | |
25 | ||
7ac61736 CF |
26 | enum executable_states |
27 | { | |
28 | is_executable, | |
29 | dont_care_if_executable, | |
30 | not_executable = dont_care_if_executable, | |
31 | dont_know_if_executable | |
32 | }; | |
33 | ||
1fd5e000 CF |
34 | struct suffix_info |
35 | { | |
36 | const char *name; | |
37 | int addon; | |
1dc16fc7 | 38 | suffix_info (const char *s, int addit = 0): name (s), addon (addit) {} |
1fd5e000 CF |
39 | }; |
40 | ||
4a971ce4 CV |
41 | extern suffix_info stat_suffixes[]; |
42 | ||
fde4eaa1 CV |
43 | /* DO NOT copy any of these files into the same set of flags as the |
44 | below path_types. Ever. */ | |
5bc584ba | 45 | enum pathconv_arg |
1fd5e000 | 46 | { |
2caaa810 CV |
47 | PC_SYM_FOLLOW = _BIT ( 0), /* follow symlinks */ |
48 | PC_SYM_NOFOLLOW = _BIT ( 1), /* don't follow symlinks (but honor | |
49 | trailing slashes) */ | |
50 | PC_SYM_NOFOLLOW_REP = _BIT ( 2), /* don't follow dir reparse point */ | |
51 | PC_SYM_CONTENTS = _BIT ( 3), /* don't follow, return content only */ | |
52 | PC_NOFULL = _BIT ( 4), /* keep relative path */ | |
53 | PC_NULLEMPTY = _BIT ( 5), /* empty path is no error */ | |
54 | PC_NONULLEMPTY = _BIT ( 6), /* override PC_NULLEMPTY default */ | |
55 | PC_POSIX = _BIT ( 7), /* return normalized posix path */ | |
c1023ee3 CV |
56 | PC_OPEN = _BIT ( 9), /* use open semantics */ |
57 | PC_CTTY = _BIT (10), /* could later be used as ctty */ | |
2caaa810 CV |
58 | PC_SYM_NOFOLLOW_PROCFD = _BIT (11), /* allow /proc/PID/fd redirection */ |
59 | PC_KEEP_HANDLE = _BIT (12), /* keep handle for later stat calls */ | |
60 | PC_NO_ACCESS_CHECK = _BIT (13), /* helper flag for error check */ | |
26425142 | 61 | PC_SYM_NOFOLLOW_DIR = _BIT (14), /* don't follow a trailing slash */ |
c1023ee3 | 62 | PC_DONT_USE = _BIT (31) /* conversion to signed happens. */ |
1fd5e000 CF |
63 | }; |
64 | ||
5bc584ba | 65 | enum path_types |
1fd5e000 | 66 | { |
c1023ee3 CV |
67 | PATH_CTTY = _BIT ( 0), /* could later be used as ctty */ |
68 | PATH_OPEN = _BIT ( 1), /* use open semantics */ | |
e9bc4ccc CV |
69 | PATH_LNK = _BIT ( 2), /* *.lnk-type symlink */ |
70 | PATH_REP = _BIT ( 3), /* reparse point known to Cygwin */ | |
71 | PATH_SYMLINK = _BIT ( 4), /* symlink understood by Cygwin */ | |
72 | PATH_SOCKET = _BIT ( 5), /* AF_UNIX socket file */ | |
73 | PATH_RESOLVE_PROCFD = _BIT ( 6), /* fd symlink via /proc */ | |
aec64798 | 74 | PATH_REP_NOAPI = _BIT ( 7), /* rep. point unknown to WinAPI */ |
c1023ee3 | 75 | PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */ |
1fd5e000 CF |
76 | }; |
77 | ||
9dae73ed CV |
78 | enum fetch_fh_flags |
79 | { | |
80 | FFH_LINKAT = (1 << 0), | |
81 | }; | |
82 | ||
f91865c8 | 83 | NTSTATUS file_get_fai (HANDLE, PFILE_ALL_INFORMATION); |
3e80cefb CV |
84 | int check_reparse_point_target (HANDLE, bool, PREPARSE_DATA_BUFFER, |
85 | PUNICODE_STRING); | |
f91865c8 | 86 | |
c80480bf | 87 | class symlink_info; |
c80480bf | 88 | |
5a0d1edb CV |
89 | class path_conv_handle |
90 | { | |
91 | HANDLE hdl; | |
2d355410 | 92 | union { |
eed35efb | 93 | FILE_ALL_INFORMATION _fai; |
2d355410 CV |
94 | /* For NFS. */ |
95 | fattr3 _fattr3; | |
96 | } attribs; | |
5a0d1edb | 97 | public: |
dd0821e3 CV |
98 | path_conv_handle () : hdl (NULL) {} |
99 | inline void set (HANDLE h) { hdl = h; } | |
5a0d1edb CV |
100 | inline void close () |
101 | { | |
102 | if (hdl) | |
103 | CloseHandle (hdl); | |
dd0821e3 | 104 | set (NULL); |
5a0d1edb | 105 | } |
23771fa1 | 106 | inline void dup (const path_conv_handle &pch) |
5a0d1edb CV |
107 | { |
108 | if (!DuplicateHandle (GetCurrentProcess (), pch.handle (), | |
109 | GetCurrentProcess (), &hdl, | |
110 | 0, TRUE, DUPLICATE_SAME_ACCESS)) | |
dd0821e3 | 111 | hdl = NULL; |
5a0d1edb CV |
112 | } |
113 | inline HANDLE handle () const { return hdl; } | |
f91865c8 | 114 | inline PFILE_ALL_INFORMATION fai () const |
eed35efb | 115 | { return (PFILE_ALL_INFORMATION) &attribs._fai; } |
f91865c8 | 116 | inline struct fattr3 *nfsattr () const |
2d355410 | 117 | { return (struct fattr3 *) &attribs._fattr3; } |
f91865c8 CV |
118 | inline NTSTATUS get_finfo (HANDLE h, bool nfs) |
119 | { | |
120 | return nfs ? nfs_fetch_fattr3 (h, nfsattr ()) : file_get_fai (h, fai ()); | |
121 | } | |
122 | inline ino_t get_ino (bool nfs) const | |
123 | { | |
124 | return nfs ? nfsattr ()->fileid | |
125 | : fai ()->InternalInformation.IndexNumber.QuadPart; | |
126 | } | |
127 | inline DWORD get_dosattr (bool nfs) const | |
128 | { | |
129 | if (nfs) | |
130 | return (nfsattr ()->type & 7) == NF3DIR ? FILE_ATTRIBUTE_DIRECTORY : 0; | |
131 | return fai ()->BasicInformation.FileAttributes; | |
132 | } | |
5a0d1edb CV |
133 | }; |
134 | ||
29ee580d CF |
135 | class path_conv |
136 | { | |
99138976 | 137 | DWORD fileattr; |
e4b57503 | 138 | ULONG caseinsensitive; |
29ee580d | 139 | fs_info fs; |
26d95368 | 140 | |
91d2f6ee CV |
141 | PWCHAR wide_path; |
142 | UNICODE_STRING uni_path; | |
fafbf755 CF |
143 | DWORD symlink_length; |
144 | const char *path; | |
c1023ee3 CV |
145 | uint32_t mount_flags; |
146 | uint32_t path_flags; | |
d2bd82aa CV |
147 | const char *suffix; |
148 | const char *posix_path; | |
5a0d1edb | 149 | path_conv_handle conv_handle; |
26d95368 CV |
150 | |
151 | void add_ext_from_sym (symlink_info&); | |
152 | char *modifiable_path () {return (char *) path;} | |
153 | ||
1fd5e000 | 154 | public: |
47063f00 | 155 | int error; |
7ac61736 | 156 | device dev; |
ecfb6f11 | 157 | |
91b264c7 CV |
158 | void *serialize (HANDLE, unsigned int &) const; |
159 | HANDLE deserialize (void *); | |
160 | ||
d2bd82aa | 161 | const char *known_suffix () { return suffix; } |
330a2fae | 162 | bool isremote () const {return fs.is_remote_drive ();} |
e4b57503 | 163 | ULONG objcaseinsensitive () const {return caseinsensitive;} |
c1023ee3 CV |
164 | bool has_acls () const {return !(mount_flags & MOUNT_NOACL) |
165 | && fs.has_acls (); } | |
166 | bool hasgood_inode () const {return !(mount_flags & MOUNT_IHASH); } | |
61522196 | 167 | bool isgood_inode (ino_t ino) const; |
05297cca CV |
168 | bool support_sparse () const |
169 | { | |
c1023ee3 | 170 | return (mount_flags & MOUNT_SPARSE) |
05297cca CV |
171 | && (fs_flags () & FILE_SUPPORTS_SPARSE_FILES); |
172 | } | |
c1023ee3 | 173 | int has_dos_filenames_only () const {return mount_flags & MOUNT_DOS;} |
4c9d01fd | 174 | int has_buggy_reopen () const {return fs.has_buggy_reopen ();} |
d79a78e5 | 175 | int has_buggy_fileid_dirinfo () const {return fs.has_buggy_fileid_dirinfo ();} |
c04ed45d | 176 | int has_buggy_basic_info () const {return fs.has_buggy_basic_info ();} |
e35f391f CF |
177 | int binmode () const |
178 | { | |
367c1ae1 | 179 | return (mount_flags & MOUNT_TEXT) ? O_TEXT : O_BINARY; |
e35f391f | 180 | } |
ecfb6f11 | 181 | int issymlink () const {return path_flags & PATH_SYMLINK;} |
762520f3 | 182 | int is_lnk_symlink () const {return path_flags & PATH_LNK;} |
aec64798 | 183 | /* This indicates any known reparse point */ |
7ae89fe7 | 184 | int is_known_reparse_point () const {return path_flags & PATH_REP;} |
aec64798 CV |
185 | /* This indicates any known reparse point, handled sanely by WinAPI. |
186 | The difference is crucial: WSL symlinks, for instance, are known | |
187 | reparse points, so we want to open them as reparse points usually. | |
188 | However they are foreign to WinAPI and not handled sanely. If one | |
189 | is part of $PATH, WinAPI functions may fail under the hood with | |
190 | STATUS_IO_REPARSE_TAG_NOT_HANDLED. */ | |
191 | int is_winapi_reparse_point () const | |
192 | { | |
193 | return (path_flags & (PATH_REP | PATH_REP_NOAPI)) == PATH_REP; | |
194 | } | |
44d2fc0a CF |
195 | int isdevice () const {return dev.not_device (FH_FS) && dev.not_device (FH_FIFO);} |
196 | int isfifo () const {return dev.is_device (FH_FIFO);} | |
197 | int isspecial () const {return dev.not_device (FH_FS);} | |
198 | int iscygdrive () const {return dev.is_device (FH_CYGDRIVE);} | |
c57b13f9 | 199 | int is_fs_special () const {return dev.is_fs_special ();} |
73f81953 KB |
200 | |
201 | int is_lnk_special () const {return (isdevice () && is_fs_special () | |
202 | && !issocket ()) | |
af4d29e1 | 203 | || isfifo () || is_lnk_symlink ();} |
6c55be9d | 204 | #ifdef __WITH_AF_UNIX |
aa467e6e CV |
205 | int issocket () const {return dev.is_device (FH_LOCAL) |
206 | || dev.is_device (FH_UNIX);} | |
6c55be9d CV |
207 | #else |
208 | int issocket () const {return dev.is_device (FH_LOCAL);} | |
209 | #endif /* __WITH_AF_UNIX */ | |
c1023ee3 | 210 | int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;} |
23771fa1 CF |
211 | int isopen () const {return path_flags & PATH_OPEN;} |
212 | int isctty_capable () const {return path_flags & PATH_CTTY;} | |
ba12614f | 213 | int follow_fd_symlink () const {return path_flags & PATH_RESOLVE_PROCFD;} |
70d0243c CF |
214 | void set_cygexec (bool isset) |
215 | { | |
216 | if (isset) | |
c1023ee3 | 217 | mount_flags |= MOUNT_CYGWIN_EXEC; |
70d0243c | 218 | else |
c1023ee3 | 219 | mount_flags &= ~MOUNT_CYGWIN_EXEC; |
70d0243c | 220 | } |
61522196 CV |
221 | void set_cygexec (void *target) |
222 | { | |
223 | if (target) | |
c1023ee3 | 224 | mount_flags |= MOUNT_CYGWIN_EXEC; |
61522196 | 225 | else |
c1023ee3 | 226 | mount_flags &= ~MOUNT_CYGWIN_EXEC; |
61522196 | 227 | } |
c1023ee3 | 228 | bool isro () const {return !!(mount_flags & MOUNT_RO);} |
7eddac1b | 229 | bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;} |
47063f00 CF |
230 | bool has_attribute (DWORD x) const {return exists () && (fileattr & x);} |
231 | int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);} | |
95a8465b CF |
232 | executable_states exec_state () |
233 | { | |
234 | extern int _check_for_executable; | |
c1023ee3 | 235 | if (mount_flags & (MOUNT_CYGWIN_EXEC | MOUNT_EXEC)) |
95a8465b | 236 | return is_executable; |
c1023ee3 | 237 | if (mount_flags & MOUNT_NOTEXEC) |
95a8465b CF |
238 | return not_executable; |
239 | if (!_check_for_executable) | |
240 | return dont_care_if_executable; | |
241 | return dont_know_if_executable; | |
242 | } | |
1fd5e000 | 243 | |
b923181e | 244 | void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;} |
c1023ee3 | 245 | void set_exec (int x = 1) {mount_flags |= x ? MOUNT_EXEC : MOUNT_NOTEXEC;} |
1fd5e000 | 246 | |
c1023ee3 | 247 | void __reg3 check (const UNICODE_STRING *upath, uint32_t opt = PC_SYM_FOLLOW, |
6e75c72b | 248 | const suffix_info *suffixes = NULL); |
c1023ee3 | 249 | void __reg3 check (const char *src, uint32_t opt = PC_SYM_FOLLOW, |
6e75c72b | 250 | const suffix_info *suffixes = NULL); |
5bc584ba | 251 | |
c211f8eb | 252 | path_conv (const device& in_dev) |
7f01964f | 253 | : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), |
c1023ee3 CV |
254 | mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), |
255 | error (0), dev (in_dev) | |
c211f8eb | 256 | { |
b2867a68 | 257 | set_path (in_dev.native ()); |
c211f8eb | 258 | } |
7ac61736 | 259 | |
c1023ee3 | 260 | path_conv (const UNICODE_STRING *src, uint32_t opt = PC_SYM_FOLLOW, |
214c3a11 | 261 | const suffix_info *suffixes = NULL) |
6259826e | 262 | : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), |
c1023ee3 | 263 | mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) |
214c3a11 | 264 | { |
c1023ee3 | 265 | check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes); |
214c3a11 CV |
266 | } |
267 | ||
c1023ee3 | 268 | path_conv (const char *src, uint32_t opt = PC_SYM_FOLLOW, |
5bc584ba | 269 | const suffix_info *suffixes = NULL) |
6259826e | 270 | : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), |
c1023ee3 | 271 | mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) |
55fc91b9 | 272 | { |
c1023ee3 | 273 | check (src, opt | ((opt & PC_NONULLEMPTY) ? 0 : PC_NULLEMPTY), suffixes); |
55fc91b9 CF |
274 | } |
275 | ||
c211f8eb | 276 | path_conv () |
fafbf755 | 277 | : fileattr (INVALID_FILE_ATTRIBUTES), wide_path (NULL), path (NULL), |
c1023ee3 | 278 | mount_flags (0), path_flags (0), suffix (NULL), posix_path (NULL), error (0) |
0986989f | 279 | {} |
55fc91b9 | 280 | |
720c33ae | 281 | ~path_conv (); |
d2bd82aa | 282 | inline const char *get_win32 () const { return path; } |
5abb0ed1 | 283 | void set_nt_native_path (PUNICODE_STRING); |
91d2f6ee | 284 | PUNICODE_STRING get_nt_native_path (); |
4c9d01fd CV |
285 | inline POBJECT_ATTRIBUTES get_object_attr (OBJECT_ATTRIBUTES &attr, |
286 | SECURITY_ATTRIBUTES &sa) | |
287 | { | |
288 | if (!get_nt_native_path ()) | |
289 | return NULL; | |
290 | InitializeObjectAttributes (&attr, &uni_path, | |
291 | objcaseinsensitive () | |
292 | | (sa.bInheritHandle ? OBJ_INHERIT : 0), | |
293 | NULL, sa.lpSecurityDescriptor); | |
294 | return &attr; | |
295 | } | |
dc847e6b | 296 | inline POBJECT_ATTRIBUTES init_reopen_attr (OBJECT_ATTRIBUTES &attr, HANDLE h) |
4c9d01fd CV |
297 | { |
298 | if (has_buggy_reopen ()) | |
dc847e6b | 299 | InitializeObjectAttributes (&attr, get_nt_native_path (), |
4c9d01fd CV |
300 | objcaseinsensitive (), NULL, NULL) |
301 | else | |
dc847e6b | 302 | InitializeObjectAttributes (&attr, &ro_u_empty, objcaseinsensitive (), |
4c9d01fd | 303 | h, NULL); |
dc847e6b | 304 | return &attr; |
4c9d01fd | 305 | } |
891b6e88 CV |
306 | inline size_t get_wide_win32_path_len () |
307 | { | |
308 | get_nt_native_path (); | |
309 | return uni_path.Length / sizeof (WCHAR); | |
310 | } | |
311 | ||
91d2f6ee | 312 | PWCHAR get_wide_win32_path (PWCHAR wc); |
291be307 | 313 | operator DWORD &() {return fileattr;} |
9d1e72a1 | 314 | operator int () {return fileattr; } |
b2099ee7 CF |
315 | # define cfree_and_null(x) \ |
316 | if (x) \ | |
317 | { \ | |
318 | cfree ((void *) (x)); \ | |
319 | (x) = NULL; \ | |
320 | } | |
321 | void free_strings () | |
322 | { | |
323 | cfree_and_null (path); | |
d2bd82aa | 324 | cfree_and_null (posix_path); |
b2099ee7 CF |
325 | cfree_and_null (wide_path); |
326 | } | |
1dfffe8e | 327 | path_conv& eq_worker (const path_conv& pc, const char *in_path) |
19afaa1a | 328 | { |
b2099ee7 | 329 | free_strings (); |
f0cf44dc | 330 | memcpy ((void *) this, &pc, sizeof pc); |
b2867a68 CV |
331 | /* The device info might contain pointers to allocated strings, in |
332 | contrast to statically allocated strings. Calling device::dup() | |
333 | will duplicate the string if the source was allocated. */ | |
334 | dev.dup (); | |
22d1ebac KB |
335 | if (in_path) |
336 | path = cstrdup (in_path); | |
5a0d1edb | 337 | conv_handle.dup (pc.conv_handle); |
22d1ebac KB |
338 | if (pc.posix_path) |
339 | posix_path = cstrdup(pc.posix_path); | |
303dc023 CV |
340 | if (pc.wide_path) |
341 | { | |
342 | wide_path = cwcsdup (uni_path.Buffer); | |
343 | if (!wide_path) | |
344 | api_fatal ("cwcsdup would have returned NULL"); | |
345 | uni_path.Buffer = wide_path; | |
346 | } | |
19afaa1a CV |
347 | return *this; |
348 | } | |
6ae28c22 CF |
349 | |
350 | path_conv &operator << (const path_conv& pc) | |
351 | { | |
352 | const char *save_path; | |
1dfffe8e | 353 | |
6ae28c22 CF |
354 | if (!path) |
355 | save_path = pc.path; | |
356 | else | |
357 | { | |
358 | save_path = (char *) alloca (strlen (path) + 1); | |
359 | strcpy ((char *) save_path, path); | |
360 | } | |
1dfffe8e | 361 | return eq_worker (pc, save_path); |
6ae28c22 CF |
362 | } |
363 | ||
364 | path_conv &operator =(const path_conv& pc) | |
365 | { | |
1dfffe8e | 366 | return eq_worker (pc, pc.path); |
6ae28c22 | 367 | } |
61522196 | 368 | dev_t get_device () {return dev.get_device ();} |
330a2fae | 369 | DWORD file_attributes () const {return fileattr;} |
0175b531 | 370 | void file_attributes (DWORD new_attr) {fileattr = new_attr;} |
05297cca CV |
371 | DWORD fs_flags () const {return fs.flags ();} |
372 | DWORD fs_name_len () const {return fs.name_len ();} | |
da827464 | 373 | bool fs_got_fs () const { return fs.got_fs (); } |
330a2fae | 374 | bool fs_is_fat () const {return fs.is_fat ();} |
0c25ca40 CV |
375 | bool fs_is_exfat () const {return fs.is_exfat ();} |
376 | bool fs_is_any_fat () const {return fs.is_fat () || fs.is_exfat ();} | |
330a2fae | 377 | bool fs_is_ntfs () const {return fs.is_ntfs ();} |
115d74b9 | 378 | bool fs_is_refs () const {return fs.is_refs ();} |
330a2fae CV |
379 | bool fs_is_samba () const {return fs.is_samba ();} |
380 | bool fs_is_nfs () const {return fs.is_nfs ();} | |
90c2ba78 CF |
381 | bool fs_is_netapp () const {return fs.is_netapp ();} |
382 | bool fs_is_cdrom () const {return fs.is_cdrom ();} | |
0fb0fb83 | 383 | bool fs_is_mvfs () const {return fs.is_mvfs ();} |
4a49c715 CV |
384 | bool fs_is_cifs () const {return fs.is_cifs ();} |
385 | bool fs_is_nwfs () const {return fs.is_nwfs ();} | |
69178ca0 | 386 | bool fs_is_ncfsd () const {return fs.is_ncfsd ();} |
9ecd475c | 387 | bool fs_is_afs () const {return fs.is_afs ();} |
57d93beb | 388 | bool fs_is_prlfs () const {return fs.is_prlfs ();} |
34ce8088 | 389 | fs_info_type fs_type () const {return fs.what_fs ();} |
636c94d8 | 390 | ULONG fs_serial_number () const {return fs.serial_number ();} |
fafbf755 CF |
391 | inline const char *set_path (const char *p) |
392 | { | |
393 | if (path) | |
394 | cfree (modifiable_path ()); | |
395 | char *new_path = (char *) cmalloc_abort (HEAP_STR, strlen (p) + 7); | |
396 | strcpy (new_path, p); | |
397 | return path = new_path; | |
398 | } | |
9235f3ea | 399 | bool is_binary (); |
7ac61736 | 400 | |
5a0d1edb | 401 | HANDLE handle () const { return conv_handle.handle (); } |
eed35efb | 402 | PFILE_ALL_INFORMATION fai () { return conv_handle.fai (); } |
2d355410 | 403 | struct fattr3 *nfsattr () { return conv_handle.nfsattr (); } |
f91865c8 CV |
404 | inline NTSTATUS get_finfo (HANDLE h) |
405 | { | |
406 | return conv_handle.get_finfo (h, fs.is_nfs ()); | |
407 | } | |
408 | inline ino_t get_ino () const { return conv_handle.get_ino (fs.is_nfs ()); } | |
dd0821e3 | 409 | void reset_conv_handle () { conv_handle.set (NULL); } |
5a0d1edb CV |
410 | void close_conv_handle () { conv_handle.close (); } |
411 | ||
61522196 | 412 | ino_t get_ino_by_handle (HANDLE h); |
d2bd82aa CV |
413 | inline const char *get_posix () const { return posix_path; } |
414 | void __reg2 set_posix (const char *); | |
b923181e | 415 | DWORD get_symlink_length () { return symlink_length; }; |
1fd5e000 CF |
416 | }; |
417 | ||
418 | /* Symlink marker */ | |
419 | #define SYMLINK_COOKIE "!<symlink>" | |
420 | ||
421 | /* Socket marker */ | |
422 | #define SOCKET_COOKIE "!<socket >" | |
423 | ||
2671595b CV |
424 | /* Interix symlink marker */ |
425 | #define INTERIX_SYMLINK_COOKIE "IntxLNK\1" | |
426 | ||
6ea0c04e CF |
427 | enum fe_types |
428 | { | |
429 | FE_NADA = 0, /* Nothing special */ | |
430 | FE_NNF = 1, /* Return NULL if not found */ | |
4b84e3dc CV |
431 | FE_CWD = 4, /* Search CWD for program */ |
432 | FE_DLL = 8 /* Search for DLLs, not executables. */ | |
6ea0c04e | 433 | }; |
6e75c72b | 434 | const char *__reg3 find_exec (const char *name, path_conv& buf, |
117b1b1e | 435 | const char *search = "PATH", |
1ffe3e67 | 436 | unsigned opt = FE_NADA, |
6e75c72b | 437 | const char **known_suffix = NULL); |
bccd5e0d | 438 | |
1fd5e000 | 439 | /* Common macros for checking for invalid path names */ |
ec50441f | 440 | #define isdrive(s) (isalpha (*(s)) && (s)[1] == ':') |
752b16ce | 441 | #define iswdrive(s) (iswalpha (*(s)) && (s)[1] == L':') |
7e24f1bf | 442 | |
b12796a0 CF |
443 | static inline bool |
444 | has_exec_chars (const char *buf, int len) | |
445 | { | |
446 | return len >= 2 && | |
447 | ((buf[0] == '#' && buf[1] == '!') || | |
448 | (buf[0] == ':' && buf[1] == '\n') || | |
449 | (buf[0] == 'M' && buf[1] == 'Z')); | |
450 | } | |
451 | ||
6e75c72b CF |
452 | int __reg3 pathmatch (const char *path1, const char *path2, bool caseinsensitive); |
453 | int __reg3 pathnmatch (const char *path1, const char *path2, int len, bool caseinsensitive); | |
454 | bool __reg2 has_dot_last_component (const char *dir, bool test_dot_dot); | |
291be307 | 455 | |
6e75c72b CF |
456 | int __reg3 path_prefix_p (const char *path1, const char *path2, int len1, |
457 | bool caseinsensitive); | |
7905c4f1 | 458 | |
ade47a34 CF |
459 | int normalize_win32_path (const char *, char *, char *&); |
460 | int normalize_posix_path (const char *, char *, char *&); | |
6e75c72b | 461 | PUNICODE_STRING __reg3 get_nt_native_path (const char *, UNICODE_STRING&, bool); |
db27ea41 | 462 | |
4bfa93f1 | 463 | int __reg3 symlink_worker (const char *, path_conv &, bool); |