Add case-sensitivity.
Unconditionally handle mount points case-sensitive. Unconditionally handle virtual paths case-sensitive. Unconditionally handle registry paths case-insensitive. Otherwise, accommodate case-sensitivity of given path throughout. * cygheap.cc (cygheap_root::set): Get additional caseinsensitive parameter and store it. * cygheap.h (struct cygheap_root_mount_info): Add member caseinsensitive. * dlfcn.cc (get_full_path_of_dll): Drop PC_NOFULL parameter from call to path_conv::check. * environ.cc (pcheck_case): Remove. (check_case_init): Remove. (known): Drop "check_case" option. * exceptions.cc (open_stackdumpfile): Add comment. * fhandler.cc (fhandler_base::get_default_fmode): Call pathmatch instead of strcasematch. * fhandler_disk_file.cc: Accommodate case-sensitivity of given path throughout. (__DIR_mounts::check_mount): Unconditionally check virtual paths case-sensitive. (fhandler_disk_file::link): Drop case clash handling. (fhandler_disk_file::open): Ditto. (fhandler_disk_file::readdir_helper): Drop managed mount code. * mount.cc: Remove managed mount code and datastructures. (struct opt): Remove "managed" option. Add "posix=0" and "posix=1" options. (fillout_mntent): Remove "managed" output. Add "posix" output. * path.cc (struct symlink_info): Remove case_clash member and case_check method. (pcheck_case): Remove. (path_prefix_p): Take additional bool parameter "caseinsensitive". (pathnmatch): Ditto. (pathmatch): Ditto. (mkrelpath): Ditto. (fs_info::update): Set caseinsensitive flag according to file system name and FILE_CASE_SENSITIVE_SEARCH flag. Add comment. (tfx_chars_managed): Remove. (transform_chars): Drop "managed" parameter. Always use tfx_chars. (get_nt_native_path): Drop "managed" parameter. Make sure drive letters are always upper case. (getfileattr): Change second parameter to denote caseinsensitivity. (path_conv::check): Initialize caseinsensitive to OBJ_CASE_INSENSITIVE. Set caseinsensitive according to global obcaseinsensitive flag, file system case sensitivity and MOUNT_NOPOSIX mount flag. Drop case_clash and all the related code. (symlink_worker): Drop case clash handling. (symlink_info::set): Drop setting case_clash. (symlink_info::case_check): Remove. (cwdstuff::set): Add comment. (etc::init): Take path_conv instead of PUNICODE_STRING as parameter to allow case sensitivity. * path.h (enum pathconv_arg): Drop PC_SYM_IGNORE. (enum case_checking): Remove. (enum path_types): Drop PATH_ENC, add PATH_NOPOSIX flag. (struct fs_info): Add caseinsensitive flag and accessor methods. (class path_conv): Add caseinsensitive member and define objcaseinsensitive method. Drop case_clash member and isencoded method. (pathmatch): Change prototype according to above change. (pathnmatch): Ditto. (path_prefix_p): Ditto. (get_nt_native_path): Ditto. (class etc): Ditto. (fnunmunge): Remove prototype. * shared.cc (shared_info::init_obcaseinsensitive): Initialize obcaseinsensitive flag from obcaseinsensitive registry value. (shared_info::initialize): Call init_obcaseinsensitive here by the first process creating the shared memory. * shared_info.h (mount_item::fnmunge): Remove. (shared_info::obcaseinsensitive): Rename from obcaseinsensitivity. (shared_info::init_obcaseinsensitive): Declare. * syscalls.cc (try_to_bin): Add comment. * include/sys/mount.h (MOUNT_ENC): Remove flag. (MOUNT_NOPOSIX): Add flag.
This commit is contained in:
parent
bed5a336c4
commit
e4b575030b
@ -1,3 +1,80 @@
|
|||||||
|
2008-07-16 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
Add case-sensitivity.
|
||||||
|
Unconditionally handle mount points case-sensitive.
|
||||||
|
Unconditionally handle virtual paths case-sensitive.
|
||||||
|
Unconditionally handle registry paths case-insensitive.
|
||||||
|
Otherwise, accommodate case-sensitivity of given path throughout.
|
||||||
|
* cygheap.cc (cygheap_root::set): Get additional caseinsensitive
|
||||||
|
parameter and store it.
|
||||||
|
* cygheap.h (struct cygheap_root_mount_info): Add member
|
||||||
|
caseinsensitive.
|
||||||
|
* dlfcn.cc (get_full_path_of_dll): Drop PC_NOFULL parameter from call
|
||||||
|
to path_conv::check.
|
||||||
|
* environ.cc (pcheck_case): Remove.
|
||||||
|
(check_case_init): Remove.
|
||||||
|
(known): Drop "check_case" option.
|
||||||
|
* exceptions.cc (open_stackdumpfile): Add comment.
|
||||||
|
* fhandler.cc (fhandler_base::get_default_fmode): Call pathmatch
|
||||||
|
instead of strcasematch.
|
||||||
|
* fhandler_disk_file.cc: Accommodate case-sensitivity of given path
|
||||||
|
throughout.
|
||||||
|
(__DIR_mounts::check_mount): Unconditionally check virtual paths
|
||||||
|
case-sensitive.
|
||||||
|
(fhandler_disk_file::link): Drop case clash handling.
|
||||||
|
(fhandler_disk_file::open): Ditto.
|
||||||
|
(fhandler_disk_file::readdir_helper): Drop managed mount code.
|
||||||
|
* mount.cc: Remove managed mount code and datastructures.
|
||||||
|
(struct opt): Remove "managed" option. Add "posix=0" and "posix=1"
|
||||||
|
options.
|
||||||
|
(fillout_mntent): Remove "managed" output. Add "posix" output.
|
||||||
|
* path.cc (struct symlink_info): Remove case_clash member and
|
||||||
|
case_check method.
|
||||||
|
(pcheck_case): Remove.
|
||||||
|
(path_prefix_p): Take additional bool parameter "caseinsensitive".
|
||||||
|
(pathnmatch): Ditto.
|
||||||
|
(pathmatch): Ditto.
|
||||||
|
(mkrelpath): Ditto.
|
||||||
|
(fs_info::update): Set caseinsensitive flag according to file system
|
||||||
|
name and FILE_CASE_SENSITIVE_SEARCH flag. Add comment.
|
||||||
|
(tfx_chars_managed): Remove.
|
||||||
|
(transform_chars): Drop "managed" parameter. Always use tfx_chars.
|
||||||
|
(get_nt_native_path): Drop "managed" parameter. Make sure drive letters
|
||||||
|
are always upper case.
|
||||||
|
(getfileattr): Change second parameter to denote caseinsensitivity.
|
||||||
|
(path_conv::check): Initialize caseinsensitive to OBJ_CASE_INSENSITIVE.
|
||||||
|
Set caseinsensitive according to global obcaseinsensitive flag, file
|
||||||
|
system case sensitivity and MOUNT_NOPOSIX mount flag.
|
||||||
|
Drop case_clash and all the related code.
|
||||||
|
(symlink_worker): Drop case clash handling.
|
||||||
|
(symlink_info::set): Drop setting case_clash.
|
||||||
|
(symlink_info::case_check): Remove.
|
||||||
|
(cwdstuff::set): Add comment.
|
||||||
|
(etc::init): Take path_conv instead of PUNICODE_STRING as parameter to
|
||||||
|
allow case sensitivity.
|
||||||
|
* path.h (enum pathconv_arg): Drop PC_SYM_IGNORE.
|
||||||
|
(enum case_checking): Remove.
|
||||||
|
(enum path_types): Drop PATH_ENC, add PATH_NOPOSIX flag.
|
||||||
|
(struct fs_info): Add caseinsensitive flag and accessor methods.
|
||||||
|
(class path_conv): Add caseinsensitive member and define
|
||||||
|
objcaseinsensitive method. Drop case_clash member and isencoded method.
|
||||||
|
(pathmatch): Change prototype according to above change.
|
||||||
|
(pathnmatch): Ditto.
|
||||||
|
(path_prefix_p): Ditto.
|
||||||
|
(get_nt_native_path): Ditto.
|
||||||
|
(class etc): Ditto.
|
||||||
|
(fnunmunge): Remove prototype.
|
||||||
|
* shared.cc (shared_info::init_obcaseinsensitive): Initialize
|
||||||
|
obcaseinsensitive flag from obcaseinsensitive registry value.
|
||||||
|
(shared_info::initialize): Call init_obcaseinsensitive here by the
|
||||||
|
first process creating the shared memory.
|
||||||
|
* shared_info.h (mount_item::fnmunge): Remove.
|
||||||
|
(shared_info::obcaseinsensitive): Rename from obcaseinsensitivity.
|
||||||
|
(shared_info::init_obcaseinsensitive): Declare.
|
||||||
|
* syscalls.cc (try_to_bin): Add comment.
|
||||||
|
* include/sys/mount.h (MOUNT_ENC): Remove flag.
|
||||||
|
(MOUNT_NOPOSIX): Add flag.
|
||||||
|
|
||||||
2008-07-15 Corinna Vinschen <corinna@vinschen.de>
|
2008-07-15 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_tape.cc (mtinfo::initialize): Remove synchronization stuff.
|
* fhandler_tape.cc (mtinfo::initialize): Remove synchronization stuff.
|
||||||
|
@ -396,7 +396,7 @@ cstrdup1 (const char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cygheap_root::set (const char *posix, const char *native)
|
cygheap_root::set (const char *posix, const char *native, bool caseinsensitive)
|
||||||
{
|
{
|
||||||
if (*posix == '/' && posix[1] == '\0')
|
if (*posix == '/' && posix[1] == '\0')
|
||||||
{
|
{
|
||||||
@ -418,6 +418,7 @@ cygheap_root::set (const char *posix, const char *native)
|
|||||||
m->native_pathlen = strlen (native);
|
m->native_pathlen = strlen (native);
|
||||||
if (m->native_pathlen >= 1 && m->native_path[m->native_pathlen - 1] == '\\')
|
if (m->native_pathlen >= 1 && m->native_path[m->native_pathlen - 1] == '\\')
|
||||||
m->native_path[--m->native_pathlen] = '\0';
|
m->native_path[--m->native_pathlen] = '\0';
|
||||||
|
m->caseinsensitive = caseinsensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
cygheap_user::~cygheap_user ()
|
cygheap_user::~cygheap_user ()
|
||||||
|
@ -53,6 +53,7 @@ struct cygheap_root_mount_info
|
|||||||
unsigned posix_pathlen;
|
unsigned posix_pathlen;
|
||||||
char native_path[CYG_MAX_PATH];
|
char native_path[CYG_MAX_PATH];
|
||||||
unsigned native_pathlen;
|
unsigned native_pathlen;
|
||||||
|
bool caseinsensitive;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CGF: FIXME This doesn't belong here */
|
/* CGF: FIXME This doesn't belong here */
|
||||||
@ -68,7 +69,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (!m)
|
if (!m)
|
||||||
return 1;
|
return 1;
|
||||||
return path_prefix_p (m->posix_path, path, m->posix_pathlen);
|
return path_prefix_p (m->posix_path, path, m->posix_pathlen,
|
||||||
|
m->caseinsensitive);
|
||||||
}
|
}
|
||||||
bool ischroot_native (const char *path)
|
bool ischroot_native (const char *path)
|
||||||
{
|
{
|
||||||
@ -87,7 +89,7 @@ public:
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
bool exists () {return !!m;}
|
bool exists () {return !!m;}
|
||||||
void set (const char *, const char *);
|
void set (const char *, const char *, bool);
|
||||||
size_t posix_length () const { return m->posix_pathlen; }
|
size_t posix_length () const { return m->posix_pathlen; }
|
||||||
const char *posix_path () const { return m->posix_path; }
|
const char *posix_path () const { return m->posix_path; }
|
||||||
size_t native_length () const { return m->native_pathlen; }
|
size_t native_length () const { return m->native_pathlen; }
|
||||||
|
@ -63,7 +63,7 @@ get_full_path_of_dll (const char* str, char *name)
|
|||||||
if (isabspath (name) ||
|
if (isabspath (name) ||
|
||||||
(ret = check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
|
(ret = check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
|
||||||
?: check_path_access ("/usr/lib", name, real_filename)) == NULL)
|
?: check_path_access ("/usr/lib", name, real_filename)) == NULL)
|
||||||
real_filename.check (name, PC_SYM_FOLLOW | PC_NOFULL | PC_NULLEMPTY); /* Convert */
|
real_filename.check (name, PC_SYM_FOLLOW | PC_NULLEMPTY); /* Convert */
|
||||||
|
|
||||||
if (!real_filename.error)
|
if (!real_filename.error)
|
||||||
ret = strcpy (name, real_filename.get_win32 ());
|
ret = strcpy (name, real_filename.get_win32 ());
|
||||||
|
@ -34,7 +34,6 @@ extern bool allow_glob;
|
|||||||
extern bool ignore_case_with_glob;
|
extern bool ignore_case_with_glob;
|
||||||
extern bool allow_winsymlinks;
|
extern bool allow_winsymlinks;
|
||||||
extern bool strip_title_path;
|
extern bool strip_title_path;
|
||||||
extern int pcheck_case;
|
|
||||||
bool reset_com = false;
|
bool reset_com = false;
|
||||||
static bool envcache = true;
|
static bool envcache = true;
|
||||||
#ifdef USE_SERVER
|
#ifdef USE_SERVER
|
||||||
@ -490,33 +489,6 @@ glob_init (const char *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
check_case_init (const char *buf)
|
|
||||||
{
|
|
||||||
if (!buf || !*buf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ascii_strncasematch (buf, "relax", 5))
|
|
||||||
{
|
|
||||||
pcheck_case = PCHECK_RELAXED;
|
|
||||||
debug_printf ("File case checking set to RELAXED");
|
|
||||||
}
|
|
||||||
else if (ascii_strcasematch (buf, "adjust"))
|
|
||||||
{
|
|
||||||
pcheck_case = PCHECK_ADJUST;
|
|
||||||
debug_printf ("File case checking set to ADJUST");
|
|
||||||
}
|
|
||||||
else if (ascii_strcasematch (buf, "strict"))
|
|
||||||
{
|
|
||||||
pcheck_case = PCHECK_STRICT;
|
|
||||||
debug_printf ("File case checking set to STRICT");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf ("Wrong case checking name: %s", buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_file_api_mode (codepage_type cp)
|
set_file_api_mode (codepage_type cp)
|
||||||
{
|
{
|
||||||
@ -595,7 +567,6 @@ static struct parse_thing
|
|||||||
} known[] NO_COPY =
|
} known[] NO_COPY =
|
||||||
{
|
{
|
||||||
{"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},
|
{"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},
|
||||||
{"check_case", {func: &check_case_init}, isfunc, NULL, {{0}, {0}}},
|
|
||||||
{"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}},
|
{"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
{"dosfilewarning", {&dos_file_warning}, justset, NULL, {{false}, {true}}},
|
{"dosfilewarning", {&dos_file_warning}, justset, NULL, {{false}, {true}}},
|
||||||
{"envcache", {&envcache}, justset, NULL, {{true}, {false}}},
|
{"envcache", {&envcache}, justset, NULL, {{true}, {false}}},
|
||||||
|
@ -149,7 +149,7 @@ open_stackdumpfile ()
|
|||||||
p, strlen (p)) * sizeof (WCHAR);
|
p, strlen (p)) * sizeof (WCHAR);
|
||||||
RtlAppendUnicodeToString (&ucore, L".stackdump");
|
RtlAppendUnicodeToString (&ucore, L".stackdump");
|
||||||
/* Create an object attribute which refers to <progname>.stackdump
|
/* Create an object attribute which refers to <progname>.stackdump
|
||||||
in Cygwin's cwd. */
|
in Cygwin's cwd. Stick to caseinsensitivity. */
|
||||||
InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
|
||||||
cygheap->cwd.get_handle (), NULL);
|
cygheap->cwd.get_handle (), NULL);
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
@ -325,7 +325,7 @@ fhandler_base::get_default_fmode (int flags)
|
|||||||
if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
|
if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
|
||||||
continue;
|
continue;
|
||||||
else if ((pf->flags & O_ACCMODE) == accflags
|
else if ((pf->flags & O_ACCMODE) == accflags
|
||||||
&& strcasematch (stem, pf->name))
|
&& pathmatch (stem, pf->name, !!pc.objcaseinsensitive ()))
|
||||||
{
|
{
|
||||||
fmode = pf->flags & ~O_ACCMODE;
|
fmode = pf->flags & ~O_ACCMODE;
|
||||||
break;
|
break;
|
||||||
|
@ -81,20 +81,20 @@ public:
|
|||||||
UNICODE_STRING proc;
|
UNICODE_STRING proc;
|
||||||
|
|
||||||
RtlInitUnicodeString (&proc, L"proc");
|
RtlInitUnicodeString (&proc, L"proc");
|
||||||
if (RtlEqualUnicodeString (fname, &proc, TRUE))
|
if (RtlEqualUnicodeString (fname, &proc, FALSE))
|
||||||
{
|
{
|
||||||
found[__DIR_PROC] = true;
|
found[__DIR_PROC] = true;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (fname->Length / sizeof (WCHAR) == mount_table->cygdrive_len - 2
|
if (fname->Length / sizeof (WCHAR) == mount_table->cygdrive_len - 2
|
||||||
&& RtlEqualUnicodeString (fname, &cygdrive, TRUE))
|
&& RtlEqualUnicodeString (fname, &cygdrive, FALSE))
|
||||||
{
|
{
|
||||||
found[__DIR_CYGDRIVE] = true;
|
found[__DIR_CYGDRIVE] = true;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
if (RtlEqualUnicodeString (fname, &mounts[i], TRUE))
|
if (RtlEqualUnicodeString (fname, &mounts[i], FALSE))
|
||||||
{
|
{
|
||||||
found[i] = true;
|
found[i] = true;
|
||||||
return eval ? eval_ino (i) : 1;
|
return eval ? eval_ino (i) : 1;
|
||||||
@ -233,7 +233,7 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
|||||||
RtlInitCountedUnicodeString (&fname, pfdi->FileName,
|
RtlInitCountedUnicodeString (&fname, pfdi->FileName,
|
||||||
pfdi->FileNameLength);
|
pfdi->FileNameLength);
|
||||||
InitializeObjectAttributes (&attr, &fname,
|
InitializeObjectAttributes (&attr, &fname,
|
||||||
OBJ_CASE_INSENSITIVE, fh, NULL);
|
objcaseinsensitive (), fh, NULL);
|
||||||
if (is_volume_mountpoint (&attr))
|
if (is_volume_mountpoint (&attr))
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@ -379,7 +379,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
|||||||
LARGE_INTEGER FileId;
|
LARGE_INTEGER FileId;
|
||||||
|
|
||||||
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
|
||||||
InitializeObjectAttributes (&attr, &dirname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &dirname, pc.objcaseinsensitive (),
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
@ -1123,7 +1123,7 @@ fhandler_disk_file::link (const char *newpath)
|
|||||||
path_conv newpc (newpath, PC_SYM_NOFOLLOW | PC_POSIX, stat_suffixes);
|
path_conv newpc (newpath, PC_SYM_NOFOLLOW | PC_POSIX, stat_suffixes);
|
||||||
if (newpc.error)
|
if (newpc.error)
|
||||||
{
|
{
|
||||||
set_errno (newpc.case_clash ? ECASECLASH : newpc.error);
|
set_errno (newpc.error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1135,7 +1135,7 @@ fhandler_disk_file::link (const char *newpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char new_buf[strlen (newpath) + 5];
|
char new_buf[strlen (newpath) + 5];
|
||||||
if (!newpc.error && !newpc.case_clash)
|
if (!newpc.error)
|
||||||
{
|
{
|
||||||
if (allow_winsymlinks && pc.is_lnk_special ())
|
if (allow_winsymlinks && pc.is_lnk_special ())
|
||||||
{
|
{
|
||||||
@ -1298,13 +1298,6 @@ fhandler_disk_file::open (int flags, mode_t mode)
|
|||||||
int
|
int
|
||||||
fhandler_base::open_fs (int flags, mode_t mode)
|
fhandler_base::open_fs (int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
if (pc.case_clash && flags & O_CREAT)
|
|
||||||
{
|
|
||||||
debug_printf ("case clash detected");
|
|
||||||
set_errno (ECASECLASH);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unfortunately NT allows to open directories for writing, but that's
|
/* Unfortunately NT allows to open directories for writing, but that's
|
||||||
disallowed according to SUSv3. */
|
disallowed according to SUSv3. */
|
||||||
if (pc.isdir () && (flags & O_ACCMODE) != O_RDONLY)
|
if (pc.isdir () && (flags & O_ACCMODE) != O_RDONLY)
|
||||||
@ -1683,7 +1676,7 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
|
||||||
InitializeObjectAttributes (&attr, fname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, fname, pc.objcaseinsensitive (),
|
||||||
get_handle (), NULL);
|
get_handle (), NULL);
|
||||||
if (is_volume_mountpoint (&attr)
|
if (is_volume_mountpoint (&attr)
|
||||||
&& (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, &attr, &io,
|
&& (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, &attr, &io,
|
||||||
@ -1729,16 +1722,6 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (pc.isencoded ())
|
|
||||||
{
|
|
||||||
char tmp[NAME_MAX + 1];
|
|
||||||
sys_wcstombs (tmp, NAME_MAX + 1, fname->Buffer,
|
|
||||||
fname->Length / sizeof (WCHAR));
|
|
||||||
fnunmunge (de->d_name, tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
|
sys_wcstombs (de->d_name, NAME_MAX + 1, fname->Buffer,
|
||||||
fname->Length / sizeof (WCHAR));
|
fname->Length / sizeof (WCHAR));
|
||||||
|
|
||||||
@ -1886,7 +1869,8 @@ go_ahead:
|
|||||||
{
|
{
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
|
|
||||||
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &fname,
|
||||||
|
pc.objcaseinsensitive (),
|
||||||
get_handle (), NULL);
|
get_handle (), NULL);
|
||||||
if (NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
if (NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS,
|
FILE_SHARE_VALID_FLAGS,
|
||||||
@ -1964,7 +1948,7 @@ fhandler_disk_file::rewinddir (DIR *dir)
|
|||||||
HANDLE new_dir;
|
HANDLE new_dir;
|
||||||
|
|
||||||
RtlInitUnicodeString (&fname, L"");
|
RtlInitUnicodeString (&fname, L"");
|
||||||
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &fname, pc.objcaseinsensitive (),
|
||||||
get_handle (), NULL);
|
get_handle (), NULL);
|
||||||
status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
|
@ -117,7 +117,8 @@ fhandler_proc::get_proc_fhandler (const char *path)
|
|||||||
|
|
||||||
for (int i = 0; proc_listing[i]; i++)
|
for (int i = 0; proc_listing[i]; i++)
|
||||||
{
|
{
|
||||||
if (path_prefix_p (proc_listing[i], path, strlen (proc_listing[i])))
|
if (path_prefix_p (proc_listing[i], path, strlen (proc_listing[i]),
|
||||||
|
false))
|
||||||
return proc_fhandlers[i];
|
return proc_fhandlers[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ fhandler_proc::exists ()
|
|||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
return 2;
|
return 2;
|
||||||
for (int i = 0; proc_listing[i]; i++)
|
for (int i = 0; proc_listing[i]; i++)
|
||||||
if (pathmatch (path + 1, proc_listing[i]))
|
if (!strcmp (path + 1, proc_listing[i]))
|
||||||
{
|
{
|
||||||
fileid = i;
|
fileid = i;
|
||||||
return (proc_fhandlers[i] == FH_PROC) ? (i == PROC_SELF ? -2 : -1) : 1;
|
return (proc_fhandlers[i] == FH_PROC) ? (i == PROC_SELF ? -2 : -1) : 1;
|
||||||
@ -188,7 +189,7 @@ fhandler_proc::fstat (struct __stat64 *buf)
|
|||||||
{
|
{
|
||||||
path++;
|
path++;
|
||||||
for (int i = 0; proc_listing[i]; i++)
|
for (int i = 0; proc_listing[i]; i++)
|
||||||
if (pathmatch (path, proc_listing[i]))
|
if (!strcmp (path, proc_listing[i]))
|
||||||
{
|
{
|
||||||
if (proc_fhandlers[i] != FH_PROC)
|
if (proc_fhandlers[i] != FH_PROC)
|
||||||
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
@ -273,7 +274,8 @@ fhandler_proc::open (int flags, mode_t mode)
|
|||||||
|
|
||||||
proc_file_no = -1;
|
proc_file_no = -1;
|
||||||
for (int i = 0; proc_listing[i]; i++)
|
for (int i = 0; proc_listing[i]; i++)
|
||||||
if (path_prefix_p (proc_listing[i], path + 1, strlen (proc_listing[i])))
|
if (path_prefix_p (proc_listing[i], path + 1, strlen (proc_listing[i]),
|
||||||
|
false))
|
||||||
{
|
{
|
||||||
proc_file_no = i;
|
proc_file_no = i;
|
||||||
if (proc_fhandlers[i] != FH_PROC)
|
if (proc_fhandlers[i] != FH_PROC)
|
||||||
|
@ -107,12 +107,12 @@ fhandler_process::exists ()
|
|||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
for (int i = 0; process_listing[i]; i++)
|
for (int i = 0; process_listing[i]; i++)
|
||||||
if (pathmatch (path + 1, process_listing[i]))
|
if (!strcmp (path + 1, process_listing[i]))
|
||||||
{
|
{
|
||||||
fileid = i;
|
fileid = i;
|
||||||
return is_symlink (i) ? -2 : (i == PROCESS_FD) ? 1 : -1;
|
return is_symlink (i) ? -2 : (i == PROCESS_FD) ? 1 : -1;
|
||||||
}
|
}
|
||||||
if (pathnmatch (strchr (path, '/') + 1, "fd/", 3))
|
if (!strncmp (strchr (path, '/') + 1, "fd/", 3))
|
||||||
{
|
{
|
||||||
fileid = PROCESS_FD;
|
fileid = PROCESS_FD;
|
||||||
if (fill_filebuf ())
|
if (fill_filebuf ())
|
||||||
@ -270,8 +270,8 @@ fhandler_process::open (int flags, mode_t mode)
|
|||||||
process_file_no = -1;
|
process_file_no = -1;
|
||||||
for (int i = 0; process_listing[i]; i++)
|
for (int i = 0; process_listing[i]; i++)
|
||||||
{
|
{
|
||||||
if (path_prefix_p
|
if (path_prefix_p (process_listing[i], path + 1,
|
||||||
(process_listing[i], path + 1, strlen (process_listing[i])))
|
strlen (process_listing[i]), false))
|
||||||
process_file_no = i;
|
process_file_no = i;
|
||||||
}
|
}
|
||||||
if (process_file_no == -1)
|
if (process_file_no == -1)
|
||||||
|
@ -65,7 +65,7 @@ fhandler_procnet::exists ()
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for (int i = 0; process_listing[i]; i++)
|
for (int i = 0; process_listing[i]; i++)
|
||||||
if (pathmatch (path + 1, process_listing[i]))
|
if (!strcmp (path + 1, process_listing[i]))
|
||||||
{
|
{
|
||||||
if (i == PROCNET_IFINET6)
|
if (i == PROCNET_IFINET6)
|
||||||
{
|
{
|
||||||
@ -167,8 +167,8 @@ fhandler_procnet::open (int flags, mode_t mode)
|
|||||||
process_file_no = -1;
|
process_file_no = -1;
|
||||||
for (int i = 0; process_listing[i]; i++)
|
for (int i = 0; process_listing[i]; i++)
|
||||||
{
|
{
|
||||||
if (path_prefix_p
|
if (path_prefix_p (process_listing[i], path + 1,
|
||||||
(process_listing[i], path + 1, strlen (process_listing[i])))
|
strlen (process_listing[i]), false))
|
||||||
process_file_no = i;
|
process_file_no = i;
|
||||||
}
|
}
|
||||||
if (process_file_no == -1)
|
if (process_file_no == -1)
|
||||||
|
@ -117,8 +117,8 @@ fhandler_registry::exists ()
|
|||||||
if (file == path)
|
if (file == path)
|
||||||
{
|
{
|
||||||
for (int i = 0; registry_listing[i]; i++)
|
for (int i = 0; registry_listing[i]; i++)
|
||||||
if (path_prefix_p
|
if (path_prefix_p (registry_listing[i], path,
|
||||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
strlen (registry_listing[i]), true))
|
||||||
{
|
{
|
||||||
file_type = 1;
|
file_type = 1;
|
||||||
goto out;
|
goto out;
|
||||||
@ -140,7 +140,7 @@ fhandler_registry::exists ()
|
|||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
|| (error == ERROR_MORE_DATA))
|
|| (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (pathmatch (buf, file))
|
if (strcasematch (buf, file))
|
||||||
{
|
{
|
||||||
file_type = 1;
|
file_type = 1;
|
||||||
goto out;
|
goto out;
|
||||||
@ -159,8 +159,8 @@ fhandler_registry::exists ()
|
|||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
|| (error == ERROR_MORE_DATA))
|
|| (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (pathmatch (buf, file) || (buf[0] == '\0' &&
|
if (strcasematch (buf, file)
|
||||||
pathmatch (file, DEFAULT_VALUE_NAME)))
|
|| (buf[0] == '\0' && strcasematch (file, DEFAULT_VALUE_NAME)))
|
||||||
{
|
{
|
||||||
file_type = -1;
|
file_type = -1;
|
||||||
goto out;
|
goto out;
|
||||||
@ -461,8 +461,8 @@ fhandler_registry::open (int flags, mode_t mode)
|
|||||||
if (file == path)
|
if (file == path)
|
||||||
{
|
{
|
||||||
for (int i = 0; registry_listing[i]; i++)
|
for (int i = 0; registry_listing[i]; i++)
|
||||||
if (path_prefix_p
|
if (path_prefix_p (registry_listing[i], path,
|
||||||
(registry_listing[i], path, strlen (registry_listing[i])))
|
strlen (registry_listing[i]), true))
|
||||||
{
|
{
|
||||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||||
{
|
{
|
||||||
@ -520,7 +520,7 @@ fhandler_registry::open (int flags, mode_t mode)
|
|||||||
|
|
||||||
set_io_handle (handle);
|
set_io_handle (handle);
|
||||||
|
|
||||||
if (pathmatch (file, DEFAULT_VALUE_NAME))
|
if (strcasematch (file, DEFAULT_VALUE_NAME))
|
||||||
value_name = cstrdup ("");
|
value_name = cstrdup ("");
|
||||||
else
|
else
|
||||||
value_name = cstrdup (file);
|
value_name = cstrdup (file);
|
||||||
@ -631,7 +631,7 @@ value_not_found:
|
|||||||
(error = RegEnumKeyEx (handle, index++, buf, &buf_size, NULL, NULL,
|
(error = RegEnumKeyEx (handle, index++, buf, &buf_size, NULL, NULL,
|
||||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||||
{
|
{
|
||||||
if (pathmatch (buf, value_name))
|
if (strcasematch (buf, value_name))
|
||||||
{
|
{
|
||||||
set_errno (EISDIR);
|
set_errno (EISDIR);
|
||||||
return false;
|
return false;
|
||||||
@ -694,7 +694,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; registry_listing[i]; i++)
|
for (int i = 0; registry_listing[i]; i++)
|
||||||
if (pathmatch (component, registry_listing[i]))
|
if (strcasematch (component, registry_listing[i]))
|
||||||
hKey = registry_keys[i];
|
hKey = registry_keys[i];
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
return hKey;
|
return hKey;
|
||||||
|
@ -29,9 +29,9 @@ enum
|
|||||||
MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */
|
MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */
|
||||||
MOUNT_DEVFS = 0x0200, /* /device "filesystem" */
|
MOUNT_DEVFS = 0x0200, /* /device "filesystem" */
|
||||||
MOUNT_PROC = 0x0400, /* /proc "filesystem" */
|
MOUNT_PROC = 0x0400, /* /proc "filesystem" */
|
||||||
MOUNT_ENC = 0x0800, /* encode special characters */
|
|
||||||
MOUNT_RO = 0x1000, /* read-only "filesystem" */
|
MOUNT_RO = 0x1000, /* read-only "filesystem" */
|
||||||
MOUNT_NOACL = 0x2000 /* support reading/writing ACLs */
|
MOUNT_NOACL = 0x2000, /* support reading/writing ACLs */
|
||||||
|
MOUNT_NOPOSIX = 0x4000 /* Case insensitve path handling */
|
||||||
};
|
};
|
||||||
|
|
||||||
int mount (const char *, const char *, unsigned __flags);
|
int mount (const char *, const char *, unsigned __flags);
|
||||||
|
@ -841,7 +841,7 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
|
|||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
|
||||||
RtlInitUnicodeString (&fname, L"");
|
RtlInitUnicodeString (&fname, L"");
|
||||||
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
|
InitializeObjectAttributes (&attr, &fname, fh->pc.objcaseinsensitive (),
|
||||||
fh->get_handle (), NULL);
|
fh->get_handle (), NULL);
|
||||||
status = NtOpenFile (&h,
|
status = NtOpenFile (&h,
|
||||||
fh->get_access () | GENERIC_EXECUTE | SYNCHRONIZE,
|
fh->get_access () | GENERIC_EXECUTE | SYNCHRONIZE,
|
||||||
|
@ -32,7 +32,7 @@ details. */
|
|||||||
|
|
||||||
/* Determine if path prefix matches current cygdrive */
|
/* Determine if path prefix matches current cygdrive */
|
||||||
#define iscygdrive(path) \
|
#define iscygdrive(path) \
|
||||||
(path_prefix_p (mount_table->cygdrive, (path), mount_table->cygdrive_len))
|
(path_prefix_p (mount_table->cygdrive, (path), mount_table->cygdrive_len, false))
|
||||||
|
|
||||||
#define iscygdrive_device(path) \
|
#define iscygdrive_device(path) \
|
||||||
(isalpha (path[mount_table->cygdrive_len]) && \
|
(isalpha (path[mount_table->cygdrive_len]) && \
|
||||||
@ -40,7 +40,7 @@ details. */
|
|||||||
!path[mount_table->cygdrive_len + 1]))
|
!path[mount_table->cygdrive_len + 1]))
|
||||||
|
|
||||||
#define isproc(path) \
|
#define isproc(path) \
|
||||||
(path_prefix_p (proc, (path), proc_len))
|
(path_prefix_p (proc, (path), proc_len, false))
|
||||||
|
|
||||||
/* is_unc_share: Return non-zero if PATH begins with //server/share
|
/* is_unc_share: Return non-zero if PATH begins with //server/share
|
||||||
or with one of the native prefixes //./ or //?/
|
or with one of the native prefixes //./ or //?/
|
||||||
@ -150,161 +150,6 @@ set_flags (unsigned *flags, unsigned val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char dot_special_chars[] =
|
|
||||||
"."
|
|
||||||
"\001" "\002" "\003" "\004" "\005" "\006" "\007" "\010"
|
|
||||||
"\011" "\012" "\013" "\014" "\015" "\016" "\017" "\020"
|
|
||||||
"\021" "\022" "\023" "\024" "\025" "\026" "\027" "\030"
|
|
||||||
"\031" "\032" "\033" "\034" "\035" "\036" "\037" ":"
|
|
||||||
"\\" "*" "?" "%" "\"" "<" ">" "|"
|
|
||||||
"A" "B" "C" "D" "E" "F" "G" "H"
|
|
||||||
"I" "J" "K" "L" "M" "N" "O" "P"
|
|
||||||
"Q" "R" "S" "T" "U" "V" "W" "X"
|
|
||||||
"Y" "Z";
|
|
||||||
static char *special_chars = dot_special_chars + 1;
|
|
||||||
static char special_introducers[] =
|
|
||||||
"anpcl";
|
|
||||||
|
|
||||||
static char
|
|
||||||
special_char (const char *s, const char *valid_chars = special_chars)
|
|
||||||
{
|
|
||||||
if (*s != '%' || strlen (s) < 3)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
char *p;
|
|
||||||
char hex[] = {s[1], s[2], '\0'};
|
|
||||||
unsigned char c = strtoul (hex, &p, 16);
|
|
||||||
p = strechr (valid_chars, c);
|
|
||||||
return *p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determines if name is "special". Assumes that name is empty or "absolute" */
|
|
||||||
static int
|
|
||||||
special_name (const char *s, int inc = 1)
|
|
||||||
{
|
|
||||||
if (!*s)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
s += inc;
|
|
||||||
|
|
||||||
if (strcmp (s, ".") == 0 || strcmp (s, "..") == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int n;
|
|
||||||
const char *p = NULL;
|
|
||||||
if (ascii_strncasematch (s, "conin$", n = 5)
|
|
||||||
|| ascii_strncasematch (s, "conout$", n = 7)
|
|
||||||
|| ascii_strncasematch (s, "nul", n = 3)
|
|
||||||
|| ascii_strncasematch (s, "aux", 3)
|
|
||||||
|| ascii_strncasematch (s, "prn", 3)
|
|
||||||
|| ascii_strncasematch (s, "con", 3))
|
|
||||||
p = s + n;
|
|
||||||
else if (ascii_strncasematch (s, "com", 3)
|
|
||||||
|| ascii_strncasematch (s, "lpt", 3))
|
|
||||||
strtoul (s + 3, (char **) &p, 10);
|
|
||||||
if (p && (*p == '\0' || *p == '.'))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (strchr (s, '\0')[-1] == '.')
|
|
||||||
|| (strpbrk (s, special_chars) && !ascii_strncasematch (s, "%2f", 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
fnunmunge (char *dst, const char *src)
|
|
||||||
{
|
|
||||||
bool converted = false;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
if ((c = special_char (src, special_introducers)))
|
|
||||||
{
|
|
||||||
__small_sprintf (dst, "%c%s", c, src + 3);
|
|
||||||
if (special_name (dst, 0))
|
|
||||||
{
|
|
||||||
*dst++ = c;
|
|
||||||
src += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*src)
|
|
||||||
if (!(c = special_char (src, dot_special_chars)))
|
|
||||||
*dst++ = *src++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
converted = true;
|
|
||||||
*dst++ = c;
|
|
||||||
src += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dst = *src;
|
|
||||||
return converted;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
copy1 (char *&d, const char *&src, int& left)
|
|
||||||
{
|
|
||||||
left--;
|
|
||||||
if (left || !*src)
|
|
||||||
*d++ = *src++;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
copyenc (char *&d, const char *&src, int& left)
|
|
||||||
{
|
|
||||||
char buf[16];
|
|
||||||
int n = __small_sprintf (buf, "%%%02x", (unsigned char) *src++);
|
|
||||||
left -= n;
|
|
||||||
if (left <= 0)
|
|
||||||
return true;
|
|
||||||
strcpy (d, buf);
|
|
||||||
d += n;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
mount_item::fnmunge (char *dst, const char *src, int& left)
|
|
||||||
{
|
|
||||||
int name_type;
|
|
||||||
if (!(name_type = special_name (src)))
|
|
||||||
{
|
|
||||||
if ((int) strlen (src) >= left)
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
else
|
|
||||||
strcpy (dst, src);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *d = dst;
|
|
||||||
if (copy1 (d, src, left))
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
if (name_type < 0 && copyenc (d, src, left))
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
|
|
||||||
while (*src)
|
|
||||||
if (!strchr (special_chars, *src) || (*src == '%' && !special_char (src)))
|
|
||||||
{
|
|
||||||
if (copy1 (d, src, left))
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
}
|
|
||||||
else if (copyenc (d, src, left))
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
|
|
||||||
char dot[] = ".";
|
|
||||||
const char *p = dot;
|
|
||||||
if (*--d != '.')
|
|
||||||
d++;
|
|
||||||
else if (copyenc (d, p, left))
|
|
||||||
return ENAMETOOLONG;
|
|
||||||
|
|
||||||
*d = *src;
|
|
||||||
}
|
|
||||||
|
|
||||||
backslashify (dst, dst, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigned chroot_pathlen)
|
mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigned chroot_pathlen)
|
||||||
{
|
{
|
||||||
@ -328,37 +173,12 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne
|
|||||||
const char *p = src + real_posix_pathlen;
|
const char *p = src + real_posix_pathlen;
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
else if ((!(flags & MOUNT_ENC) && isdrive (dst) && !dst[2]) || *p)
|
else if ((isdrive (dst) && !dst[2]) || *p)
|
||||||
dst[n++] = '\\';
|
dst[n++] = '\\';
|
||||||
//if (!*p || !(flags & MOUNT_ENC))
|
|
||||||
//{
|
|
||||||
if ((n + strlen (p)) >= NT_MAX_PATH)
|
if ((n + strlen (p)) >= NT_MAX_PATH)
|
||||||
err = ENAMETOOLONG;
|
err = ENAMETOOLONG;
|
||||||
else
|
else
|
||||||
backslashify (p, dst + n, 0);
|
backslashify (p, dst + n, 0);
|
||||||
#if 0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int left = NT_MAX_PATH - n;
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
char slash = 0;
|
|
||||||
char *s = strchr (p + 1, '/');
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
slash = *s;
|
|
||||||
*s = '\0';
|
|
||||||
}
|
|
||||||
err = fnmunge (dst += n, p, left);
|
|
||||||
if (!s || err)
|
|
||||||
break;
|
|
||||||
n = strlen (dst);
|
|
||||||
*s = slash;
|
|
||||||
p = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +313,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_prefix_p (path, src_path, len))
|
if (path_prefix_p (path, src_path, len, mi->flags & MOUNT_NOPOSIX))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,7 +513,8 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
|||||||
for (int i = 0; i < nmounts; ++i)
|
for (int i = 0; i < nmounts; ++i)
|
||||||
{
|
{
|
||||||
mount_item &mi = mount[native_sorted[i]];
|
mount_item &mi = mount[native_sorted[i]];
|
||||||
if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen))
|
if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen,
|
||||||
|
mi.flags & MOUNT_NOPOSIX))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (cygheap->root.exists () && !cygheap->root.posix_ok (mi.posix_path))
|
if (cygheap->root.exists () && !cygheap->root.posix_ok (mi.posix_path))
|
||||||
@ -726,14 +547,6 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
|||||||
const char *p = cygheap->root.unchroot (posix_path);
|
const char *p = cygheap->root.unchroot (posix_path);
|
||||||
memmove (posix_path, p, strlen (p) + 1);
|
memmove (posix_path, p, strlen (p) + 1);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
if (mi.flags & MOUNT_ENC)
|
|
||||||
{
|
|
||||||
char *tmpbuf = tp.c_get ();
|
|
||||||
if (fnunmunge (tmpbuf, posix_path))
|
|
||||||
strcpy (posix_path, tmpbuf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +595,8 @@ mount_info::set_flags_from_win32_path (const char *p)
|
|||||||
for (int i = 0; i < nmounts; i++)
|
for (int i = 0; i < nmounts; i++)
|
||||||
{
|
{
|
||||||
mount_item &mi = mount[native_sorted[i]];
|
mount_item &mi = mount[native_sorted[i]];
|
||||||
if (path_prefix_p (mi.native_path, p, mi.native_pathlen))
|
if (path_prefix_p (mi.native_path, p, mi.native_pathlen,
|
||||||
|
mi.flags & MOUNT_NOPOSIX))
|
||||||
return mi.flags;
|
return mi.flags;
|
||||||
}
|
}
|
||||||
return PATH_BINARY;
|
return PATH_BINARY;
|
||||||
@ -831,9 +645,10 @@ struct opt
|
|||||||
{"notexec", MOUNT_NOTEXEC, 0},
|
{"notexec", MOUNT_NOTEXEC, 0},
|
||||||
{"cygexec", MOUNT_CYGWIN_EXEC, 0},
|
{"cygexec", MOUNT_CYGWIN_EXEC, 0},
|
||||||
{"nosuid", 0, 0},
|
{"nosuid", 0, 0},
|
||||||
{"managed", MOUNT_ENC, 0},
|
|
||||||
{"acl", MOUNT_NOACL, 1},
|
{"acl", MOUNT_NOACL, 1},
|
||||||
{"noacl", MOUNT_NOACL, 0}
|
{"noacl", MOUNT_NOACL, 0},
|
||||||
|
{"posix=1", MOUNT_NOPOSIX, 1},
|
||||||
|
{"posix=0", MOUNT_NOPOSIX, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1196,7 +1011,7 @@ mount_info::add_item (const char *native, const char *posix,
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nmounts; i++)
|
for (i = 0; i < nmounts; i++)
|
||||||
{
|
{
|
||||||
if (strcasematch (mount[i].posix_path, posixtmp))
|
if (!strcmp (mount[i].posix_path, posixtmp))
|
||||||
{
|
{
|
||||||
/* Don't allow to override a system mount with a user mount. */
|
/* Don't allow to override a system mount with a user mount. */
|
||||||
if ((mount[i].flags & MOUNT_SYSTEM) && !(mountflags & MOUNT_SYSTEM))
|
if ((mount[i].flags & MOUNT_SYSTEM) && !(mountflags & MOUNT_SYSTEM))
|
||||||
@ -1258,7 +1073,7 @@ mount_info::del_item (const char *path, unsigned flags)
|
|||||||
{
|
{
|
||||||
int ent = native_sorted[i]; /* in the same order as getmntent() */
|
int ent = native_sorted[i]; /* in the same order as getmntent() */
|
||||||
if (((posix_path_p)
|
if (((posix_path_p)
|
||||||
? strcasematch (mount[ent].posix_path, pathtmp)
|
? !strcmp (mount[ent].posix_path, pathtmp)
|
||||||
: strcasematch (mount[ent].native_path, pathtmp)))
|
: strcasematch (mount[ent].native_path, pathtmp)))
|
||||||
{
|
{
|
||||||
/* Don't allow to remove a system mount. */
|
/* Don't allow to remove a system mount. */
|
||||||
@ -1315,7 +1130,7 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
|||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
UNICODE_STRING unat;
|
UNICODE_STRING unat;
|
||||||
tp.u_get (&unat);
|
tp.u_get (&unat);
|
||||||
get_nt_native_path (native_path, unat, flags & MOUNT_ENC);
|
get_nt_native_path (native_path, unat);
|
||||||
if (append_bs)
|
if (append_bs)
|
||||||
RtlAppendUnicodeToString (&unat, L"\\");
|
RtlAppendUnicodeToString (&unat, L"\\");
|
||||||
mntinfo.update (&unat, NULL);
|
mntinfo.update (&unat, NULL);
|
||||||
@ -1352,12 +1167,13 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
|||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",exec");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",exec");
|
||||||
else if (flags & MOUNT_NOTEXEC)
|
else if (flags & MOUNT_NOTEXEC)
|
||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",noexec");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",noexec");
|
||||||
if (flags & MOUNT_ENC)
|
|
||||||
strcat (_my_tls.locals.mnt_opts, ",managed");
|
|
||||||
|
|
||||||
if (flags & MOUNT_NOACL)
|
if (flags & MOUNT_NOACL)
|
||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",noacl");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",noacl");
|
||||||
|
|
||||||
|
if (flags & MOUNT_NOPOSIX)
|
||||||
|
strcat (_my_tls.locals.mnt_opts, (char *) ",posix=0");
|
||||||
|
|
||||||
if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */
|
if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */
|
||||||
strcat (_my_tls.locals.mnt_opts, (char *) ",noumount");
|
strcat (_my_tls.locals.mnt_opts, (char *) ",noumount");
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ntdll.h>
|
#include <ntdll.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
bool dos_file_warning = true;
|
bool dos_file_warning = true;
|
||||||
|
|
||||||
@ -84,7 +85,6 @@ struct symlink_info
|
|||||||
int issymlink;
|
int issymlink;
|
||||||
bool ext_tacked_on;
|
bool ext_tacked_on;
|
||||||
int error;
|
int error;
|
||||||
bool case_clash;
|
|
||||||
bool isdevice;
|
bool isdevice;
|
||||||
_major_t major;
|
_major_t major;
|
||||||
_minor_t minor;
|
_minor_t minor;
|
||||||
@ -93,7 +93,6 @@ struct symlink_info
|
|||||||
fs_info &fs);
|
fs_info &fs);
|
||||||
int set (char *path);
|
int set (char *path);
|
||||||
bool parse_device (const char *);
|
bool parse_device (const char *);
|
||||||
bool case_check (char *path);
|
|
||||||
int check_sysfile (HANDLE h);
|
int check_sysfile (HANDLE h);
|
||||||
int check_shortcut (HANDLE h);
|
int check_shortcut (HANDLE h);
|
||||||
int check_reparse_point (HANDLE h);
|
int check_reparse_point (HANDLE h);
|
||||||
@ -104,8 +103,6 @@ struct symlink_info
|
|||||||
|
|
||||||
muto NO_COPY cwdstuff::cwd_lock;
|
muto NO_COPY cwdstuff::cwd_lock;
|
||||||
|
|
||||||
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
|
||||||
|
|
||||||
static const GUID GUID_shortcut
|
static const GUID GUID_shortcut
|
||||||
= { 0x00021401L, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0x46 };
|
= { 0x00021401L, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0x46 };
|
||||||
|
|
||||||
@ -154,7 +151,8 @@ struct win_shortcut_hdr
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
path_prefix_p (const char *path1, const char *path2, int len1)
|
path_prefix_p (const char *path1, const char *path2, int len1,
|
||||||
|
bool caseinsensitive)
|
||||||
{
|
{
|
||||||
/* Handle case where PATH1 has trailing '/' and when it doesn't. */
|
/* Handle case where PATH1 has trailing '/' and when it doesn't. */
|
||||||
if (len1 > 0 && isdirsep (path1[len1 - 1]))
|
if (len1 > 0 && isdirsep (path1[len1 - 1]))
|
||||||
@ -164,7 +162,8 @@ path_prefix_p (const char *path1, const char *path2, int len1)
|
|||||||
return isdirsep (path2[0]) && !isdirsep (path2[1]);
|
return isdirsep (path2[0]) && !isdirsep (path2[1]);
|
||||||
|
|
||||||
if (isdirsep (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':')
|
if (isdirsep (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':')
|
||||||
return pathnmatch (path1, path2, len1);
|
return caseinsensitive ? strncasematch (path1, path2, len1)
|
||||||
|
: !strncmp (path1, path2, len1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -172,19 +171,19 @@ path_prefix_p (const char *path1, const char *path2, int len1)
|
|||||||
/* Return non-zero if paths match in first len chars.
|
/* Return non-zero if paths match in first len chars.
|
||||||
Check is dependent of the case sensitivity setting. */
|
Check is dependent of the case sensitivity setting. */
|
||||||
int
|
int
|
||||||
pathnmatch (const char *path1, const char *path2, int len)
|
pathnmatch (const char *path1, const char *path2, int len, bool caseinsensitive)
|
||||||
{
|
{
|
||||||
return pcheck_case == PCHECK_STRICT ? !strncmp (path1, path2, len)
|
return caseinsensitive
|
||||||
: strncasematch (path1, path2, len);
|
? strncasematch (path1, path2, len) : !strncmp (path1, path2, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return non-zero if paths match. Check is dependent of the case
|
/* Return non-zero if paths match. Check is dependent of the case
|
||||||
sensitivity setting. */
|
sensitivity setting. */
|
||||||
int
|
int
|
||||||
pathmatch (const char *path1, const char *path2)
|
pathmatch (const char *path1, const char *path2, bool caseinsensitive)
|
||||||
{
|
{
|
||||||
return pcheck_case == PCHECK_STRICT ? !strcmp (path1, path2)
|
return caseinsensitive
|
||||||
: strcasematch (path1, path2);
|
? strcasematch (path1, path2) : !strcmp (path1, path2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: This function is used in mkdir and rmdir to generate correct
|
/* TODO: This function is used in mkdir and rmdir to generate correct
|
||||||
@ -326,9 +325,9 @@ path_conv::add_ext_from_sym (symlink_info &sym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __stdcall mkrelpath (char *dst) __attribute__ ((regparm (2)));
|
static void __stdcall mkrelpath (char *dst, bool caseinsensitive) __attribute__ ((regparm (2)));
|
||||||
static void __stdcall
|
static void __stdcall
|
||||||
mkrelpath (char *path)
|
mkrelpath (char *path, bool caseinsensitive)
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
char *cwd_win32 = tp.c_get ();
|
char *cwd_win32 = tp.c_get ();
|
||||||
@ -336,7 +335,7 @@ mkrelpath (char *path)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned cwdlen = strlen (cwd_win32);
|
unsigned cwdlen = strlen (cwd_win32);
|
||||||
if (!path_prefix_p (cwd_win32, path, cwdlen))
|
if (!path_prefix_p (cwd_win32, path, cwdlen, caseinsensitive))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size_t n = strlen (path);
|
size_t n = strlen (path);
|
||||||
@ -394,6 +393,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||||||
vol = in_vol;
|
vol = in_vol;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Always caseinsensitive. We really just need access to the drive. */
|
||||||
InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
|
InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
|
status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
|
||||||
@ -523,6 +523,12 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||||||
in fhandler.cc (fhandler_disk_file::open). */
|
in fhandler.cc (fhandler_disk_file::open). */
|
||||||
RtlInitUnicodeString (&testname, L"SUNWNFS");
|
RtlInitUnicodeString (&testname, L"SUNWNFS");
|
||||||
has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, FALSE));
|
has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, FALSE));
|
||||||
|
/* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
|
||||||
|
except on Samba which handles Windows clients case insensitive.
|
||||||
|
NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
|
||||||
|
sensitive. */
|
||||||
|
caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
|
||||||
|
&& !is_nfs ());
|
||||||
|
|
||||||
if (!in_vol)
|
if (!in_vol)
|
||||||
NtClose (vol);
|
NtClose (vol);
|
||||||
@ -581,34 +587,14 @@ WCHAR tfx_chars[] NO_COPY = {
|
|||||||
'x', 'y', 'z', '{', 0xf000 | '|', '}', '~', 127
|
'x', 'y', 'z', '{', 0xf000 | '|', '}', '~', 127
|
||||||
};
|
};
|
||||||
|
|
||||||
WCHAR tfx_chars_managed[] NO_COPY = {
|
|
||||||
0, 1, 2, 3, 4, 5, 6, 7,
|
|
||||||
8, 9, 10, 11, 12, 13, 14, 15,
|
|
||||||
16, 17, 18, 19, 20, 21, 22, 23,
|
|
||||||
24, 25, 26, 27, 28, 29, 30, 31,
|
|
||||||
32, '!', 0xf000 | '"', '#', '$', '%', '&', 39,
|
|
||||||
'(', ')', 0xf000 | '*', '+', ',', '-', '.', '/',
|
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
|
||||||
'8', '9', 0xf000 | ':', ';', 0xf000 | '<', '=', 0xf000 | '>', 0xf000 | '?',
|
|
||||||
'@', 0xf000 | 'A', 0xf000 | 'B', 0xf000 | 'C', 0xf000 | 'D', 0xf000 | 'E', 0xf000 | 'F', 0xf000 | 'G',
|
|
||||||
0xf000 | 'H', 0xf000 | 'I', 0xf000 | 'J', 0xf000 | 'K', 0xf000 | 'L', 0xf000 | 'M', 0xf000 | 'N', 0xf000 | 'O',
|
|
||||||
0xf000 | 'P', 0xf000 | 'Q', 0xf000 | 'R', 0xf000 | 'S', 0xf000 | 'T', 0xf000 | 'U', 0xf000 | 'V', 0xf000 | 'W',
|
|
||||||
0xf000 | 'X', 0xf000 | 'Y', 0xf000 | 'Z', '[', '\\', ']', '^', '_',
|
|
||||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
|
||||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
|
||||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
|
||||||
'x', 'y', 'z', '{', 0xf000 | '|', '}', '~', 127
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
transform_chars (PUNICODE_STRING upath, USHORT start_idx, bool managed)
|
transform_chars (PUNICODE_STRING upath, USHORT start_idx)
|
||||||
{
|
{
|
||||||
register PWCHAR buf = upath->Buffer;
|
register PWCHAR buf = upath->Buffer;
|
||||||
register PWCHAR end = buf + upath->Length / sizeof (WCHAR) - 1;
|
register PWCHAR end = buf + upath->Length / sizeof (WCHAR) - 1;
|
||||||
register PWCHAR tfx = managed ? tfx_chars_managed : tfx_chars;
|
|
||||||
for (buf += start_idx; buf <= end; ++buf)
|
for (buf += start_idx; buf <= end; ++buf)
|
||||||
if (*buf < 128)
|
if (*buf < 128)
|
||||||
*buf = tfx[*buf];
|
*buf = tfx_chars[*buf];
|
||||||
#if 0
|
#if 0
|
||||||
/* Win32 can't handle trailing dots and spaces. Transform the last of them
|
/* Win32 can't handle trailing dots and spaces. Transform the last of them
|
||||||
to the private use area, too, to create a valid Win32 filename. */
|
to the private use area, too, to create a valid Win32 filename. */
|
||||||
@ -620,7 +606,7 @@ transform_chars (PUNICODE_STRING upath, USHORT start_idx, bool managed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PUNICODE_STRING
|
PUNICODE_STRING
|
||||||
get_nt_native_path (const char *path, UNICODE_STRING& upath, bool managed)
|
get_nt_native_path (const char *path, UNICODE_STRING& upath)
|
||||||
{
|
{
|
||||||
upath.Length = 0;
|
upath.Length = 0;
|
||||||
if (path[0] == '/') /* special path w/o NT path representation. */
|
if (path[0] == '/') /* special path w/o NT path representation. */
|
||||||
@ -628,9 +614,15 @@ get_nt_native_path (const char *path, UNICODE_STRING& upath, bool managed)
|
|||||||
else if (path[0] != '\\') /* X:\... or relative path. */
|
else if (path[0] != '\\') /* X:\... or relative path. */
|
||||||
{
|
{
|
||||||
if (path[1] == ':') /* X:\... */
|
if (path[1] == ':') /* X:\... */
|
||||||
|
{
|
||||||
str2uni_cat (upath, "\\??\\");
|
str2uni_cat (upath, "\\??\\");
|
||||||
str2uni_cat (upath, path);
|
str2uni_cat (upath, path);
|
||||||
transform_chars (&upath, 7, managed);
|
/* The drive letter must be upper case. */
|
||||||
|
upath.Buffer[4] = towupper (upath.Buffer[4]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
str2uni_cat (upath, path);
|
||||||
|
transform_chars (&upath, 7);
|
||||||
}
|
}
|
||||||
else if (path[1] != '\\') /* \Device\... */
|
else if (path[1] != '\\') /* \Device\... */
|
||||||
str2uni_cat (upath, path);
|
str2uni_cat (upath, path);
|
||||||
@ -639,7 +631,7 @@ get_nt_native_path (const char *path, UNICODE_STRING& upath, bool managed)
|
|||||||
{
|
{
|
||||||
str2uni_cat (upath, "\\??\\UNC\\");
|
str2uni_cat (upath, "\\??\\UNC\\");
|
||||||
str2uni_cat (upath, path + 2);
|
str2uni_cat (upath, path + 2);
|
||||||
transform_chars (&upath, 8, managed);
|
transform_chars (&upath, 8);
|
||||||
}
|
}
|
||||||
else /* \\.\device or \\?\foo */
|
else /* \\.\device or \\?\foo */
|
||||||
{
|
{
|
||||||
@ -658,7 +650,7 @@ path_conv::get_nt_native_path ()
|
|||||||
uni_path.MaximumLength = (strlen (path) + 10) * sizeof (WCHAR);
|
uni_path.MaximumLength = (strlen (path) + 10) * sizeof (WCHAR);
|
||||||
wide_path = (PWCHAR) cmalloc_abort (HEAP_STR, uni_path.MaximumLength);
|
wide_path = (PWCHAR) cmalloc_abort (HEAP_STR, uni_path.MaximumLength);
|
||||||
uni_path.Buffer = wide_path;
|
uni_path.Buffer = wide_path;
|
||||||
::get_nt_native_path (path, uni_path, isencoded ());
|
::get_nt_native_path (path, uni_path);
|
||||||
}
|
}
|
||||||
return &uni_path;
|
return &uni_path;
|
||||||
}
|
}
|
||||||
@ -669,7 +661,7 @@ path_conv::get_object_attr (OBJECT_ATTRIBUTES &attr, SECURITY_ATTRIBUTES &sa)
|
|||||||
if (!get_nt_native_path ())
|
if (!get_nt_native_path ())
|
||||||
return NULL;
|
return NULL;
|
||||||
InitializeObjectAttributes (&attr, &uni_path,
|
InitializeObjectAttributes (&attr, &uni_path,
|
||||||
OBJ_CASE_INSENSITIVE
|
objcaseinsensitive ()
|
||||||
| (sa.bInheritHandle ? OBJ_INHERIT : 0),
|
| (sa.bInheritHandle ? OBJ_INHERIT : 0),
|
||||||
NULL, sa.lpSecurityDescriptor);
|
NULL, sa.lpSecurityDescriptor);
|
||||||
return &attr;
|
return &attr;
|
||||||
@ -708,7 +700,7 @@ warn_msdos (const char *src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
static DWORD
|
||||||
getfileattr (const char *path, bool managed) /* path has to be always absolute. */
|
getfileattr (const char *path, bool caseinsensitive) /* path has to be always absolute. */
|
||||||
{
|
{
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
UNICODE_STRING upath;
|
UNICODE_STRING upath;
|
||||||
@ -718,8 +710,10 @@ getfileattr (const char *path, bool managed) /* path has to be always absolute.
|
|||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
|
|
||||||
tp.u_get (&upath);
|
tp.u_get (&upath);
|
||||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &upath,
|
||||||
get_nt_native_path (path, upath, managed);
|
caseinsensitive ? OBJ_CASE_INSENSITIVE : 0,
|
||||||
|
NULL, NULL);
|
||||||
|
get_nt_native_path (path, upath);
|
||||||
|
|
||||||
status = NtQueryAttributesFile (&attr, &fbi);
|
status = NtQueryAttributesFile (&attr, &fbi);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
@ -736,7 +730,8 @@ getfileattr (const char *path, bool managed) /* path has to be always absolute.
|
|||||||
|
|
||||||
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
||||||
InitializeObjectAttributes (&attr, &dirname,
|
InitializeObjectAttributes (&attr, &dirname,
|
||||||
OBJ_CASE_INSENSITIVE, NULL, NULL);
|
caseinsensitive ? OBJ_CASE_INSENSITIVE : 0,
|
||||||
|
NULL, NULL);
|
||||||
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT
|
FILE_SYNCHRONOUS_IO_NONALERT
|
||||||
@ -825,10 +820,10 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
path_flags = 0;
|
path_flags = 0;
|
||||||
known_suffix = NULL;
|
known_suffix = NULL;
|
||||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||||
|
caseinsensitive = OBJ_CASE_INSENSITIVE;
|
||||||
if (wide_path)
|
if (wide_path)
|
||||||
cfree (wide_path);
|
cfree (wide_path);
|
||||||
wide_path = NULL;
|
wide_path = NULL;
|
||||||
case_clash = false;
|
|
||||||
memset (&dev, 0, sizeof (dev));
|
memset (&dev, 0, sizeof (dev));
|
||||||
fs.clear ();
|
fs.clear ();
|
||||||
if (!normalized_path_size && normalized_path)
|
if (!normalized_path_size && normalized_path)
|
||||||
@ -918,7 +913,8 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fileattr = getfileattr (this->path, sym.pflags & MOUNT_ENC);
|
fileattr = getfileattr (this->path,
|
||||||
|
sym.pflags & MOUNT_NOPOSIX);
|
||||||
dev.devn = FH_FS;
|
dev.devn = FH_FS;
|
||||||
}
|
}
|
||||||
goto out;
|
goto out;
|
||||||
@ -927,7 +923,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
{
|
{
|
||||||
dev.devn = FH_FS;
|
dev.devn = FH_FS;
|
||||||
#if 0
|
#if 0
|
||||||
fileattr = getfileattr (this->path, sym.pflags & MOUNT_ENC);
|
fileattr = getfileattr (this->path, sym.pflags & MOUNT_NOPOSIX);
|
||||||
if (!component && fileattr == INVALID_FILE_ATTRIBUTES)
|
if (!component && fileattr == INVALID_FILE_ATTRIBUTES)
|
||||||
{
|
{
|
||||||
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
fileattr = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY;
|
||||||
@ -1031,27 +1027,14 @@ is_virtual_symlink:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym.case_clash)
|
|
||||||
{
|
|
||||||
if (pcheck_case == PCHECK_STRICT)
|
|
||||||
{
|
|
||||||
case_clash = true;
|
|
||||||
error = ENOENT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/* If pcheck_case==PCHECK_ADJUST the case_clash is remembered
|
|
||||||
if the last component is concerned. This allows functions
|
|
||||||
which shall create files to avoid overriding already existing
|
|
||||||
files with another case. */
|
|
||||||
if (!component)
|
|
||||||
case_clash = true;
|
|
||||||
}
|
|
||||||
if (!(opt & PC_SYM_IGNORE))
|
|
||||||
{
|
|
||||||
if (!component)
|
if (!component)
|
||||||
{
|
{
|
||||||
fileattr = sym.fileattr;
|
fileattr = sym.fileattr;
|
||||||
path_flags = sym.pflags;
|
path_flags = sym.pflags;
|
||||||
|
if (cygwin_shared->obcaseinsensitive || fs.caseinsensitive ())
|
||||||
|
path_flags |= PATH_NOPOSIX;
|
||||||
|
caseinsensitive = (path_flags & PATH_NOPOSIX)
|
||||||
|
? OBJ_CASE_INSENSITIVE : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If symlink.check found an existing non-symlink file, then
|
/* If symlink.check found an existing non-symlink file, then
|
||||||
@ -1067,11 +1050,7 @@ is_virtual_symlink:
|
|||||||
error = ENOTDIR;
|
error = ENOTDIR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (pcheck_case == PCHECK_RELAXED)
|
|
||||||
goto out; // file found
|
goto out; // file found
|
||||||
/* Avoid further symlink evaluation. Only case checks are
|
|
||||||
done now. */
|
|
||||||
opt |= PC_SYM_IGNORE;
|
|
||||||
}
|
}
|
||||||
/* Found a symlink if symlen > 0. If component == 0, then the
|
/* Found a symlink if symlen > 0. If component == 0, then the
|
||||||
src path itself was a symlink. If !follow_mode then
|
src path itself was a symlink. If !follow_mode then
|
||||||
@ -1090,11 +1069,7 @@ is_virtual_symlink:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
add_ext_from_sym (sym);
|
add_ext_from_sym (sym);
|
||||||
if (pcheck_case == PCHECK_RELAXED)
|
|
||||||
goto out;
|
goto out;
|
||||||
/* Avoid further symlink evaluation. Only case checks are
|
|
||||||
done now. */
|
|
||||||
opt |= PC_SYM_IGNORE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@ -1105,7 +1080,6 @@ is_virtual_symlink:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* No existing file found. */
|
/* No existing file found. */
|
||||||
}
|
|
||||||
|
|
||||||
virtual_component_retry:
|
virtual_component_retry:
|
||||||
/* Find the new "tail" of the path, e.g. in '/for/bar/baz',
|
/* Find the new "tail" of the path, e.g. in '/for/bar/baz',
|
||||||
@ -1246,7 +1220,7 @@ out:
|
|||||||
if (opt & PC_NOFULL)
|
if (opt & PC_NOFULL)
|
||||||
{
|
{
|
||||||
if (is_relpath)
|
if (is_relpath)
|
||||||
mkrelpath (this->path);
|
mkrelpath (this->path, !!caseinsensitive);
|
||||||
if (need_directory)
|
if (need_directory)
|
||||||
{
|
{
|
||||||
size_t n = strlen (this->path);
|
size_t n = strlen (this->path);
|
||||||
@ -1587,7 +1561,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||||||
|
|
||||||
if (win32_newpath.error)
|
if (win32_newpath.error)
|
||||||
{
|
{
|
||||||
set_errno (win32_newpath.case_clash ? ECASECLASH : win32_newpath.error);
|
set_errno (win32_newpath.error);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2334,7 +2308,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
|||||||
minor = 0;
|
minor = 0;
|
||||||
mode = 0;
|
mode = 0;
|
||||||
pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
|
pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
|
||||||
case_clash = false;
|
ULONG ci_flag = cygwin_shared->obcaseinsensitive || (pflags & PATH_NOPOSIX)
|
||||||
|
? OBJ_CASE_INSENSITIVE : 0;
|
||||||
|
|
||||||
/* TODO: Temporarily do all char->UNICODE conversion here. This should
|
/* TODO: Temporarily do all char->UNICODE conversion here. This should
|
||||||
already be slightly faster than using Ascii functions. */
|
already be slightly faster than using Ascii functions. */
|
||||||
@ -2342,7 +2317,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
|||||||
UNICODE_STRING upath;
|
UNICODE_STRING upath;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
tp.u_get (&upath);
|
tp.u_get (&upath);
|
||||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &upath, ci_flag, NULL, NULL);
|
||||||
|
|
||||||
PVOID eabuf = &nfs_aol_ffei;
|
PVOID eabuf = &nfs_aol_ffei;
|
||||||
ULONG easize = sizeof nfs_aol_ffei;
|
ULONG easize = sizeof nfs_aol_ffei;
|
||||||
@ -2355,7 +2330,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
|||||||
bool no_ea = false;
|
bool no_ea = false;
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
get_nt_native_path (suffix.path, upath, pflags & MOUNT_ENC);
|
get_nt_native_path (suffix.path, upath);
|
||||||
if (h)
|
if (h)
|
||||||
{
|
{
|
||||||
NtClose (h);
|
NtClose (h);
|
||||||
@ -2434,8 +2409,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
|||||||
} fdi_buf;
|
} fdi_buf;
|
||||||
|
|
||||||
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
RtlSplitUnicodePath (&upath, &dirname, &basename);
|
||||||
InitializeObjectAttributes (&dattr, &dirname,
|
InitializeObjectAttributes (&dattr, &dirname, ci_flag,
|
||||||
OBJ_CASE_INSENSITIVE, NULL, NULL);
|
NULL, NULL);
|
||||||
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
&dattr, &io, FILE_SHARE_VALID_FLAGS,
|
&dattr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT
|
FILE_SYNCHRONOUS_IO_NONALERT
|
||||||
@ -2475,10 +2450,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
|
|||||||
|
|
||||||
ext_tacked_on = !!*ext_here;
|
ext_tacked_on = !!*ext_here;
|
||||||
|
|
||||||
if (pcheck_case != PCHECK_RELAXED && !case_check (path)
|
|
||||||
|| (opt & PC_SYM_IGNORE))
|
|
||||||
goto file_not_symlink;
|
|
||||||
|
|
||||||
res = -1;
|
res = -1;
|
||||||
|
|
||||||
/* Windows shortcuts are potentially treated as symlinks. Valid Cygwin
|
/* Windows shortcuts are potentially treated as symlinks. Valid Cygwin
|
||||||
@ -2569,54 +2540,12 @@ symlink_info::set (char *path)
|
|||||||
error = 0;
|
error = 0;
|
||||||
issymlink = true;
|
issymlink = true;
|
||||||
isdevice = false;
|
isdevice = false;
|
||||||
ext_tacked_on = case_clash = false;
|
ext_tacked_on = false;
|
||||||
ext_here = NULL;
|
ext_here = NULL;
|
||||||
extn = major = minor = mode = 0;
|
extn = major = minor = mode = 0;
|
||||||
return strlen (path);
|
return strlen (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the correct case of the last path component (given in DOS style).
|
|
||||||
Adjust the case in this->path if pcheck_case == PCHECK_ADJUST or return
|
|
||||||
false if pcheck_case == PCHECK_STRICT.
|
|
||||||
Dont't call if pcheck_case == PCHECK_RELAXED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
symlink_info::case_check (char *path)
|
|
||||||
{
|
|
||||||
WIN32_FIND_DATA data;
|
|
||||||
HANDLE h;
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
/* Set a pointer to the beginning of the last component. */
|
|
||||||
if (!(c = strrchr (path, '\\')))
|
|
||||||
c = path;
|
|
||||||
else
|
|
||||||
++c;
|
|
||||||
|
|
||||||
if ((h = FindFirstFile (path, &data))
|
|
||||||
!= INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
FindClose (h);
|
|
||||||
|
|
||||||
/* If that part of the component exists, check the case. */
|
|
||||||
if (strncmp (c, data.cFileName, strlen (data.cFileName)))
|
|
||||||
{
|
|
||||||
case_clash = true;
|
|
||||||
|
|
||||||
/* If check is set to STRICT, a wrong case results
|
|
||||||
in returning a ENOENT. */
|
|
||||||
if (pcheck_case == PCHECK_STRICT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* PCHECK_ADJUST adjusts the case in the incoming
|
|
||||||
path which points to the path in *this. */
|
|
||||||
strcpy (c, data.cFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* readlink system call */
|
/* readlink system call */
|
||||||
|
|
||||||
extern "C" ssize_t
|
extern "C" ssize_t
|
||||||
@ -3267,6 +3196,7 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit)
|
|||||||
phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
|
phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
|
||||||
if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */
|
if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */
|
||||||
RtlInitUnicodeString (&upath, L"");
|
RtlInitUnicodeString (&upath, L"");
|
||||||
|
/* This is for Win32 apps only. No case sensitivity here... */
|
||||||
InitializeObjectAttributes (&attr, &upath,
|
InitializeObjectAttributes (&attr, &upath,
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
|
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
|
||||||
nat_cwd ? NULL : *phdl, NULL);
|
nat_cwd ? NULL : *phdl, NULL);
|
||||||
@ -3461,7 +3391,7 @@ OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1];
|
|||||||
LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
|
LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
|
||||||
|
|
||||||
int
|
int
|
||||||
etc::init (int n, PUNICODE_STRING etc_fn)
|
etc::init (int n, path_conv &pc)
|
||||||
{
|
{
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
/* ok */;
|
/* ok */;
|
||||||
@ -3470,7 +3400,7 @@ etc::init (int n, PUNICODE_STRING etc_fn)
|
|||||||
else
|
else
|
||||||
api_fatal ("internal error");
|
api_fatal ("internal error");
|
||||||
|
|
||||||
InitializeObjectAttributes (&fn[n], etc_fn, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
pc.get_object_attr (fn[n], sec_none_nih);
|
||||||
change_possible[n] = false;
|
change_possible[n] = false;
|
||||||
test_file_change (n);
|
test_file_change (n);
|
||||||
paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix);
|
paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix);
|
||||||
|
@ -49,7 +49,6 @@ enum pathconv_arg
|
|||||||
{
|
{
|
||||||
PC_SYM_FOLLOW = 0x0001,
|
PC_SYM_FOLLOW = 0x0001,
|
||||||
PC_SYM_NOFOLLOW = 0x0002,
|
PC_SYM_NOFOLLOW = 0x0002,
|
||||||
PC_SYM_IGNORE = 0x0004,
|
|
||||||
PC_SYM_CONTENTS = 0x0008,
|
PC_SYM_CONTENTS = 0x0008,
|
||||||
PC_NOFULL = 0x0010,
|
PC_NOFULL = 0x0010,
|
||||||
PC_NULLEMPTY = 0x0020,
|
PC_NULLEMPTY = 0x0020,
|
||||||
@ -59,13 +58,6 @@ enum pathconv_arg
|
|||||||
PC_NO_ACCESS_CHECK = 0x00800000
|
PC_NO_ACCESS_CHECK = 0x00800000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum case_checking
|
|
||||||
{
|
|
||||||
PCHECK_RELAXED = 0,
|
|
||||||
PCHECK_ADJUST = 1,
|
|
||||||
PCHECK_STRICT = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PC_NONULLEMPTY -1
|
#define PC_NONULLEMPTY -1
|
||||||
|
|
||||||
#include "sys/mount.h"
|
#include "sys/mount.h"
|
||||||
@ -78,9 +70,9 @@ enum path_types
|
|||||||
PATH_EXEC = MOUNT_EXEC,
|
PATH_EXEC = MOUNT_EXEC,
|
||||||
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
||||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||||
PATH_ENC = MOUNT_ENC,
|
|
||||||
PATH_RO = MOUNT_RO,
|
PATH_RO = MOUNT_RO,
|
||||||
PATH_NOACL = MOUNT_NOACL,
|
PATH_NOACL = MOUNT_NOACL,
|
||||||
|
PATH_NOPOSIX = MOUNT_NOPOSIX,
|
||||||
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
||||||
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
|
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
|
||||||
PATH_LNK = 0x01000000,
|
PATH_LNK = 0x01000000,
|
||||||
@ -103,6 +95,7 @@ struct fs_info
|
|||||||
unsigned has_buggy_open : 1;
|
unsigned has_buggy_open : 1;
|
||||||
unsigned has_acls : 1;
|
unsigned has_acls : 1;
|
||||||
unsigned hasgood_inode : 1;
|
unsigned hasgood_inode : 1;
|
||||||
|
unsigned caseinsensitive : 1;
|
||||||
unsigned is_fat : 1;
|
unsigned is_fat : 1;
|
||||||
unsigned is_ntfs : 1;
|
unsigned is_ntfs : 1;
|
||||||
unsigned is_samba : 1;
|
unsigned is_samba : 1;
|
||||||
@ -122,6 +115,7 @@ struct fs_info
|
|||||||
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
|
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, has_acls)
|
IMPLEMENT_STATUS_FLAG (bool, has_acls)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
|
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
|
||||||
|
IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_fat)
|
IMPLEMENT_STATUS_FLAG (bool, is_fat)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
|
IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
|
||||||
IMPLEMENT_STATUS_FLAG (bool, is_samba)
|
IMPLEMENT_STATUS_FLAG (bool, is_samba)
|
||||||
@ -136,6 +130,7 @@ struct fs_info
|
|||||||
class path_conv
|
class path_conv
|
||||||
{
|
{
|
||||||
DWORD fileattr;
|
DWORD fileattr;
|
||||||
|
ULONG caseinsensitive;
|
||||||
fs_info fs;
|
fs_info fs;
|
||||||
PWCHAR wide_path;
|
PWCHAR wide_path;
|
||||||
UNICODE_STRING uni_path;
|
UNICODE_STRING uni_path;
|
||||||
@ -146,15 +141,14 @@ class path_conv
|
|||||||
char *known_suffix;
|
char *known_suffix;
|
||||||
int error;
|
int error;
|
||||||
device dev;
|
device dev;
|
||||||
bool case_clash;
|
|
||||||
|
|
||||||
bool isremote () const {return fs.is_remote_drive ();}
|
bool isremote () const {return fs.is_remote_drive ();}
|
||||||
|
ULONG objcaseinsensitive () const {return caseinsensitive;}
|
||||||
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
|
bool has_acls () const {return !(path_flags & PATH_NOACL) && fs.has_acls (); }
|
||||||
bool hasgood_inode () const {return fs.hasgood_inode (); }
|
bool hasgood_inode () const {return fs.hasgood_inode (); }
|
||||||
bool isgood_inode (__ino64_t ino) const;
|
bool isgood_inode (__ino64_t ino) const;
|
||||||
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
|
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
|
||||||
int has_buggy_open () const {return fs.has_buggy_open ();}
|
int has_buggy_open () const {return fs.has_buggy_open ();}
|
||||||
bool isencoded () const {return path_flags & PATH_ENC;}
|
|
||||||
int binmode () const
|
int binmode () const
|
||||||
{
|
{
|
||||||
if (path_flags & PATH_BINARY)
|
if (path_flags & PATH_BINARY)
|
||||||
@ -333,18 +327,17 @@ has_exec_chars (const char *buf, int len)
|
|||||||
(buf[0] == 'M' && buf[1] == 'Z'));
|
(buf[0] == 'M' && buf[1] == 'Z'));
|
||||||
}
|
}
|
||||||
|
|
||||||
int pathmatch (const char *path1, const char *path2) __attribute__ ((regparm (2)));
|
int pathmatch (const char *path1, const char *path2, bool caseinsensitive) __attribute__ ((regparm (3)));
|
||||||
int pathnmatch (const char *path1, const char *path2, int len) __attribute__ ((regparm (2)));
|
int pathnmatch (const char *path1, const char *path2, int len, bool caseinsensitive) __attribute__ ((regparm (3)));
|
||||||
bool has_dot_last_component (const char *dir, bool test_dot_dot) __attribute__ ((regparm (2)));
|
bool has_dot_last_component (const char *dir, bool test_dot_dot) __attribute__ ((regparm (2)));
|
||||||
|
|
||||||
bool fnunmunge (char *, const char *) __attribute__ ((regparm (2)));
|
int path_prefix_p (const char *path1, const char *path2, int len1,
|
||||||
|
bool caseinsensitive) __attribute__ ((regparm (3)));
|
||||||
int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
|
|
||||||
|
|
||||||
bool is_floppy (const char *);
|
bool is_floppy (const char *);
|
||||||
int normalize_win32_path (const char *, char *, char *&);
|
int normalize_win32_path (const char *, char *, char *&);
|
||||||
int normalize_posix_path (const char *, char *, char *&);
|
int normalize_posix_path (const char *, char *, char *&);
|
||||||
PUNICODE_STRING get_nt_native_path (const char *, UNICODE_STRING&, bool);
|
PUNICODE_STRING get_nt_native_path (const char *, UNICODE_STRING&);
|
||||||
|
|
||||||
/* FIXME: Move to own include file eventually */
|
/* FIXME: Move to own include file eventually */
|
||||||
|
|
||||||
@ -358,7 +351,7 @@ class etc
|
|||||||
static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
|
static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
|
||||||
static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];
|
static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];
|
||||||
static bool dir_changed (int);
|
static bool dir_changed (int);
|
||||||
static int init (int, PUNICODE_STRING);
|
static int init (int, path_conv &pc);
|
||||||
static bool file_changed (int);
|
static bool file_changed (int);
|
||||||
static bool test_file_change (int);
|
static bool test_file_change (int);
|
||||||
friend class pwdgrp;
|
friend class pwdgrp;
|
||||||
|
@ -240,6 +240,25 @@ user_shared_initialize (bool reinit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize obcaseinsensitive. Default to case insensitive on pre-XP. */
|
||||||
|
void
|
||||||
|
shared_info::init_obcaseinsensitive ()
|
||||||
|
{
|
||||||
|
HKEY key;
|
||||||
|
DWORD size = sizeof (DWORD);
|
||||||
|
|
||||||
|
obcaseinsensitive = 1;
|
||||||
|
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
||||||
|
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\kernel",
|
||||||
|
0, KEY_READ, &key) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegQueryValueEx (key, "obcaseinsensitive", NULL, NULL,
|
||||||
|
(LPBYTE) &obcaseinsensitive, &size);
|
||||||
|
RegCloseKey (key);
|
||||||
|
}
|
||||||
|
debug_printf ("obcaseinsensitive set to %d", obcaseinsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
shared_info::initialize ()
|
shared_info::initialize ()
|
||||||
{
|
{
|
||||||
@ -260,8 +279,10 @@ shared_info::initialize ()
|
|||||||
|
|
||||||
if (!sversion)
|
if (!sversion)
|
||||||
{
|
{
|
||||||
|
|
||||||
tty.init (); /* Initialize tty table. */
|
tty.init (); /* Initialize tty table. */
|
||||||
mt.initialize (); /* Initialize shared tape information. */
|
mt.initialize (); /* Initialize shared tape information. */
|
||||||
|
init_obcaseinsensitive ();/* Initialize obcaseinsensitive. */
|
||||||
cb = sizeof (*this); /* Do last, after all shared memory initialization */
|
cb = sizeof (*this); /* Do last, after all shared memory initialization */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ class mount_item
|
|||||||
void init (const char *dev, const char *path, unsigned flags);
|
void init (const char *dev, const char *path, unsigned flags);
|
||||||
|
|
||||||
struct mntent *getmntent ();
|
struct mntent *getmntent ();
|
||||||
int fnmunge (char *, const char *, int&);
|
|
||||||
int build_win32 (char *, const char *, unsigned *, unsigned);
|
int build_win32 (char *, const char *, unsigned *, unsigned);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +119,7 @@ public:
|
|||||||
|
|
||||||
#define SHARED_INFO_CB 31136
|
#define SHARED_INFO_CB 31136
|
||||||
|
|
||||||
#define CURR_SHARED_MAGIC 0xace17c0fU
|
#define CURR_SHARED_MAGIC 0x18da899eU
|
||||||
|
|
||||||
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
/* NOTE: Do not make gratuitous changes to the names or organization of the
|
||||||
below class. The layout is checksummed to determine compatibility between
|
below class. The layout is checksummed to determine compatibility between
|
||||||
@ -136,10 +135,11 @@ class shared_info
|
|||||||
DWORD sys_mount_table_counter;
|
DWORD sys_mount_table_counter;
|
||||||
tty_list tty;
|
tty_list tty;
|
||||||
LONG last_used_bindresvport;
|
LONG last_used_bindresvport;
|
||||||
DWORD obcaseinsensitivity;
|
DWORD obcaseinsensitive;
|
||||||
mtinfo mt;
|
mtinfo mt;
|
||||||
|
|
||||||
void initialize ();
|
void initialize ();
|
||||||
|
void init_obcaseinsensitive ();
|
||||||
unsigned heap_chunk_size ();
|
unsigned heap_chunk_size ();
|
||||||
unsigned heap_slop_size ();
|
unsigned heap_slop_size ();
|
||||||
};
|
};
|
||||||
|
@ -197,7 +197,7 @@ try_to_bin (path_conv &win32_path, HANDLE h)
|
|||||||
RtlSplitUnicodePath (win32_path.get_nt_native_path (), &root, NULL);
|
RtlSplitUnicodePath (win32_path.get_nt_native_path (), &root, NULL);
|
||||||
root.Length -= fname.Length - sizeof (WCHAR);
|
root.Length -= fname.Length - sizeof (WCHAR);
|
||||||
|
|
||||||
/* Open root directory. */
|
/* Open root directory. All recycler bin ops are caseinsensitive. */
|
||||||
InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE, NULL, NULL);
|
||||||
status = NtOpenFile (&rootdir, FILE_TRAVERSE, &attr, &io,
|
status = NtOpenFile (&rootdir, FILE_TRAVERSE, &attr, &io,
|
||||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||||
@ -1602,13 +1602,13 @@ rename (const char *oldpath, const char *newpath)
|
|||||||
/* This test is necessary in almost every case, so just do it once here. */
|
/* This test is necessary in almost every case, so just do it once here. */
|
||||||
equal_path = RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
equal_path = RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
||||||
newpc.get_nt_native_path (),
|
newpc.get_nt_native_path (),
|
||||||
TRUE);
|
oldpc.objcaseinsensitive ());
|
||||||
|
|
||||||
/* First check if oldpath and newpath only differ by case. If so, it's
|
/* First check if oldpath and newpath only differ by case. If so, it's
|
||||||
just a request to change the case of the filename. By simply setting
|
just a request to change the case of the filename. By simply setting
|
||||||
the file attributes to INVALID_FILE_ATTRIBUTES (which translates to
|
the file attributes to INVALID_FILE_ATTRIBUTES (which translates to
|
||||||
"file doesn't exist"), all later tests are skipped. */
|
"file doesn't exist"), all later tests are skipped. */
|
||||||
if (newpc.exists () && equal_path)
|
if (oldpc.objcaseinsensitive () && newpc.exists () && equal_path)
|
||||||
{
|
{
|
||||||
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
||||||
newpc.get_nt_native_path (),
|
newpc.get_nt_native_path (),
|
||||||
@ -1646,7 +1646,7 @@ rename (const char *oldpath, const char *newpath)
|
|||||||
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
||||||
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
||||||
newpc.get_nt_native_path (),
|
newpc.get_nt_native_path (),
|
||||||
TRUE))
|
oldpc.objcaseinsensitive ()))
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1674,7 +1674,7 @@ rename (const char *oldpath, const char *newpath)
|
|||||||
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
newpc.check (newpath, PC_SYM_NOFOLLOW);
|
||||||
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
if (RtlEqualUnicodeString (oldpc.get_nt_native_path (),
|
||||||
newpc.get_nt_native_path (),
|
newpc.get_nt_native_path (),
|
||||||
TRUE))
|
oldpc.objcaseinsensitive ()))
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
goto out;
|
goto out;
|
||||||
@ -2776,7 +2776,8 @@ chroot (const char *newroot)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
getwinenv("PATH="); /* Save the native PATH */
|
getwinenv("PATH="); /* Save the native PATH */
|
||||||
cygheap->root.set (path.normalized_path, path.get_win32 ());
|
cygheap->root.set (path.normalized_path, path.get_win32 (),
|
||||||
|
!!path.objcaseinsensitive ());
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ utimens_worker (path_conv &win32, const struct timespec *tvp)
|
|||||||
if (cfd->get_access () & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE)
|
if (cfd->get_access () & (FILE_WRITE_ATTRIBUTES | GENERIC_WRITE)
|
||||||
&& RtlEqualUnicodeString (cfd->pc.get_nt_native_path (),
|
&& RtlEqualUnicodeString (cfd->pc.get_nt_native_path (),
|
||||||
win32.get_nt_native_path (),
|
win32.get_nt_native_path (),
|
||||||
TRUE))
|
cfd->pc.objcaseinsensitive ()))
|
||||||
{
|
{
|
||||||
fh = cfd;
|
fh = cfd;
|
||||||
fromfd = true;
|
fromfd = true;
|
||||||
|
@ -527,7 +527,7 @@ pwdgrp::load (const char *posix_fname)
|
|||||||
curr_lines = 0;
|
curr_lines = 0;
|
||||||
|
|
||||||
pc.check (posix_fname);
|
pc.check (posix_fname);
|
||||||
etc_ix = etc::init (etc_ix, pc.get_nt_native_path ());
|
etc_ix = etc::init (etc_ix, pc);
|
||||||
|
|
||||||
paranoid_printf ("%s", posix_fname);
|
paranoid_printf ("%s", posix_fname);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user