home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1994 June / NEBULA_SE.ISO / SourceCode / MiscKit / Source / MiscStringUNIX.m < prev    next >
Encoding:
Text File  |  1994-02-07  |  6.1 KB  |  221 lines

  1. //
  2. //    MiscStringUNIX.m
  3. //        Written by Don Yacktman (c) 1993 by Don Yacktman.
  4. //                Version 1.7  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.     if (!aString) return nil;  // maybe we should _strip_ extensions here
  104.     if (![self endcmp:aString]) return self;
  105.     if ([self charAt:(length - 1)] != theMiscExtensionSeparator)
  106.         [self addCharToEndOfString:theMiscExtensionSeparator];
  107.     [self cat:aString];
  108.     return self;
  109. }
  110.  
  111. - replaceHomeWithTilde
  112. {
  113.     id homestr = [[self class] newWithString:NXHomeDirectory()];
  114.  
  115.     if (![self compareTo:homestr n:[homestr length]]) {
  116.       [self replaceFrom:0 length:[homestr length] withChar:'~'];
  117.      }
  118.     else {
  119.       id home2 = [homestr pathName];
  120.       if (![home2 length]) return self;
  121.       if (![self compareTo:home2 n:[home2 length]]) {
  122.         [self replaceFrom:0 length:[home2 length]+1 withChar:'~'];
  123.       }
  124.       [home2 free];
  125.      }
  126.     [homestr free];
  127.     return self;
  128. }
  129.  
  130. - replaceTildeWithHome
  131. {    // ***** I'd like to see this do proper csh substitution rather than
  132.     // just the simple implementation done here. -don
  133.     id home = [[self class] newWithString:NXHomeDirectory()];
  134.     if (buffer[0] == '~') {
  135.       if (buffer[1] == theMiscPathSeparator)
  136.         [self replaceFrom:0 length:1 withString:home];
  137.       else { // This assumption of all users in the same dir. is dangerous -don
  138.         id home2 = [home pathName];
  139.         [home2 addChar:theMiscPathSeparator];
  140.         [self replaceFrom:0 length:1 withString:home2];
  141.         [home2 free];
  142.        }
  143.      }
  144.     [home free];
  145.     return self;
  146. }
  147.  
  148. - (BOOL)isRelativePath
  149. // Returns YES if the path is non-empty and does NOT begin with pathSeparator.
  150. {
  151.     id tempPath = [self pathName];
  152.     if ([tempPath length] && ([tempPath charAt:0] != theMiscPathSeparator)) {
  153.         [tempPath free];
  154.         return YES;
  155.     }
  156.     [tempPath free];
  157.     return NO;
  158. }
  159.  
  160. - (BOOL)isAbsolutePath
  161. // Returns YES if the path is non-empty and DOES begin with pathSeparator.
  162. {
  163.     id tempPath = [self pathName];
  164.     if ([tempPath length] && ([tempPath charAt:0] == theMiscPathSeparator)) {
  165.         [tempPath free];
  166.         return YES;
  167.     }
  168.     [tempPath free];
  169.     return NO;
  170. }
  171.  
  172. - (BOOL)doesExistInFileSystem
  173. // Returns YES if the a file exists at our path, and is visible to the user 
  174. // id of the process.  A NO can mean any number of things, but a YES 
  175. // definitely indicates that the file is there and visible.
  176. {
  177.     struct stat statBuff;
  178.     if (!buffer) return NO;
  179.     if (stat([self stringValue], &statBuff) == -1) return NO;
  180.     return YES;
  181. }
  182.  
  183. - (BOOL)isFileOfType:(MiscFileType)fileType
  184. // Returns YES if the named file exists, and is visible to the user id of
  185. // the process and it is a file of type fileType.  A NO can mean any number
  186. // of things,  but a YES definitely indicates that the file is there and
  187. // visible and of the fileType type.  
  188. {
  189.     struct stat statBuff;
  190.     if (!buffer) return NO;
  191.     if (stat([self stringValue], &statBuff) == -1) return NO;
  192.     return ((statBuff.st_mode & fileType) == fileType);
  193. }
  194.  
  195. - pathComponentAt:(int)index
  196. {
  197.     if ((index < 0) || (index >= [self numberOfPathComponents]))
  198.         return [[self class] newWithString:""];
  199.     return [self extractPart:([self isAbsolutePath] ? (index + 1) : index)
  200.                 useAsDelimiter:theMiscPathSeparator
  201.                 caseSensitive:YES fromZone:[self zone]];
  202. }
  203.  
  204. - (int)numberOfPathComponents
  205. {
  206.     return ([self numOfChar:theMiscPathSeparator] -
  207.             ([self isAbsolutePath] ? 1 : 0));    
  208. }
  209.  
  210. - setDirectory:(const char *)dir file:(const char *)file
  211. {
  212.     return [self setFromFormat:"%s/%s", dir, file];
  213. }
  214.  
  215. - initDirectory:(const char *)dir file:(const char *)file
  216. {
  217.     return [self initFromFormat:"%s/%s", dir, file];
  218. }
  219.  
  220. @end
  221.