1/* fullpath.c - fully resolve a pathname. */ 2 3#include "config.h" 4#include "system.h" 5 6 7#ifdef FULL_PATHS_IN_ERRORS 8#if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__))) 9 10extern char *getpwd PROTO((void)); 11 12char * 13convert_to_full_path(const char *file) 14{ 15 static char *full_path_buffer = 0; 16 const char *cwd; 17 char *outp, *inp; 18 19 if (file == NULL || file[0] == '/') /* file already full path */ 20 return (char *)file; 21 22 cwd = getpwd (); 23 if (!cwd) 24 return (char *)file; 25 26 if (full_path_buffer == NULL) 27 full_path_buffer = xmalloc (2 * MAXPATHLEN + 1); 28 29 strcpy (full_path_buffer, cwd); 30 strcat (full_path_buffer, "/"); 31 strcat (full_path_buffer, file); 32 33 /* Now make a copy of full_path_buffer into full_path_buffer, shortening the 34 filename (by taking out slashes and dots) as we go. */ 35 36 outp = inp = full_path_buffer; 37 *outp++ = *inp++; /* copy first slash */ 38 for (;;) 39 { 40 if (!inp[0]) 41 break; 42 /* ??? FIXME: Care for POSIXly correct leading double slash. */ 43 else if (inp[0] == '/' && outp[-1] == '/') 44 { 45 inp++; 46 continue; 47 } 48 else if (inp[0] == '.' && outp[-1] == '/') 49 { 50 if (!inp[1]) 51 break; 52 else if (inp[1] == '/') 53 { 54 inp += 2; 55 continue; 56 } 57 else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/')) 58 { 59 inp += (inp[2] == '/') ? 3 : 2; 60 outp -= 2; 61 while (outp >= full_path_buffer && *outp != '/') 62 outp--; 63 if (outp < full_path_buffer) 64 { 65 /* Catch cases like /.. where we try to backup to a 66 point above the absolute root of the logical file 67 system. */ 68 69 return (char *)file; 70 } 71 *++outp = '\0'; 72 continue; 73 } 74 } 75 *outp++ = *inp++; 76 } 77 78 /* On exit, make sure that there is a trailing null, and make sure that 79 the last character of the returned string is *not* a slash. */ 80 81 *outp = '\0'; 82 if (outp[-1] == '/') 83 *--outp = '\0'; 84 85 return full_path_buffer; 86} 87 88 89#else /* VMS || _WIN32 && !__CYGWIN__ */ 90 91char * 92convert_to_full_path(const char *file) 93{ 94 return (char *) file; 95} 96 97#endif /* VMS || _WIN32 && !__CYGWIN__ */ 98#endif /* FULL_PATHS_IN_ERRORS */ 99