Rewrite attribute handling code.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14454 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2002-09-16 11:30:22 +00:00
parent 4aabe798ba
commit a48b2ccb08
4 changed files with 648 additions and 350 deletions

View file

@ -1,3 +1,11 @@
2002-09-16 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSFileManager.m: Basic/dummy implementations of new MacOS-X
methods added. Attribute handling totally rewritten to work in a lazy
way ... so we only set up attribute info in the dictionary when we
actually need it. Account 'Number' methods and dictionary keys changed
to be account 'ID' instead ... in accordance with MacOS-X usage.
2002-09-15 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSFileManager.m: MacOS-X ([componentsToDisplayForPath:]) and

View file

@ -130,14 +130,18 @@
@end /* NSDirectoryEnumerator */
/* File Attributes */
GS_EXPORT NSString* const NSFileAppendOnly;
GS_EXPORT NSString* const NSFileCreationDate;
GS_EXPORT NSString* const NSFileDeviceIdentifier;
GS_EXPORT NSString* const NSFileExtensionHidden;
GS_EXPORT NSString* const NSFileGroupOwnerAccountID;
GS_EXPORT NSString* const NSFileGroupOwnerAccountName;
GS_EXPORT NSString* const NSFileGroupOwnerAccountNumber;
GS_EXPORT NSString* const NSFileDeviceIdentifier;
GS_EXPORT NSString* const NSFileHFSCreatorCode;
GS_EXPORT NSString* const NSFileHFSTypeCode;
GS_EXPORT NSString* const NSFileImmutable;
GS_EXPORT NSString* const NSFileModificationDate;
GS_EXPORT NSString* const NSFileOwnerAccountID;
GS_EXPORT NSString* const NSFileOwnerAccountName;
GS_EXPORT NSString* const NSFileOwnerAccountNumber;
GS_EXPORT NSString* const NSFilePosixPermissions;
GS_EXPORT NSString* const NSFileReferenceCount;
GS_EXPORT NSString* const NSFileSize;
@ -166,19 +170,22 @@ GS_EXPORT NSString* const NSFileSystemFreeNodes;
/* Easy access to attributes in a dictionary */
@interface NSDictionary(NSFileAttributes)
- (NSDate*) fileCreationDate;
- (BOOL) fileExtensionHidden;
- (int) fileHFSCreatorCode;
- (int) fileHFSTypeCode;
- (BOOL) fileIsAppendOnly;
- (BOOL) fileIsImmutable;
- (unsigned long long) fileSize;
- (NSString*) fileType;
- (unsigned long) fileOwnerAccountID;
- (NSString*) fileOwnerAccountName;
- (unsigned long) fileGroupOwnerAccountID;
- (NSString*) fileGroupOwnerAccountName;
- (NSDate*) fileModificationDate;
- (unsigned long) filePosixPermissions;
- (unsigned long) fileSystemNumber;
- (unsigned long) fileSystemFileNumber;
#ifndef STRICT_MACOS_X
- (unsigned long) fileOwnerAccountNumber;
- (unsigned long) fileGroupOwnerAccountNumber;
#endif
@end
#endif

View file

@ -41,6 +41,9 @@
#include <Foundation/NSLock.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSEnumerator.h>
#include <Foundation/NSSet.h>
#include <stdio.h>
@ -154,6 +157,34 @@
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSFileManager.h>
/**
* GSAttrDictionary is a private NSDictionary subclass used to
* handle file attributes efficiently ... using lazy evaluation
* to ensure that we only do the minimum work necessary at any time.
*/
@interface GSAttrDictionary : NSDictionary
{
#ifdef __MINGW__
const char *name;
#endif
struct stat statbuf;
}
+ (NSDictionary*) attributesAt: (const char*)cpath traverseLink: (BOOL)traverse;
@end
/**
* We also need a special enumerator class to enumerate the dictionary.
*/
@interface GSAttrDictionaryEnumerator : NSEnumerator
{
NSDictionary *dictionary;
NSEnumerator *enumerator;
}
+ (NSEnumerator*) enumeratorFor: (NSDictionary*)d;
@end
@interface NSFileManager (PrivateMethods)
/* Copies the contents of source file to destination file. Assumes source
@ -167,16 +198,8 @@
toPath: (NSString*)destination
handler: (id)handler;
- (NSDictionary*) _attributesAtPath: (NSString*)path
traverseLink: (BOOL)traverse
forCopy: (BOOL)copy;
@end /* NSFileManager (PrivateMethods) */
@interface NSDirectoryEnumerator (PrivateMethods)
- (NSDictionary*) _attributesForCopy;
@end
/*
* NSFileManager implementation
*/
@ -278,8 +301,8 @@ static NSFileManager* defaultManager = nil;
* If there is no file owner specified, and we are running setuid to
* root, then we assume we need to change ownership to correct user.
*/
if ([attributes objectForKey: NSFileOwnerAccountName] == nil
&& [attributes objectForKey: NSFileOwnerAccountNumber] == nil
if ([attributes objectForKey: NSFileOwnerAccountID] == nil
&& [attributes objectForKey: NSFileOwnerAccountName] == nil
&& geteuid() == 0 && [@"root" isEqualToString: NSUserName()] == NO)
{
needChown = [NSDictionary dictionaryWithObjectsAndKeys:
@ -341,7 +364,7 @@ static NSFileManager* defaultManager = nil;
return NO;
}
// if last directory and attributes then change
if (cur == len && attributes)
if (cur == len && attributes != nil)
{
if ([self changeFileAttributes: attributes
atPath: [self stringWithFileSystemRepresentation: dirpath
@ -395,20 +418,14 @@ static NSFileManager* defaultManager = nil;
toPath: (NSString*)destination
handler: handler
{
BOOL fileExists;
NSDictionary *attrs;
NSString *fileType;
attrs = [self _attributesAtPath: source traverseLink: NO forCopy: YES];
attrs = [self fileAttributesAtPath: source traverseLink: NO];
if (attrs == nil)
{
return NO;
}
fileExists = [self fileExistsAtPath: destination];
if (fileExists)
{
return NO;
}
fileType = [attrs objectForKey: NSFileType];
if ([fileType isEqualToString: NSFileTypeDirectory] == YES)
{
@ -495,11 +512,6 @@ static NSFileManager* defaultManager = nil;
{
return NO;
}
fileExists = [self fileExistsAtPath: destination];
if (fileExists)
{
return NO;
}
/* Check to see if the source and destination's parent are on the same
physical device so we can perform a rename syscall directly. */
@ -526,9 +538,8 @@ static NSFileManager* defaultManager = nil;
{
NSDictionary *attributes;
attributes = [self _attributesAtPath: source
traverseLink: NO
forCopy: YES];
attributes = [self fileAttributesAtPath: source
traverseLink: NO];
[self changeFileAttributes: attributes atPath: destination];
return [self removeFileAtPath: source handler: handler];
}
@ -758,8 +769,8 @@ static NSFileManager* defaultManager = nil;
* If there is no file owner specified, and we are running setuid to
* root, then we assume we need to change ownership to correct user.
*/
if ([attributes objectForKey: NSFileOwnerAccountName] == nil
&& [attributes objectForKey: NSFileOwnerAccountNumber] == nil
if ([attributes objectForKey: NSFileOwnerAccountID] == nil
&& [attributes objectForKey: NSFileOwnerAccountName] == nil
&& geteuid() == 0 && [@"root" isEqualToString: NSUserName()] == NO)
{
attributes = [NSDictionary dictionaryWithObjectsAndKeys:
@ -1016,7 +1027,11 @@ static NSFileManager* defaultManager = nil;
- (NSDictionary*) fileAttributesAtPath: (NSString*)path traverseLink: (BOOL)flag
{
return [self _attributesAtPath: path traverseLink: flag forCopy: NO];
const char *cpath = [self fileSystemRepresentationWithPath: path];
NSDictionary *d;
d = [GSAttrDictionary attributesAt: cpath traverseLink: flag];
return d;
}
- (NSDictionary*) fileSystemAttributesAtPath: (NSString*)path
@ -1104,23 +1119,35 @@ static NSFileManager* defaultManager = nil;
#endif /* MINGW */
}
/**
* Change the attributes of the file at path to those specified.<br />
* Returns YES if all requested changes were made (or if the dictionary
* was nil or empty, so no changes were requested), NO otherwise.<br />
* On failure, some fo the requested changes may have taken place.<br />
*/
- (BOOL) changeFileAttributes: (NSDictionary*)attributes atPath: (NSString*)path
{
const char *cpath = [self fileSystemRepresentationWithPath: path];
NSNumber *num;
const char *cpath;
unsigned long num;
NSString *str;
NSDate *date;
BOOL allOk = YES;
#ifndef __MINGW__
num = [attributes objectForKey: NSFileOwnerAccountNumber];
if (num)
if (attributes == nil)
{
if (chown(cpath, [num intValue], -1) != 0)
return YES;
}
cpath = [self fileSystemRepresentationWithPath: path];
#ifndef __MINGW__
num = [attributes fileOwnerAccountID];
if (num != NSNotFound)
{
if (chown(cpath, num, -1) != 0)
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFileOwnerAccountNumber to '%@'", num];
@"Unable to change NSFileOwnerAccountID to '%u' - %s",
num, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
@ -1132,7 +1159,7 @@ static NSFileManager* defaultManager = nil;
#ifdef HAVE_PWD_H
struct passwd *pw = getpwnam([str cString]);
if (pw)
if (pw != 0)
{
ok = (chown(cpath, pw->pw_uid, -1) == 0);
chown(cpath, -1, pw->pw_gid);
@ -1142,20 +1169,22 @@ static NSFileManager* defaultManager = nil;
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFileOwnerAccountName to '%@'", str];
@"Unable to change NSFileOwnerAccountName to '%@' - %s",
str, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
}
num = [attributes objectForKey: NSFileGroupOwnerAccountNumber];
if (num)
num = [attributes fileGroupOwnerAccountID];
if (num != NSNotFound)
{
if (chown(cpath, -1, [num intValue]) != 0)
if (chown(cpath, -1, num) != 0)
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFileGroupOwnerAccountNumber to '%@'", num];
@"Unable to change NSFileGroupOwnerAccountID to '%u' - %s",
num, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
@ -1175,26 +1204,28 @@ static NSFileManager* defaultManager = nil;
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFileGroupOwnerAccountName to '%@'", str];
@"Unable to change NSFileGroupOwnerAccountName to '%@' - %s",
str, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
#endif /* __MINGW__ */
num = [attributes objectForKey: NSFilePosixPermissions];
if (num)
num = [attributes filePosixPermissions];
if (num != NSNotFound)
{
if (chmod(cpath, [num intValue]) != 0)
if (chmod(cpath, num) != 0)
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFilePosixPermissions to '%o'", [num intValue]];
@"Unable to change NSFilePosixPermissions to '%o' - %s",
num, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
date = [attributes objectForKey: NSFileModificationDate];
if (date)
if (date != nil)
{
BOOL ok = NO;
struct stat sb;
@ -1230,7 +1261,8 @@ static NSFileManager* defaultManager = nil;
{
allOk = NO;
str = [NSString stringWithFormat:
@"Unable to change NSFileModificationDate to '%@'", date];
@"Unable to change NSFileModificationDate to '%@' - %s",
date, GSLastErrorStr(errno)];
ASSIGN(_lastError, str);
}
}
@ -1409,12 +1441,11 @@ static NSFileManager* defaultManager = nil;
path = [path stringByStandardizingPath];
newpath = path;
c_path = [path cString];
l = strlen(c_path);
if (c_path == 0)
{
return 0;
}
l = strlen(c_path);
if (l >= 2 && c_path[0] == '~' && isalpha(c_path[1])
&& (l == 2 || c_path[2] == '/'))
{
@ -1898,74 +1929,174 @@ static SEL swfsSel = 0;
@end /* NSDirectoryEnumerator */
@implementation NSDirectoryEnumerator (PrivateMethods)
- (NSDictionary*) _attributesForCopy
{
NSString *currentFilePath;
currentFilePath = _stringWithFileSysImp(defaultManager, swfsSel,
_current_file_path,
strlen(_current_file_path));
return [defaultManager _attributesAtPath: currentFilePath
traverseLink: _flags.isFollowing
forCopy: YES];
}
@end
/*
* Attributes dictionary access
*/
@implementation NSDictionary(NSFileAttributes)
- (unsigned long long) fileSize
/**
* Return the file creation date attribute (or nil if not found).
*/
- (NSDate*) fileCreationDate
{
return [[self objectForKey: NSFileSize] unsignedLongLongValue];
return [self objectForKey: NSFileCreationDate];
}
/**
* Return the file extension hidden attribute (or NO if not found).
*/
- (BOOL) fileExtensionHidden
{
return [[self objectForKey: NSFileExtensionHidden] boolValue];
}
- (int) fileHFSCreatorCode
{
return [[self objectForKey: NSFileHFSCreatorCode] intValue];
}
- (int) fileHFSTypeCode
{
return [[self objectForKey: NSFileHFSTypeCode] intValue];
}
/**
* Return the file append only attribute (or NO if not found).
*/
- (BOOL) fileIsAppendOnly
{
return [[self objectForKey: NSFileAppendOnly] boolValue];
}
/**
* Return the file immutable attribute (or NO if not found).
*/
- (BOOL) fileIsImmutable
{
return [[self objectForKey: NSFileImmutable] boolValue];
}
/**
* Return the size of the file, or NSNotFound if the file size attribute
* is not found in the dictionary.
*/
- (unsigned long long) fileSize
{
NSNumber *n = [self objectForKey: NSFileSize];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedLongLongValue];
}
/**
* Return the file type attribute or nil if not present.
*/
- (NSString*) fileType
{
return [self objectForKey: NSFileType];
}
/**
* Return the file owner account name attribute or nil if not present.
*/
- (NSString*) fileOwnerAccountName
{
return [self objectForKey: NSFileOwnerAccountName];
}
- (unsigned long) fileOwnerAccountNumber
/**
* Return the numeric value of the NSFileOwnerAccountID attribute
* in the dictionary, or NSNotFound if the attribute is not present.
*/
- (unsigned long) fileOwnerAccountID
{
return [[self objectForKey: NSFileOwnerAccountNumber] unsignedIntValue];
NSNumber *n = [self objectForKey: NSFileOwnerAccountID];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedIntValue];
}
/**
* Return the file group owner account name attribute or nil if not present.
*/
- (NSString*) fileGroupOwnerAccountName
{
return [self objectForKey: NSFileGroupOwnerAccountName];
}
- (unsigned long) fileGroupOwnerAccountNumber
/**
* Return the numeric value of the NSFileGroupOwnerAccountID attribute
* in the dictionary, or NSNotFound if the attribute is not present.
*/
- (unsigned long) fileGroupOwnerAccountID
{
return [[self objectForKey: NSFileGroupOwnerAccountNumber] unsignedIntValue];
NSNumber *n = [self objectForKey: NSFileGroupOwnerAccountID];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedIntValue];
}
/**
* Return the file modification date attribute (or nil if not found)
*/
- (NSDate*) fileModificationDate
{
return [self objectForKey: NSFileModificationDate];
}
/**
* Return the file posix permissions attribute (or NSNotFound if
* the attribute is not present in the dictionary).
*/
- (unsigned long) filePosixPermissions
{
return [[self objectForKey: NSFilePosixPermissions] unsignedLongValue];
NSNumber *n = [self objectForKey: NSFilePosixPermissions];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedLongValue];
}
/**
* Return the file system number attribute (or NSNotFound if
* the attribute is not present in the dictionary).
*/
- (unsigned long) fileSystemNumber
{
return [[self objectForKey: NSFileSystemNumber] unsignedLongValue];
NSNumber *n = [self objectForKey: NSFileSystemNumber];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedLongValue];
}
/**
* Return the file system file identification number attribute
* or NSNotFound if the attribute is not present in the dictionary).
*/
- (unsigned long) fileSystemFileNumber
{
return [[self objectForKey: NSFileSystemFileNumber] unsignedLongValue];
NSNumber *n = [self objectForKey: NSFileSystemFileNumber];
if (n == nil)
{
return NSNotFound;
}
return [n unsignedLongValue];
}
@end
@ -2012,7 +2143,7 @@ static SEL swfsSel = 0;
NSAssert1 ([self fileExistsAtPath: source],
@"source file '%@' does not exist!", source);
attributes = [self _attributesAtPath: source traverseLink: NO forCopy: YES];
attributes = [self fileAttributesAtPath: source traverseLink: NO];
NSAssert1 (attributes, @"could not get the attributes for file '%@'",
source);
@ -2132,7 +2263,7 @@ static SEL swfsSel = 0;
NSString *destinationFile;
NSDictionary *attributes;
attributes = [enumerator _attributesForCopy];
attributes = [enumerator fileAttributes];
fileType = [attributes objectForKey: NSFileType];
sourceFile = [source stringByAppendingPathComponent: dirEntry];
destinationFile
@ -2219,101 +2350,179 @@ static SEL swfsSel = 0;
return YES;
}
@end /* NSFileManager (PrivateMethods) */
@implementation GSAttrDictionary
static NSSet *fileKeys = nil;
+ (NSDictionary*) attributesAt: (const char*)cpath traverseLink: (BOOL)traverse
{
GSAttrDictionary *d;
d = (GSAttrDictionary*)NSAllocateObject(self, 0, NSDefaultMallocZone());
#ifdef __MINGW__
d->name = NSZoneMalloc(NSDefaultMallocZone(), strlen(cpath)+1);
strcpy(d->name, cpath);
#endif
#if defined(S_IFLNK) && !defined(__MINGW__)
if (traverse == NO)
{
if (lstat(cpath, &d->statbuf) != 0)
{
DESTROY(d);
}
}
else
#endif
if (stat(cpath, &d->statbuf) != 0)
{
DESTROY(d);
}
return AUTORELEASE(d);
}
+ (void) initialize
{
if (fileKeys == nil)
{
fileKeys = [NSSet setWithObjects:
NSFileAppendOnly,
NSFileCreationDate,
NSFileDeviceIdentifier,
NSFileExtensionHidden,
NSFileGroupOwnerAccountName,
NSFileGroupOwnerAccountID,
NSFileHFSCreatorCode,
NSFileHFSTypeCode,
NSFileImmutable,
NSFileModificationDate,
NSFileOwnerAccountName,
NSFileOwnerAccountID,
NSFilePosixPermissions,
NSFileReferenceCount,
NSFileSize,
NSFileSystemFileNumber,
NSFileSystemNumber,
NSFileType,
nil];
RETAIN(fileKeys);
}
}
- (unsigned int) count
{
return [fileKeys count];
}
- (void) dealloc
{
#ifdef __MINGW__
if (name != 0)
NSZoneFree(name);
#endif
[super dealloc];
}
- (NSDate*) fileCreationDate
{
/*
* FIXME ... not sure there is any way to get a creation date :-(
* Use the earlier of ctime or mtime
*/
if (statbuf.st_ctime < statbuf.st_mtime)
return [NSDate dateWithTimeIntervalSince1970: statbuf.st_ctime];
else
return [NSDate dateWithTimeIntervalSince1970: statbuf.st_mtime];
}
- (BOOL) fileExtensionHidden
{
return NO;
}
- (unsigned long) fileGroupOwnerAccountID
{
return statbuf.st_gid;
}
#if (defined(sparc) && defined(DEBUG))
static int sparc_warn = 0;
#endif
- (NSDictionary*) _attributesAtPath: (NSString*)path
traverseLink: (BOOL)traverse
forCopy: (BOOL)copy
- (NSString*) fileGroupOwnerAccountName
{
struct stat statbuf;
const char* cpath = [self fileSystemRepresentationWithPath: path];
int mode;
int count;
id values[13];
id keys[13] = {
NSFileSize,
NSFileCreationDate,
NSFileModificationDate,
NSFileReferenceCount,
NSFileSystemNumber,
NSFileSystemFileNumber,
NSFileDeviceIdentifier,
NSFilePosixPermissions,
NSFileType,
NSFileOwnerAccountName,
NSFileGroupOwnerAccountName,
NSFileOwnerAccountNumber,
NSFileGroupOwnerAccountNumber
};
NSString *result = @"UnknownGroup";
#if defined(HAVE_GRP_H) && !(defined(sparc) && defined(DEBUG))
struct group *gp;
#if defined(__MINGW__)
if (stat(cpath, &statbuf) != 0)
gp = getgrgid(statbuf.st_gid);
if (gp != 0)
{
return nil;
result = [NSString stringWithCString: gp->gr_name];
}
#else /* !(__MINGW__) */
if (traverse)
#else
#if (defined(sparc) && defined(DEBUG))
if (sparc_warn == 0)
{
if (stat(cpath, &statbuf) != 0)
{
return nil;
sparc_warn = 1;
/* Can't be NSLog - causes recursion in [NSUser -synchronize] */
fprintf(stderr, "WARNING (NSFileManager): Disabling group enums (setgrent, etc) since this crashes gdb on sparc machines\n");
}
}
#ifdef S_IFLNK
else
{
if (lstat(cpath, &statbuf) != 0)
{
return nil;
}
}
#endif /* (S_IFLNK) */
#endif /* (__MINGW__) */
values[0] = [NSNumber numberWithUnsignedLongLong: statbuf.st_size];
values[1] = [NSDate dateWithTimeIntervalSince1970: statbuf.st_ctime];
values[2] = [NSDate dateWithTimeIntervalSince1970: statbuf.st_mtime];
values[3] = [NSNumber numberWithUnsignedInt: statbuf.st_nlink];
values[4] = [NSNumber numberWithUnsignedLong: statbuf.st_dev];
values[5] = [NSNumber numberWithUnsignedLong: statbuf.st_ino];
values[6] = [NSNumber numberWithUnsignedInt: statbuf.st_dev];
values[7] = [NSNumber numberWithUnsignedInt: statbuf.st_mode];
mode = statbuf.st_mode & S_IFMT;
if (mode == S_IFREG)
values[8] = NSFileTypeRegular;
else if (mode == S_IFDIR)
values[8] = NSFileTypeDirectory;
else if (mode == S_IFCHR)
values[8] = NSFileTypeCharacterSpecial;
else if (mode == S_IFBLK)
values[8] = NSFileTypeBlockSpecial;
#ifdef S_IFLNK
else if (mode == S_IFLNK)
values[8] = NSFileTypeSymbolicLink;
#endif
else if (mode == S_IFIFO)
values[8] = NSFileTypeFifo;
#ifdef S_IFSOCK
else if (mode == S_IFSOCK)
values[8] = NSFileTypeSocket;
#endif
else
values[8] = NSFileTypeUnknown;
return result;
}
if (copy == NO)
- (int) fileHFSCreatorCode
{
return 0;
}
- (int) fileHFSTypeCode
{
return 0;
}
- (BOOL) fileIsAppendOnly
{
return 0;
}
- (BOOL) fileIsImmutable
{
return 0;
}
- (NSDate*) fileModificationDate
{
return [NSDate dateWithTimeIntervalSince1970: statbuf.st_mtime];
}
- (unsigned long) filePosixPermissions
{
return (statbuf.st_mode & ~S_IFMT);
}
- (unsigned long) fileOwnerAccountID
{
return statbuf.st_uid;
}
- (NSString*) fileOwnerAccountName
{
NSString *result = @"UnknownUser";
#ifdef __MINGW_NOT_AVAILABLE_YET
{
DWORD dwRtnCode = 0;
PSID pSidOwner;
BOOL bRtnBool = TRUE;
LPTSTR AcctName, DomainName;
DWORD dwAcctName = 1, dwDomainName = 1;
LPTSTR AcctName;
LPTSTR DomainName;
DWORD dwAcctName = 1;
DWORD dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD;
@ -2435,96 +2644,168 @@ static int sparc_warn = 0;
return 0;
}
#endif
#ifdef HAVE_PWD_H
{
struct passwd *pw;
pw = getpwuid(statbuf.st_uid);
if (pw)
if (pw != 0)
{
values[9] = [NSString stringWithCString: pw->pw_name];
result = [NSString stringWithCString: pw->pw_name];
}
else
{
values[9] = @"UnknownUser";
}
}
#else
values[9] = @"UnknownUser";
#endif /* HAVE_PWD_H */
return result;
}
#if defined(HAVE_GRP_H) && !(defined(sparc) && defined(DEBUG))
- (unsigned long long) fileSize
{
struct group *gp;
return statbuf.st_size;
}
setgrent();
while ((gp = getgrent()) != 0)
- (unsigned long) fileSystemFileNumber
{
if (gp->gr_gid == statbuf.st_gid)
return statbuf.st_ino;
}
- (unsigned long) fileSystemNumber
{
break;
return statbuf.st_dev;
}
}
if (gp)
- (NSString*) fileType
{
values[10] = [NSString stringWithCString: gp->gr_name];
}
else
switch (statbuf.st_mode & S_IFMT)
{
values[10] = @"UnknownGroup";
}
endgrent();
}
#else
#if (defined(sparc) && defined(DEBUG))
if (sparc_warn == 0)
{
sparc_warn = 1;
/* Can't be NSLog - causes recursion in [NSUser -synchronize] */
fprintf(stderr, "WARNING (NSFileManager): Disabling group enums (setgrent, etc) since this crashes gdb on sparc machines\n");
}
case S_IFREG: return NSFileTypeRegular;
case S_IFDIR: return NSFileTypeDirectory;
case S_IFCHR: return NSFileTypeCharacterSpecial;
case S_IFBLK: return NSFileTypeBlockSpecial;
#ifdef S_IFLNK
case S_IFLNK: return NSFileTypeSymbolicLink;
#endif
values[10] = @"UnknownGroup";
case S_IFIFO: return NSFileTypeFifo;
#ifdef S_IFSOCK
case S_IFSOCK: return NSFileTypeSocket;
#endif
values[11] = [NSNumber numberWithUnsignedInt: statbuf.st_uid];
values[12] = [NSNumber numberWithUnsignedInt: statbuf.st_gid];
count = 13;
default: return NSFileTypeUnknown;
}
}
else
{
NSString *u = NSUserName();
count = 9; /* No ownership details needed. */
- (NSEnumerator*) keyEnumerator
{
return [fileKeys objectEnumerator];
}
- (NSEnumerator*) objectEnumerator
{
return [GSAttrDictionaryEnumerator enumeratorFor: self];
}
- (id) objectForKey: (NSString*)key
{
int count = 0;
while (key != 0 && count < 2)
{
if (key == NSFileAppendOnly)
return [NSNumber numberWithBool: [self fileIsAppendOnly]];
if (key == NSFileCreationDate)
return [self fileCreationDate];
if (key == NSFileDeviceIdentifier)
return [NSNumber numberWithUnsignedInt: statbuf.st_dev];
if (key == NSFileExtensionHidden)
return [NSNumber numberWithBool: [self fileExtensionHidden]];
if (key == NSFileGroupOwnerAccountName)
return [self fileGroupOwnerAccountName];
if (key == NSFileGroupOwnerAccountID)
return [NSNumber numberWithInt: [self fileGroupOwnerAccountID]];
if (key == NSFileHFSCreatorCode)
return [NSNumber numberWithInt: [self fileHFSCreatorCode]];
if (key == NSFileHFSTypeCode)
return [NSNumber numberWithInt: [self fileHFSTypeCode]];
if (key == NSFileImmutable)
return [NSNumber numberWithBool: [self fileIsImmutable]];
if (key == NSFileModificationDate)
return [self fileModificationDate];
if (key == NSFileOwnerAccountName)
return [self fileOwnerAccountName];
if (key == NSFileOwnerAccountID)
return [NSNumber numberWithInt: [self fileOwnerAccountID]];
if (key == NSFilePosixPermissions)
return [NSNumber numberWithUnsignedInt: [self filePosixPermissions]];
if (key == NSFileReferenceCount)
return [NSNumber numberWithUnsignedInt: statbuf.st_nlink];
if (key == NSFileSize)
return [NSNumber numberWithUnsignedLongLong: [self fileSize]];
if (key == NSFileSystemFileNumber)
return [NSNumber numberWithUnsignedInt: [self fileSystemFileNumber]];
if (key == NSFileSystemNumber)
return [NSNumber numberWithUnsignedInt: [self fileSystemNumber]];
if (key == NSFileType)
return [self fileType];
/*
* If we are running setuid to root - we need to specify the user
* to be the owner of copied files.
* Now, if we didn't get an exact pointer match, check for
* string equalities and ensure we get an exact match next
* time round the loop.
*/
#ifdef HAVE_GETEUID
if (geteuid() == 0 && [@"root" isEqualToString: u] == NO)
count++;
key = [fileKeys member: key];
}
if (count >= 2)
{
values[count++] = u;
NSLog(@"Warning ... key '%@' not handled", key);
}
#endif
return nil;
}
return [NSDictionary dictionaryWithObjects: values
forKeys: keys
count: count];
@end /* GSAttrDictionary */
@implementation GSAttrDictionaryEnumerator
+ (NSEnumerator*) enumeratorFor: (NSDictionary*)d
{
GSAttrDictionaryEnumerator *e;
e = (GSAttrDictionaryEnumerator*)
NSAllocateObject(self, 0, NSDefaultMallocZone());
e->dictionary = RETAIN(d);
e->enumerator = RETAIN([fileKeys objectEnumerator]);
return AUTORELEASE(e);
}
@end /* NSFileManager (PrivateMethods) */
- (void) dealloc
{
RELEASE(enumerator);
RELEASE(dictionary);
[super dealloc];
}
- (id) nextObject
{
NSString *key = [enumerator nextObject];
id val = nil;
if (key != nil)
{
val = [dictionary objectForKey: key];
}
return val;
}
@end
NSString * const NSFileAppendOnly = @"NSFileAppendOnly";
NSString * const NSFileCreationDate = @"NSFileCreationDate";
NSString * const NSFileDeviceIdentifier = @"NSFileDeviceIdentifier";
NSString * const NSFileExtensionHidden = @"NSFileExtensionHidden";
NSString * const NSFileGroupOwnerAccountID = @"NSFileGroupOwnerAccountID";
NSString * const NSFileGroupOwnerAccountName = @"NSFileGroupOwnerAccountName";
NSString * const NSFileGroupOwnerAccountNumber = @"NSFileGroupOwnerAccountNumber";
NSString * const NSFileHFSCreatorCode = @"NSFileHFSCreatorCode";
NSString * const NSFileHFSTypeCode = @"NSFileHFSTypeCode";
NSString * const NSFileImmutable = @"NSFileImmutable";
NSString * const NSFileModificationDate = @"NSFileModificationDate";
NSString * const NSFileOwnerAccountID = @"NSFileOwnerAccountID";
NSString * const NSFileOwnerAccountName = @"NSFileOwnerAccountName";
NSString * const NSFileOwnerAccountNumber = @"NSFileOwnerAccountNumber";
NSString * const NSFilePosixPermissions = @"NSFilePosixPermissions";
NSString * const NSFileReferenceCount = @"NSFileReferenceCount";
NSString * const NSFileSize = @"NSFileSize";
@ -2543,3 +2824,5 @@ NSString * const NSFileTypeRegular = @"NSFileTypeRegular";
NSString * const NSFileTypeSocket = @"NSFileTypeSocket";
NSString * const NSFileTypeSymbolicLink = @"NSFileTypeSymbolicLink";
NSString * const NSFileTypeUnknown = @"NSFileTypeUnknown";

View file

@ -516,7 +516,7 @@ AC_CHECK_HEADERS(sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h pwd.h grp.h)
AC_CHECK_HEADERS(sys/mount.h sys/types.h windows.h locale.h langinfo.h)
saved_LIBS="$LIBS"
AC_CHECK_LIB(m, main)
AC_CHECK_FUNCS(statvfs symlink readlink geteuid getlogin getpwnam getpwuid rint)
AC_CHECK_FUNCS(statvfs symlink readlink geteuid getlogin getpwnam getpwuid getgrgid rint)
LIBS="$saved_LIBS"
#--------------------------------------------------------------------