1: /*_ filespec.c   Mon Jul  3 1989   Modified by: Walter Bright */
  2: /* Copyright (C) 1986-1987 by Northwest Software        */
  3: /* All Rights Reserved                                  */
  4: /* Written by Walter Bright                             */
  5: 
  6: /* Package with which to manipulate filespecs   */
  7: 
  8: #include        <stdio.h>
  9: #include        "filespec.h"
 10: 
 11: #ifndef MEM_H
 12: #include        "mem.h"
 13: #endif
 14: 
 15: #ifndef VAX11C
 16: #include <string.h>
 17: #endif
 18: 
 19: #if BSDUNIX
 20: #include        <pwd.h>
 21: #endif
 22: 
 23: #if MSDOS || __OS2__ || __NT__ || _WIN32
 24: #include        <direct.h>
 25: #include        <ctype.h>
 26: #endif
 27: 
 28: #if M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4
 29: #include        <stdlib.h>
 30: #include        <unistd.h>
 31: #endif
 32: 
 33: #ifndef assert
 34: #include        <assert.h>
 35: #endif
 36: 
 37: /* Macro to determine if char is a path or drive delimiter      */
 38: #if MSDOS || __OS2__ || __NT__ || _WIN32
 39: #define ispathdelim(c)  ((c) == '\\' || (c) == ':' || (c) == '/')
 40: #else
 41: #ifdef VMS
 42: #define ispathdelim(c)  ((c)==':' || (c)=='[' || (c)==']' )
 43: #else
 44: #ifdef MPW
 45: #define ispathdelim(c)  ((c) == ':')
 46: #else
 47: #define ispathdelim(c)  ((c) == '/')
 48: #endif /* MPW */
 49: #endif /* VMS */
 50: #endif
 51: 
 52: /**********************/
 53: 
 54: char * filespecaddpath(const char *path,const char *filename)
 55: {   register char *filespec;
 56:     register unsigned pathlen;
 57: 
 58:     if (!path || (pathlen = strlen(path)) == 0)
 59:         filespec = mem_strdup(filename);
 60:     else
 61:     {
 62:         filespec = (char *) mem_malloc(pathlen + 1 + strlen(filename) + 1);
 63:         if (filespec)
 64:         {   strcpy(filespec,path);
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
65: #if MSDOS || __OS2__ || __NT__ || _WIN32 66: if (!ispathdelim(filespec[pathlen - 1])) 67: strcat(filespec,"\\");
warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(110) : see declaration of 'strcat'
68: #else 69: #if VMS 70: #else 71: #if MPW 72: if (!ispathdelim(filespec[pathlen - 1])) 73: strcat(filespec,":"); 74: #else 75: if (!ispathdelim(filespec[pathlen - 1])) 76: strcat(filespec,"/"); 77: #endif /* MPW */ 78: #endif /* VMS */ 79: #endif 80: strcat(filespec,filename);
warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(110) : see declaration of 'strcat'
81: } 82: } 83: return filespec; 84: } 85: 86: #ifndef MPW 87: /**********************/ 88: char * filespecrootpath(char *filespec) 89: { 90: #if SUN || M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 91: #define DIRCHAR '/' 92: #endif 93: #if MSDOS || __OS2__ || __NT__ || _WIN32 94: #define DIRCHAR '\\' 95: #endif 96: #ifdef MPW 97: #define DIRCHAR ':' 98: #endif 99: 100: char *cwd, *cwd_t; 101: char *p, *p2; 102: 103: if (!filespec) 104: return filespec; 105: #if MSDOS || __OS2__ || __NT__ || _WIN32 106: /* if already absolute (with \ or drive:) ... */ 107: if (*filespec == DIRCHAR || (isalpha(*filespec) && *(filespec+1) == ':'))
warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'isalpha'
108: return filespec; /* ... return input string */ 109: #else 110: if (*filespec == DIRCHAR) /* already absolute ... */ 111: return filespec; /* ... return input string */ 112: #endif 113: 114: /* get current working directory path */ 115: #if SUN || M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 116: cwd_t = (char *)getcwd(NULL, 256); 117: #endif 118: #if MSDOS || __OS2__ || __NT__ || _WIN32 119: char cwd_d[132]; 120: if (getcwd(cwd_d, sizeof(cwd_d)))
warning C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\direct.h(117) : see declaration of 'getcwd'
121: cwd_t = cwd_d; 122: else 123: cwd_t = NULL; 124: #endif 125: 126: if (cwd_t == NULL) 127: { 128: mem_free(filespec); 129: return NULL; /* error - path too long (more than 256 chars !)*/ 130: } 131: cwd = mem_strdup(cwd_t); /* convert cwd to mem package */ 132: #if MSDOS 133: assert(strlen(cwd) > 0); 134: if (cwd[strlen(cwd) - 1] == DIRCHAR) 135: cwd[strlen(cwd) - 1] = '\0'; 136: #endif 137: #if SUN || M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 138: free(cwd_t); 139: #endif 140: p = filespec; 141: while (p != NULL) 142: { 143: p2 = (char *)strchr(p, DIRCHAR); 144: if (p2 != NULL) 145: { 146: *p2 = '\0'; 147: if (strcmp(p, "..") == 0) /* move up cwd */ 148: /* remove last directory from cwd */ 149: *((char *)strrchr(cwd, DIRCHAR)) = '\0'; 150: else if (strcmp(p, ".") != 0) /* not current directory */ 151: { 152: cwd_t = cwd; 153: cwd = (char *)mem_calloc(strlen(cwd_t) + 1 + strlen(p) + 1); 154: #if SUN || M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 155: sprintf(cwd, "%s/%s", cwd_t, p); /* add relative directory */ 156: #endif 157: #if MSDOS || __OS2__ || __NT__ || _WIN32 158: sprintf(cwd, "%s\\%s", cwd_t, p); /* add relative directory */
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
159: #endif 160: mem_free(cwd_t); 161: } 162: /* else if ".", then ignore - it means current directory */ 163: *p2 = DIRCHAR; 164: p2++; 165: } 166: else if (strcmp(p,"..") == 0) /* move up cwd */ 167: { 168: /* remove last directory from cwd */ 169: *((char *)strrchr(cwd, DIRCHAR)) = '\0'; 170: } 171: else if (strcmp(p,".") != 0) /* no more subdirectories ... */ 172: { /* ... save remaining string */ 173: cwd_t = cwd; 174: cwd = (char *)mem_calloc(strlen(cwd_t) + 1 + strlen(p) + 1); 175: #if SUN || M_UNIX || M_XENIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 176: sprintf(cwd, "%s/%s", cwd_t, p); /* add relative directory */ 177: #endif 178: #if MSDOS || __OS2__ || __NT__ || _WIN32 179: sprintf(cwd, "%s\\%s", cwd_t, p); /* add relative directory */
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
180: #endif 181: mem_free(cwd_t); 182: } 183: p = p2; 184: } 185: mem_free(filespec); 186: 187: return cwd; 188: #ifdef VMS 189: assert(0); 190: #endif 191: } 192: #endif 193: 194: /**********************/ 195: 196: char * filespecdotext(const char *filespec) 197: { register const char *p; 198: register int len; 199: 200: if ((p = filespec) != NULL) 201: { p += (len = strlen(p)); 202: while (1) 203: { if (*p == '.') 204: break; 205: if (p <= filespec || ispathdelim(*p)) 206: { p = filespec + len; 207: break; 208: } 209: p--; 210: } 211: } 212: return (char *)p; 213: } 214: 215: /**********************/ 216: 217: char * filespecname(const char *filespec) 218: { register const char *p; 219: 220: /* Start at end of string and back up till we find the beginning */ 221: /* of the filename or a path. */ 222: for (p = filespec + strlen(filespec); 223: p != filespec && !ispathdelim(*(p - 1)); 224: p-- 225: ) 226: ; 227: return (char *)p; 228: } 229: 230: /***********************/ 231: 232: char * filespecgetroot(const char *name) 233: { char *root,*p,c; 234: 235: p = filespecdotext(name); 236: c = *p; 237: *p = 0; 238: root = mem_strdup(name); 239: *p = c; 240: return root; 241: } 242: 243: /*****************************/ 244: 245: char * filespecforceext(const char *filespec,const char *ext) 246: { register char *p; 247: register const char *pext; 248: 249: if (*ext == '.') 250: ext++; 251: if ((p = (char *)filespec) != NULL) 252: { pext = filespecdotext(filespec); 253: if (ext) 254: { int n = pext - filespec; 255: p = (char *) mem_malloc(n + 1 + strlen(ext) + 1); 256: if (p) 257: { memcpy(p,filespec,n); 258: p[n] = '.'; 259: strcpy(&p[n + 1],ext);
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
260: } 261: } 262: else 263: p = mem_strdup(filespec); 264: } 265: return p; 266: } 267: 268: /*****************************/ 269: 270: char * filespecdefaultext(const char *filespec,const char *ext) 271: { register char *p; 272: register const char *pext; 273: 274: pext = filespecdotext(filespec); 275: if (*pext == '.') /* if already got an extension */ 276: { 277: p = mem_strdup(filespec); 278: } 279: else 280: { int n = pext - filespec; 281: p = (char *) mem_malloc(n + 1 + strlen(ext) + 1); 282: if (p) 283: { 284: memcpy(p,filespec,n); 285: p[n] = '.'; 286: strcpy(&p[n + 1],ext);
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
287: } 288: } 289: return p; 290: } 291: 292: /************************************/ 293: 294: #if !(MSDOS || __OS2__ || __NT__ || _WIN32) 295: 296: char *filespectilde(char *filespec) 297: { 298: #if BSDUNIX 299: struct passwd *passwdPtr; 300: register char *f; 301: 302: if (filespec && *filespec == '~') 303: { 304: passwdPtr = NULL; 305: if (filespec[1] == '/' || filespec[1] == 0) /* if ~/... or ~ */ 306: { f = filespec + 1; 307: passwdPtr = getpwuid(getuid()); 308: } 309: else /* else ~name */ 310: { 311: char c; 312: 313: f = strpbrk(filespec," /"); 314: if (!f) 315: f = filespec + strlen(filespec); /* point at trailing 0 */ 316: c = *f; 317: *f = 0; 318: passwdPtr = getpwnam(filespec + 1); 319: *f = c; 320: } 321: if (passwdPtr) 322: { char *p; 323: 324: p = (char *) mem_malloc(strlen(passwdPtr->pw_dir) + strlen(f) + 1); 325: if (p) 326: { 327: strcpy(p,passwdPtr->pw_dir); 328: strcat(p,f); 329: mem_free(filespec); 330: filespec = p; 331: } 332: } 333: } 334: #endif 335: #if MSDOS || __OS2__ || __NT__ || _WIN32 336: #endif 337: #if VMS 338: assert(0); 339: #endif 340: return filespec; 341: } 342: 343: /************************************/ 344: 345: char *filespecmultitilde(char *string) 346: { 347: register char *p, *p2, *p3, *p4; 348: 349: string = filespectilde(string); /* expand if first character is a '~' */ 350: 351: if (string) 352: { 353: for (p = string; *p != '\0'; p++) 354: { 355: if (*p == '~') 356: { 357: *p = '\0'; /* terminate sub string */ 358: p2 = mem_strdup(string); /* get new sub string from old string */ 359: *p = '~'; /* reset ~ character */ 360: for (p3 = p + 1; *p3 != ' ' && *p3 != '\0'; p3++) 361: ; /* scan to next name, or end of the string */ 362: p4 = NULL; 363: if (*p3 == ' ') 364: { 365: p4 = mem_strdup(p3); /* save reminder of the string */ 366: *p3 = '\0'; 367: } 368: p = mem_strdup(p); /* get tilde string */ 369: mem_free(string); 370: p = filespectilde(p); 371: 372: /* reconstruct the string from pieces */ 373: if (p4) 374: { 375: string = (char *) 376: mem_calloc(strlen(p2) + strlen(p) + strlen(p4) + 1); 377: sprintf(string, "%s%s%s", p2, p, p4); 378: } 379: else 380: { 381: string = (char *) 382: mem_calloc(strlen(p2) + strlen(p) + 1); 383: sprintf(string, "%s%s", p2, p); 384: } 385: mem_free(p); 386: p = string + strlen(p2) + 2; 387: mem_free(p2); 388: if (p4) 389: mem_free(p4); 390: } 391: } 392: } 393: return string; 394: } 395: 396: #endif 397: 398: #ifndef MPW 399: /************************************/ 400: 401: char * filespecbackup(const char *filespec) 402: { 403: #if MSDOS || __OS2__ || __NT__ || _WIN32 404: return filespecforceext(filespec,"BAK"); 405: #endif 406: #if BSDUNIX || linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4 407: char *p,*f; 408: 409: /* Prepend .B to file name, if it isn't already there */ 410: if (!filespec) 411: return (char *)filespec; 412: p = filespecname(filespec); 413: if (p[0] == '.' && p[1] == 'B') 414: return mem_strdup(filespec); 415: f = (char *) mem_malloc(strlen(filespec) + 2 + 1); 416: if (f) 417: { strcpy(f,filespec); 418: strcpy(&f[p - filespec],".B"); 419: strcat(f,p); 420: } 421: return f; 422: #endif 423: } 424: #endif 425: