home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume22
/
wp2x
/
part01
/
dopen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-23
|
4KB
|
156 lines
/*$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);
}