jay@unm-la.UUCP (01/05/85)
getmaps: get the lastest maps from mod.map.all cc -O [-DLOG] -o getmaps getmaps.c getmaps [-l logfile] [-g map_dir] [-s seq_file] [-a archive_dir] This corrects a bug in Lee's earlier posting whereby the seq file sometimes winds up with the wrong value, confusing next month's extraction. It borrows a few ideas from a similar fix sent to Lee by ncr-tp!greg (Greg Noel). The contextual diffs wound up about the same size as the source, so here's the whole thing again. > Gotta have libndir though. [ie, 4.2bsd with scandir()] > > (Don't forget to strip the .signature at the end) #ifndef lint char *Rcsid = "$Header: getmaps.c,v 1.4 85/01/04 13:56:20 jay Exp $"; #endif /* * getmaps * * Get the net maps from USENET as published by Karen and Mark Horton, in * "shar" format. Because of paranoia the sh is not used but instead a DFA * recognizing the appropriate commands. * * lee Ward 10/13/84 */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> char *mapgrp = "/usr/spool/news/mod/map/news"; char *mapdir = "/usr/lib/news/maps"; char *seqfil = "/usr/lib/news/maps/.seq"; #ifdef LOG char *logfil = "/usr/lib/news/maps/.log"; #endif LOG #ifdef LOG char *usestr = "[-l logfil] [-g group] [-s seqfile] [-a archiv-dir]"; FILE *logsd = NULL; int seqn, curn; #else LOG char *usestr = "[-g group] [-s seqfile] [-a archiv-dir]"; #endif LOG void domaps(), myabort(), mkmaps(), getwrd(); #ifdef LOG void log(), logtime(); #endif LOG main(argc, argv) int argc; char *argv[]; { int x; FILE *seqsd; for (x = 1; x < argc; x++) { if (*argv[x]++ != '-') { fprintf(stderr, "Bad usage\n"); fprintf(stderr, "Usage: %s %s\n", argv[0], usestr); exit(-1); } switch (*argv[x]) { #ifdef LOG case 'l': logfil = argv[++x]; break; #endif LOG case 'g': mapgrp = argv[++x]; break; case 's': seqfil = argv[++x]; break; case 'a': mapdir = argv[++x]; break; default: fprintf(stderr, "Bad switch\n"); fprintf(stderr, "Usage: %s %s\n", argv[0], usestr); exit(-1); } } #ifdef LOG logsd = fopen(logfil, "a"); logtime("Start"); #endif LOG if (chdir(mapdir) != 0) myabort("Could not change directory to %s", mapdir); if ((seqsd = fopen(seqfil, "r")) != NULL) { if (fscanf(seqsd, "%d", &seqn) != 1) myabort("Bad seq file"); (void )fclose(seqsd); } if ((seqsd = fopen(seqfil, "a")) == NULL) myabort("Could not open seq file for writing"); (void )fseek(seqsd, 0L, 0); domaps(mapgrp, seqn, seqsd); (void )fclose(seqsd); #ifdef LOG logtime("End"); #endif LOG } void domaps(grp, seqn, seqsd) char *grp; FILE *seqsd; { char nbuf[BUFSIZ], *nptr; struct direct **filst; int nfils, x; struct stat stbuf; extern int scandir(); int numsort(), select(); extern char *strcpy(), *strncat(); if ((nfils = scandir(grp, &filst, select, numsort)) == -1) myabort("scandir failed"); (void )strncpy(nbuf, grp, BUFSIZ-2); nptr = nbuf + strlen(nbuf); *nptr++ = '/'; *nptr = NULL; nbuf[BUFSIZ-1] = NULL; #ifdef LOG log("Getting maps from %s", nbuf); #endif LOG for (x = 0; x < nfils; x++) { (void )strncpy(nptr, filst[x]->d_name, BUFSIZ - (nptr - nbuf) - 1); if (stat(nbuf, &stbuf) != 0) { #ifdef LOG log("Could not stat %s", nbuf); #endif LOG continue; } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) continue; curn = atoi(filst[x]->d_name); mkmaps(nbuf); (void )fseek(seqsd, 0L, 0); (void )fprintf(seqsd, "%d\n", curn); (void )fflush(seqsd); } } void mkmaps(file) char *file; { #define SEARCH 1 #define INAMAP 2 #define SKIPPING 3 char buf[BUFSIZ], tofil[BUFSIZ], delim[BUFSIZ]; int state = SEARCH, sizdel = 0; FILE *isd, *osd; extern FILE *fopen(); if ((isd = fopen(file, "r")) == NULL) { #ifdef LOG log("Could not open %s. Skipping...", file); #endif LOG return; } #ifdef LOG log("Unarchive %d", curn); #endif LOG while (fgets(buf, sizeof(buf) - 1, isd) != NULL) { buf[sizeof(buf)] = NULL; switch (state) { case SEARCH: if (gotcat(buf, tofil, BUFSIZ, delim, BUFSIZ)) { state = INAMAP; sizdel = strlen(delim); if ((osd = fopen(tofil, "w")) == NULL) { #ifdef LOG log("Could not open %s", tofil); #endif LOG state = SKIPPING; } } break; case SKIPPING: case INAMAP: if (strncmp(buf, delim, sizdel) == 0) { state = SEARCH; if (osd != NULL) (void )fclose(osd); } else if (osd != NULL) fputs(buf, osd); break; } } #ifdef LOG if (state != SEARCH) log("Read/sync error on %s", file); #endif LOG (void )fclose(isd); #undef SEARCH #undef INAMAP #undef SKIPPING } /* * gotcat * * Use a DFA to recognize * cat << DELIM > OUT * or * cat > OUT << DELIM * */ /* Transition table for the DFA */ int ttbl[9][4] = { 1,-1,-1,-1, -1,6,2,-1, -1,-1,-1,3, -1,4,-1,-1, -1,-1,-1,5, -1,-1,-1,-1, -1,-1,-1,7, -1,-1,8,-1, -1,-1,-1,5, }; gotcat(buf, tofil, tofilln, delim, delimln) char *buf, *tofil, *delim; int tofilln, delimln; { int state; char *ptr; state = 0; /* Start state */ while (state != -1 && state != 5) { /* Eat up white */ while (*buf != '\n' && (*buf == ' ' || *buf == '\t')) buf++; if (*buf == '>') { buf++; state = ttbl[state][1]; continue; } if (*buf == '<' && *(buf + 1) == '<') { buf += 2; state = ttbl[state][2]; continue; } if (*buf == 'c' && *(buf + 1) == 'a' && *(buf + 2) == 't') { buf += 3; state = ttbl[state][0]; continue; } ptr = buf; while (*buf != '\n' && *buf != ' ' && *buf != '\t') buf++; if (state == 2 || state == 8) getwrd(ptr, buf, delim, delimln); else if (state == 6 || state == 4) getwrd(ptr, buf, tofil, tofilln); state = ttbl[state][3]; } if (state == 5) return(1); return(0); } void getwrd(fc, lc, buf, maxlen) char *fc, *lc, *buf; int maxlen; { char *ptr, *t1ptr, *t2ptr; maxlen--; maxlen = lc - fc > maxlen ? maxlen : lc - fc; ptr = buf; t1ptr = fc; while (maxlen-- != 0) *ptr++ = *t1ptr++; *ptr = NULL; /* Strip quotes */ ptr = buf; while (*ptr != NULL) { if (*ptr == '\\' && (*(ptr + 1) == '\'' || *(ptr + 1) == '"')) ptr += 2; else if (*ptr == '\'' || *ptr == '"') { t1ptr = ptr; t2ptr = ptr + 1; while ((*t1ptr++ = *t2ptr++) != NULL) ; } else ptr++; } } /*VARARGS1*/ void myabort(s, a, b, c, d, e, f, g, h, i, j, k, l) char *s; { #ifdef LOG if (logsd != NULL) { fputs("ABORT - ", logsd); fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l); (void )fputc('\n', logsd); logtime("End"); } #endif LOG exit(-1); } #ifdef LOG /*VARARGS1*/ void log(s, a, b, c, d, e, f, g, h, i, j, k, l) char *s; { if (logsd == NULL) return; fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l); (void )fputc('\n', logsd); (void )fflush(logsd); } void logtime(s) char *s; { time_t clock; extern char *ctime(); if (logsd == NULL) return; (void )time(&clock); fprintf(logsd, "%s %s", s, ctime(&clock)); (void )fflush(logsd); } #endif LOG numsort(a, b) struct direct **a, **b; { return(atoi((*a)->d_name) - atoi((*b)->d_name)); } select(d) struct direct *d; { char *cp = d->d_name; int i = 0; while (isdigit(*cp)) i = 10 * i + *(cp++) - '0'; return(*cp == NULL && i > seqn); } -- Jay Plett {{ucbvax,gatech}!unmvax, lanl}!unm-la!jay
jsq@ut-sally.UUCP (John Quarterman) (01/07/85)
# This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by ut-sally!jsq on Sat Jan 5 14:41:10 CST 1985 # Contents: README.2 uucpnews.sh patches echo x - README.2 sed 's/^@//' > "README.2" <<'@//E*O*F README.2//' This is a fix for my previous posting of uuhosts. It contains a very minor fix to the display part of uuhosts.sh, addition of some chmod commands to Makefile, and uucpnews.sh to replace uucp.from.news.sh, together with the appropriate changes to Makefile. Uucpnews is a hack to fill out the UUCP map information from mod.map.uucp with information from mod.map.news so that pathalias can produce a usable routing database. When this article is run through sh, it will first extract the files README.2 and uucpnews.sh, then it will attempt to use Larry Wall's patch program to modify uuhosts.sh and Makefile. If you don't have patch, you can make the changes by hand. @//E*O*F README.2// chmod u=rw,g=r,o=r README.2 echo x - uucpnews.sh sed 's/^@//' > "uucpnews.sh" <<'@//E*O*F uucpnews.sh//' #!/bin/sh # # This command, uucpnews, is a stopgap measure for use until # the UUCP map is complete. It extracts mail information from the # USENET news map and uses it to fill in gaps in the UUCP mail map. # # With no arguments, uucpnews changes to the news map directory, # $MAPS/$NEWSMAP, and uses all the files there as input. # (Alternatively, a list of file names may be given as arguments.) # # It looks through the news map entries for ones with mail information, # extracts those into individual files in $DIR by host name, and later # copies all those for which there are not already host entries in # the mail map directory to the mail map directory, $MAPS/UUCPMAP. # The new mail map files all have '-' appended so they can be easily # distinguished. If uucpnews is run again, such $MAPS/UUCPMAP/*- # entries will be overwritten. # # The temporary directory $DIR is removed after the command is done. # PATH=/usr/local:/usr/ucb:/bin:/usr/bin umask 0002 LIB=/usr/local/lib NEWS=$LIB/news MAPS=$NEWS/maps NEWSMAPGROUP=mod.map.news UUCPMAPGROUP=mod.map.uucp NEWSMAP=$NEWSMAPGROUP UUCPMAP=$UUCPMAPGROUP DIR=uucptmp if [ $1x = x ]; then cd $MAPS/$NEWSMAP args=* else args=$* fi mkdir $DIR awk ' BEGIN { sbetween = 0; sinside = 1; state = sbetween; Date = "'"`date`"'"; split (Date, date, " "); Mark = "uucpnews " date[3] " " date[2] " " date[6]; dir = "'$DIR'"; } state == sbetween && $1 == "Name:" { state = sinside; last = ""; Name = ""; System = ""; Organization = ""; Contact = ""; Telephone = ""; Postal = ""; Address = ""; News = ""; Mail = ""; Latlong = ""; Remarks = ""; Written = ""; Comments = ""; } state != sinside { next; } # { print $0; } $1 == "Name:" { Name = $2; next; } $1 == "Organization:" { Organization = $2; for (x = 3; x <= NF; x++) Organization = Organization " " $x; last = $1; next; } $1 == "Contact:" { Contact = $2; for (x = 3; x <= NF; x++) Contact = Contact " " $x; last = $1; next; } $1 == "Phone:" { Telephone = $2; for (x = 3; x <= NF; x++) Telephone = Telephone " " $x; last = $1; next; } $1 == "Postal-Address:" { Postal = $2; for (x = 3; x <= NF; x++) Postal = Postal " " $x; last = $1; next; } $1 == "Electronic-Address:" { Address = $2; for (x = 3; x <= NF; x++) Address = Address " " $x; last = $1; next; } $1 == "News:" { News = $2; for (x = 3; x <= NF; x++) News = News " " $x; last = $1; next; } (/^ / || /^ /) && last == "News:" { for (x = 1; x <= NF; x++) News = News " " $x; next; } $1 == "Mail:" { Mail = $2; for (x = 3; x <= NF; x++) Mail = Mail " " $x; last = $1; next; } (/^ / || /^ /) && last == "Mail:" { for (x = 1; x <= NF; x++) Mail = Mail " " $x; next; } $1 == "Comments:" { last = $1; if ($2 == "last" && $3 == "edited") { Written = $4; for (x = 5; x <= NF; x++) Written = Written " " $x; next; } Comments = $2; for (x = 3; x <= NF; x++) Comments = Comments " " $x; next; } /^$/ { state = sbetween; if (Mail == "") Mail = News; if (Mail == "") next; output = dir "/" Name; printf ("echo x - %s\n", output); printf ("cat > %s << '\''End-of-%s'\''\n", output, output); printf ("#N\t%s\n", Name); printf ("#S\t%s\n", System); printf ("#O\t%s\n", Organization); printf ("#C\t%s\n", Contact); printf ("#E\t%s\n", Address); printf ("#T\t%s\n", Telephone); printf ("#P\t%s\n", Postal); printf ("#L\t%s\n", Latlong); printf ("#R\t%s\n", Mark); # split (News, news, ""); # printf ("#R\tNews: %s", news[1]); # for (x = 2; news[x] != ""; x++) { # if ((x % 8) == 0) # printf ("\n\t"); # else # printf (", "); # printf ("%s", news[x]); # } # printf ("\n"); printf ("#W\t%s\n", Written); printf ("#\n"); split (Mail, mail, " "); printf ("%s\t%s", Name, mail[1]); for (x = 2; mail[x] != ""; x++) { if ((x % 8) == 0) printf ("\n\t"); else printf (", "); printf ("%s", mail[x]); } printf ("\n"); if (Comments != "") { printf ("#\n"); printf ("#%s\n", Comments); } printf ("\n"); printf ("End-of-%s\n", output); next; } ' $args | sh cd $DIR for f in * do there=$MAPS/$UUCPMAP/$f if [ -r ${there} ]; then echo ${there} continue fi if [ -r ${there}. ]; then echo ${there}. continue fi if [ -r ${there}% ]; then echo ${there}% continue fi # if [ -r ${there}- ]; then # echo ${there}- # continue # fi echo new ${there}- mv $f ${there}- done cd .. rm -rf $DIR @//E*O*F uucpnews.sh// chmod u=r,g=r,o=r uucpnews.sh echo x - j/z patch <<'@//E*O*F patches/' diff -c -r ./Makefile ../Makefile *** ./Makefile Sat Jan 5 14:28:49 1985 --- ../Makefile Mon Dec 17 06:31:20 1984 *************** *** 7,14 # The maps from mod.map.all are under this directory. MAPS=$(NEWS)/maps ! SOURCES=uuhosts.sh mapsh.c uucp.from.news.sh ! ALL=uuhosts mapsh uucp.from.news all: $(ALL) --- 7,14 ----- # The maps from mod.map.all are under this directory. MAPS=$(NEWS)/maps ! SOURCES=uuhosts.sh mapsh.c uucpnews.sh ! ALL=uuhosts mapsh uucpnews all: $(ALL) *************** *** 16,21 sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ uuhosts.sh > uuhosts mapsh: mapsh.c $(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c --- 16,22 ----- sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ uuhosts.sh > uuhosts + chmod +x uuhosts mapsh: mapsh.c $(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c *************** *** 20,26 mapsh: mapsh.c $(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c ! uucp.from.news: uucp.from.news.sh sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ uucp.from.news.sh > uucp.from.news --- 21,27 ----- mapsh: mapsh.c $(CC) -o mapsh -DMAPS=\"$(MAPS)\" mapsh.c ! uucpnews: uucpnews.sh sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ uucpnews.sh > uucpnews *************** *** 23,29 uucp.from.news: uucp.from.news.sh sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ ! uucp.from.news.sh > uucp.from.news install: mapsh cp uuhosts /usr/local/uuhosts --- 24,31 ----- uucpnews: uucpnews.sh sed -e \ 's%^LIB=.*$$%LIB=$(LIB)%;s%^NEWS=.*$$%NEWS=$(NEWS)%;s%^MAPS=.*$$%MAPS=$(MAPS)%'\ ! uucpnews.sh > uucpnews ! chmod +x uucpnews install: mapsh cp uuhosts /usr/local/uuhosts diff -c -r ./uuhosts.sh ../uuhosts.sh *** ./uuhosts.sh Sat Jan 5 14:28:53 1985 --- ../uuhosts.sh Tue Dec 18 09:18:13 1984 *************** *** 1,5 #!/bin/sh ! # '@(#) uuhosts.sh 1.39 84/12/15' # PATH will have to be adjusted for non-BSD systems. PATH=/usr/local:/usr/ucb:/bin:/usr/bin --- 1,5 ----- #!/bin/sh ! # '@(#) uuhosts.sh 1.40 84/12/18' # PATH will have to be adjusted for non-BSD systems. PATH=/usr/local:/usr/ucb:/bin:/usr/bin *************** *** 221,227 echo ' USENET news host information:' sed -n -e "/^Name:[ ]*${arg}/,/^$/p" \ ! `$look $lookopt$arg Index | awk '{print $2}'` done exit 0 ;; --- 221,227 ----- echo ' USENET news host information:' sed -n -e "/^Name:[ ]*${arg}/,/^$/p" \ ! `$look $lookopt$arg Index | awk '{print $2}'` /dev/null done exit 0 ;; @//E*O*F patches/ exit 0 -- John Quarterman, CS Dept., University of Texas, Austin, Texas 78712 USA jsq@ut-sally.ARPA, jsq@ut-sally.UUCP, {ihnp4,seismo,ctvax}!ut-sally!jsq
lee@unmvax.UUCP (01/08/85)
After receiving a letter from Mr. Quarterman it becomes obvious that I opened my mouth without thinking again. My reply to his posting (upon rereading it) obviously came across a bit smart-alecky. I did not intend it as such, so I apologize. So, to restate my argument, with a little more thought and explanation this time. chroot is not available to the normal user. The small piece of code I posted was intended to be used in place of his similar (in function) one so that Joe User could make use of his package. I disagree with his use of chroot because it is unnecessary. If someone chooses to use my algorithm instead of his I suggest that they get the fixed version posted by Jay Plett as mine was erroneous. -- --Lee (Ward) {ucbvax,convex,gatech,pur-ee}!unmvax!lee