mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
File access improvements
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3764 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
4091f6f778
commit
4d15192f41
7 changed files with 340 additions and 145 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
Sat Feb 20 20:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSUser.m: Added GSSetUserName() and rewrote NSUserName() to
|
||||
work consistently - use the LOGNAME environment variable as first
|
||||
choice of username.
|
||||
* Source/include/NSPathUtilities.h: Added GSSetUserName()
|
||||
* Source/NSUserDefaults.m: Added GNUstep specific method -
|
||||
([+resetUserDefaults]) to reset the standard defaults in the event of
|
||||
a change os username. Also changed to create defaults withe correct
|
||||
ownership, and to create a defaults file containing a valid (empty)
|
||||
dictionary.
|
||||
* Source/include/NSUserDefaults.h: Added ([+resetUserDefaults])
|
||||
* Source/NSData.m: Try to preserve file ownership etc with
|
||||
([-writeToFile:atomically:])
|
||||
* Source/NSFileManager.m: ([-changeFileAttributes:atPath:]) added
|
||||
code to handle owner and group names if owner and group IDs are not
|
||||
supplied. Also added code to ensure that programs running setuid to
|
||||
root create new files and directories with the ownership of their
|
||||
actual login user by default.
|
||||
|
||||
1999-02-19 Michael Hanni <mhanni@sprintmail.com
|
||||
|
||||
* Source/NSArray.m: Added @end for NSArrayEnumeratorReverse.
|
||||
|
|
|
@ -27,9 +27,21 @@
|
|||
#include <base/preface.h>
|
||||
#include <Foundation/NSString.h>
|
||||
|
||||
extern NSString *NSUserName ();
|
||||
extern NSString *NSHomeDirectory ();
|
||||
extern NSString *NSHomeDirectoryForUser (NSString *userName);
|
||||
#ifndef NO_GNUSTEP
|
||||
/*
|
||||
* This extension permits a change of username from that specified in the
|
||||
* LOGNAME environment variable. Using it will almost certainly cause
|
||||
* trouble if the process does not posess the file access priviliges of the
|
||||
* new name. This is provided primarily for use by processes that run as
|
||||
* system-manager and need to act as particular users. If uses the
|
||||
* [NSUserDefaults +resetUserDefaults] extension to reset the defaults system
|
||||
* to use the defaults belonging to the new user.
|
||||
*/
|
||||
extern void GSSetUserName(NSString *name);
|
||||
#endif
|
||||
extern NSString *NSUserName();
|
||||
extern NSString *NSHomeDirectory();
|
||||
extern NSString *NSHomeDirectoryForUser(NSString *userName);
|
||||
|
||||
#ifndef STRICT_OPENSTEP
|
||||
extern NSString *NSFullUserName(void);
|
||||
|
|
|
@ -124,6 +124,13 @@ extern NSString* const NSDateTimeOrdering;
|
|||
|
||||
/* Getting the Shared Instance */
|
||||
+ (NSUserDefaults*) standardUserDefaults;
|
||||
#ifndef NO_GNUSTEP
|
||||
/*
|
||||
* Called by GSSetUserName() to get the defaults system to use the defaults
|
||||
* of a new user.
|
||||
*/
|
||||
+ (void) resetUserDefaults;
|
||||
#endif
|
||||
+ (NSArray*) userLanguages;
|
||||
+ (void) setUserLanguages: (NSArray*)languages;
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@
|
|||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <string.h> /* for memset() */
|
||||
#include <unistd.h> /* SEEK_* on SunOS 4 */
|
||||
|
||||
|
@ -500,6 +502,7 @@ failure:
|
|||
NSLog(@"Open (%s) attempt failed - bad path", theRealPath);
|
||||
return NO;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MKSTEMP
|
||||
if (useAuxiliaryFile)
|
||||
{
|
||||
|
@ -576,17 +579,43 @@ failure:
|
|||
}
|
||||
|
||||
/* If we used a temporary file, we still need to rename() it be the
|
||||
* real file. Am I forgetting anything here? */
|
||||
* real file. Also, we need to try to retain the file attributes of
|
||||
* the original file we are overwriting (if we are) */
|
||||
if (useAuxiliaryFile)
|
||||
{
|
||||
c = rename(thePath, theRealPath);
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
NSMutableDictionary *att = nil;
|
||||
|
||||
if (c != 0) /* Many things could go wrong, I
|
||||
* guess. */
|
||||
if ([mgr fileExistsAtPath: path])
|
||||
{
|
||||
att = [[mgr fileAttributesAtPath:path traverseLink:YES] mutableCopy];
|
||||
if (att)
|
||||
[att autorelease];
|
||||
}
|
||||
|
||||
c = rename(thePath, theRealPath);
|
||||
if (c != 0) /* Many things could go wrong, I guess. */
|
||||
{
|
||||
NSLog(@"Rename (%s) failed - %s", thePath, strerror(errno));
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (att)
|
||||
{
|
||||
/*
|
||||
* We have created a new file - so we attempt to make it's
|
||||
* attributes match that of the original.
|
||||
*/
|
||||
[att removeObjectForKey: NSFileSize];
|
||||
[att removeObjectForKey: NSFileModificationDate];
|
||||
[att removeObjectForKey: NSFileReferenceCount];
|
||||
[att removeObjectForKey: NSFileSystemNumber];
|
||||
[att removeObjectForKey: NSFileSystemFileNumber];
|
||||
[att removeObjectForKey: NSFileDeviceIdentifier];
|
||||
[att removeObjectForKey: NSFileType];
|
||||
if ([mgr changeFileAttributes: att atPath: path] == NO)
|
||||
NSLog(@"Unable to correctly set all attributes for '%@'", path);
|
||||
}
|
||||
}
|
||||
|
||||
/* success: */
|
||||
|
|
|
@ -184,63 +184,93 @@ static NSFileManager* defaultManager = nil;
|
|||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)createDirectoryAtPath:(NSString*)path
|
||||
attributes:(NSDictionary*)attributes
|
||||
- (BOOL) createDirectoryAtPath:(NSString*)path
|
||||
attributes:(NSDictionary*)attributes
|
||||
{
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
return CreateDirectory([self fileSystemRepresentationWithPath: path], NULL);
|
||||
#else
|
||||
const char* cpath;
|
||||
char dirpath[PATH_MAX+1];
|
||||
struct stat statbuf;
|
||||
int len, cur;
|
||||
const char* cpath;
|
||||
char dirpath[PATH_MAX+1];
|
||||
struct stat statbuf;
|
||||
int len, cur;
|
||||
NSDictionary *needChown = nil;
|
||||
|
||||
cpath = [self fileSystemRepresentationWithPath:path];
|
||||
len = strlen(cpath);
|
||||
if (len > PATH_MAX)
|
||||
// name too long
|
||||
return NO;
|
||||
|
||||
if (strcmp(cpath, "/") == 0 || len == 0)
|
||||
// cannot use "/" or "" as a new dir path
|
||||
return NO;
|
||||
|
||||
strcpy(dirpath, cpath);
|
||||
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) {
|
||||
if (cur == len)
|
||||
return NO; // already existing last path
|
||||
}
|
||||
else {
|
||||
// make new directory
|
||||
if (mkdir(dirpath, 0777) != 0)
|
||||
return NO; // could not create component
|
||||
// if last directory and attributes then change
|
||||
if (cur == len && attributes)
|
||||
return [self changeFileAttributes:attributes
|
||||
atPath:[self stringWithFileSystemRepresentation:dirpath
|
||||
length:cur]];
|
||||
}
|
||||
dirpath[cur] = '/';
|
||||
cur++;
|
||||
} while (cur < len);
|
||||
/*
|
||||
* 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
|
||||
&& geteuid() == 0 && [@"root" isEqualToString: NSUserName()] == NO)
|
||||
{
|
||||
needChown = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSFileOwnerAccountName, NSUserName(), nil];
|
||||
}
|
||||
|
||||
return YES;
|
||||
cpath = [self fileSystemRepresentationWithPath:path];
|
||||
len = strlen(cpath);
|
||||
if (len > PATH_MAX) // name too long
|
||||
return NO;
|
||||
|
||||
if (strcmp(cpath, "/") == 0 || len == 0) // cannot use "/" or ""
|
||||
return NO;
|
||||
|
||||
strcpy(dirpath, cpath);
|
||||
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)
|
||||
{
|
||||
if (cur == len)
|
||||
return NO; // already existing last path
|
||||
}
|
||||
else
|
||||
{
|
||||
// make new directory
|
||||
if (mkdir(dirpath, 0777) != 0)
|
||||
return NO; // could not create component
|
||||
// if last directory and attributes then change
|
||||
if (cur == len && attributes)
|
||||
{
|
||||
if ([self changeFileAttributes:attributes
|
||||
atPath:[self stringWithFileSystemRepresentation:dirpath
|
||||
length:cur]] == NO)
|
||||
return NO;
|
||||
if (needChown)
|
||||
{
|
||||
if ([self changeFileAttributes: needChown
|
||||
atPath:[self stringWithFileSystemRepresentation:dirpath
|
||||
length:cur]] == NO)
|
||||
{
|
||||
NSLog(@"Failed to change ownership of '%s' to '%@'",
|
||||
dirpath, NSUserName());
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
dirpath[cur] = '/';
|
||||
cur++;
|
||||
}
|
||||
while (cur < len);
|
||||
|
||||
return YES;
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
|
@ -267,7 +297,7 @@ static NSFileManager* defaultManager = nil;
|
|||
// File operations
|
||||
|
||||
- (BOOL)copyPath:(NSString*)source toPath:(NSString*)destination
|
||||
handler:handler
|
||||
handler:handler
|
||||
{
|
||||
BOOL sourceIsDir, fileExists;
|
||||
NSDictionary* attributes;
|
||||
|
@ -327,7 +357,7 @@ static NSFileManager* defaultManager = nil;
|
|||
}
|
||||
|
||||
- (BOOL)movePath:(NSString*)source toPath:(NSString*)destination
|
||||
handler:handler
|
||||
handler:handler
|
||||
{
|
||||
BOOL sourceIsDir, fileExists;
|
||||
const char* sourcePath = [self fileSystemRepresentationWithPath:source];
|
||||
|
@ -485,29 +515,48 @@ static NSFileManager* defaultManager = nil;
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)createFileAtPath:(NSString*)path contents:(NSData*)contents
|
||||
attributes:(NSDictionary*)attributes
|
||||
- (BOOL) createFileAtPath: (NSString*)path
|
||||
contents: (NSData*)contents
|
||||
attributes: (NSDictionary*)attributes
|
||||
{
|
||||
int fd, len, written;
|
||||
int fd, len, written;
|
||||
|
||||
fd = open ([self fileSystemRepresentationWithPath:path],
|
||||
fd = open ([self fileSystemRepresentationWithPath:path],
|
||||
O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
if (fd < 0)
|
||||
return NO;
|
||||
if (fd < 0)
|
||||
return NO;
|
||||
|
||||
if (![self changeFileAttributes:attributes atPath:path]) {
|
||||
close (fd);
|
||||
return NO;
|
||||
if (![self changeFileAttributes: attributes atPath: path])
|
||||
{
|
||||
close (fd);
|
||||
return NO;
|
||||
}
|
||||
|
||||
len = [contents length];
|
||||
if (len)
|
||||
written = write (fd, [contents bytes], len);
|
||||
else
|
||||
written = 0;
|
||||
close (fd);
|
||||
/*
|
||||
* 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
|
||||
&& geteuid() == 0 && [@"root" isEqualToString: NSUserName()] == NO)
|
||||
{
|
||||
attributes = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSFileOwnerAccountName, NSUserName(), nil];
|
||||
if (![self changeFileAttributes: attributes atPath: path])
|
||||
{
|
||||
NSLog(@"Failed to change ownership of '%@' to '%@'",
|
||||
path, NSUserName());
|
||||
}
|
||||
}
|
||||
|
||||
return written == len;
|
||||
len = [contents length];
|
||||
if (len)
|
||||
written = write (fd, [contents bytes], len);
|
||||
else
|
||||
written = 0;
|
||||
close (fd);
|
||||
|
||||
return written == len;
|
||||
}
|
||||
|
||||
// Getting and comparing file contents
|
||||
|
@ -781,55 +830,95 @@ static NSFileManager* defaultManager = nil;
|
|||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
- (BOOL)changeFileAttributes:(NSDictionary*)attributes atPath:(NSString*)path
|
||||
- (BOOL) changeFileAttributes: (NSDictionary*)attributes atPath: (NSString*)path
|
||||
{
|
||||
const char* cpath = [self fileSystemRepresentationWithPath:path];
|
||||
NSNumber* num;
|
||||
NSDate* date;
|
||||
BOOL allOk = YES;
|
||||
const char *cpath = [self fileSystemRepresentationWithPath:path];
|
||||
NSNumber *num;
|
||||
NSString *str;
|
||||
NSDate *date;
|
||||
BOOL allOk = YES;
|
||||
|
||||
#ifndef __WIN32__
|
||||
num = [attributes objectForKey:NSFileOwnerAccountNumber];
|
||||
if (num) {
|
||||
allOk &= (chown(cpath, [num intValue], -1) == 0);
|
||||
num = [attributes objectForKey: NSFileOwnerAccountNumber];
|
||||
if (num)
|
||||
{
|
||||
allOk &= (chown(cpath, [num intValue], -1) == 0);
|
||||
}
|
||||
|
||||
num = [attributes objectForKey:NSFileGroupOwnerAccountNumber];
|
||||
if (num) {
|
||||
allOk &= (chown(cpath, -1, [num intValue]) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
num = [attributes objectForKey:NSFilePosixPermissions];
|
||||
if (num) {
|
||||
allOk &= (chmod(cpath, [num intValue]) == 0);
|
||||
}
|
||||
|
||||
date = [attributes objectForKey:NSFileModificationDate];
|
||||
if (date) {
|
||||
struct stat sb;
|
||||
#ifdef _POSIX_VERSION
|
||||
struct utimbuf ub;
|
||||
else
|
||||
{
|
||||
if ((str = [attributes objectForKey:NSFileOwnerAccountName]) != nil)
|
||||
{
|
||||
#if HAVE_PWD_H
|
||||
struct passwd *pw = getpwnam([str cString]);
|
||||
|
||||
if (pw)
|
||||
{
|
||||
allOk &= (chown(cpath, pw->pw_uid, -1) == 0);
|
||||
chown(cpath, -1, pw->pw_gid);
|
||||
}
|
||||
else
|
||||
allOk = NO;
|
||||
#else
|
||||
time_t ub[2];
|
||||
allOk = NO;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
num = [attributes objectForKey:NSFileGroupOwnerAccountNumber];
|
||||
if (num)
|
||||
{
|
||||
allOk &= (chown(cpath, -1, [num intValue]) == 0);
|
||||
}
|
||||
else if ((str = [attributes objectForKey:NSFileGroupOwnerAccountName]) != nil)
|
||||
#if HAVE_GRP_H
|
||||
{
|
||||
struct group *gp = getgrnam([str cString]);
|
||||
|
||||
if (gp)
|
||||
{
|
||||
allOk &= (chown(cpath, -1, gp->gr_gid) == 0);
|
||||
}
|
||||
else
|
||||
allOk = NO;
|
||||
}
|
||||
#else
|
||||
allOk = NO;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (stat(cpath, &sb) != 0)
|
||||
allOk = NO;
|
||||
else {
|
||||
num = [attributes objectForKey:NSFilePosixPermissions];
|
||||
if (num)
|
||||
{
|
||||
allOk &= (chmod(cpath, [num intValue]) == 0);
|
||||
}
|
||||
|
||||
date = [attributes objectForKey:NSFileModificationDate];
|
||||
if (date)
|
||||
{
|
||||
struct stat sb;
|
||||
#ifdef _POSIX_VERSION
|
||||
ub.actime = sb.st_atime;
|
||||
ub.modtime = [date timeIntervalSince1970];
|
||||
allOk &= (utime(cpath, &ub) == 0);
|
||||
struct utimbuf ub;
|
||||
#else
|
||||
ub[0] = sb.st_atime;
|
||||
ub[1] = [date timeIntervalSince1970];
|
||||
allOk &= (utime((char*)cpath, ub) == 0);
|
||||
time_t ub[2];
|
||||
#endif
|
||||
|
||||
if (stat(cpath, &sb) != 0)
|
||||
allOk = NO;
|
||||
else
|
||||
{
|
||||
#ifdef _POSIX_VERSION
|
||||
ub.actime = sb.st_atime;
|
||||
ub.modtime = [date timeIntervalSince1970];
|
||||
allOk &= (utime(cpath, &ub) == 0);
|
||||
#else
|
||||
ub[0] = sb.st_atime;
|
||||
ub[1] = [date timeIntervalSince1970];
|
||||
allOk &= (utime((char*)cpath, ub) == 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return allOk;
|
||||
return allOk;
|
||||
}
|
||||
|
||||
// Discovering directory contents
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
#include <base/preface.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSPathUtilities.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
#include <stdlib.h> // for getenv()
|
||||
#if !defined(__WIN32__) && !defined(_WIN32)
|
||||
|
@ -39,38 +41,62 @@
|
|||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Return the caller's login name as an NSString object. */
|
||||
static NSString *theUserName = nil;
|
||||
|
||||
void
|
||||
GSSetUserName(NSString* name)
|
||||
{
|
||||
if (theUserName == nil)
|
||||
theUserName = RETAIN(name);
|
||||
else if ([theUserName isEqualToString: name] == NO)
|
||||
{
|
||||
ASSIGN(theUserName, name);
|
||||
[NSUserDefaults resetUserDefaults];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the caller's login name as an NSString object.
|
||||
* The 'LOGNAME' environment variable is our primary source, but we use
|
||||
* other system-dependent sources if LOGNAME is not set.
|
||||
*/
|
||||
NSString *
|
||||
NSUserName ()
|
||||
{
|
||||
if (theUserName == nil)
|
||||
{
|
||||
const char *login_name = 0;
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
/* The GetUserName function returns the current user name */
|
||||
char buf[1024];
|
||||
DWORD n = 1024;
|
||||
/* The GetUserName function returns the current user name */
|
||||
char buf[1024];
|
||||
DWORD n = 1024;
|
||||
|
||||
if (GetUserName(buf, &n))
|
||||
return [NSString stringWithCString: buf];
|
||||
else
|
||||
return [NSString stringWithCString: ""];
|
||||
#elif __SOLARIS__ || defined(BSD)
|
||||
int uid = geteuid(); // get the effective user id
|
||||
struct passwd *pwent = getpwuid (uid);
|
||||
NSString* name = [NSString stringWithCString: pwent->pw_name];
|
||||
return name;
|
||||
if (GetEnvironmentVariable("LOGNAME", buf, 1024);
|
||||
login_name = buf;
|
||||
else if (GetUserName(buf, &n))
|
||||
login_name = buf;
|
||||
#else
|
||||
const char *login_name = getlogin ();
|
||||
|
||||
if (!login_name)
|
||||
login_name = cuserid(NULL);
|
||||
|
||||
if (!login_name)
|
||||
login_name= getenv ("LOGNAME");
|
||||
|
||||
if (login_name)
|
||||
return [NSString stringWithCString: login_name];
|
||||
else
|
||||
return nil;
|
||||
login_name = getenv("LOGNAME");
|
||||
if (login_name == 0 || getpwnam(login_name) == 0)
|
||||
{
|
||||
# if __SOLARIS__ || defined(BSD)
|
||||
int uid = geteuid(); // get the effective user id
|
||||
struct passwd *pwent = getpwuid (uid);
|
||||
login_name = pwent->pw_name;
|
||||
# else
|
||||
login_name = getlogin();
|
||||
if (!login_name)
|
||||
login_name = cuserid(NULL);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if (login_name)
|
||||
GSSetUserName([NSString stringWithCString: login_name]);
|
||||
else
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Unable to determine curren user name"];
|
||||
}
|
||||
return theUserName;
|
||||
}
|
||||
|
||||
/* Return the caller's home directory as an NSString object. */
|
||||
|
@ -78,8 +104,6 @@ NSString *
|
|||
NSHomeDirectory ()
|
||||
{
|
||||
return NSHomeDirectoryForUser (NSUserName ());
|
||||
/* xxx Was using this. Is there a reason to prefer it?
|
||||
return [NSString stringWithCString: getenv ("HOME")]; */
|
||||
}
|
||||
|
||||
/* Return LOGIN_NAME's home directory as an NSString object. */
|
||||
|
|
|
@ -79,6 +79,17 @@ static NSMutableString *processName = nil;
|
|||
/*************************************************************************
|
||||
*** Getting the Shared Instance
|
||||
*************************************************************************/
|
||||
static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */
|
||||
|
||||
+ (void) resetUserDefaults
|
||||
{
|
||||
id defs = sharedDefaults;
|
||||
|
||||
setSharedDefaults = NO;
|
||||
sharedDefaults = nil;
|
||||
[defs release];
|
||||
}
|
||||
|
||||
+ (NSUserDefaults *)standardUserDefaults
|
||||
/*
|
||||
Returns the shared defaults object. If it doesn't exist yet, it's
|
||||
|
@ -88,11 +99,9 @@ static NSMutableString *processName = nil;
|
|||
convenience; other instances may also be created.
|
||||
*/
|
||||
{
|
||||
static BOOL beenHere = NO; /* Flag to prevent infinite recursion */
|
||||
|
||||
if (beenHere)
|
||||
if (setSharedDefaults)
|
||||
return sharedDefaults;
|
||||
beenHere = YES;
|
||||
setSharedDefaults = YES;
|
||||
// Create new sharedDefaults (NOTE: Not added to the autorelease pool!)
|
||||
sharedDefaults = [[self alloc] init];
|
||||
|
||||
|
@ -663,10 +672,15 @@ static NSMutableString *processName = nil;
|
|||
}
|
||||
else
|
||||
{
|
||||
NSDictionary *attr;
|
||||
|
||||
attr = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSUserName(), NSFileOwnerAccountName, nil];
|
||||
NSLog(@"Creating defaults database file %@", defaultsDatabase);
|
||||
[[NSFileManager defaultManager] createFileAtPath: defaultsDatabase
|
||||
contents: nil
|
||||
attributes: nil];
|
||||
contents: nil
|
||||
attributes: attr];
|
||||
[[NSDictionary dictionary] writeToFile: defaultsDatabase atomically: YES];
|
||||
}
|
||||
|
||||
if (!newDict)
|
||||
|
|
Loading…
Reference in a new issue