* cygtls.cc (_cygtls::remove): Eliminate compiler warning.
* dir.cc (mkdir): Check path for writability. (rmdir): Ditto. Remove check for special directories. * path.cc (path_conv::check): Set PATH_RO for virtual devices. Set error if read-only and asked for writability. * path.h (pathconv_arg): Add PC_WRITABLE. (path_types): Add PATH_RO. (path_conv::isro): Add (currently unused) check for read-only filesystem. Return "ENOSHARE" when we know a share doesn't exist. * include/sys/mount.h: Add MOUNT_RO flag. * autoload.cc (WNetGetResourceInformationA): Import. * fhandler_netdrive.cc (fhandler_netdrive::exists): Detect actual existence of remote system rather than always assuming that it exists.
This commit is contained in:
parent
cf55bf5ee8
commit
66582dd6e7
@ -1,3 +1,20 @@
|
|||||||
|
2005-05-12 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
|
* cygtls.cc (_cygtls::remove): Eliminate compiler warning.
|
||||||
|
|
||||||
|
* dir.cc (mkdir): Check path for writability.
|
||||||
|
(rmdir): Ditto. Remove check for special directories.
|
||||||
|
* path.cc (path_conv::check): Set PATH_RO for virtual devices. Set
|
||||||
|
error if read-only and asked for writability.
|
||||||
|
* path.h (pathconv_arg): Add PC_WRITABLE.
|
||||||
|
(path_types): Add PATH_RO.
|
||||||
|
(path_conv::isro): Add (currently unused) check for read-only
|
||||||
|
filesystem. Return "ENOSHARE" when we know a share doesn't exist.
|
||||||
|
* include/sys/mount.h: Add MOUNT_RO flag.
|
||||||
|
* autoload.cc (WNetGetResourceInformationA): Import.
|
||||||
|
* fhandler_netdrive.cc (fhandler_netdrive::exists): Detect actual
|
||||||
|
existence of remote system rather than always assuming that it exists.
|
||||||
|
|
||||||
2005-05-11 Christopher Faylor <cgf@timesys.com>
|
2005-05-11 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* dcrt0.cc (do_global_dtors): Don't call dll_global_dtors here.
|
* dcrt0.cc (do_global_dtors): Don't call dll_global_dtors here.
|
||||||
|
@ -557,6 +557,8 @@ LoadDLLfuncEx (waveInStart, 4, winmm, 1)
|
|||||||
LoadDLLfuncEx (waveInReset, 4, winmm, 1)
|
LoadDLLfuncEx (waveInReset, 4, winmm, 1)
|
||||||
LoadDLLfuncEx (waveInClose, 4, winmm, 1)
|
LoadDLLfuncEx (waveInClose, 4, winmm, 1)
|
||||||
|
|
||||||
|
LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
|
||||||
|
|
||||||
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
|
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
|
||||||
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
|
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ _cygtls::remove (DWORD wait)
|
|||||||
if (locals.exitsock != INVALID_SOCKET)
|
if (locals.exitsock != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
closesocket (locals.exitsock);
|
closesocket (locals.exitsock);
|
||||||
locals.exitsock = NULL;
|
locals.exitsock = (SOCKET) NULL;
|
||||||
}
|
}
|
||||||
free_local (process_ident);
|
free_local (process_ident);
|
||||||
free_local (ntoa_buf);
|
free_local (ntoa_buf);
|
||||||
|
@ -224,7 +224,7 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
||||||
security_descriptor sd;
|
security_descriptor sd;
|
||||||
|
|
||||||
path_conv real_dir (dir, PC_SYM_NOFOLLOW);
|
path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_WRITABLE);
|
||||||
|
|
||||||
if (real_dir.error)
|
if (real_dir.error)
|
||||||
{
|
{
|
||||||
@ -263,15 +263,11 @@ extern "C" int
|
|||||||
rmdir (const char *dir)
|
rmdir (const char *dir)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
DWORD devn;
|
|
||||||
|
|
||||||
path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL);
|
path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL | PC_WRITABLE);
|
||||||
|
|
||||||
if (real_dir.error)
|
if (real_dir.error)
|
||||||
set_errno (real_dir.error);
|
set_errno (real_dir.error);
|
||||||
else if ((devn = real_dir.get_devn ()) == FH_PROC || devn == FH_REGISTRY
|
|
||||||
|| devn == FH_PROCESS)
|
|
||||||
set_errno (EROFS);
|
|
||||||
else if (!real_dir.exists ())
|
else if (!real_dir.exists ())
|
||||||
set_errno (ENOENT);
|
set_errno (ENOENT);
|
||||||
else if (!real_dir.isdir ())
|
else if (!real_dir.isdir ())
|
||||||
|
@ -8,6 +8,7 @@ This software is a copyrighted work licensed under the terms of the
|
|||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -19,12 +20,31 @@ details. */
|
|||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
|
||||||
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||||
-1 if path is a file, -2 if it's a symlink. */
|
-1 if path is a file, -2 if it's a symlink. */
|
||||||
int
|
int
|
||||||
fhandler_netdrive::exists ()
|
fhandler_netdrive::exists ()
|
||||||
{
|
{
|
||||||
|
char *to;
|
||||||
|
const char *from;
|
||||||
|
char namebuf[strlen (get_name ()) + 1];
|
||||||
|
for (to = namebuf, from = get_name (); *from; to++, from++)
|
||||||
|
*to = (*from == '/') ? '\\' : *from;
|
||||||
|
*to = '\0';
|
||||||
|
|
||||||
|
NETRESOURCE nr = {0};
|
||||||
|
nr.dwScope = RESOURCE_GLOBALNET;
|
||||||
|
nr.dwType = RESOURCETYPE_DISK;
|
||||||
|
nr.lpLocalName = NULL;
|
||||||
|
nr.lpRemoteName = namebuf;
|
||||||
|
LPTSTR sys = NULL;
|
||||||
|
char buf[8192];
|
||||||
|
DWORD n = sizeof (buf);
|
||||||
|
DWORD rc = WNetGetResourceInformation (&nr, &buf, &n, &sys);
|
||||||
|
if (rc != ERROR_MORE_DATA && rc != NO_ERROR)
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,19 +17,20 @@ extern "C" {
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MOUNT_SYMLINK = 0x001, /* "mount point" is a symlink */
|
MOUNT_SYMLINK = 0x0001, /* "mount point" is a symlink */
|
||||||
MOUNT_BINARY = 0x002, /* "binary" format read/writes */
|
MOUNT_BINARY = 0x0002, /* "binary" format read/writes */
|
||||||
MOUNT_SYSTEM = 0x008, /* mount point came from system table */
|
MOUNT_SYSTEM = 0x0008, /* mount point came from system table */
|
||||||
MOUNT_EXEC = 0x010, /* Any file in the mounted directory gets 'x' bit */
|
MOUNT_EXEC = 0x0010, /* Any file in the mounted directory gets 'x' bit */
|
||||||
MOUNT_CYGDRIVE = 0x020, /* mount point refers to cygdrive device mount */
|
MOUNT_CYGDRIVE = 0x0020, /* mount point refers to cygdrive device mount */
|
||||||
MOUNT_CYGWIN_EXEC = 0x040, /* file or directory is or contains a cygwin
|
MOUNT_CYGWIN_EXEC = 0x0040, /* file or directory is or contains a cygwin
|
||||||
executable */
|
executable */
|
||||||
MOUNT_MIXED = 0x080, /* reads are text, writes are binary
|
MOUNT_MIXED = 0x0080, /* reads are text, writes are binary
|
||||||
not yet implemented */
|
not yet implemented */
|
||||||
MOUNT_NOTEXEC = 0x100, /* don't check files for executable magic */
|
MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */
|
||||||
MOUNT_DEVFS = 0x200, /* /device "filesystem" */
|
MOUNT_DEVFS = 0x0200, /* /device "filesystem" */
|
||||||
MOUNT_PROC = 0x400, /* /proc "filesystem" */
|
MOUNT_PROC = 0x0400, /* /proc "filesystem" */
|
||||||
MOUNT_ENC = 0x800 /* encode special characters */
|
MOUNT_ENC = 0x0800, /* encode special characters */
|
||||||
|
MOUNT_RO = 0x1000 /* read-only "filesystem" */
|
||||||
};
|
};
|
||||||
|
|
||||||
int mount (const char *, const char *, unsigned __flags);
|
int mount (const char *, const char *, unsigned __flags);
|
||||||
|
@ -675,6 +675,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||||
goto virtual_component_retry;
|
goto virtual_component_retry;
|
||||||
}
|
}
|
||||||
|
path_flags |= PATH_RO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* 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. */
|
||||||
@ -881,15 +882,21 @@ virtual_component_retry:
|
|||||||
out:
|
out:
|
||||||
bool strip_tail = false;
|
bool strip_tail = false;
|
||||||
/* If the user wants a directory, do not return a symlink */
|
/* If the user wants a directory, do not return a symlink */
|
||||||
if (!need_directory || error)
|
if ((opt & PC_WRITABLE) && (path_flags & PATH_RO))
|
||||||
|
{
|
||||||
|
debug_printf ("%s is on a read-only filesystem", path);
|
||||||
|
error = EROFS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (isvirtual_dev (dev.devn) && fileattr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
error = dev.devn == FH_NETDRIVE ? ENOSHARE : ENOENT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!need_directory || error)
|
||||||
/* nothing to do */;
|
/* nothing to do */;
|
||||||
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
path_flags &= ~PATH_SYMLINK;
|
path_flags &= ~PATH_SYMLINK;
|
||||||
else if (isvirtual_dev (dev.devn) && fileattr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
{
|
|
||||||
error = ENOENT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug_printf ("%s is a non-directory", path);
|
debug_printf ("%s is a non-directory", path);
|
||||||
|
@ -39,7 +39,8 @@ enum pathconv_arg
|
|||||||
PC_NULLEMPTY = 0x0020,
|
PC_NULLEMPTY = 0x0020,
|
||||||
PC_CHECK_EA = 0x0040,
|
PC_CHECK_EA = 0x0040,
|
||||||
PC_POSIX = 0x0080,
|
PC_POSIX = 0x0080,
|
||||||
PC_NO_ACCESS_CHECK = 0x00800000
|
PC_NO_ACCESS_CHECK = 0x00800000,
|
||||||
|
PC_WRITABLE = 0x00400000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum case_checking
|
enum case_checking
|
||||||
@ -51,7 +52,7 @@ enum case_checking
|
|||||||
|
|
||||||
#define PC_NONULLEMPTY -1
|
#define PC_NONULLEMPTY -1
|
||||||
|
|
||||||
#include <sys/mount.h>
|
#include "sys/mount.h"
|
||||||
|
|
||||||
enum path_types
|
enum path_types
|
||||||
{
|
{
|
||||||
@ -62,6 +63,7 @@ enum path_types
|
|||||||
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_ENC = MOUNT_ENC,
|
||||||
|
PATH_RO = MOUNT_RO,
|
||||||
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,
|
||||||
@ -149,6 +151,7 @@ class path_conv
|
|||||||
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
|
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
|
||||||
int issocket () const {return dev.devn == FH_UNIX;}
|
int issocket () const {return dev.devn == FH_UNIX;}
|
||||||
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
|
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
|
||||||
|
bool isro () const {return !!(path_flags & PATH_RO);}
|
||||||
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
||||||
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
||||||
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user