home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / parseargs / openpath.c < prev    next >
C/C++ Source or Header  |  1990-02-16  |  3KB  |  143 lines

  1. #include <useful.h>
  2.  
  3. VERSIONID("$Header: openpath.c,v 2.0 89/12/24 00:56:26 eric Exp $");
  4.  
  5. /*
  6. **  OPENPATH -- open a file, searching through a path
  7. **
  8. **    Parameters:
  9. **        fname -- the file name, relative to the desired path.
  10. **        mode -- the open mode, just like fopen.
  11. **        path -- the search path.
  12. **
  13. **    Returns:
  14. **        FILENULL if the file could not be found at all.
  15. **        A FILE pointer open for reading for the first instance
  16. **            of the file that could be found in the path
  17. **            otherwise.
  18. **
  19. **    Side Effects:
  20. **        none.
  21. **
  22. **    Notes:
  23. **        Should really just find the file, not open it.
  24. **
  25. **    Author:
  26. **        Eric Allman
  27. **        University of California, Berkeley
  28. */
  29.  
  30. char    *DefaultPath =        CHARNULL;
  31.  
  32. #ifndef DEFAULTROOTPATH
  33. #define DEFAULTROOTPATH        "/usr/local:/usr:~:"
  34. #endif
  35.  
  36. FILE *
  37. openpath(fname, mode, path)
  38.     char *fname;
  39.     char *mode;
  40.     char *path;
  41. {
  42.     register char *dp;
  43.     register char *ep;
  44.     register char *bp;
  45.     FILE *fp;
  46.     char fbuf[200];
  47.     extern char *getenv ARGS((char *));
  48.  
  49.     dp = path;
  50.     if (dp == CHARNULL)
  51.     {
  52.         dp = DefaultPath;
  53.         if (dp == CHARNULL)
  54.         {
  55.             /* locate the root of our utility tree */
  56.             dp = getenv("ROOTPATH");
  57.             if (dp == CHARNULL)
  58.                 dp = DEFAULTROOTPATH;
  59.             DefaultPath = dp;
  60.         }
  61.     }
  62.     for (;; dp = ++ep)
  63.     {
  64.         register int l;
  65.         int i;
  66.         int fspace;
  67.  
  68.         /* extract a component */
  69.         ep = strchr(dp, ':');
  70.         if (ep == CHARNULL)
  71.             ep = &dp[strlen(dp)];
  72.  
  73.         /* find the length of that component */
  74.         l = ep - dp;
  75.         bp = fbuf;
  76.         fspace = sizeof fbuf - 2;
  77.         if (l > 0)
  78.         {
  79.             /*
  80.             **  If the length of the component is zero length,
  81.             **  start from the current directory.  If the
  82.             **  component begins with "~", start from the
  83.             **  user's $HOME environment variable.  Otherwise
  84.             **  take the path literally.
  85.             */
  86.  
  87.             if (*dp == '~' && (l == 1 || dp[1] == '/'))
  88.             {
  89.                 char *home;
  90.  
  91.                 home = getenv("HOME");
  92.                 if (home != CHARNULL)
  93.                 {
  94.                     i = strlen(home);
  95.                     if ((fspace -= i) < 0)
  96.                         goto toolong;
  97.                     bcopy(home, bp, i);
  98.                     bp += i;
  99.                 }
  100.                 dp++;
  101.                 l--;
  102.             }
  103.             if (l > 0)
  104.             {
  105.                 if ((fspace -= l) < 0)
  106.                     goto toolong;
  107.                 bcopy(dp, bp, l);
  108.                 bp += l;
  109.             }
  110.  
  111.             /* add a "/" between directory and filename */
  112.             if (ep[-1] != '/')
  113.                 *bp++ = '/';
  114.         }
  115.  
  116.         /* now append the file name */
  117.         i = strlen(fname);
  118.         if ((fspace -= i) < 0)
  119.         {
  120.     toolong:
  121.             fprintf(stderr, "openpath: pathname too long (ignored)\n");
  122.             *bp = '\0';
  123.             fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
  124.             fprintf(stderr, "\tFile \"%s\"\n", fname);
  125.             continue;
  126.         }
  127.         bcopy(fname, bp, i + 1);
  128.  
  129.         /* try to open that file */
  130.         fp = fopen(fbuf, mode);
  131.  
  132.         /* if it exists, all is well */
  133.         if (fp != FILENULL)
  134.             return (fp);
  135.  
  136.         /* if not, and no other alternatives, life is bleak */
  137.         if (*ep == '\0')
  138.             return (FILENULL);
  139.  
  140.         /* otherwise try the next component in the search path */
  141.     }
  142. }
  143.