|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T u
Length: 13269 (0x33d5)
Types: TextFile
Names: »uuwho.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦2fafebccf⟧ »EurOpenD3/mail/smail3.1.19.tar.Z«
└─⟦bcd2bc73f⟧
└─⟦this⟧ »pd/uuwho/uuwho.c«
/* @(#)uuwho.c 1.13 12/18/88 21:28:55 */
/*
* uuwho:
* store/retrieve uucp map info in dbm format
*
* uuwho uses a dbm file with pointers into the real map files,
* hence initialization MUST be done any time a map file has changed.
*
* usage:
* initialize: uuwho -i [-d dbmfile] mapfile ...
* retrieve : uuwho [-d dbmfile] [sitename ...]
*
* NOTE: this program requires DBM
*
* Based on a program written by someone in the public domain,
* which was then ported to System V by Gordon Moffett, which
* was then improved by Landon Noll, which was then re-written
* again to fit into the smail system.
*/
#include <stdio.h>
#include "defs.h"
#ifdef HAVE_DBM
#ifdef UNIX_SYS5
#include <sys/utsname.h>
#endif /* UNIX_SYS5 */
#undef NULL /* dbm.h often defines NULL */
#include <dbm.h>
#undef NULL /* in case dbm.h does not define NULL */
#define NULL 0
#define NLEN 255 /* max sitename length */
#define W_DBM "uuwho" /* database basename in SMAIL_LIB_DIR */
char *cmdname; /* same as argv[0] */
/* variable length record stored in who database */
typedef struct {
long pos;
char name[NLEN+1]; /* NLEN+1 is max size, is often smaller */
} position;
datum fileinfo;
datum sitename;
void dbmtouch(); /* be sure that the .dir and .pag files exist */
void printmap(); /* print a map form using the location form dbm */
char *get_hostname(); /* get our histname */
char line[BUFSIZ + 1];
FILE *fp;
extern char *strcpy();
extern int errno; /* last system error */
main(argc, argv)
int argc;
char *argv[];
{
char *fbasename=W_DBM; /* database basename */
char *fname; /* database filename */
char *hostname=NULL; /* != NULL ==> only print hostname */
char *malloc(); /* mem allocator */
char *realloc(); /* mem expander */
int opt; /* flag char */
int namelen; /* length of sitename */
int newdbm = 0; /* 1 ==> new database creation is requested */
position *p; /* the fetched record */
extern char *optarg; /* the arg of a flag */
extern int optind; /* the first non flag */
/*
* parse args
*/
cmdname = argv[0];
while ((opt = getopt(argc,argv,"id:")) != EOF) {
switch (opt) {
case 'i': /* new database being formed */
newdbm = 1;
break;
case 'd':
fbasename = optarg;
break;
case '?':
usage();
break;
}
}
if (newdbm == 1 && optind >= argc) {
usage(); /* -i flag must have args */
} else if (newdbm == 0 && optind >= argc) {
/* looking now for the hostname, get it */
hostname = get_hostname();
}
/*
* open the database
*/
if (fbasename[0] == '/' || fbasename[0] == '.') {
fname = fbasename;
} else {
fname = malloc(strlen(SMAIL_LIB_DIR)+1+strlen(fbasename)+1);
if (fname == NULL) {
perror(cmdname);
exit(1);
}
sprintf(fname, "%s/%s", SMAIL_LIB_DIR, fbasename);
}
dbmtouch(fname,newdbm);
if (dbminit(fname) < 0) {
fprintf(stderr, "%s: dbminit(%s) failed\n", cmdname, fname);
exit(2);
}
/*
* process each map or site
*/
do {
/*
* if we are initializing a database, just load each file
*/
if (newdbm) {
getfile(argv[optind]); /* add entries to database */
/*
* we are not loading but rather doing a querry, so look it up
*/
} else {
/*
* try to fetch something from the database
*/
sitename.dptr = (hostname) ? hostname : argv[optind];
namelen = strlen(sitename.dptr);
sitename.dsize = namelen > NLEN ? NLEN : namelen;
fileinfo = fetch(sitename);
/*
* did we fetch something from the database? If so, process it
*/
if ((p = (position *)fileinfo.dptr) == (position *)NULL) {
/* no entry found, complain */
fprintf(stderr, "no site entry for %s\n", sitename.dptr);
} else {
printmap(p);
}
}
} while (++optind < argc);
/* end of the show */
exit(0);
}
/*
* printmap - print a map file
*/
void
printmap(p)
position *p; /* the fetched record */
{
int comment; /* 1 ==> within a #comment set */
int pathdata; /* 1 ==> have seen path data */
int ctr = 0; /* >0 ==> we have a new #N record */
char *cp; /* pointer */
char *tp; /* pointer */
char c; /* the char we are looking at */
char unknown[2]; /* unknown #x line name */
/*
* open the file
*/
if ((fp = fopen(p->name, "r")) == (FILE *)NULL) {
fprintf(stderr, "%s: Can't open data file %s\n",
cmdname, p->name);
return;
}
/* seek to the starting location in the file */
fseek(fp, p->pos, 0);
/*
* process the entry one line at a time
*/
pathdata = 0; /* no path data seen yet */
comment = 0; /* not in a #comment set */
unknown[1] = '\0'; /* terminate string */
while (fgets(line, BUFSIZ, fp)) {
/* always print non # (route) lines */
if (*(cp = line) != '#') {
pathdata = 1; /* we have seen path data */
/* deal with trailing #comments */
if ( comment != 0 ) {
putchar('\n');
comment = 0; /* no more comments */
}
fputs(line, stdout);
continue;
}
/* skip the '#' */
++cp;
/* print out #<space>, #<tab> and #\n lines always */
if (*cp == ' ' || *cp == '\t' || *cp == '\n') {
/* deal with #comment white spacing */
if ( pathdata == 0 && comment == 0 ) {
/* white space before #comment set */
putchar('\n');
/* we have seen #comment lines */
comment = 1;
}
fputs(line, stdout);
continue;
/* turn of #comment white spacing if needed */
} else if ( pathdata == 0 && comment != 0 ) {
putchar('\n');
comment = 0; /* no more comments */
}
/* note if it is another #N line */
if (*cp == 'N' && ctr++) {
/* a new entry, so stop reading */
break;
}
/* skip the x in #x, saving x in the process */
c = *cp;
if (*cp != '\n' && *cp != '\0') {
++cp;
}
/* skip white space after #x for later use */
while (*cp == ' ' || *cp == '\t') {
++cp;
}
/* determine the name of the #X line */
switch (c) {
case 'N':
tp = "System name:";
break;
case 'S':
tp = "System type:";
break;
case 'F':
tp = "Arpa forwarder:";
break;
case 'O':
tp = "Organization:";
break;
case 'C':
tp = "Contact person:";
break;
case 'E':
tp = "Email Address:";
break;
case 'T':
tp = "Telephone:";
break;
case 'P':
tp = "Postal Address:";
break;
case 'L':
tp = "Long/Lat:";
break;
case 'R':
tp = "Remarks:";
break;
case 'U':
tp = "News links:";
break;
case 'W':
tp = "Author & date:";
break;
case '\t': /* line starts at #<tab>, special case */
case '\n': /* line just as a #, special case */
tp = 0;
break;
default: /* unknown #x line */
unknown[0] = c;
tp = unknown;
break;
}
/* print the #X line name and contents */
printf("%-16.16s %s", tp, cp);
}
fclose(fp);
}
/*
* get a file and install it in the who database
*/
getfile(filename)
char *filename; /* the file to add */
{
register char *cp; /* pointer */
register int namelen; /* length of sitename */
static int input=0; /* 1 ==> already read input */
char *malloc(); /* storage allocator */
int linelen; /* the length of the current line */
long pos = 0; /* current file position */
position pp; /* the variable length record to save */
/* try to open the new file */
if (input == 0 && strcmp(filename, "-") == 0) {
fp = stdin;
input = 1;
filename = "[stdin]";
} else if (input == 1 && strcmp(filename, "-") == 0) {
fprintf(stderr,
"%s: already processed standard input\n", cmdname);
return;
} else if ((fp = fopen(filename, "r")) == (FILE *)NULL) {
fprintf(stderr, "%s: Can't open %s\n", cmdname, filename);
return;
}
/*
* build up a new database entry skelliten
*/
fileinfo.dptr = (char *)&pp;
fileinfo.dsize = sizeof(pp.pos) + strlen(filename) + 1; /* real size */
strcpy(pp.name, filename);
/*
* for each entry, note the position in the file
*/
pos = 0; /* we start at the beginning */
while (fgets(line, BUFSIZ, fp)) { /* one line at a time */
char *p; /* start of filename */
char *q; /* after filename */
char *r; /* pointer */
/* watch for a file entry */
if (strncmp(line, "file", 4) == 0) {
/* skip over whitespace */
p = line + 4 + strspn(&line[4], " \t\n");
/* skip over the opening { */
if (*p != '{') {
continue; /* not a useful line */
}
/* skip whitespace to find the filename */
p += strspn(p+1, " \t\n") + 1;
if (*p == '\0') {
continue; /* not a useful line */
}
/* find the end of the filename */
q = p + strcspn(p, " \t\n}");
if (*q == '\0') {
continue; /* not a useful line */
}
/* skip whitespace */
r = q + strspn(q, " \t\n");
/* skip over the closing } */
if (*r != '}') {
continue; /* not a useful line */
}
/* verify end of line */
if (*(r+1) != '\n' || *(r+2) != '\0') {
continue; /* not a useful line */
}
/* form new fileinfo module */
strncpy(pp.name, p, q-p);
pp.name[q-p] = '\0';
fileinfo.dsize = sizeof(pp.pos) + q-p + 1;
pos = 0; /* assume beginning of the filename */
continue;
}
/* watch for a new entry */
if (strncmp(line, "#N", 2) == 0) {
/*
* we have new entry, determine the name
*
* note that lines are of the form:
* #N sitename
* #N name1, name2, ...
*/
cp = line + 2; /* skip over #N */
while (1) {
/* skip white space or ',' */
cp += strspn(cp, " \t,");
/* if no more #N names stop processing line */
if (*cp == '\n') {
break;
}
/* note size of name */
sitename.dptr = cp; /* name start addr */
cp += strcspn(cp, "\n, \t");
namelen = cp - sitename.dptr; /* length */
/* limit name length for sanity */
sitename.dsize = (namelen > NLEN) ? NLEN : namelen;
/* note the file position of the #N line */
pp.pos = pos;
/*
* store the file/position info with the
* sitename as the fetch key
*/
store(sitename, fileinfo);
/* process other sitenames on the line */
}
}
/* note the new position */
linelen = strlen(line);
if (linelen >= BUFSIZ-2) { /* avoid excessively bogus lines */
fprintf(stderr,
"%s: %s has a line >= %d chars\n",
cmdname, filename, BUFSIZ-2);
exit(1);
}
pos += (long)linelen;
}
/* cleanup */
fclose(fp);
}
/*
* show command usage, and die
*/
usage()
{
fprintf(stderr, "usage: %s [-d dbmfile] -i mapfile ...\n", cmdname);
fprintf(stderr, "usage: %s [-d dbmfile] [sitename ...]\n", cmdname);
exit(-1);
}
/*
* dbmtouch - be sure that the dbm files .pag and .dir exist
*/
void
dbmtouch(name,wr)
char *name; /* basename of the dbm file */
int wr; /* 1=>open for writing, 0=> reading */
{
char *filename; /* the .dir and .pag names*/
int fd; /* .dir or .pag file */
/*
* form the namespace for filename
*/
filename = malloc(strlen(name) + 4 + 1);
if (filename == NULL) {
perror(cmdname);
exit(1);
}
/*
* be sure that the .pag name exists
*/
sprintf(filename, "%s.pag", name);
fd = open(filename, wr);
if (fd < 0 && ! wr) {
fprintf(stderr, "%s: can not open %s\n", cmdname, filename);
exit(1);
} else if (fd < 0 && (fd = creat(filename, 0664)) < 0) {
fprintf(stderr, "%s: can not create or write %s\n", cmdname, filename);
exit(1);
}
close(fd);
/*
* be sure that the .dir name exists
*/
sprintf(filename, "%s.dir", name);
fd = open(filename, wr);
if (fd < 0 && ! wr) {
fprintf(stderr, "%s: can not open %s\n", cmdname, filename);
exit(1);
} else if (fd < 0 && (fd = creat(filename, 0664)) < 0) {
fprintf(stderr, "%s: can not create or write %s\n", cmdname, filename);
exit(1);
}
close(fd);
}
/*
* get_hostname - get our hostname for a no arg querry
*/
#ifdef UNIX_BSD
char *
get_hostname()
{
char *hostname; /* who we are */
char *malloc(); /* memory allocator */
/*
* My man page says that 255 chars (plus nul byte) is the limit
* on length of the local host name. There appears to be no
* #define for it in 4.2BSD.
*/
hostname = malloc(NLEN+1+1);
if (hostname == NULL) {
fprintf(stderr, "%s: bad mallof of hostname\n", cmdname);
exit(3);
}
if (gethostname(hostname, NLEN+1) < 0) {
hostname = NULL; /* unknown hostname */
}
return(hostname);
}
#else /* not UNIX_BSD */
# ifdef UNIX_SYS5
char *
get_hostname()
{
static struct utsname utsname;
(void) uname(&utsname);
/* is the sysname tag used for something interesting? */
return(utsname.nodename);
}
#else /* not UNIX_SYS5 */
char *
get_hostname()
{
return NULL;
}
# endif /* UNIX_SYS5 */
#endif /* not UNIX_BSD */
#else /* HAVE_DBM */ /* in case they have no dbm */
main(argc, argv)
int argc; /* arg count */
char *argv[]; /* ars */
{
fprintf(stderr, "%s: %s was not configured with DBM\n",
argv[0], argv[0]);
exit(1);
}
#endif /* HAVE_DBM */