home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Mint / mntlib32.zoo / findfile.c < prev    next >
C/C++ Source or Header  |  1993-05-25  |  3KB  |  125 lines

  1. /* findfile: given a base filename, a list of directories, and a list
  2.    of possible extensions to the filename, attempts to find a file.
  3.    Useful for doing, e.g. spawnvp. Note that the current directory
  4.    is always searched first! If the filename already contains a
  5.    path specification (or extension) then the given path list
  6.    (or extension list) is ignored.
  7.    Returns the name by which the file was found, or NULL.
  8.  
  9.    Written by Eric R. Smith and placed in the public domain.
  10.  
  11.    rehacked by Uwe Ohse, 28.4.93, to support reentrant spawn/popen.
  12. */
  13.  
  14. #include <compiler.h>
  15. #include <limits.h>    /* needed for PATH_MAX */
  16. #include <support.h>
  17. #include <stddef.h>
  18. #include <types.h>
  19. #include <stat.h>
  20. #include <string.h>
  21.  
  22. /* characters used to separate components in a path list */
  23. #define PATHSEP1        ':'
  24. #define PATHSEP2        ','
  25.  
  26. /* characters used to separate directory names in a file */
  27. #define DIRSEP1         '\\'    /* native OS directory separator */
  28. #define DIRSEP2         '/'     /* for emulating another OS */
  29.  
  30. static char *nullext[] = { NULL };
  31.  
  32. static int EXISTS __PROTO((char *));
  33.  
  34. static int
  35. EXISTS(name)
  36.     char *name;
  37. {
  38.     struct stat dummy;
  39.  
  40.     if (stat(name, &dummy) != 0)
  41.         return 0;
  42.     if ( (dummy.st_mode & S_IFMT) != S_IFREG )
  43.         return 0;
  44.     return 1;
  45. }
  46.  
  47.  
  48. char *
  49. findfile(fname, fpath, fext)
  50.         char *fname, *fpath, **fext;
  51. {
  52.       /* simply calls buffindfile */
  53.       static char try[PATH_MAX];
  54.       return buffindfile(fname,fpath,fext,try);
  55. }
  56.  
  57.  
  58. char *
  59. buffindfile(fname, fpath, fext, try)
  60.       char *fname, *fpath, **fext, *try;
  61. {
  62.       char *s, *t, *extplace, **nextext, c;
  63.       int  hasext = 0, haspath = 0;
  64.  
  65.     if (!fname || !*fname)
  66.         return NULL;
  67.  
  68.       s = try; t = fname;
  69.  
  70. /* copy the file in, checking to see if a path and/or extension are already
  71.    given */
  72.  
  73.       while ( (c = *t++) != 0 )
  74.       {
  75.               if (c == DIRSEP1 || c == DIRSEP2)
  76.               {
  77.                       haspath = 1;
  78.                       hasext = 0;
  79.               }
  80.               else if (c == '.')
  81.                       hasext = 1;
  82.               *s++ = c;
  83.       }
  84.       extplace = s;
  85.       *s++ = 0;
  86.  
  87.       if (haspath || !fpath)
  88.               fpath = "";
  89.       if (hasext || !fext)
  90.               fext = nullext;
  91.  
  92.       for(;;) {               /* loop on path elements */
  93.               nextext = fext;
  94.         if (!hasext) {
  95.             extplace[0] = 0;
  96.             extplace[1] = 0;
  97.         }
  98.  
  99.         if (EXISTS(try))
  100.             return try;
  101.         extplace[0] = '.';
  102.               while(*nextext) {       /* loop on extensions */
  103.                       (void)strcpy(&extplace[1], *nextext++);
  104.                       if (EXISTS(try))
  105.                               return try;
  106.               }
  107.               if (!*fpath) break;  /* no more places to look */
  108.  
  109. /* copy in next element of path list */
  110.               s = try;
  111.               while ((c = *fpath) != 0 && c != PATHSEP1 && c != PATHSEP2) {
  112.                       *s++ = c;
  113.                       fpath++;
  114.               }
  115.               if (c)
  116.                       fpath++;
  117.               *s++ = DIRSEP1;
  118.               t = fname;
  119.               while ((*s++ = *t++) != 0)
  120.                       ;
  121.               extplace = --s ;        /* where the extension gets written */
  122.       }
  123.       return NULL;
  124. }
  125.