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:
@@ -32,7 +32,7 @@ details. */
|
||||
|
||||
/* Determine if path prefix matches current cygdrive */
|
||||
#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) \
|
||||
(isalpha (path[mount_table->cygdrive_len]) && \
|
||||
@@ -40,7 +40,7 @@ details. */
|
||||
!path[mount_table->cygdrive_len + 1]))
|
||||
|
||||
#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
|
||||
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
|
||||
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;
|
||||
if (*p == '/')
|
||||
/* nothing */;
|
||||
else if ((!(flags & MOUNT_ENC) && isdrive (dst) && !dst[2]) || *p)
|
||||
else if ((isdrive (dst) && !dst[2]) || *p)
|
||||
dst[n++] = '\\';
|
||||
//if (!*p || !(flags & MOUNT_ENC))
|
||||
//{
|
||||
if ((n + strlen (p)) >= NT_MAX_PATH)
|
||||
err = ENAMETOOLONG;
|
||||
else
|
||||
backslashify (p, dst + n, 0);
|
||||
#if 0
|
||||
}
|
||||
if ((n + strlen (p)) >= NT_MAX_PATH)
|
||||
err = ENAMETOOLONG;
|
||||
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
|
||||
backslashify (p, dst + n, 0);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -493,7 +313,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (path_prefix_p (path, src_path, len))
|
||||
if (path_prefix_p (path, src_path, len, mi->flags & MOUNT_NOPOSIX))
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -782,7 +595,8 @@ mount_info::set_flags_from_win32_path (const char *p)
|
||||
for (int i = 0; i < nmounts; 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 PATH_BINARY;
|
||||
@@ -831,9 +645,10 @@ struct opt
|
||||
{"notexec", MOUNT_NOTEXEC, 0},
|
||||
{"cygexec", MOUNT_CYGWIN_EXEC, 0},
|
||||
{"nosuid", 0, 0},
|
||||
{"managed", MOUNT_ENC, 0},
|
||||
{"acl", MOUNT_NOACL, 1},
|
||||
{"noacl", MOUNT_NOACL, 0}
|
||||
{"noacl", MOUNT_NOACL, 0},
|
||||
{"posix=1", MOUNT_NOPOSIX, 1},
|
||||
{"posix=0", MOUNT_NOPOSIX, 0}
|
||||
};
|
||||
|
||||
static bool
|
||||
@@ -1196,7 +1011,7 @@ mount_info::add_item (const char *native, const char *posix,
|
||||
int 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. */
|
||||
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() */
|
||||
if (((posix_path_p)
|
||||
? strcasematch (mount[ent].posix_path, pathtmp)
|
||||
? !strcmp (mount[ent].posix_path, pathtmp)
|
||||
: strcasematch (mount[ent].native_path, pathtmp)))
|
||||
{
|
||||
/* 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;
|
||||
UNICODE_STRING 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)
|
||||
RtlAppendUnicodeToString (&unat, L"\\");
|
||||
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");
|
||||
else if (flags & MOUNT_NOTEXEC)
|
||||
strcat (_my_tls.locals.mnt_opts, (char *) ",noexec");
|
||||
if (flags & MOUNT_ENC)
|
||||
strcat (_my_tls.locals.mnt_opts, ",managed");
|
||||
|
||||
if (flags & MOUNT_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 */
|
||||
strcat (_my_tls.locals.mnt_opts, (char *) ",noumount");
|
||||
|
||||
|
Reference in New Issue
Block a user