/* ** $Id: defaults.c,v 2.0 90/09/19 19:42:09 paul Rel $ ** ** Routines to access runtime defaults file. ** This is to allow program features to be configured ** without the need to recompile. ** ** XENIX has defopen(S) and defread(S), but I think this is better, ** since it reads the file only once, storing the values in core. ** It is certainly more portable. */ /* ** Copyright 1989,1990 by Paul Sutcliffe Jr. ** ** Permission is hereby granted to copy, reproduce, redistribute, ** or otherwise use this software as long as: there is no monetary ** profit gained specifically from the use or reproduction or this ** software, it is not sold, rented, traded or otherwise marketed, ** and this copyright notice is included prominently in any copy ** made. ** ** The author make no claims as to the fitness or correctness of ** this software for any use whatsoever, and it is provided as is. ** Any use of this software is at the user's own risk. */ /* ** $Log: defaults.c,v $ ** Revision 2.0 90/09/19 19:42:09 paul ** Initial 2.0 release ** */ #include "getty.h" #include "defaults.h" #include #include #if defined(RCSID) && !defined(lint) static char *RcsId = "@(#)$Id: defaults.c,v 2.0 90/09/19 19:42:09 paul Rel $"; #endif #ifndef DEFAULTS #define DEFAULTS "/etc/default/%s" /* location of defaults file */ #endif /* DEFAULTS */ #ifndef MAXLINE #define MAXLINE 256 /* maximum # chars in a line */ #endif /* MAXLINE */ #ifndef MAXDEF #define MAXDEF 100 /* maximum # of lines in defaults file */ #endif /* MAXDEF */ /* ** defbuild() - create in-core list of defaults ** ** Returns (DEF**)NULL if no defaults file found or an error occurs. */ DEF ** defbuild(filename) char *filename; { register int i; register DEF *dp; register DEF *next; FILE *fp; char *fname, defname[MAXLINE+1], buf[MAXLINE+1]; static DEF *deflist[MAXDEF+1]; /* in-core list */ struct stat st; extern int errno; debug3(D_DEF, "defbuild(%s) called\n", ((filename == (char *) NULL) ? "NULL" : filename)); /* look to see if there's a DEFAULTS/MyName.Device file */ (void) sprintf(buf, "%s", DEFAULTS); (void) strcat(buf, ".%s"); (void) sprintf(defname, buf, MyName, Device); debug3(D_DEF, "looking for %s\n", defname); if ((stat(defname, &st) == FAIL) && errno == ENOENT) { /* Nope */ debug2(D_DEF, "stat failed, no file\n"); (void) sprintf(defname, DEFAULTS, MyName); } fname = (filename != (char *) NULL) ? filename : defname; /* if fname doesn't begin with a '/', assume it's a * filename to be made "DEFAULTS/fname" */ if (*fname != '/') { (void) sprintf(defname, DEFAULTS, fname); fname = defname; } debug3(D_DEF, "fname = (%s)\n", fname); if ((fp = defopen(fname)) == (FILE *) NULL) { debug2(D_DEF, "defopen() failed\n"); return((DEF **) NULL); /* couldn't open file */ } for (i=0; i < MAXDEF; i++) { if ((dp = defread(fp)) == (DEF *) NULL) break; if ((next = (DEF *) malloc((unsigned) sizeof(DEF))) == (DEF *) NULL) { logerr("malloc() failed: defaults list truncated"); break; } next->name = dp->name; next->value = dp->value; deflist[i] = next; debug5(D_DEF, "deflist[%d]: name=(%s), value=(%s)\n", i, deflist[i]->name, deflist[i]->value); } deflist[i] = (DEF *) NULL; /* terminate list */ (void) defclose(fp); debug2(D_DEF, "defbuild() successful\n"); return(deflist); } /* ** defvalue() - locate the value in "deflist" that matches "name" ** ** Returns (char*)NULL if no match is made. */ char * defvalue(deflist, name) register DEF **deflist; register char *name; { debug3(D_DEF, "defvalue(%s) called\n", name); if (deflist != (DEF **) NULL) for (; *deflist != (DEF *) NULL; *deflist++) if (strequal(name, (*deflist)->name)) { debug3(D_DEF, "defvalue returns (%s)\n", (*deflist)->value); return((*deflist)->value); /* normal exit */ } debug2(D_DEF, "defvalue returns NULL\n"); return((char *) NULL); } /* ** defopen() - open the defaults file ** ** Returns (FILE*)NULL if file not found or an error occurs. */ FILE * defopen(filename) register char *filename; { if (filename != (char *) NULL) return(fopen(filename, "r")); return((FILE *) NULL); } /* ** defread() - read a line from the defaults file ** ** Returns (DEF*)NULL if an error occurs. */ DEF * defread(fp) register FILE *fp; { register char *p; STDCHAR buf[MAXLINE+1]; /* buffer large enough for 1 line */ static DEF def; do { if (fgets(buf, sizeof(buf), fp) == (char *) NULL) return((DEF *) NULL); /* no more lines */ } while ((buf[0] == '#') || (buf[0] == '\n')); /* SMR - ignore comment lines */ buf[strlen(buf)-1] = '\0'; /* rm trailing \n */ /* lines should be in the form "NAME=value" */ if ((p = index(buf, '=')) == (char *) NULL) { (void) sprintf(MsgBuf, "bad defaults line: %s", buf); logerr(MsgBuf); return((DEF *) NULL); } *p++ = '\0'; /* split into two fields, name and value */ def.name = strdup(buf); def.value = strdup(p); return(&def); } /* ** defclose() - closes the defaults file ** ** Returns EOF if an error occurs. */ int defclose(fp) register FILE *fp; { return(fclose(fp)); } /* end of defaults.c */