* cygheap.cc (cygheap_root::cygheap_rot): Remove constructor.
(cygheap_root::~cygheap_root): Remove destructor. (cygheap_root::operator =): Remove. (cygheap_root::set): New method. * cygheap.h (cygheap_root): Reflect above changes. Store root info in mount-like structure. (cygheap_root:posix_ok): New method. (cygheap_root::ischroot_native): Ditto. (cygheap_root::unchroot): Ditto. (cygheap_root::exists): Ditto. (cygheap_root::posix_length): Ditto. (cygheap_root::posix_path): Ditto. (cygheap_root::native_length): Ditto. (cygheap_root::native_path): Ditto. * dir.cc (opendir): Remove special chroot test. * path.cc (path_prefix_p): Remove front end. (normalize_posix_path): Reorganize chroot tests to accomodate new convention of allowing paths using posix chroot prefix. (path_conv::check): Pass a "already ran normalize" option to conv_to_win32_path. Return if there is an error from this function. (mount_info::conv_to_win32_path): Add extra argument. Don't call normalize_posix_path if caller has already done so. Substitute chroot setting, if any, for root translation. Add chroot checking to final output step. * shared_info (mount_info): Accomodate additional argument to conv_to_win32_path. * syscalls.cc (chroot): Store both normalized posix path and native path in chroot.
This commit is contained in:
parent
bb8251474c
commit
7ceb1cac3a
|
@ -1,3 +1,34 @@
|
||||||
|
Sat Jun 2 14:07:28 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
|
* cygheap.cc (cygheap_root::cygheap_rot): Remove constructor.
|
||||||
|
(cygheap_root::~cygheap_root): Remove destructor.
|
||||||
|
(cygheap_root::operator =): Remove.
|
||||||
|
(cygheap_root::set): New method.
|
||||||
|
* cygheap.h (cygheap_root): Reflect above changes. Store root info in
|
||||||
|
mount-like structure.
|
||||||
|
(cygheap_root:posix_ok): New method.
|
||||||
|
(cygheap_root::ischroot_native): Ditto.
|
||||||
|
(cygheap_root::unchroot): Ditto.
|
||||||
|
(cygheap_root::exists): Ditto.
|
||||||
|
(cygheap_root::posix_length): Ditto.
|
||||||
|
(cygheap_root::posix_path): Ditto.
|
||||||
|
(cygheap_root::native_length): Ditto.
|
||||||
|
(cygheap_root::native_path): Ditto.
|
||||||
|
* dir.cc (opendir): Remove special chroot test.
|
||||||
|
* path.cc (path_prefix_p): Remove front end.
|
||||||
|
(normalize_posix_path): Reorganize chroot tests to accomodate new
|
||||||
|
convention of allowing paths using posix chroot prefix.
|
||||||
|
(path_conv::check): Pass a "already ran normalize" option to
|
||||||
|
conv_to_win32_path. Return if there is an error from this function.
|
||||||
|
(mount_info::conv_to_win32_path): Add extra argument. Don't call
|
||||||
|
normalize_posix_path if caller has already done so. Substitute chroot
|
||||||
|
setting, if any, for root translation. Add chroot checking to final
|
||||||
|
output step.
|
||||||
|
* shared_info (mount_info): Accomodate additional argument to
|
||||||
|
conv_to_win32_path.
|
||||||
|
* syscalls.cc (chroot): Store both normalized posix path and native
|
||||||
|
path in chroot.
|
||||||
|
|
||||||
Fri Jun 1 10:57:19 2001 Christopher Faylor <cgf@cygnus.com>
|
Fri Jun 1 10:57:19 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* path.cc (chdir): Really make sure that isspace gets only an unsigned
|
* path.cc (chdir): Really make sure that isspace gets only an unsigned
|
||||||
|
|
|
@ -290,40 +290,20 @@ cstrdup1 (const char *s)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
cygheap_root::cygheap_root (cygheap_root &nroot)
|
void
|
||||||
|
cygheap_root::set (const char *posix, const char *native)
|
||||||
{
|
{
|
||||||
rootlen = nroot.rootlen;
|
if (!m)
|
||||||
root = nroot.root ? cstrdup (nroot.root) : NULL;
|
m = (struct cygheap_root_mount_info *) ccalloc (HEAP_MOUNT, 1, sizeof (*m));
|
||||||
}
|
strcpy (m->posix_path, posix);
|
||||||
|
m->posix_pathlen = strlen (posix);
|
||||||
|
if (m->posix_pathlen >= 1 && m->posix_path[m->posix_pathlen - 1] == '/')
|
||||||
|
m->posix_path[--m->posix_pathlen] = '\0';
|
||||||
|
|
||||||
cygheap_root::~cygheap_root ()
|
strcpy (m->native_path, native);
|
||||||
{
|
m->native_pathlen = strlen (native);
|
||||||
if (root)
|
if (m->native_pathlen >= 1 && m->native_path[m->native_pathlen - 1] == '\\')
|
||||||
cfree (root);
|
m->native_path[--m->native_pathlen] = '\0';
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
cygheap_root::operator =(const char *new_root)
|
|
||||||
{
|
|
||||||
if (root)
|
|
||||||
{
|
|
||||||
cfree (root);
|
|
||||||
root = NULL;
|
|
||||||
}
|
|
||||||
rootlen = 0;
|
|
||||||
if (new_root && *new_root)
|
|
||||||
{
|
|
||||||
root = cstrdup (new_root);
|
|
||||||
rootlen = strlen (root);
|
|
||||||
if (rootlen >= 1 && root[rootlen - 1] == '/')
|
|
||||||
root[--rootlen] = '\0';
|
|
||||||
if (!rootlen)
|
|
||||||
{
|
|
||||||
cfree (root);
|
|
||||||
root = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cygheap_user::~cygheap_user ()
|
cygheap_user::~cygheap_user ()
|
||||||
|
|
|
@ -16,6 +16,7 @@ enum cygheap_types
|
||||||
HEAP_STR,
|
HEAP_STR,
|
||||||
HEAP_ARGV,
|
HEAP_ARGV,
|
||||||
HEAP_BUF,
|
HEAP_BUF,
|
||||||
|
HEAP_MOUNT,
|
||||||
HEAP_1_START,
|
HEAP_1_START,
|
||||||
HEAP_1_STR,
|
HEAP_1_STR,
|
||||||
HEAP_1_ARGV,
|
HEAP_1_ARGV,
|
||||||
|
@ -37,18 +38,51 @@ struct _cmalloc_entry
|
||||||
char data[0];
|
char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cygheap_root_mount_info
|
||||||
|
{
|
||||||
|
char posix_path[MAX_PATH];
|
||||||
|
unsigned posix_pathlen;
|
||||||
|
char native_path[MAX_PATH];
|
||||||
|
unsigned native_pathlen;
|
||||||
|
};
|
||||||
|
|
||||||
class cygheap_root
|
class cygheap_root
|
||||||
{
|
{
|
||||||
/* Root directory information.
|
/* Root directory information.
|
||||||
This is used after a chroot is called. */
|
This is used after a chroot is called. */
|
||||||
size_t rootlen;
|
struct cygheap_root_mount_info *m;
|
||||||
char *root;
|
|
||||||
public:
|
public:
|
||||||
cygheap_root (cygheap_root &nroot);
|
bool posix_ok (const char *path)
|
||||||
~cygheap_root ();
|
{
|
||||||
char *operator =(const char *new_root);
|
extern int path_prefix_p (const char *, const char *, int);
|
||||||
size_t length () const { return rootlen; }
|
if (!m)
|
||||||
const char *path () const { return root; }
|
return 1;
|
||||||
|
return path_prefix_p (m->posix_path, path, m->posix_pathlen);
|
||||||
|
}
|
||||||
|
bool ischroot_native (const char *path)
|
||||||
|
{
|
||||||
|
if (!m)
|
||||||
|
return 1;
|
||||||
|
return strncasematch (m->native_path, path, m->native_pathlen)
|
||||||
|
&& (path[m->native_pathlen] == '\\' || !path[m->native_pathlen]);
|
||||||
|
|
||||||
|
}
|
||||||
|
const char *unchroot (const char *path)
|
||||||
|
{
|
||||||
|
if (!m)
|
||||||
|
return path;
|
||||||
|
const char *p = path + m->posix_pathlen;
|
||||||
|
if (!*p)
|
||||||
|
p = "/";
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
bool exists () {return !!m;}
|
||||||
|
void set (const char *posix, const char *native);
|
||||||
|
size_t posix_length () const { return m->posix_pathlen; }
|
||||||
|
const char *posix_path () const { return m->posix_path; }
|
||||||
|
size_t native_length () const { return m->native_pathlen; }
|
||||||
|
const char *native_path () const { return m->native_path; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class cygheap_user
|
class cygheap_user
|
||||||
|
|
|
@ -78,8 +78,7 @@ opendir (const char *dirname)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat (cygheap->root.length () ? dirname : real_dirname.get_win32 (),
|
if (stat (real_dirname, &statbuf) == -1)
|
||||||
&statbuf) == -1)
|
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
if (!(statbuf.st_mode & S_IFDIR))
|
if (!(statbuf.st_mode & S_IFDIR))
|
||||||
|
@ -88,7 +87,7 @@ opendir (const char *dirname)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen (real_dirname.get_win32 ());
|
len = strlen (real_dirname);
|
||||||
if (len > MAX_PATH - 3)
|
if (len > MAX_PATH - 3)
|
||||||
{
|
{
|
||||||
set_errno (ENAMETOOLONG);
|
set_errno (ENAMETOOLONG);
|
||||||
|
|
|
@ -89,7 +89,7 @@ static DWORD available_drives;
|
||||||
static int normalize_win32_path (const char *src, char *dst);
|
static int normalize_win32_path (const char *src, char *dst);
|
||||||
static void slashify (const char *src, char *dst, int trailing_slash_p);
|
static void slashify (const char *src, char *dst, int trailing_slash_p);
|
||||||
static void backslashify (const char *src, char *dst, int trailing_slash_p);
|
static void backslashify (const char *src, char *dst, int trailing_slash_p);
|
||||||
static int path_prefix_p_ (const char *path1, const char *path2, int len1);
|
static int path_prefix_p (const char *path1, const char *path2, int len1);
|
||||||
|
|
||||||
struct symlink_info
|
struct symlink_info
|
||||||
{
|
{
|
||||||
|
@ -108,10 +108,6 @@ struct symlink_info
|
||||||
|
|
||||||
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
||||||
|
|
||||||
#define path_prefix_p(p1, p2, l1) \
|
|
||||||
((cyg_tolower(*(p1))==cyg_tolower(*(p2))) && \
|
|
||||||
path_prefix_p_(p1, p2, l1))
|
|
||||||
|
|
||||||
/* 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))
|
||||||
|
@ -121,12 +117,6 @@ int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
||||||
(isdirsep(path[mount_table->cygdrive_len + 1]) || \
|
(isdirsep(path[mount_table->cygdrive_len + 1]) || \
|
||||||
!path[mount_table->cygdrive_len + 1]))
|
!path[mount_table->cygdrive_len + 1]))
|
||||||
|
|
||||||
#define ischrootpath(p) \
|
|
||||||
(cygheap->root.length () && \
|
|
||||||
strncasematch (cygheap->root.path (), p, cygheap->root.length ()) && \
|
|
||||||
(p[cygheap->root.length ()] == '/' \
|
|
||||||
|| p[cygheap->root.length ()] == '\0'))
|
|
||||||
|
|
||||||
/* Return non-zero if PATH1 is a prefix of PATH2.
|
/* Return non-zero if PATH1 is a prefix of PATH2.
|
||||||
Both are assumed to be of the same path style and / vs \ usage.
|
Both are assumed to be of the same path style and / vs \ usage.
|
||||||
Neither may be "".
|
Neither may be "".
|
||||||
|
@ -141,8 +131,8 @@ int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
||||||
/foo is not a prefix of /foobar
|
/foo is not a prefix of /foobar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
int
|
||||||
path_prefix_p_ (const char *path1, const char *path2, int len1)
|
path_prefix_p (const char *path1, const char *path2, int len1)
|
||||||
{
|
{
|
||||||
/* 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 && SLASH_P (path1[len1 - 1]))
|
if (len1 > 0 && SLASH_P (path1[len1 - 1]))
|
||||||
|
@ -182,7 +172,7 @@ pathmatch (const char *path1, const char *path2)
|
||||||
|
|
||||||
#define isslash(c) ((c) == '/')
|
#define isslash(c) ((c) == '/')
|
||||||
|
|
||||||
static int
|
int
|
||||||
normalize_posix_path (const char *src, char *dst)
|
normalize_posix_path (const char *src, char *dst)
|
||||||
{
|
{
|
||||||
const char *src_start = src;
|
const char *src_start = src;
|
||||||
|
@ -211,11 +201,6 @@ normalize_posix_path (const char *src, char *dst)
|
||||||
/* Two leading /'s? If so, preserve them. */
|
/* Two leading /'s? If so, preserve them. */
|
||||||
else if (isslash (src[1]))
|
else if (isslash (src[1]))
|
||||||
{
|
{
|
||||||
if (cygheap->root.length ())
|
|
||||||
{
|
|
||||||
debug_printf ("ENOENT = normalize_posix_path (%s)", src);
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
*dst++ = '/';
|
*dst++ = '/';
|
||||||
*dst++ = '/';
|
*dst++ = '/';
|
||||||
src += 2;
|
src += 2;
|
||||||
|
@ -226,12 +211,6 @@ normalize_posix_path (const char *src, char *dst)
|
||||||
src = src_start + 1;
|
src = src_start + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Exactly one leading slash. Absolute path. Check for chroot. */
|
|
||||||
else if (cygheap->root.length ())
|
|
||||||
{
|
|
||||||
strcpy (dst, cygheap->root.path ());
|
|
||||||
dst += cygheap->root.length ();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
|
|
||||||
|
@ -264,14 +243,6 @@ normalize_posix_path (const char *src, char *dst)
|
||||||
}
|
}
|
||||||
else if (src[2] && !isslash (src[2]))
|
else if (src[2] && !isslash (src[2]))
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!ischrootpath (dst_start) ||
|
|
||||||
dst - dst_start != (int) cygheap->root.length ())
|
|
||||||
while (dst > dst_start && !isslash (*--dst))
|
|
||||||
continue;
|
|
||||||
src++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst++ = '/';
|
*dst++ = '/';
|
||||||
|
@ -442,7 +413,10 @@ path_conv::check (const char *src, unsigned opt,
|
||||||
|
|
||||||
/* Convert to native path spec sans symbolic link info. */
|
/* Convert to native path spec sans symbolic link info. */
|
||||||
error = mount_table->conv_to_win32_path (path_copy, full_path, devn,
|
error = mount_table->conv_to_win32_path (path_copy, full_path, devn,
|
||||||
unit, &sym.pflags);
|
unit, &sym.pflags, 1);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
|
||||||
/* devn should not be a device. If it is, then stop parsing now. */
|
/* devn should not be a device. If it is, then stop parsing now. */
|
||||||
if (devn != FH_BAD)
|
if (devn != FH_BAD)
|
||||||
|
@ -891,25 +865,9 @@ normalize_win32_path (const char *src, char *dst)
|
||||||
|
|
||||||
if (beg_src_slash && isdirsep (src[1]))
|
if (beg_src_slash && isdirsep (src[1]))
|
||||||
{
|
{
|
||||||
if (cygheap->root.length ())
|
|
||||||
{
|
|
||||||
debug_printf ("ENOENT = normalize_win32_path (%s)", src);
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
*dst++ = '\\';
|
*dst++ = '\\';
|
||||||
++src;
|
++src;
|
||||||
}
|
}
|
||||||
/* If absolute path, care for chroot. */
|
|
||||||
else if (beg_src_slash && cygheap->root.length ())
|
|
||||||
{
|
|
||||||
strcpy (dst, cygheap->root.path ());
|
|
||||||
char *c;
|
|
||||||
while ((c = strchr (dst, '/')) != NULL)
|
|
||||||
*c = '\\';
|
|
||||||
dst += cygheap->root.length ();
|
|
||||||
dst_root_start = dst;
|
|
||||||
*dst++ = '\\';
|
|
||||||
}
|
|
||||||
else if (strchr (src, ':') == NULL && *src != '/')
|
else if (strchr (src, ':') == NULL && *src != '/')
|
||||||
{
|
{
|
||||||
if (!cygheap->cwd.get (dst, 0))
|
if (!cygheap->cwd.get (dst, 0))
|
||||||
|
@ -1127,7 +1085,8 @@ mount_info::init ()
|
||||||
|
|
||||||
int
|
int
|
||||||
mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
DWORD &devn, int &unit, unsigned *flags)
|
DWORD &devn, int &unit, unsigned *flags,
|
||||||
|
bool no_normalize)
|
||||||
{
|
{
|
||||||
while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter)
|
while (sys_mount_table_counter < cygwin_shared->sys_mount_table_counter)
|
||||||
{
|
{
|
||||||
|
@ -1137,6 +1096,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
int src_path_len = strlen (src_path);
|
int src_path_len = strlen (src_path);
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
unsigned dummy_flags;
|
unsigned dummy_flags;
|
||||||
|
int chroot_ok = !cygheap->root.exists ();
|
||||||
|
|
||||||
devn = FH_BAD;
|
devn = FH_BAD;
|
||||||
unit = 0;
|
unit = 0;
|
||||||
|
@ -1173,22 +1133,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
*flags = set_flags_from_win32_path (dst);
|
*flags = set_flags_from_win32_path (dst);
|
||||||
if (cygheap->root.length () && dst[0] && dst[1] == ':')
|
|
||||||
{
|
|
||||||
char posix_path[MAX_PATH + 1];
|
|
||||||
|
|
||||||
rc = mount_table->conv_to_posix_path (dst, posix_path, 0);
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
debug_printf ("conv_to_posix_path failed, rc %d", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
if (!ischrootpath (posix_path))
|
|
||||||
{
|
|
||||||
debug_printf ("ischrootpath failed");
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1208,6 +1152,10 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
converting it to a DOS-style path, looking up the appropriate drive
|
converting it to a DOS-style path, looking up the appropriate drive
|
||||||
in the mount table. */
|
in the mount table. */
|
||||||
|
|
||||||
|
if (no_normalize)
|
||||||
|
strcpy (pathbuf, src_path);
|
||||||
|
else
|
||||||
|
{
|
||||||
rc = normalize_posix_path (src_path, pathbuf);
|
rc = normalize_posix_path (src_path, pathbuf);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -1216,12 +1164,14 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* See if this is a cygwin "device" */
|
/* See if this is a cygwin "device" */
|
||||||
if (win32_device_name (pathbuf, dst, devn, unit))
|
if (win32_device_name (pathbuf, dst, devn, unit))
|
||||||
{
|
{
|
||||||
*flags = MOUNT_BINARY; /* FIXME: Is this a sensible default for devices? */
|
*flags = MOUNT_BINARY; /* FIXME: Is this a sensible default for devices? */
|
||||||
goto out;
|
rc = 0;
|
||||||
|
goto out_no_chroot_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the cygdrive prefix was specified. If so, just strip
|
/* Check if the cygdrive prefix was specified. If so, just strip
|
||||||
|
@ -1235,11 +1185,33 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int chrooted_path_len;
|
||||||
|
chrooted_path_len = 0;
|
||||||
/* Check the mount table for prefix matches. */
|
/* Check the mount table for prefix matches. */
|
||||||
for (i = 0; i < nmounts; i++)
|
for (i = 0; i < nmounts; i++)
|
||||||
{
|
{
|
||||||
|
const char *path;
|
||||||
|
int len;
|
||||||
|
|
||||||
mi = mount + posix_sorted[i];
|
mi = mount + posix_sorted[i];
|
||||||
if (path_prefix_p (mi->posix_path, pathbuf, mi->posix_pathlen))
|
if (!cygheap->root.exists ()
|
||||||
|
|| (mi->posix_pathlen == 1 && mi->posix_path[0] == '/'))
|
||||||
|
{
|
||||||
|
path = mi->posix_path;
|
||||||
|
len = mi->posix_pathlen;
|
||||||
|
}
|
||||||
|
else if (cygheap->root.posix_ok (mi->posix_path))
|
||||||
|
{
|
||||||
|
path = cygheap->root.unchroot (mi->posix_path);
|
||||||
|
chrooted_path_len = len = strlen (path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chrooted_path_len = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path_prefix_p (path, pathbuf, len))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1250,9 +1222,26 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int n = mi->native_pathlen;
|
int n;
|
||||||
memcpy (dst, mi->native_path, n + 1);
|
const char *native_path;
|
||||||
char *p = pathbuf + mi->posix_pathlen;
|
int posix_pathlen;
|
||||||
|
if (chroot_ok || chrooted_path_len || mi->posix_pathlen != 1
|
||||||
|
|| mi->posix_path[0] != '/')
|
||||||
|
{
|
||||||
|
n = mi->native_pathlen;
|
||||||
|
native_path = mi->native_path;
|
||||||
|
posix_pathlen = chrooted_path_len ?: mi->posix_pathlen;
|
||||||
|
chroot_ok = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n = cygheap->root.native_length ();
|
||||||
|
native_path = cygheap->root.native_path ();
|
||||||
|
posix_pathlen = mi->posix_pathlen;
|
||||||
|
chroot_ok = 1;
|
||||||
|
}
|
||||||
|
memcpy (dst, native_path, n + 1);
|
||||||
|
const char *p = pathbuf + posix_pathlen;
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
else if ((isdrive (dst) && !dst[2]) || *p)
|
else if ((isdrive (dst) && !dst[2]) || *p)
|
||||||
|
@ -1264,8 +1253,18 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
debug_printf ("src_path %s, dst %s, flags %p", src_path, dst, *flags);
|
if (chroot_ok || cygheap->root.ischroot_native (dst))
|
||||||
return 0;
|
rc = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf ("attempt to access outside of chroot '%s = %s'",
|
||||||
|
cygheap->root.posix_path (), cygheap->root.native_path ());
|
||||||
|
rc = ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_no_chroot_check:
|
||||||
|
debug_printf ("src_path %s, dst %s, flags %p, rc %d", src_path, dst, *flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cygdrive_posix_path: Build POSIX path used as the
|
/* cygdrive_posix_path: Build POSIX path used as the
|
||||||
|
@ -1370,6 +1369,9 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
||||||
if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen))
|
if (!path_prefix_p (mi.native_path, pathbuf, mi.native_pathlen))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (cygheap->root.exists () && !cygheap->root.posix_ok (mi.posix_path))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* SRC_PATH is in the mount table. */
|
/* SRC_PATH is in the mount table. */
|
||||||
int nextchar;
|
int nextchar;
|
||||||
const char *p = pathbuf + mi.native_pathlen;
|
const char *p = pathbuf + mi.native_pathlen;
|
||||||
|
@ -1391,9 +1393,31 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path,
|
||||||
slashify (p,
|
slashify (p,
|
||||||
posix_path + addslash + (mi.posix_pathlen == 1 ? 0 : mi.posix_pathlen),
|
posix_path + addslash + (mi.posix_pathlen == 1 ? 0 : mi.posix_pathlen),
|
||||||
trailing_slash_p);
|
trailing_slash_p);
|
||||||
|
|
||||||
|
if (cygheap->root.exists ())
|
||||||
|
{
|
||||||
|
const char *p = cygheap->root.unchroot (posix_path);
|
||||||
|
memmove (posix_path, p, strlen (p) + 1);
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cygheap->root.exists ())
|
||||||
|
/* nothing */;
|
||||||
|
else if (cygheap->root.ischroot_native (pathbuf))
|
||||||
|
{
|
||||||
|
const char *p = pathbuf + cygheap->root.native_length ();
|
||||||
|
if (*p)
|
||||||
|
slashify (p, posix_path, trailing_slash_p);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
posix_path[0] = '/';
|
||||||
|
posix_path[1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return ENOENT;
|
||||||
|
|
||||||
/* Not in the database. This should [theoretically] only happen if either
|
/* Not in the database. This should [theoretically] only happen if either
|
||||||
the path begins with //, or / isn't mounted, or the path has a drive
|
the path begins with //, or / isn't mounted, or the path has a drive
|
||||||
letter not covered by the mount table. If it's a relative path then the
|
letter not covered by the mount table. If it's a relative path then the
|
||||||
|
@ -3336,11 +3360,9 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
|
||||||
if (!need_posix)
|
if (!need_posix)
|
||||||
tocopy = win32;
|
tocopy = win32;
|
||||||
else
|
else
|
||||||
tocopy = with_chroot && ischrootpath(posix) ?
|
tocopy = posix;
|
||||||
posix + cygheap->root.length () : posix;
|
|
||||||
|
|
||||||
debug_printf("cygheap->root: %s, posix: %s",
|
debug_printf("posix %s", posix);
|
||||||
(const char *) cygheap->root.path (), posix);
|
|
||||||
if (strlen (tocopy) >= ulen)
|
if (strlen (tocopy) >= ulen)
|
||||||
{
|
{
|
||||||
set_errno (ERANGE);
|
set_errno (ERANGE);
|
||||||
|
|
|
@ -77,7 +77,7 @@ class mount_info
|
||||||
|
|
||||||
unsigned set_flags_from_win32_path (const char *path);
|
unsigned set_flags_from_win32_path (const char *path);
|
||||||
int conv_to_win32_path (const char *src_path, char *dst, DWORD &devn,
|
int conv_to_win32_path (const char *src_path, char *dst, DWORD &devn,
|
||||||
int &unit, unsigned *flags = NULL);
|
int &unit, unsigned *flags = NULL, bool no_normalize = 0);
|
||||||
int conv_to_posix_path (const char *src_path, char *posix_path,
|
int conv_to_posix_path (const char *src_path, char *posix_path,
|
||||||
int keep_rel_p);
|
int keep_rel_p);
|
||||||
struct mntent *getmntent (int x);
|
struct mntent *getmntent (int x);
|
||||||
|
|
|
@ -38,6 +38,8 @@ details. */
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
|
||||||
|
extern int normalize_posix_path (const char *, char *);
|
||||||
|
|
||||||
SYSTEM_INFO system_info;
|
SYSTEM_INFO system_info;
|
||||||
|
|
||||||
/* Close all files and process any queued deletions.
|
/* Close all files and process any queued deletions.
|
||||||
|
@ -2200,14 +2202,9 @@ chroot (const char *newroot)
|
||||||
set_errno (ENOTDIR);
|
set_errno (ENOTDIR);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
char buf[MAX_PATH + 1];
|
char buf[MAX_PATH];
|
||||||
ret = mount_table->conv_to_posix_path (path.get_win32 (), buf, 0);
|
normalize_posix_path (newroot, buf);
|
||||||
if (ret)
|
cygheap->root.set (buf, path);
|
||||||
{
|
|
||||||
set_errno (ret);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
cygheap->root = buf;
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
Loading…
Reference in New Issue