home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Misc / aa_m68k_Only / NDCamera.0.21 / Source / MiscSources.subproj / MiscStringUNIX.m < prev    next >
Encoding:
Text File  |  1995-04-14  |  6.5 KB  |  238 lines

  1. //
  2. //    MiscStringUNIX.m
  3. //        Written by Don Yacktman Copyright (c) 1993 by Don Yacktman.
  4. //                Version 1.95  All rights reserved.
  5. //        This notice may not be removed from this source code.
  6. //
  7. //    This object is included in the MiscKit by permission from the author
  8. //    and its use is governed by the MiscKit license, found in the file
  9. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  10. //    for a list of all applicable permissions and restrictions.
  11. //    
  12.  
  13. #import <misckit/MiscString.h>
  14.  
  15. static char theMiscPathSeparator = '/';
  16. static char theMiscExtensionSeparator = '.';
  17.  
  18. @implementation MiscString(UNIX)
  19.  
  20. // This category includes methods to support various UNIX features,
  21. // such as file/path name parsing and encryption of passwords.
  22.  
  23. + setPathSeparator:(char)c { theMiscPathSeparator = c; return self; }
  24. + setExtensionSeparator:(char)c { theMiscExtensionSeparator = c; return self; }
  25. + (char)extensionSeparator { return theMiscExtensionSeparator; }
  26. + (char)pathSeparator { return theMiscPathSeparator; }
  27.  
  28. - encrypt:salt
  29. {    // encrypt as a UNIX password using the MiscString "salt" as the salt...
  30.     // see crypt(3) for more info
  31.     // The cast prevents a warning:  -stringValue returns a const char *.
  32.     // Assuming crypt() doesn't change the salt, the cast is OK.
  33.     char *strv;
  34.     if ([salt respondsTo:@selector(stringValue)])
  35.         strv = (char *)[salt stringValue];
  36.     else return nil;
  37.     if (!(buffer && strv)) return nil;
  38.     if (!length || !strlen(strv)) return nil;
  39.     return [[[self class] alloc] initString:crypt(buffer, strv)];
  40. }
  41.  
  42. - fileNameFromZone:(NXZone *)zone
  43. {
  44.     return [self extractPart:MISC_STRING_LAST
  45.                 useAsDelimiter:theMiscPathSeparator
  46.                 caseSensitive:YES fromZone:zone];
  47. }
  48.  
  49. - fileName
  50. {
  51.     return [self fileNameFromZone:[self zone]];
  52. }
  53.  
  54. - pathNameFromZone:(NXZone *)zone
  55. {
  56.     id temp = [self left:[self rspotOf:theMiscPathSeparator] fromZone:zone];
  57.     if (temp) return temp;
  58.     return [[self class] new];
  59. }
  60.  
  61. - pathName
  62. {
  63.     return [self pathNameFromZone:[self zone]];
  64. }
  65.  
  66. - fileExtensionFromZone:(NXZone *)zone
  67. {
  68.     id temp = [self fileNameFromZone:[self zone]];
  69.     id extension = [temp extractPart:MISC_STRING_LAST
  70.                 useAsDelimiter:theMiscExtensionSeparator
  71.                 caseSensitive:YES fromZone:zone];
  72.     if ([temp isEqual:extension] ||
  73.             (0 == [temp rspotOf:theMiscExtensionSeparator
  74.             occurrenceNum:0 caseSensitive:YES]))
  75.         [extension setStringValue:""];
  76.     [temp free];
  77.     return extension;
  78. }
  79.  
  80. - fileExtension
  81. {
  82.     return [self fileExtensionFromZone:[self zone]];
  83. }
  84.  
  85. - fileBasenameFromZone:(NXZone *)zone
  86. {
  87.     id base, temp = [self fileNameFromZone:[self zone]];
  88.     int right = [temp rspotOf:theMiscExtensionSeparator
  89.             occurrenceNum:0 caseSensitive:YES] - 1;
  90.     if (right < 0) right = length - 1;
  91.     base = [temp midFrom:0 to:right fromZone:zone];
  92.     [temp free];
  93.     return (base ? base : [[self class] new]);
  94. }
  95.  
  96. - fileBasename
  97. {
  98.     return [self fileBasenameFromZone:[self zone]];
  99. }
  100.  
  101. - addExtensionIfNeeded:(const char *)aString
  102. {
  103.     id    ourExtension;
  104.     
  105.     if (!aString) return nil;  // maybe we should _strip_ extensions here
  106.     
  107.     ourExtension = [self fileExtension];
  108.  
  109.     if ( [ourExtension length] == 0 ||
  110.         [ourExtension cmp:aString] != 0 ) {
  111.         if ([self charAt:(length - 1)] != theMiscExtensionSeparator)
  112.             [self addChar:theMiscExtensionSeparator];
  113.         [self cat:aString];
  114.     }    
  115.     [ourExtension free];
  116.     return self;
  117. }
  118.  
  119. - replaceHomeWithTilde
  120. {
  121.     id homestr = [[self class] newWithString:NXHomeDirectory()];
  122.  
  123.     if (![self compareTo:homestr n:[homestr length]]) {
  124.       [self replaceFrom:0 length:[homestr length] withChar:'~'];
  125.      }
  126.     else {
  127.       id home2 = [homestr pathName];
  128.       if (![home2 length]) return self;
  129.       if (![self compareTo:home2 n:[home2 length]]) {
  130.         [self replaceFrom:0 length:[home2 length]+1 withChar:'~'];
  131.       }
  132.       [home2 free];
  133.      }
  134.     [homestr free];
  135.     return self;
  136. }
  137.  
  138. - replaceTildeWithHome
  139. {    // ***** I'd like to see this do proper csh substitution rather than
  140.     // just the simple implementation done here. -don
  141.     id home = [[self class] newWithString:NXHomeDirectory()];
  142.     if (buffer[0] == '~') {
  143.         if ((buffer[1] == theMiscPathSeparator) || (length == 1))
  144.             [self replaceFrom:0 length:1 withString:home];
  145.         else { // This assumption of all users in the same dir. is bad -don
  146.             id home2 = [home pathName];
  147.             [home2 addChar:theMiscPathSeparator];
  148.             [self replaceFrom:0 length:1 withString:home2];
  149.             [home2 free];
  150.         }
  151.     }
  152.     [home free];
  153.     return self;
  154. }
  155.  
  156. - (BOOL)isRelativePath
  157. // Returns YES if the path is non-empty and does NOT begin with pathSeparator.
  158. {
  159.     id tempPath = [self pathName];
  160.     if ([tempPath length] && ([tempPath charAt:0] != theMiscPathSeparator)) {
  161.         [tempPath free];
  162.         return YES;
  163.     }
  164.     [tempPath free];
  165.     return NO;
  166. }
  167.  
  168. - (BOOL)isAbsolutePath
  169. // Returns YES if the path is non-empty and DOES begin with pathSeparator.
  170. {
  171.     id tempPath = [self pathName];
  172.     if ([tempPath length] && ([tempPath charAt:0] == theMiscPathSeparator)) {
  173.         [tempPath free];
  174.         return YES;
  175.     }
  176.     [tempPath free];
  177.     return NO;
  178. }
  179.  
  180. - (BOOL)doesExistInFileSystem
  181. // Returns YES if the a file exists at our path, and is visible to the user 
  182. // id of the process.  A NO can mean any number of things, but a YES 
  183. // definitely indicates that the file is there and visible.
  184. {
  185.     struct stat statBuff;
  186.     if (!buffer) return NO;
  187.     if (stat([self stringValue], &statBuff) == -1) return NO;
  188.     return YES;
  189. }
  190.  
  191. - (BOOL)isFileOfType:(MiscFileType)fileType
  192. // Returns YES if the named file exists, and is visible to the user id of
  193. // the process and it is a file of type fileType.  A NO can mean any number
  194. // of things,  but a YES definitely indicates that the file is there and
  195. // visible and of the fileType type.  
  196. {
  197.     struct stat statBuff;
  198.     if (!buffer) return NO;
  199.     if (stat([self stringValue], &statBuff) == -1) return NO;
  200.     return ((statBuff.st_mode & fileType) == fileType);
  201. }
  202.  
  203. - pathComponentAt:(int)index
  204. {
  205.     if ((index < 0) || (index >= [self numberOfPathComponents]))
  206.         return [[self class] newWithString:""];
  207.     return [self extractPart:([self isAbsolutePath] ? (index + 1) : index)
  208.                 useAsDelimiter:theMiscPathSeparator
  209.                 caseSensitive:YES fromZone:[self zone]];
  210. }
  211.  
  212. - (int)numberOfPathComponents
  213. {
  214.     return ([self numOfChar:theMiscPathSeparator] -
  215.             ([self isAbsolutePath] ? 1 : 0));    
  216. }
  217.  
  218. /*
  219.  * Modified [-setDirectory:file:] and [-initDirectory:file:] to use the
  220.  * official misc path separator, rather than a hard-coded '/'. BJM 7/9/94
  221.  */
  222. - setDirectory:(const char *)dir file:(const char *)file
  223. {
  224.     return [self setFromFormat:"%s%c%s", dir, theMiscPathSeparator, file];
  225. }
  226.  
  227. - initDirectory:(const char *)dir file:(const char *)file
  228. {
  229.     return [self initFromFormat:"%s%c%s", dir, theMiscPathSeparator, file];
  230. }
  231.  
  232. - (int)system
  233. {
  234.     return system([self stringValue]);
  235. }
  236.  
  237. @end
  238.