mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +00:00
simplify directory creation code
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35400 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
78206d0b38
commit
218132903e
1 changed files with 65 additions and 160 deletions
|
@ -398,16 +398,18 @@ static NSStringEncoding defaultEncoding;
|
||||||
*/
|
*/
|
||||||
- (BOOL) changeFileAttributes: (NSDictionary*)attributes atPath: (NSString*)path
|
- (BOOL) changeFileAttributes: (NSDictionary*)attributes atPath: (NSString*)path
|
||||||
{
|
{
|
||||||
|
NSDictionary *old;
|
||||||
const _CHAR *lpath = 0;
|
const _CHAR *lpath = 0;
|
||||||
unsigned long num;
|
NSUInteger num;
|
||||||
NSString *str;
|
NSString *str;
|
||||||
NSDate *date;
|
NSDate *date;
|
||||||
BOOL allOk = YES;
|
BOOL allOk = YES;
|
||||||
|
|
||||||
if (attributes == nil)
|
if (0 == [attributes count])
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
old = [self fileAttributesAtPath: path traverseLink: YES];
|
||||||
lpath = [defaultManager fileSystemRepresentationWithPath: path];
|
lpath = [defaultManager fileSystemRepresentationWithPath: path];
|
||||||
|
|
||||||
#ifndef __MINGW__
|
#ifndef __MINGW__
|
||||||
|
@ -421,7 +423,7 @@ static NSStringEncoding defaultEncoding;
|
||||||
|
|
||||||
num = tmpNum ? [tmpNum unsignedLongValue] : NSNotFound;
|
num = tmpNum ? [tmpNum unsignedLongValue] : NSNotFound;
|
||||||
}
|
}
|
||||||
if (num != NSNotFound)
|
if (num != NSNotFound && num != [[old fileOwnerAccountID] unsignedLongValue])
|
||||||
{
|
{
|
||||||
if (chown(lpath, num, -1) != 0)
|
if (chown(lpath, num, -1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -434,7 +436,8 @@ static NSStringEncoding defaultEncoding;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((str = [attributes fileOwnerAccountName]) != nil)
|
if ((str = [attributes fileOwnerAccountName]) != nil
|
||||||
|
&& NO == [str isEqual: [old fileOwnerAccountName]])
|
||||||
{
|
{
|
||||||
BOOL ok = NO;
|
BOOL ok = NO;
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
|
@ -485,7 +488,8 @@ static NSStringEncoding defaultEncoding;
|
||||||
|
|
||||||
num = tmpNum ? [tmpNum unsignedLongValue] : NSNotFound;
|
num = tmpNum ? [tmpNum unsignedLongValue] : NSNotFound;
|
||||||
}
|
}
|
||||||
if (num != NSNotFound)
|
if (num != NSNotFound
|
||||||
|
&& num != [[old fileGroupOwnerAccountID] unsignedLongValue])
|
||||||
{
|
{
|
||||||
if (chown(lpath, -1, num) != 0)
|
if (chown(lpath, -1, num) != 0)
|
||||||
{
|
{
|
||||||
|
@ -496,7 +500,8 @@ static NSStringEncoding defaultEncoding;
|
||||||
ASSIGN(_lastError, str);
|
ASSIGN(_lastError, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((str = [attributes fileGroupOwnerAccountName]) != nil)
|
else if ((str = [attributes fileGroupOwnerAccountName]) != nil
|
||||||
|
&& NO == [str isEqual: [old fileGroupOwnerAccountName]])
|
||||||
{
|
{
|
||||||
BOOL ok = NO;
|
BOOL ok = NO;
|
||||||
#ifdef HAVE_GRP_H
|
#ifdef HAVE_GRP_H
|
||||||
|
@ -538,7 +543,7 @@ static NSStringEncoding defaultEncoding;
|
||||||
#endif /* __MINGW__ */
|
#endif /* __MINGW__ */
|
||||||
|
|
||||||
num = [attributes filePosixPermissions];
|
num = [attributes filePosixPermissions];
|
||||||
if (num != NSNotFound)
|
if (num != NSNotFound && num != [old filePosixPermissions])
|
||||||
{
|
{
|
||||||
if (_CHMOD(lpath, num) != 0)
|
if (_CHMOD(lpath, num) != 0)
|
||||||
{
|
{
|
||||||
|
@ -551,7 +556,7 @@ static NSStringEncoding defaultEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
date = [attributes fileModificationDate];
|
date = [attributes fileModificationDate];
|
||||||
if (date != nil)
|
if (date != nil && NO == [date isEqual: [old fileModificationDate]])
|
||||||
{
|
{
|
||||||
BOOL ok = NO;
|
BOOL ok = NO;
|
||||||
struct _STATB sb;
|
struct _STATB sb;
|
||||||
|
@ -789,17 +794,7 @@ static NSStringEncoding defaultEncoding;
|
||||||
- (BOOL) createDirectoryAtPath: (NSString*)path
|
- (BOOL) createDirectoryAtPath: (NSString*)path
|
||||||
attributes: (NSDictionary*)attributes
|
attributes: (NSDictionary*)attributes
|
||||||
{
|
{
|
||||||
#if defined(__MINGW__)
|
BOOL isDir;
|
||||||
NSEnumerator *paths = [[path pathComponents] objectEnumerator];
|
|
||||||
NSString *subPath;
|
|
||||||
NSString *completePath = nil;
|
|
||||||
#else
|
|
||||||
const char *lpath;
|
|
||||||
char dirpath[PATH_MAX+1];
|
|
||||||
struct _STATB statbuf;
|
|
||||||
int len, cur;
|
|
||||||
NSDictionary *needChown = nil;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is consistent with MacOSX - just return NO for an invalid path. */
|
/* This is consistent with MacOSX - just return NO for an invalid path. */
|
||||||
if ([path length] == 0)
|
if ([path length] == 0)
|
||||||
|
@ -808,159 +803,69 @@ static NSStringEncoding defaultEncoding;
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (YES == [self fileExistsAtPath: path isDirectory: &isDir])
|
||||||
|
{
|
||||||
|
if (NO == isDir)
|
||||||
|
{
|
||||||
|
NSString *e;
|
||||||
|
|
||||||
|
e = [NSString stringWithFormat:
|
||||||
|
@"path %@ exists, but is not a directory", path];
|
||||||
|
ASSIGN(_lastError, e);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if defined(__MINGW__)
|
#if defined(__MINGW__)
|
||||||
while ((subPath = [paths nextObject]))
|
const _CHAR *lpath;
|
||||||
{
|
|
||||||
BOOL isDir = NO;
|
lpath = [self fileSystemRepresentationWithPath: path];
|
||||||
|
isDir = (CreateDirectoryW(lpath, 0) != FALSE) ? YES : NO;
|
||||||
if (completePath == nil)
|
|
||||||
completePath = subPath;
|
|
||||||
else
|
|
||||||
completePath = [completePath stringByAppendingPathComponent: subPath];
|
|
||||||
|
|
||||||
if ([self fileExistsAtPath: completePath isDirectory: &isDir])
|
|
||||||
{
|
|
||||||
if (!isDir)
|
|
||||||
{
|
|
||||||
NSString *e;
|
|
||||||
|
|
||||||
e = [NSString stringWithFormat:
|
|
||||||
@"path %@ exists, but is not a directory", completePath];
|
|
||||||
ASSIGN(_lastError, e);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (nil == [paths nextObject])
|
|
||||||
{
|
|
||||||
const _CHAR *lpath;
|
|
||||||
|
|
||||||
lpath = [self fileSystemRepresentationWithPath: completePath];
|
|
||||||
if (CreateDirectoryW(lpath, 0) == FALSE)
|
|
||||||
{
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSString *e;
|
|
||||||
|
|
||||||
e = [NSString stringWithFormat:
|
|
||||||
@"path %@ is not accessible", completePath];
|
|
||||||
ASSIGN(_lastError, e);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
|
const char *lpath;
|
||||||
|
|
||||||
/*
|
lpath = [self fileSystemRepresentationWithPath: path];
|
||||||
* If there is no file owner specified, and we are running setuid to
|
isDir = (mkdir(lpath, 0777) == 0) ? YES : NO;
|
||||||
* root, then we assume we need to change ownership to correct user.
|
if (YES == isDir)
|
||||||
*/
|
{
|
||||||
if (attributes == nil || ([attributes fileOwnerAccountID] == nil
|
/*
|
||||||
&& [attributes fileOwnerAccountName] == nil))
|
* If there is no file owner specified, and we are running
|
||||||
{
|
* setuid to root, then we assume we need to change ownership
|
||||||
if (geteuid() == 0 && [@"root" isEqualToString: NSUserName()] == NO)
|
* to the correct user.
|
||||||
{
|
*/
|
||||||
needChown = [NSDictionary dictionaryWithObjectsAndKeys:
|
if (attributes == nil || ([attributes fileOwnerAccountID] == nil
|
||||||
NSFileOwnerAccountName, NSUserName(), nil];
|
&& [attributes fileOwnerAccountName] == nil))
|
||||||
}
|
|
||||||
}
|
|
||||||
lpath = [self fileSystemRepresentationWithPath: path];
|
|
||||||
len = strlen(lpath);
|
|
||||||
if (len > PATH_MAX) // name too long
|
|
||||||
{
|
|
||||||
ASSIGN(_lastError, @"Could not create directory - name too long");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(lpath, "/") == 0 || len == 0) // cannot use "/" or ""
|
|
||||||
{
|
|
||||||
ASSIGN(_lastError, @"Could not create directory - no name given");
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(dirpath, lpath, len);
|
|
||||||
dirpath[len] = '\0';
|
|
||||||
if (dirpath[len-1] == '/')
|
|
||||||
dirpath[len-1] = '\0';
|
|
||||||
cur = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// find next '/'
|
|
||||||
while (dirpath[cur] != '/' && cur < len)
|
|
||||||
cur++;
|
|
||||||
// if first char is '/' then again; (cur == len) -> last component
|
|
||||||
if (cur == 0)
|
|
||||||
{
|
|
||||||
cur++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// check if path from 0 to cur is valid
|
|
||||||
dirpath[cur] = '\0';
|
|
||||||
if (_STAT(dirpath, &statbuf) != 0)
|
|
||||||
{
|
|
||||||
NSString *p;
|
|
||||||
|
|
||||||
p = [self stringWithFileSystemRepresentation: dirpath length: cur];
|
|
||||||
|
|
||||||
if (cur != len)
|
|
||||||
{
|
{
|
||||||
NSString *e;
|
if (geteuid() == 0
|
||||||
|
&& [@"root" isEqualToString: NSUserName()] == NO)
|
||||||
e = [NSString stringWithFormat: @"path %@ is not accessible", p];
|
|
||||||
ASSIGN(_lastError, e);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// make new directory
|
|
||||||
if (mkdir(dirpath, 0777) != 0)
|
|
||||||
{
|
{
|
||||||
NSString *e;
|
NSMutableDictionary *m;
|
||||||
|
|
||||||
e = [NSString stringWithFormat:
|
m = [[attributes mutableCopy] autorelease];
|
||||||
@"Could not create '%@' - '%@'",
|
if (nil == m)
|
||||||
p, [NSError _last]];
|
|
||||||
ASSIGN(_lastError, e);
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
// if last directory and attributes then change
|
|
||||||
if (attributes != nil)
|
|
||||||
{
|
|
||||||
if ([self changeFileAttributes: attributes
|
|
||||||
atPath: p] == NO)
|
|
||||||
{
|
{
|
||||||
return NO;
|
m = [NSMutableDictionary dictionaryWithCapacity: 1];
|
||||||
}
|
}
|
||||||
if (needChown != nil)
|
[m setObject: NSUserName()
|
||||||
{
|
forKey: NSFileOwnerAccountName];
|
||||||
if ([self changeFileAttributes: needChown
|
attributes = m;
|
||||||
atPath: p] == NO)
|
|
||||||
{
|
|
||||||
NSLog(@"Failed to change ownership of '%p' to '%@'",
|
|
||||||
p, NSUserName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dirpath[cur] = '/';
|
#endif
|
||||||
cur++;
|
if (NO == isDir)
|
||||||
}
|
{
|
||||||
while (cur < len);
|
NSString *e;
|
||||||
|
|
||||||
#endif /* !MINGW */
|
e = [NSString stringWithFormat:
|
||||||
|
@"Could not create '%@' - '%@'",
|
||||||
// change attributes of last directory
|
path, [NSError _last]];
|
||||||
if ([attributes count] == 0)
|
ASSIGN(_lastError, e);
|
||||||
{
|
return NO;
|
||||||
return YES;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [self changeFileAttributes: attributes atPath: path];
|
return [self changeFileAttributes: attributes atPath: path];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue