home *** CD-ROM | disk | FTP | other *** search
- /*$Id: dopen.c 1.2 91/08/20 15:18:51 raymond Exp $*/
-
- /* dopen() is a massively system-dependent function, so I've placed
- * it in a separate file.
- */
-
- /* Macros used...
- *
- * IS_ABS -- a macro that returns nonzero if the string argument is an
- * absolute path, or 0 if it is a relative path.
- * PATH_STR -- a string of characters which separate directory components.
- * SUF_STR -- suffix for configuration files
- * PATH_SEP -- character to separate directory from filename.
- * LIST_SEP -- character that separates pathnames in a list.
- * exists(f) -- returns nonzero if the file f exists.
- * if not defined, then use fopen to determine existence.
- * HAS_ENV -- if defined, environment variables are searched.
- *
- */
-
- /*
- * Our algorithm is to try the following in sequence, until one works.
- *
- * The filename as-is.
- * The filename with SUF_STR appended.
- *
- * If IS_ABS returns nonzero, then fail.
- *
- * Else, we call the system-dependent get_dir() function. Each call
- * provides a directory to look in.
- *
- * For each directory, append the filename (perhaps inserting the
- * PATH_SEP). If that fails, try again after appending SUF_STR.
- *
- * When we run out of directories, we fail.
- */
-
- #ifdef UNIX
- #define HAS_ENV
- #define exists(f) (access(f, 0) == 0)
- #define IS_ABS(f) (*f == '/')
- #define SUF_STR ".cfg"
- #define PATH_SEP '/'
- #define PATH_STR "/"
- #define LIST_SEP ':'
- #endif
-
- #ifdef MSDOS
- #define HAS_ENV
- #include <io.h>
- #define exists(f) (access(f, 0) == 0)
- #define IS_ABS(f) (f[1] == ':' || strchr(PATH_STR, *f))
- #define SUF_STR ".cfg"
- #define PATH_SEP '/'
- #define PATH_STR "/\\:"
- #define LIST_SEP ';'
- #endif
-
- #ifdef VMS /* VMS is really different */
- #define IS_ABS(f) (strchr(f, ':') || strchr(PATH_STR, *f))
- #define SUF_STR ".cfg"
- #define PATH_SEP '.'
- #define PATH_STR "[.]"
- #endif
-
- #ifdef AMIGA
- #define IS_ABS(f) (strchr(f, ':') || *f == '/')
- #define SUF_STR ".cfg"
- #define PATH_SEP '/'
- #define PATH_STR "/"
- #endif
-
- /* If user specified no operating system, be very pessimistic.
- * Don't do anything beyond adding the `.cfg. suffix.
- */
- #ifndef SUF_STR
- #define IS_ABS 1
- #define SUF_STR ".cfg"
- #undef PATH_SEP
- #undef PATH_STR
- #undef HAS_ENV
- #endif
-
- /* If we don't have an exists(), then we'll just use fopen. */
- #ifndef exists
- #define exists(f) (descriptor = fopen(f, "rt"))
- #endif
-
- #ifdef HAS_ENV
- /* We search a handful of environment variables */
- const char *envlist[] = { "PATH", "DPATH", "WP2XDIR", NULL };
-
- char *get_dir(void)
- {
- static const char **nextenv = envlist;
- static const char *nextpath = NULL;
- char *s;
-
- /* get the next environment variable */
- while (nextpath == NULL || *nextpath == '\0') {
- if (*nextenv == NULL) return NULL; /* out of ideas */
- nextpath = getenv(*nextenv++);
- }
-
- /* copy the next path component into the string pool */
- /* We can ignore the UNIX convention that a null component
- * denotes the current directory, since the current directory
- * has already been searched before we get to this point.
- */
- s = pool;
- while (*nextpath && *nextpath != LIST_SEP) *s++ = *nextpath++;
- if (*nextpath) nextpath++;
-
- return s; /* where to append the filename */
- }
- #else
- /* On non-UNIX systems, we don't have environment variables. */
- /* We might have other things, though, so insert your local version here */
- char *get_dir(void) { return NULL; }
- #endif
-
- /* s is where to copy the filename, and f is the filename to try. */
-
- int try_directory(char *s, const char *f)
- {
- if (s > pool && !strchr(PATH_STR, s[-1])) *s++ = PATH_SEP;
- strcpy(s, f);
-
- if (exists(pool) || (strcat(s, SUF_STR), exists(pool))) {
- if (!descriptor) descriptor = efopen(pool, "rt");
- return 1;
- }
-
- return 0;
- }
-
- void dopen(const char *f)
- {
- char *s;
-
- /* First, try it as-is */
- if (try_directory(pool, f)) return;
-
- #ifdef WP2X_DIR
- strcpy(pool, WP2X_DIR);
- if (try_directory(strchr(pool, '\0'), f)) return;
- #endif
-
- /* Skip if an absolute path */
- if (!IS_ABS(f)) {
- /* Iterate through the possible directories */
- while (s = get_dir()) if (try_directory(s, f)) return;
- }
- error(NULL, "Cannot find file %s\n", f);
- }
-