This is MiscStringUNIX.m in view mode; [Download] [Up]
//
// MiscStringUNIX.m
// Written by Don Yacktman (c) 1993 by Don Yacktman.
// Version 1.95 All rights reserved.
// This notice may not be removed from this source code.
//
// This object is included in the MiscKit by permission from the author
// and its use is governed by the MiscKit license, found in the file
// "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
// for a list of all applicable permissions and restrictions.
//
#import <misckit/MiscString.h>
static char theMiscPathSeparator = '/';
static char theMiscExtensionSeparator = '.';
@implementation MiscString(UNIX)
// This category includes methods to support various UNIX features,
// such as file/path name parsing and encryption of passwords.
+ setPathSeparator:(char)c { theMiscPathSeparator = c; return self; }
+ setExtensionSeparator:(char)c { theMiscExtensionSeparator = c; return self; }
+ (char)extensionSeparator { return theMiscExtensionSeparator; }
+ (char)pathSeparator { return theMiscPathSeparator; }
- encrypt:salt
{ // encrypt as a UNIX password using the MiscString "salt" as the salt...
// see crypt(3) for more info
// The cast prevents a warning: -stringValue returns a const char *.
// Assuming crypt() doesn't change the salt, the cast is OK.
char *strv;
if ([salt respondsTo:@selector(stringValue)])
strv = (char *)[salt stringValue];
else return nil;
if (!(buffer && strv)) return nil;
if (!length || !strlen(strv)) return nil;
return [[[self class] alloc] initString:crypt(buffer, strv)];
}
- fileNameFromZone:(NXZone *)zone
{
return [self extractPart:MISC_STRING_LAST
useAsDelimiter:theMiscPathSeparator
caseSensitive:YES fromZone:zone];
}
- fileName
{
return [self fileNameFromZone:[self zone]];
}
- pathNameFromZone:(NXZone *)zone
{
id temp = [self left:[self rspotOf:theMiscPathSeparator] fromZone:zone];
if (temp) return temp;
return [[self class] new];
}
- pathName
{
return [self pathNameFromZone:[self zone]];
}
- fileExtensionFromZone:(NXZone *)zone
{
id temp = [self fileNameFromZone:[self zone]];
id extension = [temp extractPart:MISC_STRING_LAST
useAsDelimiter:theMiscExtensionSeparator
caseSensitive:YES fromZone:zone];
if ([temp isEqual:extension] ||
(0 == [temp rspotOf:theMiscExtensionSeparator
occurrenceNum:0 caseSensitive:YES]))
[extension setStringValue:""];
[temp free];
return extension;
}
- fileExtension
{
return [self fileExtensionFromZone:[self zone]];
}
- fileBasenameFromZone:(NXZone *)zone
{
id base, temp = [self fileNameFromZone:[self zone]];
int right = [temp rspotOf:theMiscExtensionSeparator
occurrenceNum:0 caseSensitive:YES] - 1;
if (right < 0) right = length - 1;
base = [temp midFrom:0 to:right fromZone:zone];
[temp free];
return (base ? base : [[self class] new]);
}
- fileBasename
{
return [self fileBasenameFromZone:[self zone]];
}
- addExtensionIfNeeded:(const char *)aString
{
id ourExtension;
if (!aString) return nil; // maybe we should _strip_ extensions here
ourExtension = [self fileExtension];
if( [ourExtension length] == 0 ||
[ourExtension cmp:aString] != 0 )
{
[self addCharToEndOfString:theMiscExtensionSeparator];
[self cat:aString];
}
[ourExtension free];
return self;
}
- replaceHomeWithTilde
{
id homestr = [[self class] newWithString:NXHomeDirectory()];
if (![self compareTo:homestr n:[homestr length]]) {
[self replaceFrom:0 length:[homestr length] withChar:'~'];
}
else {
id home2 = [homestr pathName];
if (![home2 length]) return self;
if (![self compareTo:home2 n:[home2 length]]) {
[self replaceFrom:0 length:[home2 length]+1 withChar:'~'];
}
[home2 free];
}
[homestr free];
return self;
}
- replaceTildeWithHome
{ // ***** I'd like to see this do proper csh substitution rather than
// just the simple implementation done here. -don
id home = [[self class] newWithString:NXHomeDirectory()];
if (buffer[0] == '~') {
if ((buffer[1] == theMiscPathSeparator) || (length == 1))
[self replaceFrom:0 length:1 withString:home];
else { // This assumption of all users in the same dir. is bad -don
id home2 = [home pathName];
[home2 addChar:theMiscPathSeparator];
[self replaceFrom:0 length:1 withString:home2];
[home2 free];
}
}
[home free];
return self;
}
- (BOOL)isRelativePath
// Returns YES if the path is non-empty and does NOT begin with pathSeparator.
{
id tempPath = [self pathName];
if ([tempPath length] && ([tempPath charAt:0] != theMiscPathSeparator)) {
[tempPath free];
return YES;
}
[tempPath free];
return NO;
}
- (BOOL)isAbsolutePath
// Returns YES if the path is non-empty and DOES begin with pathSeparator.
{
id tempPath = [self pathName];
if ([tempPath length] && ([tempPath charAt:0] == theMiscPathSeparator)) {
[tempPath free];
return YES;
}
[tempPath free];
return NO;
}
- (BOOL)doesExistInFileSystem
// Returns YES if the a file exists at our path, and is visible to the user
// id of the process. A NO can mean any number of things, but a YES
// definitely indicates that the file is there and visible.
{
struct stat statBuff;
if (!buffer) return NO;
if (stat([self stringValue], &statBuff) == -1) return NO;
return YES;
}
- (BOOL)isFileOfType:(MiscFileType)fileType
// Returns YES if the named file exists, and is visible to the user id of
// the process and it is a file of type fileType. A NO can mean any number
// of things, but a YES definitely indicates that the file is there and
// visible and of the fileType type.
{
struct stat statBuff;
if (!buffer) return NO;
if (stat([self stringValue], &statBuff) == -1) return NO;
return ((statBuff.st_mode & fileType) == fileType);
}
- pathComponentAt:(int)index
{
if ((index < 0) || (index >= [self numberOfPathComponents]))
return [[self class] newWithString:""];
return [self extractPart:([self isAbsolutePath] ? (index + 1) : index)
useAsDelimiter:theMiscPathSeparator
caseSensitive:YES fromZone:[self zone]];
}
- (int)numberOfPathComponents
{
return ([self numOfChar:theMiscPathSeparator] -
([self isAbsolutePath] ? 1 : 0));
}
/*
* Modified [-setDirectory:file:] and [-initDirectory:file:] to use the
* official misc path separator, rather than a hard-coded '/'. BJM 7/9/94
*/
- setDirectory:(const char *)dir file:(const char *)file
{
return [self setFromFormat:"%s%c%s", dir, theMiscPathSeparator, file];
}
- initDirectory:(const char *)dir file:(const char *)file
{
return [self initFromFormat:"%s%c%s", dir, theMiscPathSeparator, file];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.