* 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>
|
||||
|
||||
* 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 (waveInClose, 4, winmm, 1)
|
||||
|
||||
LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
|
||||
|
||||
LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
|
||||
LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ _cygtls::remove (DWORD wait)
|
||||
if (locals.exitsock != INVALID_SOCKET)
|
||||
{
|
||||
closesocket (locals.exitsock);
|
||||
locals.exitsock = NULL;
|
||||
locals.exitsock = (SOCKET) NULL;
|
||||
}
|
||||
free_local (process_ident);
|
||||
free_local (ntoa_buf);
|
||||
|
@ -224,7 +224,7 @@ mkdir (const char *dir, mode_t mode)
|
||||
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
||||
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)
|
||||
{
|
||||
@ -263,15 +263,11 @@ extern "C" int
|
||||
rmdir (const char *dir)
|
||||
{
|
||||
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)
|
||||
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 ())
|
||||
set_errno (ENOENT);
|
||||
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
|
||||
details. */
|
||||
|
||||
#include <windows.h>
|
||||
#include "winsup.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@ -19,12 +20,31 @@ details. */
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include <assert.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
/* 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. */
|
||||
int
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -17,19 +17,20 @@ extern "C" {
|
||||
|
||||
enum
|
||||
{
|
||||
MOUNT_SYMLINK = 0x001, /* "mount point" is a symlink */
|
||||
MOUNT_BINARY = 0x002, /* "binary" format read/writes */
|
||||
MOUNT_SYSTEM = 0x008, /* mount point came from system table */
|
||||
MOUNT_EXEC = 0x010, /* Any file in the mounted directory gets 'x' bit */
|
||||
MOUNT_CYGDRIVE = 0x020, /* mount point refers to cygdrive device mount */
|
||||
MOUNT_CYGWIN_EXEC = 0x040, /* file or directory is or contains a cygwin
|
||||
MOUNT_SYMLINK = 0x0001, /* "mount point" is a symlink */
|
||||
MOUNT_BINARY = 0x0002, /* "binary" format read/writes */
|
||||
MOUNT_SYSTEM = 0x0008, /* mount point came from system table */
|
||||
MOUNT_EXEC = 0x0010, /* Any file in the mounted directory gets 'x' bit */
|
||||
MOUNT_CYGDRIVE = 0x0020, /* mount point refers to cygdrive device mount */
|
||||
MOUNT_CYGWIN_EXEC = 0x0040, /* file or directory is or contains a cygwin
|
||||
executable */
|
||||
MOUNT_MIXED = 0x080, /* reads are text, writes are binary
|
||||
MOUNT_MIXED = 0x0080, /* reads are text, writes are binary
|
||||
not yet implemented */
|
||||
MOUNT_NOTEXEC = 0x100, /* don't check files for executable magic */
|
||||
MOUNT_DEVFS = 0x200, /* /device "filesystem" */
|
||||
MOUNT_PROC = 0x400, /* /proc "filesystem" */
|
||||
MOUNT_ENC = 0x800 /* encode special characters */
|
||||
MOUNT_NOTEXEC = 0x0100, /* don't check files for executable magic */
|
||||
MOUNT_DEVFS = 0x0200, /* /device "filesystem" */
|
||||
MOUNT_PROC = 0x0400, /* /proc "filesystem" */
|
||||
MOUNT_ENC = 0x0800, /* encode special characters */
|
||||
MOUNT_RO = 0x1000 /* read-only "filesystem" */
|
||||
};
|
||||
|
||||
int mount (const char *, const char *, unsigned __flags);
|
||||
|
@ -675,6 +675,7 @@ path_conv::check (const char *src, unsigned opt,
|
||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||
goto virtual_component_retry;
|
||||
}
|
||||
path_flags |= PATH_RO;
|
||||
goto out;
|
||||
}
|
||||
/* devn should not be a device. If it is, then stop parsing now. */
|
||||
@ -881,15 +882,21 @@ virtual_component_retry:
|
||||
out:
|
||||
bool strip_tail = false;
|
||||
/* 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 */;
|
||||
else if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
path_flags &= ~PATH_SYMLINK;
|
||||
else if (isvirtual_dev (dev.devn) && fileattr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
error = ENOENT;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf ("%s is a non-directory", path);
|
||||
|
@ -39,7 +39,8 @@ enum pathconv_arg
|
||||
PC_NULLEMPTY = 0x0020,
|
||||
PC_CHECK_EA = 0x0040,
|
||||
PC_POSIX = 0x0080,
|
||||
PC_NO_ACCESS_CHECK = 0x00800000
|
||||
PC_NO_ACCESS_CHECK = 0x00800000,
|
||||
PC_WRITABLE = 0x00400000
|
||||
};
|
||||
|
||||
enum case_checking
|
||||
@ -51,7 +52,7 @@ enum case_checking
|
||||
|
||||
#define PC_NONULLEMPTY -1
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include "sys/mount.h"
|
||||
|
||||
enum path_types
|
||||
{
|
||||
@ -62,6 +63,7 @@ enum path_types
|
||||
PATH_NOTEXEC = MOUNT_NOTEXEC,
|
||||
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
|
||||
PATH_ENC = MOUNT_ENC,
|
||||
PATH_RO = MOUNT_RO,
|
||||
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
|
||||
PATH_NO_ACCESS_CHECK = PC_NO_ACCESS_CHECK,
|
||||
PATH_LNK = 0x01000000,
|
||||
@ -149,6 +151,7 @@ class path_conv
|
||||
int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
|
||||
int issocket () const {return dev.devn == FH_UNIX;}
|
||||
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 has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
||||
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
||||
|
Loading…
x
Reference in New Issue
Block a user