home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / dos / dir / srchpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-31  |  3.0 KB  |  144 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <libc/stubs.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <ctype.h>
  8. #include <limits.h>
  9. #include <dir.h>
  10. #include <crt0.h>
  11. #include <fcntl.h>
  12. #include <libc/environ.h>
  13. #include <libc/bss.h>
  14.  
  15. static int env_changed = 0;
  16. static int srchpath_bss_count = -1;
  17.  
  18. /* Search PATH for FILE.
  19.    If successful, store the full pathname in static buffer and return a
  20.    pointer to it.
  21.    If not sucessful, return NULL.
  22.    This is what the Borland searchpath() library function does.
  23. */
  24.  
  25. char *
  26. searchpath(const char *file)
  27. {
  28.   static char found[PATH_MAX];
  29.   static char *path;
  30.  
  31.   memset(found, 0, sizeof(found));
  32.  
  33.   /* Get $PATH and store it for reuse.  */
  34.   if (path == 0
  35.       || srchpath_bss_count != __bss_count
  36.       || env_changed != __environ_changed)
  37.   {
  38.     char *p = getenv("PATH");
  39.  
  40.     if (path && srchpath_bss_count == __bss_count)
  41.       free(path);
  42.     path = (char *)calloc(p ? strlen(p) + 3 : 2, sizeof(char));
  43.     if (path == (char *)0)
  44.       return (char *)0;
  45.  
  46.     /* Prepend `.' to the PATH, so current directory
  47.        is always searched first.  */
  48.     path[0] = '.';
  49.  
  50.     if (p)
  51.     {
  52.       register char *s, *name_start = 0;
  53.       int preserve_case = _preserve_fncase();
  54.  
  55.       path[1] = ';';
  56.       strcpy(path+2, p);
  57.  
  58.       /* switch FOO\BAR to foo/bar, downcase where appropriate */
  59.       for (s = path + 2, name_start = s; *name_start; s++)
  60.       {
  61.     char lname[FILENAME_MAX], sname[13];
  62.  
  63.     if (*s == '\\')
  64.       *s = '/';
  65.     if (s == name_start)
  66.       continue;
  67.     if (*s == ':')
  68.       name_start = s + 1;
  69.     else if (!preserve_case && (*s == '/' || *s == ';' || *s == '\0'))
  70.     {
  71.       memcpy(lname, name_start+1, s - name_start - 1);
  72.       lname[s - name_start - 1] = '\0';
  73.       if (!strcmp(_lfn_gen_short_fname(lname, sname), lname))
  74.       {
  75.         name_start++;
  76.         while (name_start < s)
  77.         {
  78.           if (*name_start >= 'A' && *name_start <= 'Z')
  79.         *name_start += 'a' - 'A';
  80.           name_start++;
  81.         }
  82.       }
  83.       else
  84.         name_start = s;
  85.     }
  86.     else if (*s == '\0')
  87.       break;
  88.       }
  89.     }
  90.     else
  91.       path[1] = 0;
  92.   }
  93.   if (strpbrk (file, "/\\:") != 0)
  94.   {
  95.     strcpy(found, file);
  96.     return found;
  97.   }
  98.   else
  99.   {
  100.     char *test_dir = path;
  101.  
  102.     do {
  103.       char *dp;
  104.  
  105.       dp = strchr(test_dir, ';');
  106.       if (dp == (char *)0)
  107.     dp = test_dir + strlen(test_dir);
  108.  
  109.       if (dp == test_dir)
  110.     strcpy(found, file);
  111.       else
  112.       {
  113.     strncpy(found, test_dir, dp - test_dir);
  114.     found[dp - test_dir] = '/';
  115.     strcpy(found + (dp - test_dir) + 1, file);
  116.       }
  117.  
  118.       if (__file_exists(found))
  119.     return found;
  120.  
  121.       if (*dp == 0)
  122.     break;
  123.       test_dir = dp + 1;
  124.     } while (*test_dir != 0);
  125.   }
  126.  
  127.   return NULL;
  128. }
  129.  
  130. #ifdef TEST
  131.  
  132. int main(int argc, char *argv[])
  133. {
  134.   if (argc > 1)
  135.     {
  136.       char *found = searchpath (argv[1]);
  137.       printf ("%s: %s%s\n",
  138.           argv[1], found ? "found as " : "not found", found ? found : " ");
  139.     }
  140.   return 0;
  141. }
  142.  
  143. #endif
  144.