This is uuwho.c in view mode; [Download] [Up]
/* @(#)pd/uuwho/uuwho.c 1.2 24 Oct 1990 05:19:37 */ /* * 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 *malloc(); 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 */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.