mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 00:07:36 +08:00
* fhandler.cc (fhandler_disk_file::open): Check for allow_ntsec
when determining exec flag. * path.cc (symlink_info::check): Remove call to get_file_attribute(). * security.cc (read_sd): Rename, ditto for variables to conform to common naming convention. Use GetFileSecurity() instead of BackupRead() to avoid permission problems when reading ACLs. (write_sd): Same renaming as for read_sd(). (alloc_sd): Change default permissions according to Linux permissions for group and world when write permission is set. * syscalls.cc (stat_worker): Avoid different permission problems when requesting file informations.
This commit is contained in:
parent
efadc1c152
commit
d6581f44d4
@ -1,3 +1,17 @@
|
|||||||
|
Thu Apr 25 16:37:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.cc (fhandler_disk_file::open): Check for allow_ntsec
|
||||||
|
when determining exec flag.
|
||||||
|
* path.cc (symlink_info::check): Remove call to get_file_attribute().
|
||||||
|
* security.cc (read_sd): Rename, ditto for variables to conform
|
||||||
|
to common naming convention. Use GetFileSecurity() instead of
|
||||||
|
BackupRead() to avoid permission problems when reading ACLs.
|
||||||
|
(write_sd): Same renaming as for read_sd().
|
||||||
|
(alloc_sd): Change default permissions according to Linux permissions
|
||||||
|
for group and world when write permission is set.
|
||||||
|
* syscalls.cc (stat_worker): Avoid different permission problems
|
||||||
|
when requesting file informations.
|
||||||
|
|
||||||
Thu Apr 25 10:50:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
Thu Apr 25 10:50:00 2000 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* net.cc: Avoid a warning in declaration inet_network.
|
* net.cc: Avoid a warning in declaration inet_network.
|
||||||
|
@ -1187,8 +1187,9 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
extern BOOL allow_ntea;
|
extern BOOL allow_ntea;
|
||||||
|
extern BOOL allow_ntsec;
|
||||||
|
|
||||||
if (!real_path.isexec () && !allow_ntea &&
|
if (!real_path.isexec () && !allow_ntea && !allow_ntsec &&
|
||||||
GetFileType (get_handle ()) == FILE_TYPE_DISK)
|
GetFileType (get_handle ()) == FILE_TYPE_DISK)
|
||||||
{
|
{
|
||||||
DWORD done;
|
DWORD done;
|
||||||
|
@ -2186,17 +2186,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
|
|||||||
if (!(pflags & PATH_SYMLINK) && !SYMLINKATTR (fileattr))
|
if (!(pflags & PATH_SYMLINK) && !SYMLINKATTR (fileattr))
|
||||||
goto file_not_symlink;
|
goto file_not_symlink;
|
||||||
|
|
||||||
/* Check the file's extended attributes, if it has any. */
|
|
||||||
int unixattr = 0;
|
|
||||||
if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
unixattr |= S_IFDIR;
|
|
||||||
|
|
||||||
if (!get_file_attribute (TRUE, path, &unixattr))
|
|
||||||
{
|
|
||||||
if (unixattr & STD_XBITS)
|
|
||||||
pflags |= PATH_EXEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open the file. */
|
/* Open the file. */
|
||||||
|
|
||||||
h = CreateFileA (path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING,
|
h = CreateFileA (path, GENERIC_READ, FILE_SHARE_READ, &sec_none_nih, OPEN_EXISTING,
|
||||||
|
@ -374,116 +374,67 @@ got_it:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ReadSD reads a security descriptor from a file.
|
/* read_sd reads a security descriptor from a file.
|
||||||
In case of error, -1 is returned and errno is set.
|
In case of error, -1 is returned and errno is set.
|
||||||
If the file doesn't have a SD, 0 is returned.
|
If the file doesn't have a SD, 0 is returned.
|
||||||
Otherwise, the size of the SD is returned and
|
Otherwise, the size of the SD is returned and
|
||||||
the SD is copied to the buffer, pointed to by sdBuf.
|
the SD is copied to the buffer, pointed to by sd_buf.
|
||||||
sdBufSize contains the size of the buffer. If
|
sd_size contains the size of the buffer. If
|
||||||
it's too small, to contain the complete SD, 0 is
|
it's too small, to contain the complete SD, 0 is
|
||||||
returned and sdBufSize is set to the needed size
|
returned and sd_size is set to the needed size
|
||||||
of the buffer.
|
of the buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
ReadSD(const char *file, PSECURITY_DESCRIPTOR sdBuf, LPDWORD sdBufSize)
|
read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size)
|
||||||
{
|
{
|
||||||
/* Check parameters */
|
/* Check parameters */
|
||||||
if (! sdBufSize)
|
if (! sd_size)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open file for read */
|
|
||||||
debug_printf("file = %s", file);
|
debug_printf("file = %s", file);
|
||||||
HANDLE hFile = CreateFile (file, GENERIC_READ,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
&sec_none_nih, OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
DWORD len = 0;
|
||||||
|
if (! GetFileSecurity (file,
|
||||||
|
OWNER_SECURITY_INFORMATION
|
||||||
|
| GROUP_SECURITY_INFORMATION
|
||||||
|
| DACL_SECURITY_INFORMATION,
|
||||||
|
sd_buf, *sd_size, &len))
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (len > *sd_size)
|
||||||
/* step through the backup streams and search for the security data */
|
|
||||||
WIN32_STREAM_ID header;
|
|
||||||
DWORD bytes_read = 0;
|
|
||||||
LPVOID context = NULL;
|
|
||||||
PSECURITY_DESCRIPTOR psd = NULL;
|
|
||||||
DWORD datasize;
|
|
||||||
LONG ret = 0;
|
|
||||||
|
|
||||||
while (BackupRead (hFile, (LPBYTE) &header,
|
|
||||||
3 * sizeof (DWORD) + sizeof (LARGE_INTEGER),
|
|
||||||
&bytes_read, FALSE, TRUE, &context))
|
|
||||||
{
|
{
|
||||||
if (header.dwStreamId != BACKUP_SECURITY_DATA)
|
*sd_size = len;
|
||||||
continue;
|
return 0;
|
||||||
|
|
||||||
/* security data found */
|
|
||||||
datasize = header.Size.LowPart + header.dwStreamNameSize;
|
|
||||||
char b[datasize];
|
|
||||||
|
|
||||||
if (! BackupRead (hFile, (LPBYTE) b, datasize, &bytes_read,
|
|
||||||
FALSE, TRUE, &context))
|
|
||||||
{
|
|
||||||
__seterrno ();
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check validity of the SD */
|
|
||||||
psd = (PSECURITY_DESCRIPTOR) &b[header.dwStreamNameSize];
|
|
||||||
if (! IsValidSecurityDescriptor (psd))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* It's a valid SD */
|
|
||||||
datasize -= header.dwStreamNameSize;
|
|
||||||
debug_printf ("SD-Size: %d", datasize);
|
|
||||||
|
|
||||||
/* buffer to small? */
|
|
||||||
if (*sdBufSize < datasize)
|
|
||||||
{
|
|
||||||
*sdBufSize = datasize;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdBuf)
|
|
||||||
memcpy (sdBuf, psd, datasize);
|
|
||||||
|
|
||||||
ret = *sdBufSize = datasize;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
BackupRead (hFile, NULL, 0, &bytes_read, TRUE, TRUE, &context);
|
return len;
|
||||||
CloseHandle (hFile);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LONG
|
LONG
|
||||||
WriteSD(const char *file, PSECURITY_DESCRIPTOR sdBuf, DWORD sdBufSize)
|
write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size)
|
||||||
{
|
{
|
||||||
/* Check parameters */
|
/* Check parameters */
|
||||||
if (! sdBuf || ! sdBufSize)
|
if (! sd_buf || ! sd_size)
|
||||||
{
|
{
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE hFile = CreateFile (file,
|
HANDLE fh;
|
||||||
WRITE_OWNER | WRITE_DAC,
|
fh = CreateFile (file,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
WRITE_OWNER | WRITE_DAC,
|
||||||
&sec_none_nih,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
OPEN_EXISTING,
|
&sec_none_nih,
|
||||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
|
OPEN_EXISTING,
|
||||||
NULL);
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (fh == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return -1;
|
return -1;
|
||||||
@ -498,19 +449,19 @@ WriteSD(const char *file, PSECURITY_DESCRIPTOR sdBuf, DWORD sdBufSize)
|
|||||||
header.dwStreamId = BACKUP_SECURITY_DATA;
|
header.dwStreamId = BACKUP_SECURITY_DATA;
|
||||||
header.dwStreamAttributes = STREAM_CONTAINS_SECURITY;
|
header.dwStreamAttributes = STREAM_CONTAINS_SECURITY;
|
||||||
header.Size.HighPart = 0;
|
header.Size.HighPart = 0;
|
||||||
header.Size.LowPart = sdBufSize;
|
header.Size.LowPart = sd_size;
|
||||||
header.dwStreamNameSize = 0;
|
header.dwStreamNameSize = 0;
|
||||||
if (!BackupWrite (hFile, (LPBYTE) &header,
|
if (!BackupWrite (fh, (LPBYTE) &header,
|
||||||
3 * sizeof (DWORD) + sizeof (LARGE_INTEGER),
|
3 * sizeof (DWORD) + sizeof (LARGE_INTEGER),
|
||||||
&bytes_written, FALSE, TRUE, &context))
|
&bytes_written, FALSE, TRUE, &context))
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
CloseHandle (hFile);
|
CloseHandle (fh);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write new security descriptor */
|
/* write new security descriptor */
|
||||||
if (!BackupWrite (hFile, (LPBYTE) sdBuf,
|
if (!BackupWrite (fh, (LPBYTE) sd_buf,
|
||||||
header.Size.LowPart + header.dwStreamNameSize,
|
header.Size.LowPart + header.dwStreamNameSize,
|
||||||
&bytes_written, FALSE, TRUE, &context))
|
&bytes_written, FALSE, TRUE, &context))
|
||||||
{
|
{
|
||||||
@ -521,15 +472,15 @@ WriteSD(const char *file, PSECURITY_DESCRIPTOR sdBuf, DWORD sdBufSize)
|
|||||||
if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR)
|
if (ret != ERROR_NOT_SUPPORTED && ret != ERROR_INVALID_SECURITY_DESCR)
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
BackupWrite (hFile, NULL, 0, &bytes_written, TRUE, TRUE, &context);
|
BackupWrite (fh, NULL, 0, &bytes_written, TRUE, TRUE, &context);
|
||||||
CloseHandle (hFile);
|
CloseHandle (fh);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* terminate the restore process */
|
/* terminate the restore process */
|
||||||
BackupWrite (hFile, NULL, 0, &bytes_written, TRUE, TRUE, &context);
|
BackupWrite (fh, NULL, 0, &bytes_written, TRUE, TRUE, &context);
|
||||||
CloseHandle (hFile);
|
CloseHandle (fh);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,9 +563,9 @@ get_nt_attribute (const char *file, int *attribute,
|
|||||||
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret = ReadSD (file, psd, &sd_size)) <= 0)
|
if ((ret = read_sd (file, psd, &sd_size)) <= 0)
|
||||||
{
|
{
|
||||||
debug_printf ("ReadSD %E");
|
debug_printf ("read_sd %E");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,8 +690,8 @@ get_nt_attribute (const char *file, int *attribute,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_file_attribute (int use_ntsec, const char *file, int *attribute,
|
get_file_attribute (int use_ntsec, const char *file,
|
||||||
uid_t *uidret, gid_t *gidret)
|
int *attribute, uid_t *uidret, gid_t *gidret)
|
||||||
{
|
{
|
||||||
if (use_ntsec && allow_ntsec)
|
if (use_ntsec && allow_ntsec)
|
||||||
return get_nt_attribute (file, attribute, uidret, gidret);
|
return get_nt_attribute (file, attribute, uidret, gidret);
|
||||||
@ -898,7 +849,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute,
|
|||||||
if (attribute & S_IRGRP)
|
if (attribute & S_IRGRP)
|
||||||
group_allow |= FILE_GENERIC_READ;
|
group_allow |= FILE_GENERIC_READ;
|
||||||
if (attribute & S_IWGRP)
|
if (attribute & S_IWGRP)
|
||||||
group_allow |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE | DELETE;
|
group_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE | DELETE;
|
||||||
if (attribute & S_IXGRP)
|
if (attribute & S_IXGRP)
|
||||||
group_allow |= FILE_GENERIC_EXECUTE;
|
group_allow |= FILE_GENERIC_EXECUTE;
|
||||||
if (! (attribute & S_ISVTX))
|
if (! (attribute & S_ISVTX))
|
||||||
@ -910,7 +861,7 @@ alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute,
|
|||||||
if (attribute & S_IROTH)
|
if (attribute & S_IROTH)
|
||||||
other_allow |= FILE_GENERIC_READ;
|
other_allow |= FILE_GENERIC_READ;
|
||||||
if (attribute & S_IWOTH)
|
if (attribute & S_IWOTH)
|
||||||
other_allow |= STANDARD_RIGHTS_ALL | FILE_GENERIC_WRITE | DELETE;
|
other_allow |= STANDARD_RIGHTS_WRITE | FILE_GENERIC_WRITE | DELETE;
|
||||||
if (attribute & S_IXOTH)
|
if (attribute & S_IXOTH)
|
||||||
other_allow |= FILE_GENERIC_EXECUTE;
|
other_allow |= FILE_GENERIC_EXECUTE;
|
||||||
if (! (attribute & S_ISVTX))
|
if (! (attribute & S_ISVTX))
|
||||||
@ -1034,9 +985,9 @@ set_nt_attribute (const char *file, uid_t uid, gid_t gid,
|
|||||||
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret = ReadSD (file, psd, &sd_size)) <= 0)
|
if ((ret = read_sd (file, psd, &sd_size)) <= 0)
|
||||||
{
|
{
|
||||||
debug_printf ("ReadSD %E");
|
debug_printf ("read_sd %E");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +995,7 @@ set_nt_attribute (const char *file, uid_t uid, gid_t gid,
|
|||||||
if (! (psd = alloc_sd (uid, gid, logsrv, attribute, psd, &sd_size)))
|
if (! (psd = alloc_sd (uid, gid, logsrv, attribute, psd, &sd_size)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return WriteSD (file, psd, sd_size);
|
return write_sd (file, psd, sd_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1100,9 +1051,9 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
|
|||||||
char sd_buf[4096];
|
char sd_buf[4096];
|
||||||
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
||||||
|
|
||||||
if (ReadSD (file, psd, &sd_size) <= 0)
|
if (read_sd (file, psd, &sd_size) <= 0)
|
||||||
{
|
{
|
||||||
debug_printf ("ReadSD %E");
|
debug_printf ("read_sd %E");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1265,7 +1216,7 @@ setacl (const char *file, int nentries, aclent_t *aclbufp)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
debug_printf ("Created SD-Size: %d", sd_size);
|
debug_printf ("Created SD-Size: %d", sd_size);
|
||||||
return WriteSD (file, psd, sd_size);
|
return write_sd (file, psd, sd_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1301,9 +1252,9 @@ getacl (const char *file, DWORD attr, int nentries, aclent_t *aclbufp)
|
|||||||
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret = ReadSD (file, psd, &sd_size)) <= 0)
|
if ((ret = read_sd (file, psd, &sd_size)) <= 0)
|
||||||
{
|
{
|
||||||
debug_printf ("ReadSD %E");
|
debug_printf ("read_sd %E");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,6 +982,8 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
|
|||||||
char *win32_name;
|
char *win32_name;
|
||||||
char root[MAX_PATH];
|
char root[MAX_PATH];
|
||||||
UINT dtype;
|
UINT dtype;
|
||||||
|
fhandler_disk_file fh (NULL);
|
||||||
|
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
|
|
||||||
debug_printf ("%s (%s, %p)", caller, name, buf);
|
debug_printf ("%s (%s, %p)", caller, name, buf);
|
||||||
@ -1009,28 +1011,15 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
|
|||||||
strcpy (root, win32_name);
|
strcpy (root, win32_name);
|
||||||
dtype = GetDriveType (rootdir (root));
|
dtype = GetDriveType (rootdir (root));
|
||||||
|
|
||||||
if (atts == -1 || !(atts & FILE_ATTRIBUTE_DIRECTORY) ||
|
if ((atts == -1 || !(atts & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||||
(os_being_run == winNT
|
(os_being_run == winNT
|
||||||
&& dtype != DRIVE_NO_ROOT_DIR
|
&& dtype != DRIVE_NO_ROOT_DIR
|
||||||
&& dtype != DRIVE_UNKNOWN))
|
&& dtype != DRIVE_UNKNOWN))
|
||||||
|
&& fh.open (real_path, O_RDONLY | O_BINARY | O_DIROPEN |
|
||||||
|
(nofollow ? O_NOSYMLINK : 0), 0))
|
||||||
{
|
{
|
||||||
fhandler_disk_file fh (NULL);
|
res = fh.fstat (buf);
|
||||||
|
fh.close ();
|
||||||
if (fh.open (real_path, O_RDONLY | O_BINARY | O_DIROPEN |
|
|
||||||
(nofollow ? O_NOSYMLINK : 0), 0))
|
|
||||||
{
|
|
||||||
res = fh.fstat (buf);
|
|
||||||
fh.close ();
|
|
||||||
/* See the comment 10 lines below */
|
|
||||||
if (atts != -1 && (atts & FILE_ATTRIBUTE_DIRECTORY))
|
|
||||||
buf->st_nlink =
|
|
||||||
(dtype == DRIVE_REMOTE ? 1 : num_entries (win32_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WIN32_FIND_DATA wfd;
|
|
||||||
HANDLE handle;
|
|
||||||
/* The number of links to a directory includes the
|
/* The number of links to a directory includes the
|
||||||
number of subdirectories in the directory, since all
|
number of subdirectories in the directory, since all
|
||||||
those subdirectories point to it.
|
those subdirectories point to it.
|
||||||
@ -1038,26 +1027,54 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
|
|||||||
set the number of links to 2. */
|
set the number of links to 2. */
|
||||||
/* Unfortunately the count of 2 confuses `find(1)' command. So
|
/* Unfortunately the count of 2 confuses `find(1)' command. So
|
||||||
let's try it with `1' as link count. */
|
let's try it with `1' as link count. */
|
||||||
buf->st_nlink = (dtype == DRIVE_REMOTE ? 1 : num_entries (win32_name));
|
if (atts != -1 && (atts & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
buf->st_nlink =
|
||||||
|
(dtype == DRIVE_REMOTE ? 1 : num_entries (win32_name));
|
||||||
|
}
|
||||||
|
else if (atts != -1 || GetLastError () != ERROR_FILE_NOT_FOUND)
|
||||||
|
{
|
||||||
|
/* Unfortunately, the above open may fail. So we have
|
||||||
|
to care for this case here, too. */
|
||||||
|
WIN32_FIND_DATA wfd;
|
||||||
|
HANDLE handle;
|
||||||
|
buf->st_nlink = 1;
|
||||||
|
if (atts != -1
|
||||||
|
&& (atts & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
|
&& dtype != DRIVE_REMOTE)
|
||||||
|
buf->st_nlink = num_entries (win32_name);
|
||||||
buf->st_dev = FHDEVN(FH_DISK) << 8;
|
buf->st_dev = FHDEVN(FH_DISK) << 8;
|
||||||
buf->st_ino = hash_path_name (0, real_path.get_win32 ());
|
buf->st_ino = hash_path_name (0, real_path.get_win32 ());
|
||||||
buf->st_mode = S_IFDIR | STD_RBITS | STD_XBITS;
|
if (atts != -1 && (atts & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
if ((atts & FILE_ATTRIBUTE_READONLY) == 0)
|
buf->st_mode = S_IFDIR;
|
||||||
buf->st_mode |= STD_WBITS;
|
else if (real_path.issymlink ())
|
||||||
|
buf->st_mode = S_IFLNK;
|
||||||
get_file_attribute (real_path.has_acls (), real_path.get_win32 (),
|
else if (real_path.issocket ())
|
||||||
NULL, &buf->st_uid, &buf->st_gid);
|
buf->st_mode = S_IFSOCK;
|
||||||
|
else
|
||||||
if ((handle = FindFirstFile (real_path.get_win32(), &wfd)) != INVALID_HANDLE_VALUE)
|
buf->st_mode = S_IFREG;
|
||||||
{
|
if (!real_path.has_acls ()
|
||||||
buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
|
|| get_file_attribute (real_path.has_acls (), real_path.get_win32 (),
|
||||||
buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
|
&buf->st_mode, &buf->st_uid, &buf->st_gid))
|
||||||
buf->st_ctime = to_time_t (&wfd.ftCreationTime);
|
{
|
||||||
buf->st_size = wfd.nFileSizeLow;
|
buf->st_mode |= STD_RBITS | STD_XBITS;
|
||||||
buf->st_blksize = S_BLKSIZE;
|
if ((atts & FILE_ATTRIBUTE_READONLY) == 0)
|
||||||
buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
|
buf->st_mode |= STD_WBITS;
|
||||||
FindClose (handle);
|
get_file_attribute (FALSE, real_path.get_win32 (),
|
||||||
}
|
NULL, &buf->st_uid, &buf->st_gid);
|
||||||
|
}
|
||||||
|
if ((handle = FindFirstFile (real_path.get_win32(), &wfd))
|
||||||
|
== INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
|
||||||
|
buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
|
||||||
|
buf->st_ctime = to_time_t (&wfd.ftCreationTime);
|
||||||
|
buf->st_size = wfd.nFileSizeLow;
|
||||||
|
buf->st_blksize = S_BLKSIZE;
|
||||||
|
buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
|
||||||
|
FindClose (handle);
|
||||||
res = 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user