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:
Corinna Vinschen
2008-07-16 20:20:45 +00:00
parent bed5a336c4
commit e4b575030b
22 changed files with 288 additions and 490 deletions

View File

@@ -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");