* fhandler.h (FH_ENC): New enum.
(fhandler_base::get_encoded): New function. (fhandler_base::set_encoded): Ditto. * fhandler_disk_file.cc (fhandler_disk_file::opendir): Set encoded flag in fhandler, as appropriate. (fhandler_disk_file::readdir): Unmunge filename as appropriate based on new encoding flag. * path.cc (normalize_posix_path): Don't punt on files with colons. (special_char): New function. (mount_item::fnmunge): Ditto. (fnunmunge): Ditto. (special_name): Ditto. (mount_item::build_win32): Avoid drive considerations when file is encoded. (mount_info::conv_to_win32_path): Handle encoded filenames. (mount_info::conv_to_posix_path): Ditto. (fillout_mntent): Add posix string when directory is encoded. * path.h (fnunmunge): Declare. (path_conv::is_encoded): Declare.
This commit is contained in:
parent
8f856553c0
commit
3f21478315
@ -1,3 +1,25 @@
|
||||
2003-07-02 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* fhandler.h (FH_ENC): New enum.
|
||||
(fhandler_base::get_encoded): New function.
|
||||
(fhandler_base::set_encoded): Ditto.
|
||||
* fhandler_disk_file.cc (fhandler_disk_file::opendir): Set encoded flag
|
||||
in fhandler, as appropriate.
|
||||
(fhandler_disk_file::readdir): Unmunge filename as appropriate based on
|
||||
new encoding flag.
|
||||
* path.cc (normalize_posix_path): Don't punt on files with colons.
|
||||
(special_char): New function.
|
||||
(mount_item::fnmunge): Ditto.
|
||||
(fnunmunge): Ditto.
|
||||
(special_name): Ditto.
|
||||
(mount_item::build_win32): Avoid drive considerations when file is
|
||||
encoded.
|
||||
(mount_info::conv_to_win32_path): Handle encoded filenames.
|
||||
(mount_info::conv_to_posix_path): Ditto.
|
||||
(fillout_mntent): Add posix string when directory is encoded.
|
||||
* path.h (fnunmunge): Declare.
|
||||
(path_conv::is_encoded): Declare.
|
||||
|
||||
2003-07-03 Christopher Faylor <cgf@redhat.com>
|
||||
|
||||
* fhandler_tty.cc (fhandler_tty_slave::open): Conditionalize a little
|
||||
|
@ -23,8 +23,7 @@ enum
|
||||
FH_WBINSET = 0x00010000, /* binary write mode has been explicitly set */
|
||||
FH_APPEND = 0x00020000, /* always append */
|
||||
FH_ASYNC = 0x00040000, /* async I/O */
|
||||
FH_SIGCLOSE = 0x00080000, /* signal handler should close fd on interrupt */
|
||||
|
||||
FH_ENC = 0x00080000, /* native path is encoded */
|
||||
FH_SYMLINK = 0x00100000, /* is a symlink */
|
||||
FH_EXECABL = 0x00200000, /* file looked like it would run:
|
||||
* ends in .exe or .bat or begins with #! */
|
||||
@ -242,6 +241,9 @@ class fhandler_base
|
||||
bool get_need_fork_fixup () { return FHISSETF (FFIXUP); }
|
||||
void set_need_fork_fixup () { FHSETF (FFIXUP); }
|
||||
|
||||
bool get_encoded () { return FHISSETF (ENC);}
|
||||
void set_encoded () { FHSETF (ENC);}
|
||||
|
||||
virtual void set_close_on_exec (int val);
|
||||
|
||||
virtual void fixup_before_fork_exec (DWORD) {}
|
||||
|
@ -607,6 +607,8 @@ fhandler_disk_file::opendir (path_conv& real_name)
|
||||
|
||||
res = dir;
|
||||
}
|
||||
if (real_name.isencoded ())
|
||||
set_encoded ();
|
||||
}
|
||||
|
||||
syscall_printf ("%p = opendir (%s)", res, get_name ());
|
||||
@ -633,9 +635,7 @@ fhandler_disk_file::readdir (DIR *dir)
|
||||
}
|
||||
}
|
||||
else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf))
|
||||
{
|
||||
DWORD lasterr = GetLastError ();
|
||||
@ -650,7 +650,10 @@ fhandler_disk_file::readdir (DIR *dir)
|
||||
}
|
||||
|
||||
/* We get here if `buf' contains valid data. */
|
||||
strcpy (dir->__d_dirent->d_name, buf.cFileName);
|
||||
if (get_encoded ())
|
||||
(void) fnunmunge (dir->__d_dirent->d_name, buf.cFileName);
|
||||
else
|
||||
strcpy (dir->__d_dirent->d_name, buf.cFileName);
|
||||
|
||||
/* Check for Windows shortcut. If it's a Cygwin or U/WIN
|
||||
symlink, drop the .lnk suffix. */
|
||||
|
@ -203,7 +203,7 @@ normalize_posix_path (const char *src, char *dst)
|
||||
|
||||
syscall_printf ("src %s", src);
|
||||
|
||||
if (isdrive (src) || strpbrk (src, "\\:"))
|
||||
if (isdrive (src))
|
||||
{
|
||||
int err = normalize_win32_path (src, dst);
|
||||
if (!err && isdrive (dst))
|
||||
@ -499,7 +499,7 @@ path_conv::check (const char *src, unsigned opt,
|
||||
|
||||
/* Scan path_copy from right to left looking either for a symlink
|
||||
or an actual existing file. If an existing file is found, just
|
||||
return. If a symlink is found exit the for loop.
|
||||
return. If a symlink is found, exit the for loop.
|
||||
Also: be careful to preserve the errno returned from
|
||||
symlink.check as the caller may need it. */
|
||||
/* FIXME: Do we have to worry about multiple \'s here? */
|
||||
@ -1390,10 +1390,99 @@ set_flags (unsigned *flags, unsigned val)
|
||||
}
|
||||
}
|
||||
|
||||
char 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 inline char
|
||||
special_char (const char *s)
|
||||
{
|
||||
char *p = strechr (special_chars, *s);
|
||||
if (*p == '%' && strlen (p) >= 3)
|
||||
{
|
||||
char hex[] = {s[1], s[2], '\0'};
|
||||
unsigned char c = strtoul (hex, &p, 16);
|
||||
p = strechr (special_chars, c);
|
||||
}
|
||||
return *p;
|
||||
}
|
||||
|
||||
bool
|
||||
fnunmunge (char *dst, const char *src)
|
||||
{
|
||||
bool converted = false;
|
||||
char c;
|
||||
|
||||
while (*src)
|
||||
if (*src != '%' || !(c = special_char (src)))
|
||||
*dst++ = *src++;
|
||||
else
|
||||
{
|
||||
converted = true;
|
||||
*dst++ = c;
|
||||
src += 3;
|
||||
}
|
||||
|
||||
*dst = *src;
|
||||
return converted;
|
||||
}
|
||||
|
||||
/* Determines if name is "special". Assumes that name is empty or "absolute" */
|
||||
static int
|
||||
special_name (const char *s)
|
||||
{
|
||||
if (!*s)
|
||||
return false;
|
||||
|
||||
if (strpbrk (++s, special_chars))
|
||||
return !strncasematch (s, "%2f", 3);
|
||||
|
||||
if (strcasematch (s, "nul")
|
||||
|| strcasematch (s, "aux")
|
||||
|| strcasematch (s, "prn"))
|
||||
return -1;
|
||||
if (!strncasematch (s, "com", 3)
|
||||
&& !strncasematch (s, "lpt", 3))
|
||||
return false;
|
||||
char *p;
|
||||
(void) strtol (s, &p, 10);
|
||||
return -(*p == '\0');
|
||||
}
|
||||
|
||||
void
|
||||
mount_item::fnmunge (char *dst, const char *src)
|
||||
{
|
||||
strcpy (dst, src);
|
||||
int name_type;
|
||||
if (!(flags & MOUNT_ENC) || !(name_type = special_name (src)))
|
||||
strcpy (dst, src);
|
||||
else
|
||||
{
|
||||
char *d = dst;
|
||||
*d++ = *src++;
|
||||
if (name_type < 0)
|
||||
{
|
||||
__small_sprintf (d, "%%%02x", (unsigned char) *src++);
|
||||
d += 3;
|
||||
}
|
||||
|
||||
while (*src)
|
||||
if (!special_char (src))
|
||||
*d++ = *src++;
|
||||
else
|
||||
{
|
||||
__small_sprintf (d, "%%%02x", (unsigned char) *src++);
|
||||
d += 3;
|
||||
}
|
||||
*d = *src;
|
||||
}
|
||||
|
||||
backslashify (dst, dst, 0);
|
||||
}
|
||||
|
||||
@ -1420,7 +1509,7 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne
|
||||
const char *p = src + real_posix_pathlen;
|
||||
if (*p == '/')
|
||||
/* nothing */;
|
||||
else if ((isdrive (dst) && !dst[2]) || *p)
|
||||
else if ((!(flags & MOUNT_ENC) && isdrive (dst) && !dst[2]) || *p)
|
||||
dst[n++] = '\\';
|
||||
fnmunge (dst + n, p);
|
||||
}
|
||||
@ -1475,22 +1564,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||
if (dst == NULL)
|
||||
goto out; /* Sanity check. */
|
||||
|
||||
/* An MS-DOS spec has either a : or a \. If this is found, short
|
||||
circuit most of the rest of this function. */
|
||||
if (strpbrk (src_path, ":\\") != NULL || slash_unc_prefix_p (src_path))
|
||||
{
|
||||
debug_printf ("%s already win32", src_path);
|
||||
rc = normalize_win32_path (src_path, dst);
|
||||
if (rc)
|
||||
{
|
||||
debug_printf ("normalize_win32_path failed, rc %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
set_flags (flags, (unsigned) set_flags_from_win32_path (dst));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Normalize the path, taking out ../../ stuff, we need to do this
|
||||
so that we can move from one mounted directory to another with relative
|
||||
stuff.
|
||||
@ -1587,17 +1660,22 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= nmounts)
|
||||
{
|
||||
backslashify (pathbuf, dst, 0); /* just convert */
|
||||
set_flags (flags, PATH_BINARY);
|
||||
chroot_ok = !cygheap->root.exists ();
|
||||
}
|
||||
else
|
||||
if (i < nmounts)
|
||||
{
|
||||
mi->build_win32 (dst, pathbuf, flags, chroot_pathlen);
|
||||
chroot_ok = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strpbrk (src_path, ":\\") != NULL || slash_unc_prefix_p (src_path))
|
||||
rc = normalize_win32_path (src_path, dst);
|
||||
else
|
||||
{
|
||||
backslashify (pathbuf, dst, 0); /* just convert */
|
||||
set_flags (flags, PATH_BINARY);
|
||||
}
|
||||
chroot_ok = !cygheap->root.exists ();
|
||||
}
|
||||
|
||||
if (!isvirtual_dev (devn))
|
||||
win32_device_name (src_path, dst, devn, unit);
|
||||
@ -1760,6 +1838,12 @@ 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 (mi.flags & MOUNT_ENC)
|
||||
{
|
||||
char tmpbuf[MAX_PATH + 1];
|
||||
if (fnunmunge (tmpbuf, posix_path))
|
||||
strcpy (posix_path, tmpbuf);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2420,6 +2504,8 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
|
||||
strcat (_reent_winsup ()->mnt_opts, (char *) ",exec");
|
||||
else if (flags & MOUNT_NOTEXEC)
|
||||
strcat (_reent_winsup ()->mnt_opts, (char *) ",noexec");
|
||||
if (flags & MOUNT_ENC)
|
||||
strcat (_reent_winsup ()->mnt_opts, ",posix");
|
||||
|
||||
if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */
|
||||
strcat (_reent_winsup ()->mnt_opts, (char *) ",noumount");
|
||||
@ -3344,7 +3430,7 @@ chdir (const char *in_dir)
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *native_dir = path.get_win32 ();
|
||||
const char *native_dir = path;
|
||||
|
||||
/* Check to see if path translates to something like C:.
|
||||
If it does, append a \ to the native directory specification to
|
||||
|
@ -46,6 +46,7 @@ enum path_types
|
||||
PATH_EXEC = MOUNT_EXEC,
|
||||
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||
PATH_ENC = MOUNT_ENC,
|
||||
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
||||
PATH_LNK = 0x01000000,
|
||||
PATH_TEXT = 0x02000000,
|
||||
@ -89,6 +90,7 @@ class path_conv
|
||||
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
|
||||
int hasgood_inode () const {return path_flags & PATH_HASACLS;} // Not strictly correct
|
||||
int has_buggy_open () const {return path_flags & PATH_HASBUGGYOPEN;}
|
||||
bool isencoded () {return path_flags & PATH_ENC;}
|
||||
int binmode () const
|
||||
{
|
||||
if (path_flags & PATH_BINARY)
|
||||
@ -210,6 +212,8 @@ has_exec_chars (const char *buf, int len)
|
||||
int pathmatch (const char *path1, const char *path2) __attribute__ ((regparm (2)));
|
||||
int pathnmatch (const char *path1, const char *path2, int len) __attribute__ ((regparm (2)));
|
||||
|
||||
bool fnunmunge (char *, const char *) __attribute__ ((regparm (2)));
|
||||
|
||||
int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
|
||||
|
||||
/* FIXME: Move to own include file eventually */
|
||||
|
Loading…
Reference in New Issue
Block a user