* 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:
Christopher Faylor 2005-05-13 03:21:39 +00:00
parent cf55bf5ee8
commit 66582dd6e7
8 changed files with 72 additions and 26 deletions

View File

@ -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.

View File

@ -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)
}

View File

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

View File

@ -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 ())

View File

@ -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;
}

View File

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

View File

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

View File

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