home *** CD-ROM | disk | FTP | other *** search
- /* @(#)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>
- #ifndef AMIGA
- #include "defs.h"
- #endif
-
- #define HAVE_DBM
- #define UNIX_BSD
- #define UULIB "UULib\0UULIB:"
-
- void *memcpy(void *, void *, int);
-
- #define memcpy __builtin_memcpy
- #define VERDATE " 1.00 (26 Aug 90) "
-
- static char *version20 = "$VER: uuwho" VERDATE "\n\r";
-
- #ifdef HAVE_DBM
- #ifdef UNIX_SYS5
- #include <sys/utsname.h>
- #endif /* UNIX_SYS5 */
- #undef NULL /* dbm.h often defines NULL */
- #include "work:unixlib/dbm/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
- */
- #ifndef AMIGA
- 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);
- }
- #else
- {
- char *MakeConfigPath();
- fname = MakeConfigPath(UULIB, fbasename);
- }
- #endif
-
- 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 (fileinfo.dptr == (char *)NULL) {
- /* no entry found, complain */
- fprintf(stderr, "no site entry for %s\n", sitename.dptr);
- }
- else
- {
- p = (position *)malloc(sizeof(position));
- if(p != (position *)NULL)
- {
- memcpy(p, fileinfo.dptr, sizeof(position)); /* align */
- printmap(p);
- }
- else
- {
- fprintf(stderr, "Out of mem\n");
- exit(-1);
- }
- }
- }
- } 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, "AmigaUUCP Plus: uuwho" VERDATE "\n");
- fprintf(stderr, "Written by Ingo Feulner\n\n");
- 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);
- }
- #ifndef AMIGA
- if (gethostname(hostname, NLEN+1) < 0) {
- hostname = NULL; /* unknown hostname */
- }
- #else
- {
- char *FindConfig();
-
- hostname = FindConfig("NodeName");
- }
- #endif
- 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 */
-