home *** CD-ROM | disk | FTP | other *** search
- #include <useful.h>
-
- VERSIONID("$Header: openpath.c,v 2.0 89/12/24 00:56:26 eric Exp $");
-
- /*
- ** OPENPATH -- open a file, searching through a path
- **
- ** Parameters:
- ** fname -- the file name, relative to the desired path.
- ** mode -- the open mode, just like fopen.
- ** path -- the search path.
- **
- ** Returns:
- ** FILENULL if the file could not be found at all.
- ** A FILE pointer open for reading for the first instance
- ** of the file that could be found in the path
- ** otherwise.
- **
- ** Side Effects:
- ** none.
- **
- ** Notes:
- ** Should really just find the file, not open it.
- **
- ** Author:
- ** Eric Allman
- ** University of California, Berkeley
- */
-
- char *DefaultPath = CHARNULL;
-
- #ifndef DEFAULTROOTPATH
- #define DEFAULTROOTPATH "/usr/local:/usr:~:"
- #endif
-
- FILE *
- openpath(fname, mode, path)
- char *fname;
- char *mode;
- char *path;
- {
- register char *dp;
- register char *ep;
- register char *bp;
- FILE *fp;
- char fbuf[200];
- extern char *getenv ARGS((char *));
-
- dp = path;
- if (dp == CHARNULL)
- {
- dp = DefaultPath;
- if (dp == CHARNULL)
- {
- /* locate the root of our utility tree */
- dp = getenv("ROOTPATH");
- if (dp == CHARNULL)
- dp = DEFAULTROOTPATH;
- DefaultPath = dp;
- }
- }
- for (;; dp = ++ep)
- {
- register int l;
- int i;
- int fspace;
-
- /* extract a component */
- ep = strchr(dp, ':');
- if (ep == CHARNULL)
- ep = &dp[strlen(dp)];
-
- /* find the length of that component */
- l = ep - dp;
- bp = fbuf;
- fspace = sizeof fbuf - 2;
- if (l > 0)
- {
- /*
- ** If the length of the component is zero length,
- ** start from the current directory. If the
- ** component begins with "~", start from the
- ** user's $HOME environment variable. Otherwise
- ** take the path literally.
- */
-
- if (*dp == '~' && (l == 1 || dp[1] == '/'))
- {
- char *home;
-
- home = getenv("HOME");
- if (home != CHARNULL)
- {
- i = strlen(home);
- if ((fspace -= i) < 0)
- goto toolong;
- bcopy(home, bp, i);
- bp += i;
- }
- dp++;
- l--;
- }
- if (l > 0)
- {
- if ((fspace -= l) < 0)
- goto toolong;
- bcopy(dp, bp, l);
- bp += l;
- }
-
- /* add a "/" between directory and filename */
- if (ep[-1] != '/')
- *bp++ = '/';
- }
-
- /* now append the file name */
- i = strlen(fname);
- if ((fspace -= i) < 0)
- {
- toolong:
- fprintf(stderr, "openpath: pathname too long (ignored)\n");
- *bp = '\0';
- fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
- fprintf(stderr, "\tFile \"%s\"\n", fname);
- continue;
- }
- bcopy(fname, bp, i + 1);
-
- /* try to open that file */
- fp = fopen(fbuf, mode);
-
- /* if it exists, all is well */
- if (fp != FILENULL)
- return (fp);
-
- /* if not, and no other alternatives, life is bleak */
- if (*ep == '\0')
- return (FILENULL);
-
- /* otherwise try the next component in the search path */
- }
- }
-