home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / 2.11news / part10 < prev    next >
Text File  |  1986-11-30  |  43KB  |  1,580 lines

  1. Subject:  v07i050:  2.11 News Miscellaneous Files, Part02/02
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rick (Rick Adams)
  6. Mod.sources: Volume 7, Issue 50
  7. Archive-name: 2.11news/Part10
  8.  
  9. # To extract, sh this file
  10. #
  11. #    news 2.11 miscellaneous File 2 of 2
  12. #
  13. if test ! -d misc
  14. then
  15.     mkdir misc
  16. fi
  17. echo x - misc/keepnews 1>&2
  18. sed 's/.//' >misc/keepnews <<'*-*-END-of-misc/keepnews-*-*'
  19. -From chuqui@nsc.UUCP (Chuq Von Rospach) Thu Jun  6 20:36:39 1985
  20. -Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.UUCP
  21. -Posting-Version: version B 2.10.2 9/17/84 chuqui version 1.7 9/23/84; site nsc.UUCP
  22. -Path: seismo!nsc!chuqui
  23. -From: chuqui@nsc.UUCP (Chuq Von Rospach)
  24. -Newsgroups: net.sources
  25. -Subject: YA News Archiver
  26. -Message-ID: <2806@nsc.UUCP>
  27. -Date: 7 Jun 85 00:36:39 GMT
  28. -Date-Received: 7 Jun 85 06:25:58 GMT
  29. -Distribution: net
  30. -Organization: The Blue Parrot
  31. -Lines: 566
  32. -
  33. -Here is a netnews archiver similar to the recently posted keepnews but
  34. -designed to work with much larger archives where the wonderful quadratic
  35. -search time feature of the Unix (Unix is a trademark of AT&T Bell Labs,
  36. -quadratic search times are a feature of Unix) becomes a real problem. This
  37. -archive also knows how to walk through a directory tree so you can simply
  38. -set it on /usr/spool/oldnews and let it do its work. There are lots of
  39. -other nifty things I call features (and you might, too) that make it a lot
  40. -easier to use than anything else I've seen set up to work on archives. Mine
  41. -simply outgrew any capability to do anything with about the same time I got
  42. -a request for information out of it. I found out (the hard way) that
  43. -keepnews wasn't terribly reliable working under 2.10.2, so I finally
  44. -decided to hack together my own.
  45. -
  46. -Comments, enhancements, bug fixes, etc... are welcome, but I can only work
  47. -on them on a time available basis...
  48. -
  49. -chuq
  50. -------- 
  51. -#    This is a shell archive.
  52. -#    Remove everything above and including the cut line.
  53. -#    Then run the rest of the file through sh.
  54. -#-----cut here-----cut here-----cut here-----cut here-----
  55. -#!/bin/sh
  56. -# shar:    Shell Archiver
  57. -#    Run the following text with /bin/sh to create:
  58. -#    README
  59. -#    Makefile
  60. -#    savenews.c
  61. -# This archive created: Thu Jun  6 17:28:50 1985
  62. -# By:    Chuq Von Rospach (The Blue Parrot)
  63. -cat << \SHAR_EOF > README
  64. -Savenews --
  65. -
  66. -Savenews is a short program designed to make handling of usenet archives
  67. -generated by 'expire -a' easier, and to make it possible to find stuff in
  68. -the archive once it is there. 
  69. -
  70. -It was created by me when I had to get something out of my archives and
  71. -realized that there was no way I was going to find anything in 70 megabytes
  72. -of random data. It keeps a set of logs of the Subject lines of the articles
  73. -and stores the articles themselves in a hashed subdirectory format designed
  74. -to minimize the quadratic lookup hassles of the unix directory system
  75. -(This, of course, is a feature). 
  76. -
  77. -It has been put into the public domain by national semiconductor, and
  78. -neither myself or national guarantee that this code even exists, much
  79. -less that it does anything useful. This, BTW, is a disclaimer.
  80. -
  81. -chuq von rospach
  82. -national semiconductor
  83. -nsc!chuqui
  84. -SHAR_EOF
  85. -cat << \SHAR_EOF > Makefile
  86. -#
  87. -# Makefile for savenews
  88. -#
  89. -CFLAGS = -g
  90. -
  91. -savenews: savenews.c
  92. -    ${CC} ${CFLAGS} savenews.c -o savenews
  93. -
  94. -clean:
  95. -    rm -f savenews
  96. -
  97. -lint:
  98. -    lint -hx savenews.c
  99. -SHAR_EOF
  100. -cat << \SHAR_EOF > savenews.c
  101. -/*
  102. - * savenews filename [filename ...]
  103. - *
  104. - * Savenews is a program designed to clean up and compact a
  105. - * usenet archive. It will take the filename(s) given to it as arguments
  106. - * and save them in a netnews archive (defined by SAVENEWS, default is
  107. - * /usr/spool/savenews).
  108. - *
  109. - * This program was set up to do two main things:
  110. - *
  111. - * 1) compact out the useless parts of the message, specifically the lines
  112. - *    in the header that don't serve a useful purpose in an archive. This 
  113. - *    is done by removing all but the following header lines: From, Date,
  114. - *    Newsgroups, Subject, and Message-ID, and seems to save an average of
  115. - *    500 bytes an article.
  116. - *
  117. - * 2) keep the quadratic nature of unix(TM AT&T Bell labs) directory searches
  118. - *    from making your life miserable. Storing a raw archive of
  119. - *    net.unix-wizards is a silly thing to do, for example. What I do is
  120. - *    create a one level subdirectory set to keep any one directory from
  121. - *    getting too large, but this program is currently set so that there
  122. - *    are enough directories to keep the total number of files in any one
  123. - *    directory below about 150 in the largest parts of my archive. The
  124. - *    algorithm I use is abs(atoi(Message-ID)%HASHVAL)) with HASHVAL being
  125. - *    prime. This quick and dirty hash gives you directories with the
  126. - *    numbers 0 to HASHVAL-1, and about the same number of files in each
  127. - *    given a random distribution of Message-ID numbers (not bad, in
  128. - *    reality)
  129. - *
  130. - * The program will add the name of the file and the subject line of the
  131. - * article in a logfile in subdirectory LOGS, the filename being the 
  132. - * newsgroup.
  133. - *
  134. - * As currently written, an article will be saved only to the first 
  135. - * newsgroup in the Newsgroups header line. This means that something
  136. - * posted to 'net.source,net.flame' will end up in net.sources, but that
  137. - * somethine posted to 'net.flame,net.sources' will end up in net.flame.
  138. - * I consider this a feature. Others may disagree.
  139. - *
  140. - * If an article is saved that has a duplicate message-ID of one already
  141. - * in the archive, then it will be saved by adding the character '_' and
  142. - * some small integer needed to make the filename unique. You can then
  143. - * use ls or find to look for these and see if they are duplicates (and
  144. - * remove them) or if they are simply botches by some other site (it does
  145. - * happen, unfortunately).
  146. - *
  147. - * This program will do intelligent things if given a non-news article,
  148. - * such as nothing. Don't push it, though -- I haven't tried it on
  149. - * special devices, symbolic links, and other wierdies and it is likely
  150. - * to throw up on some of them since I didn`t feel like protecting someone
  151. - * from trying to archive /dev (if tar can consider this a feature, so can
  152. - * I...)
  153. - *
  154. - * This program uses the 4.2 Directory routines (libndir). If you don't
  155. - * run 4.2, get ahold of a copy of the compatibility library for your
  156. - * system and use it, or hack up do_dir and is_dir to get around it
  157. - * if you believe in messing around with primitive hacks (I LIKE libndir)
  158. - *
  159. - * General usage: every so often run the program with 
  160. - * 'savenews /usr/spool/oldnews'. Look through /usr/spool/savenews
  161. - * for duplicated articles and remove them, and then copy all of the
  162. - * stuff to tape. Remove everything except the LOGS directory, so that
  163. - * people can use grep to look for things in the archive. It should be
  164. - * easy to get things back off of tape and make the archive useful this
  165. - * way. Thinking about it, if you can't use the archive, you might as well
  166. - * not have it, which is why this program got written (I needed something
  167. - * out of my archive, and it took me a week to find it).
  168. - *
  169. - * This program is designed to run under 2.10.2, but should work under any
  170. - * B news system. Anyone else is on their own. This is in
  171. - * the public domain by the kindness of my employer, national
  172. - * semiconductor, but neither I nor national make any guarantee that it
  173. - * will work, that we will support this program, or even admit that it
  174. - * exists. This is called a disclaimer, and means that if you use this 
  175. - * program, you are on your own. It DOES, however, pass lint cleanly, which
  176. - * is more than I can say for most stuff posted to the net. Feel free to 
  177. - * fix, break, enhance, change, or do anything to this program except
  178. - * claim it to be your own (unless, of course, you break it...). Passing
  179. - * enhancements back to me would be nice, too.
  180. - *
  181. - *    chuq von rospach, national semiconductor (nsc!chuqui)
  182. - *
  183. - */
  184. -
  185. -#include <stdio.h>
  186. -#include <sys/types.h>
  187. -#include <sys/stat.h>
  188. -#include <sys/dir.h>
  189. -#include <ctype.h>
  190. -
  191. -#define FALSE        0
  192. -#define TRUE        1
  193. -#define HASHVAL        37    /* hash value for sub-dirs. Prime number! */
  194. -#define NUMDIRS        1024    /* number of dirs that can be pushed */
  195. -#define SAVENEWS    "/usr/spool/savenews" /* home of the archive */
  196. -#define LOGFILE        "LOGS"  /* subdir in SAVENEWS to save logs in */
  197. -#define JOBLOG        "joblog" /* where log of this job is put */
  198. -#define DIRMODE        0755    /* mkdir with this mode */
  199. -#define COPYBUF        8192    /* block read/write buffer size */
  200. -
  201. -char *Progname;            /* name of the program for Eprintf */
  202. -char line[BUFSIZ];        /* general purpose line buffer */
  203. -
  204. -#define NUM_HEADERS    5    /* number of headers we are saving */
  205. -#define GROUP_HEADER    1    /* where Newsgroup will be found */
  206. -#define SUBJECT_HEADER    2    /* where Subject will be found */
  207. -#define MESSAGE_HEADER    3    /* where Message-ID will be found */
  208. -char header_data[NUM_HEADERS][BUFSIZ];
  209. -char *headers[NUM_HEADERS] =
  210. -{
  211. -    "From:",
  212. -    "Newsgroups:",
  213. -    "Subject:",
  214. -    "Message-ID:",
  215. -    "Date:"
  216. -};
  217. -
  218. -long num_saved = 0;        /* number of articles saved */
  219. -FILE *logfp;            /* file pointer to joblog file */
  220. -
  221. -char *rindex(), *strcat(), *pop_dir(), *strcpy(), *strsave(), *index();
  222. -
  223. -main(argc,argv)
  224. -int argc;
  225. -char *argv[];
  226. -{
  227. -    register int i;
  228. -    char joblogfile[BUFSIZ];
  229. -    char *dirname;
  230. -    
  231. -    /*
  232. -     * This removes and preceeding pathname so that
  233. -     * anything printed out by Eprintf has just the 
  234. -     * program name and not where it came from
  235. -     */
  236. -    if ((Progname = rindex(argv[0],'/')) == NULL)  
  237. -    Progname = argv[0];               
  238. -    else
  239. -    Progname++;                  
  240. -
  241. -    if (argc == 1) {
  242. -    fprintf(stderr,"Usage: %s file [file ...]\n",Progname);
  243. -    exit(1);
  244. -    }
  245. -
  246. -    sprintf(joblogfile,"%s/%s",SAVENEWS,JOBLOG);
  247. -    if ((logfp = fopen(joblogfile,"w")) == NULL)
  248. -    fprintf(stderr,"Can't open %s, logging suspended\n",joblogfile);
  249. -
  250. -    for (i = 1 ; i < argc; i++) {    /* process each parameter */
  251. -    register int rc;
  252. -    if ((rc = is_dir(argv[i])) == -1)
  253. -        continue;
  254. -    else if (rc == TRUE)
  255. -        do_dir(argv[i]);
  256. -    else
  257. -        save_file(argv[i]);
  258. -    }
  259. -    while((dirname = pop_dir()) != NULL) {
  260. -    do_dir(dirname);    /* process whatever is left on dirstack */
  261. -    }
  262. -    printf("Total articles saved was %d\n",num_saved);
  263. -    exit(0);
  264. -}
  265. -
  266. -do_dir(dname) /* process a directory, push other directories on stack */
  267. -          /* to be handled recursively later */
  268. -char *dname;
  269. -{
  270. -    DIR *dirp;
  271. -    struct direct *dp;
  272. -    char fullname[BUFSIZ];
  273. -
  274. -    if ((dirp = opendir(dname)) == NULL) {
  275. -    Eprintf("can't opendir %s\n",dname);
  276. -    return;
  277. -    }
  278. -
  279. -    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  280. -    register int rc;
  281. -
  282. -    if(dp->d_namlen == 2 && !strcmp(dp->d_name,"..") 
  283. -    || (dp->d_namlen == 1 && !strcmp(dp->d_name,".")))
  284. -        continue; /* skip . and .. */
  285. -
  286. -    sprintf(fullname,"%s/%s",dname,dp->d_name);
  287. -    if((rc = is_dir(fullname)) == -1)
  288. -        continue;
  289. -    else if (rc == TRUE)
  290. -        push_dir(fullname);
  291. -    else
  292. -        save_file(fullname);
  293. -    }
  294. -    closedir(dirp);
  295. -}
  296. -
  297. -is_dir(name)
  298. -char *name;
  299. -{
  300. -    struct stat sbuf;
  301. -
  302. -    if (stat(name,&sbuf) == -1) {
  303. -    Eprintf("can't stat '%s'\n",name);
  304. -    return(-1);
  305. -    }
  306. -    return((sbuf.st_mode & S_IFDIR) ? TRUE : FALSE);
  307. -}
  308. -
  309. -/* VARARGS */
  310. -Eprintf(s1,s2,s3,s4,s5,s6,s7,s8,s9)
  311. -char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8,*s9;
  312. -{
  313. -    if (logfp == NULL)
  314. -    return;
  315. -    fprintf(logfp,"%s: ",Progname);
  316. -    fprintf(logfp,s1,s2,s3,s4,s5,s6,s7,s8,s9);
  317. -    fflush(logfp);
  318. -}
  319. -
  320. -/*
  321. - * quick and dirty stack routines.
  322. - *
  323. - * push_dir(name) char *name; 
  324. - *    stores the given string in the stack
  325. - * char *pop_dir()
  326. - *    returns a string from the stack, or NULL if none.
  327. - */
  328. -
  329. -static char *dirstack[NUMDIRS];
  330. -static int lastdir = 0;
  331. -static char pop_name[BUFSIZ];
  332. -
  333. -push_dir(name)
  334. -char *name;
  335. -{
  336. -    if (lastdir >= NUMDIRS) {
  337. -    Eprintf("push_dir overflow!\n");
  338. -    return;
  339. -    }
  340. -    dirstack[lastdir] = strsave(name);
  341. -    if (dirstack[lastdir] == NULL)
  342. -    {
  343. -    Eprintf("malloc failed!\n");
  344. -    return;
  345. -    }
  346. -    lastdir++;
  347. -}
  348. -
  349. -char *pop_dir()
  350. -{
  351. -    if(lastdir == 0)
  352. -    return(NULL);
  353. -    lastdir--;
  354. -    strcpy(pop_name,dirstack[lastdir]);
  355. -    dirstack[lastdir] = NULL;
  356. -    free(dirstack[lastdir]);
  357. -    return(pop_name);
  358. -}
  359. -
  360. -char *strsave(s)
  361. -char *s;
  362. -{
  363. -    char *p, *malloc();
  364. -
  365. -    if ((p = malloc((unsigned)strlen(s)+1)) != NULL)
  366. -    strcpy(p,s);
  367. -    return(p);
  368. -}
  369. -
  370. -save_file(name)        /* save the article in the archive */
  371. -char *name;
  372. -{
  373. -    FILE *fp, *ofp, *fopen(), *output_file();
  374. -    register int i, nc;
  375. -    char diskbuf[COPYBUF];
  376. -
  377. -    Eprintf("saving '%s'\n",name);
  378. -    if ((fp = fopen(name,"r")) == NULL) {
  379. -    Eprintf("can't open\n");
  380. -    return;
  381. -    }
  382. -
  383. -    if ((fgets(line,BUFSIZ,fp) == NULL)) {
  384. -    Eprintf("0 length file\n");
  385. -    fclose(fp);
  386. -    return;
  387. -    }
  388. -    if (!start_header(line)) {
  389. -    Eprintf("not a news article\n");
  390. -    fclose(fp);
  391. -    return;
  392. -    }
  393. -    read_header(fp);
  394. -    if ((ofp = output_file()) == NULL) {
  395. -    Eprintf("Can't save\n");
  396. -    fclose(fp);
  397. -    return;
  398. -    }
  399. -
  400. -    for (i = 0; i < NUM_HEADERS; i++)
  401. -    fprintf(ofp,"%s\n",header_data[i]);
  402. -    fputc('\n',ofp);
  403. -
  404. -    while ((nc = fread(diskbuf,sizeof(char),COPYBUF,fp)) != 0)
  405. -    fwrite(diskbuf,sizeof(char),nc,ofp);    /* copy body of article */
  406. -    fclose(ofp);
  407. -    fclose(fp);
  408. -    num_saved++;
  409. -    return;
  410. -}
  411. -
  412. -start_header(s) /* see if this is the start of a news article */
  413. -char *s;
  414. -{
  415. -    /*
  416. -     * If this is coming from B news, the first line will 'always' be
  417. -     * Relay-Version (at least, on my system). Your mileage my vary.
  418. -     */
  419. -    if (!strncmp(s,"Relay-Version:",14))
  420. -    return(TRUE);
  421. -    /*
  422. -     * If you are copying a section of archive already archived by 
  423. -     * sendnews, then the first line will be From (unless you changed
  424. -     * the headers data structure, then its up to you...)
  425. -     */
  426. -    if (!strncmp(s,"From:",5))
  427. -    return(TRUE);
  428. -    return(FALSE);
  429. -}
  430. -
  431. -/* 
  432. - * By the time we get here, the first line will already be read in and
  433. - * checked by start_header(). If we are re-copying a savenews archive
  434. - * (which happens when you decide to play with HASHVAL, trust me) then
  435. - * we need to save the From line, so we can't just throw it away. Hence
  436. - * the funky looking do-while setup instead of something a bit more
  437. - * straightforward
  438. - */
  439. -read_header(fp)
  440. -FILE *fp;
  441. -{
  442. -    register int i;
  443. -
  444. -    for (i = 0; i < NUM_HEADERS; i++)
  445. -    header_data[i][0] = '\0';        /* remove last articles data */
  446. -
  447. -    do {
  448. -    char *cp;
  449. -
  450. -    if (line[0] == '\n')    /* always be a blank line after the header */
  451. -        return;
  452. -
  453. -    for (i = 0 ; i < NUM_HEADERS; i++) {
  454. -        if (!strncmp(headers[i],line,strlen(headers[i]))) {
  455. -        strcpy(header_data[i],line);
  456. -        if (cp = index(header_data[i],'\n'))
  457. -            *cp = '\0';                /* eat newlines */
  458. -        }
  459. -    }
  460. -    } while (fgets(line,BUFSIZ,fp) != NULL);
  461. -}
  462. -
  463. -FILE *output_file() /* generate the name in the archive */
  464. -{
  465. -    int hashval, copy = 0;
  466. -    FILE *fp, *fopen();
  467. -    char *p, newsgroup[BUFSIZ], message_id[BUFSIZ];
  468. -    char shortname[BUFSIZ], filename[BUFSIZ], filename2[BUFSIZ];
  469. -
  470. -    /* get the first newsgroup */
  471. -    p = index(header_data[GROUP_HEADER],':'); /* move past Newsgroups */
  472. -    if (!p) {
  473. -    Eprintf("Invalid newsgroups\n");
  474. -    return(NULL);
  475. -    }
  476. -    p++;    /* skip the colon */
  477. -    while (isspace(*p))
  478. -    p++;    /* skip whitespace */
  479. -    strcpy(newsgroup,p);
  480. -    if (p = index(newsgroup,','))
  481. -    *p= '\0';    /* newsgroup now only has one name in it */
  482. -    
  483. -    /* get the message-id */
  484. -    p = index(header_data[MESSAGE_HEADER],':');
  485. -    if (!p) {
  486. -    Eprintf("Invalid message-id\n");
  487. -    return(NULL);
  488. -    }
  489. -    p++;    /* skip the colon */
  490. -    while (isspace(*p))
  491. -    p++;    /* skip whitespace */
  492. -    if (*p == '<' || *p == '(')
  493. -    p++;
  494. -    if (*p == '-') /* make negative article id numbers positive (hack) */
  495. -    p++;
  496. -    strcpy(message_id,p);
  497. -    if (p = index(message_id,'.')) /* trim off the .UUCP if any */
  498. -    *p = '\0';
  499. -    else if (p = index(message_id,'>'))  /* or get the closing bracket */
  500. -    *p = '\0';
  501. -    else if (p = index(message_id,')')) /* or get the closing paren */
  502. -    *p = '\0';
  503. -    if (p = index(message_id,'@'))    /* change nnn@site */
  504. -    *p = '.';            /* to nnn.site */
  505. -
  506. -    /* generate the hash value for the subdirectory */
  507. -    hashval = atoi(message_id) % HASHVAL;
  508. -
  509. -    /* setup the filename to save to */
  510. -    sprintf(shortname,"%s/%d/%s",newsgroup,hashval,message_id);
  511. -    sprintf(filename,"%s/%s",SAVENEWS,shortname);
  512. -    while (exists(filename)) {    /* make it unique if neccessary */
  513. -
  514. -    sprintf(shortname,"%s/%d/%s_%d",newsgroup,hashval,message_id,++copy);
  515. -    sprintf(filename,"%s/%s",SAVENEWS,shortname);
  516. -    }
  517. -    
  518. -    strcpy(filename2,filename);            /* must chop off the filename */
  519. -    if (p = rindex(filename2,'/'))        /* since we don't want to */
  520. -    *p = '\0';                /* to makeparents */
  521. -    makeparents(filename2);
  522. -
  523. -    if ((fp = fopen(filename,"w")) == NULL) {
  524. -    Eprintf("Can't open %s for output\n",filename);
  525. -    return(NULL);
  526. -    }
  527. -    log(newsgroup,shortname);
  528. -    return(fp);
  529. -}
  530. -
  531. -exists(name)
  532. -char *name;
  533. -{
  534. -    struct stat sbuf;
  535. -
  536. -    if (stat(name,&sbuf) == -1) {
  537. -    return(FALSE);
  538. -    }
  539. -    return(TRUE);
  540. -}
  541. -
  542. -makeparents(name) /* recursively make parent directories */
  543. -char *name;
  544. -{
  545. -    char *p, buf[BUFSIZ];
  546. -
  547. -    if (exists(name))
  548. -    return;
  549. -    strcpy(buf,name);
  550. -    if (!(p = rindex(buf,'/'))) {
  551. -    Eprintf("makeparents failed!\n");
  552. -    return;
  553. -    }
  554. -    *p = '\0';
  555. -    makeparents(buf);
  556. -    mkdir(name,DIRMODE);
  557. -}
  558. -
  559. -log(group,name) /* write to the logfile */
  560. -char *group, *name;
  561. -{
  562. -    char *subject, logfile[BUFSIZ];
  563. -    FILE *ofp, *fopen();
  564. -
  565. -    /* get the subject */
  566. -    subject = index(header_data[SUBJECT_HEADER],':');
  567. -    if (!subject) {
  568. -    Eprintf("Invalid subject, no log entry\n");
  569. -    return;
  570. -    }
  571. -    subject++;    /* skip the colon */
  572. -    while (isspace(*subject))
  573. -    subject++;    /* skip whitespace */
  574. -
  575. -    /* generate the place where it goes */
  576. -    sprintf(logfile,"%s/%s",SAVENEWS,LOGFILE);
  577. -    makeparents(logfile);
  578. -    strcat(logfile,"/");
  579. -    strcat(logfile,group);
  580. -
  581. -    if ((ofp = fopen(logfile,"a")) == NULL)
  582. -    {
  583. -    Eprintf("open failed on %s\n",logfile);
  584. -    return;
  585. -    }
  586. -    fprintf(ofp,"%s\t%s\n", name, subject);
  587. -    fclose(ofp);
  588. -}
  589. -
  590. -SHAR_EOF
  591. -#    End of shell archive
  592. -exit 0
  593. --- 
  594. -:From the misfiring synapses of:                  Chuq Von Rospach
  595. -{cbosgd,fortune,hplabs,ihnp4,seismo}!nsc!chuqui   nsc!chuqui@decwrl.ARPA
  596. -
  597. -The offices were very nice, and the clients were only raping the land, and
  598. -then, of course, there was the money...
  599. -
  600. -
  601. *-*-END-of-misc/keepnews-*-*
  602. echo x - misc/report.awk 1>&2
  603. sed 's/.//' >misc/report.awk <<'*-*-END-of-misc/report.awk-*-*'
  604. -From cbosgd!ucbvax!usenet Mon Oct 13 05:39:17 1986
  605. -Received: by beno.CSS.GOV (5.54/5.17)
  606. -    id AA01253; Mon, 13 Oct 86 05:39:12 EDT
  607. -Received: from cbosgd.UUCP by seismo.CSS.GOV (5.54/1.14)
  608. -    id AA03513; Mon, 13 Oct 86 05:39:11 EDT
  609. -Received: by cbosgd.ATT.COM (4.12/UUCP-Project/rel-1.0/06-28-86)
  610. -    id AA08778; Mon, 13 Oct 86 03:44:14 edt
  611. -Received: by ucbvax.Berkeley.EDU (5.53/1.17)
  612. -    id AA15536; Sun, 12 Oct 86 23:51:25 PDT
  613. -Date: Sun, 12 Oct 86 23:51:25 PDT
  614. -From: ucbvax!usenet (USENET News Administration)
  615. -Message-Id: <8610130651.AA15536@ucbvax.Berkeley.EDU>
  616. -To: cbosgd!backbone
  617. -Subject: a handy awk script for netnews log reports
  618. -Status: R
  619. -
  620. -Since Mark didn't have a copy of this, I will assume that most of the
  621. -rest of you don't either, and send it along. The comments should be
  622. -explanation enough... If not, ask me.
  623. -
  624. -    Erik E. Fair    ucbvax!fair    fair@ucbarpa.berkeley.edu
  625. --------------------------------------------------------------------------------
  626. -#  USAGE: awk -f report_awk /usr/lib/news/log
  627. -#
  628. -#  AWK script which eats netnews log files and produces a summary of USENET
  629. -#  traffic and errors over the period of time that the log was collected.
  630. -#
  631. -#  August 31, 1986
  632. -#
  633. -#  Erik E. Fair <dual!fair>
  634. -#  Original Author, May 22, 1984
  635. -#
  636. -#  Brad Eacker <onyx!brad>
  637. -#  Modified to simplify the record processing and to sort the output.
  638. -#
  639. -#  Erik E. Fair <dual!fair>
  640. -#  Modifed to provide information about control messages.
  641. -#
  642. -#  Erik E. Fair <dual!fair>
  643. -#  Bug in system name extraction fixed. It was assumed that the forth field
  644. -#  (system name) always had a dot. local is one that doesn't. Some others
  645. -#  (including 2.9 sites) don't either.
  646. -#
  647. -#  Earl Wallace <pesnta!earlw>
  648. -#  The "sent" field was changed from $5 to $6 in 2.10.2 (beta)
  649. -#  named "newstats" and called with no arguments.
  650. -#
  651. -#  Erik E. Fair <dual!fair>
  652. -#  Remove support for 2.10.1, revise for 2.10.2 to provide information
  653. -#  about junked articles, garbled articles, and bad newsgroups
  654. -#
  655. -#  Erik E. Fair <ucbvax!fair>
  656. -#  Minor bug fix to bad newsgroup reporting, also now counting ``old''
  657. -#  articles as junked, with counter for number that are `old'.
  658. -#
  659. -#  Erik E. Fair <ucbvax!fair>
  660. -#  Fix up the domain & local hosts support
  661. -#
  662. -#  Erik E. Fair <ucbvax!fair>
  663. -#  Fix up the counting of gatewayed material, add counting of "linecount"
  664. -#  problems. Additional cleanup to make things faster.
  665. -#
  666. -BEGIN{
  667. -#
  668. -#    this is the prefix that your site uses in hostnames to identify your
  669. -#    hosts (e.g. ucbarpa, ucbvax, su-score, mit-mc, mit-ai)
  670. -#    You will probably want to change (or add to) the following line
  671. -#
  672. -    lprefix = "ucb";
  673. -    lplen = length(lprefix);
  674. -#
  675. -#    If you do bi-directional USENET gatewaying (e.g. mailing list
  676. -#    to newsgroup where the material flows both ways freely), this
  677. -#    should be the name in the sys file that you use to mail stuff
  678. -#    to the mailing lists.
  679. -#
  680. -    pseudo = "internet";
  681. -    rptname = "(GATEWAY)";
  682. -#
  683. -#    Top level domain names and what network they represent
  684. -#    (for use in counting stuff that is gatewayed)
  685. -#
  686. -    domains["ARPA"] = rptname;
  687. -    domains["arpa"] = rptname;
  688. -    domains["EDU"] = rptname;
  689. -    domains["edu"] = rptname;
  690. -    domains["GOV"] = rptname;
  691. -    domains["gov"] = rptname;
  692. -    domains["COM"] = rptname;
  693. -    domains["com"] = rptname;
  694. -    domains["MIL"] = rptname;
  695. -    domains["mil"] = rptname;
  696. -    domains["ORG"] = rptname;
  697. -    domains["org"] = rptname;
  698. -    domains["NET"] = rptname;
  699. -    domains["net"] = rptname;
  700. -    domains["UK"] = rptname;
  701. -    domains["uk"] = rptname;
  702. -    domains["DEC"] = rptname;
  703. -    domains["dec"] = rptname;
  704. -    domains["CSNET"] = rptname;
  705. -    domains["csnet"] = rptname;
  706. -    domains["BITNET"] = rptname;
  707. -    domains["bitnet"] = rptname;
  708. -    domains["MAILNET"] = rptname;
  709. -    domains["mailnet"] = rptname;
  710. -    domains["UUCP"] = rptname;
  711. -    domains["uucp"] = rptname;
  712. -    domains["OZ"] = rptname;
  713. -    domains["oz"] = rptname;
  714. -    domains["AU"] = rptname;
  715. -    domains["au"] = rptname;
  716. -#
  717. -#    tilde chosen because it is ASCII 126 (don't change this)
  718. -#
  719. -    invalid = "~~~~~~";
  720. -#
  721. -    accept[invalid]   = 0;
  722. -    reject[invalid]   = 0;
  723. -    xmited[invalid]   = 0;
  724. -    control[invalid]  = 0;
  725. -    junked[invalid]   = 0;
  726. -    neighbor[invalid] = 0;
  727. -    badgrp  = 0;
  728. -    garbled = 0;
  729. -    lcount  = 0;
  730. -    canfail = 0;
  731. -    candup  = 0;
  732. -    insfail = 0;
  733. -    old     = 0;
  734. -}
  735. -#
  736. -#    Skip some things that we won't bother with
  737. -#
  738. -/^$/                { next }
  739. -$5 == "from"            { next }
  740. -$5 == "make"            { next }
  741. -$5 == "Cancelling"        { next }
  742. -#
  743. -#    Or that we just count
  744. -#
  745. -$5 == "Inbound"            { garbled++; next }
  746. -$6 == "cancel"            { canfail++; next }
  747. -$6 == "Cancelled"        { candup++; next }
  748. -$6 == "install"            { insfail++; next }
  749. -#
  750. -#    Articles sent to remote systems (this is what 2.10.2 (beta) says)
  751. -#
  752. -$6 == "sent"    {
  753. -    for(j = 8; j <= NF; j++) {
  754. -        comma = index( $(j), ",");
  755. -        if (comma != 0) $(j) = substr( $(j), 1, (comma - 1));
  756. -        if ($(j) == pseudo) $(j) = rptname;
  757. -        else neighbor[$(j)] = 1;
  758. -        xmited[$(j)]++;
  759. -    }
  760. -    next;
  761. -}
  762. -#
  763. -#    Articles sent to remote systems (this is what 2.11 says)
  764. -#
  765. -$5 == "sent"    {
  766. -    for(j = 7; j <= NF; j++) {
  767. -        comma = index( $(j), ",");
  768. -        if (comma != 0) $(j) = substr( $(j), 1, (comma - 1));
  769. -        if ($(j) == pseudo) $(j) = rptname;
  770. -        else neighbor[$(j)] = 1;
  771. -        xmited[$(j)]++;
  772. -    }
  773. -    next;
  774. -}
  775. -#
  776. -#    Get the name of the system that did this,
  777. -#    taking into account that not everyone believes in domains.
  778. -#
  779. -{
  780. -#    if we get a route addr (we shouldn't, but...), take the last one
  781. -#
  782. -    nhosts = split($4, hosts, "@");
  783. -    hostname = hosts[nhosts];
  784. -#
  785. -#    get the root domain name, and the hostname
  786. -#
  787. -    ndoms = split(hostname, doms, ".");
  788. -    domain = doms[ndoms];
  789. -    sys = doms[1];
  790. -#
  791. -#    check for local system, and if not that, then internet sites.
  792. -#    special case the network name replacement of specific host names,
  793. -#    such that the network name is there only on a `local' posting
  794. -#    (which is really gatewaying in disguise)
  795. -#
  796. -    if ($5 == "posted") {
  797. -        prefix = substr(sys, 1, lplen);
  798. -        if (prefix == lprefix) {
  799. -            sys = "local";
  800. -        } else {
  801. -            dom = domains[domain];
  802. -            if (dom) sys = dom;
  803. -        }
  804. -    }
  805. -}
  806. -#  
  807. -#    Duplicates & receiveds/posted & control messages
  808. -# 
  809. -$5 == "posted" || $5 == "received" {
  810. -    accept[sys]++;
  811. -    if ($5 == "received") neighbor[sys] = 1;
  812. -    nng = split($8, ngl, ",");
  813. -    for(i = 1; i <= nng; i++) {
  814. -        dot = index(ngl[i], ".");
  815. -        if (dot) ng = substr(ngl[i], 1, (dot - 1));
  816. -        else ng = ngl[i];
  817. -        if (ng) newsgcnt[ng]++;
  818. -    }
  819. -    next;
  820. -}
  821. -$5 == "Duplicate"    { reject[hostname]++; next }
  822. -$6 == "valid"        { junked[sys]++; next }
  823. -$6 == "too"        { junked[sys]++; old++; next }
  824. -$5 == "Unknown"        {
  825. -    x = length($7) - 2;
  826. -    ng = substr($7, 2, x);
  827. -    badng[ng]++;
  828. -    badgrp++;
  829. -    next;
  830. -}
  831. -#
  832. -#    articles who actual line count differs from the Line: header count
  833. -#
  834. -$5 == "linecount"    {
  835. -    expect = $7;
  836. -# awk does very strange things with non-numeric characters in numbers
  837. -    comma = index(expect, ",");
  838. -    if (comma != 0) expect = substr(expect, 1, (comma - 1));
  839. -    got = $9;
  840. -    diff = got - expect;
  841. -    lcount++;
  842. -    alc_host[sys] = 1;
  843. -    neighbor[sys] = 1;
  844. -    if (diff < 0) {
  845. -        diff = 0 - diff;
  846. -        a_nshort[sys]++;
  847. -        a_short[sys] += diff;
  848. -        if (a_smax[sys] < diff) a_smax[sys] = diff;
  849. -    } else {
  850. -        a_nlong[sys]++;
  851. -        a_long[sys] += diff;
  852. -        if (a_lmax[sys] < diff) a_lmax[sys] = diff;
  853. -    }
  854. -    next;
  855. -}
  856. -#
  857. -#    articles who actual line count is Zero
  858. -#
  859. -$7 == "linecount"    {
  860. -    lcount++;
  861. -    a_zero[sys]++;
  862. -    reject[sys]++;
  863. -    next;
  864. -}
  865. -#
  866. -#    Control messages
  867. -#
  868. -$5 == "Ctl"    {
  869. -    ctot++;
  870. -    control[sys]++;
  871. -    ctlcnt[$(10)]++;
  872. -    next;
  873. -}
  874. -#
  875. -#    Print anything we didn't recognize, it's probably an error message.
  876. -#    For the submitted report to USENET, do sed -e '1,/^$/d' file | inews
  877. -#    so that this cruft doesn't get out the door.
  878. -#
  879. -{
  880. -    print;
  881. -}
  882. -#
  883. -#    Summarize and print the report
  884. -#
  885. -END{
  886. -#    special processing for Duplicates, because we can't tell if
  887. -#    they came from a netnews neighbor or from the gatewaying
  888. -#    activities until we have processed the entire log.
  889. -#
  890. -    for( hostname in reject ) {
  891. -#
  892. -#    get the root domain name, and the hostname
  893. -#
  894. -        ndoms = split(hostname, doms, ".");
  895. -        domain = doms[ndoms];
  896. -        sys = doms[1];
  897. -        if (! neighbor[sys]) {
  898. -            prefix = substr(sys, 1, lplen);
  899. -            if (prefix == lprefix) {
  900. -                sys = "local";
  901. -            } else {
  902. -                dom = domains[domain];
  903. -                if (dom) sys = dom;
  904. -            }
  905. -        }
  906. -        i = reject[hostname];
  907. -        reject[hostname] = 0;
  908. -        reject[sys] += i;
  909. -    }
  910. -
  911. -    rtot = 0;
  912. -    for( i in reject ) {
  913. -        if (reject[i] > 0) {
  914. -            list[i] = 1;
  915. -            rtot += reject[i];
  916. -        }
  917. -    }
  918. -
  919. -    atot = 0;
  920. -    for( i in accept ) {
  921. -        list[i] = 1;
  922. -        atot += accept[i];
  923. -    }
  924. -
  925. -    xtot = 0;
  926. -    for( i in xmited ) {
  927. -        list[i] = 1;
  928. -        xtot += xmited[i];
  929. -    }
  930. -
  931. -    ctot = 0;
  932. -    for( i in control ) {
  933. -        list[i] = 1;
  934. -        ctot += control[i];
  935. -    }
  936. -
  937. -    jtot = 0;
  938. -    for( i in junked ) {
  939. -        list[i] = 1;
  940. -        jtot += junked[i];
  941. -    }
  942. -#
  943. -# ctot is part of rtot, so we don't add it in to the grand total.
  944. -#
  945. -    totarticles = atot + rtot;
  946. -    if (totarticles == 0) totarticles = 1;
  947. -
  948. -    printf("\nSystem       \tAccept\tReject\tJunked\tXmit to\tControl\t%% total\t%% rejct\n");
  949. -    for( ; ; ) {
  950. -# selection sort
  951. -        i = invalid;
  952. -        for( j in list ) {
  953. -            if ( list[j] > 0 && j < i ) i = j;
  954. -        }
  955. -        if ( i == invalid ) break;
  956. -        list[i] = 0;
  957. -#
  958. -#    control & junked are counted under accept.
  959. -#
  960. -        sitetot = accept[i] + reject[i];
  961. -        if (sitetot == 0) sitetot = 1;
  962. -        articles[i] = sitetot;
  963. -#
  964. -# What an 'orrible printf spec
  965. -#
  966. -        printf("%-14s\t%6d\t%6d\t%6d\t%7d\t%7d\t%6d%%\t%6d%%\n", i, accept[i], reject[i], junked[i], xmited[i], control[i], (sitetot * 100) / totarticles, (reject[i] * 100) / sitetot);
  967. -#
  968. -    }
  969. -    printf("\nTOTALS        \t%6d\t%6d\t%6d\t%7d\t%7d\t%6d%%\t%6d%%\n", atot, rtot, jtot, xtot, ctot, 100, (rtot * 100) / totarticles);
  970. -    printf("\nTotal Articles processed %d", totarticles);
  971. -    if (old)    printf(", old %d", old);
  972. -    if (garbled)    printf(", garbled %d", garbled);
  973. -    if (insfail)    printf(", uninstallable %d", insfail);
  974. -    printf("\n");
  975. -
  976. -    if (ctot) {
  977. -        printf("\nControl    Invocations\n");
  978. -        for( i in ctlcnt ) {
  979. -            if (i == "cancel") {
  980. -                printf("%-12s %6d", i, ctlcnt[i]);
  981. -                if (canfail) printf(", %d failed", canfail);
  982. -                if (candup) printf(", %d duplicate", candup);
  983. -                printf("\n");
  984. -            } else {
  985. -                printf("%-12s %6d\n", i, ctlcnt[i]);
  986. -            }
  987. -        }
  988. -    }
  989. -
  990. -    if (lcount) {
  991. -        printf("\nReceived Article Length Problems\n");
  992. -        printf("System          Zero Short  Smax  Savg  Long  Lmax  Lavg Total %% Tot\n");
  993. -        for( i in alc_host ) {
  994. -            nlong = a_nlong[i];
  995. -            nshort = a_nshort[i];
  996. -            if (nlong == 0) nlong = 1;
  997. -            if (nshort == 0) nshort = 1;
  998. -            lavg = a_long[i] / nlong;
  999. -            savg = a_short[i] / nshort;
  1000. -            sitetot = (a_zero[i] + a_nshort[i] + a_nlong[i]);
  1001. -            printf("%-14s %5d %5d %5d %5d %5d %5d %5d %5d %4d%%\n", i, a_zero[i], a_nshort[i], a_smax[i], savg, a_nlong[i], a_lmax[i], lavg, sitetot, (sitetot * 100) / articles[i]);
  1002. -        }
  1003. -    }
  1004. -
  1005. -    if (atot) {
  1006. -        printf("\nNetnews Categories Received\n");
  1007. -        l = 0;
  1008. -        for( i in newsgcnt ) {
  1009. -            if (l < length(i)) l = length(i);
  1010. -        }
  1011. -        fmt = sprintf("%%-%ds %%6d\n", l);
  1012. -        for( ; ; ) {
  1013. -# selection sort
  1014. -            max = 0;
  1015. -            for( j in newsgcnt ) {
  1016. -                if (newsgcnt[j] > max) {
  1017. -                    i = j;
  1018. -                    max = newsgcnt[j];
  1019. -                }
  1020. -            }
  1021. -            if (max == 0) break;
  1022. -            printf(fmt, i, newsgcnt[i]);
  1023. -            newsgcnt[i] = 0;
  1024. -        }
  1025. -    }
  1026. -
  1027. -    if (badgrp) {
  1028. -        printf("\nBad Newsgroups Received\n");
  1029. -        l = 0;
  1030. -        for( i in badng ) {
  1031. -            if (l < length(i)) l = length(i);
  1032. -        }
  1033. -        fmt = sprintf("%%-%ds %%5d\n", l);
  1034. -        for( ; ; ) {
  1035. -# selection sort
  1036. -            i = invalid;
  1037. -            for( j in badng ) {
  1038. -                if (badng[j] > 0 && j < i) i = j;
  1039. -            }
  1040. -            if (i == invalid) break;
  1041. -            printf(fmt, i, badng[i]);
  1042. -            badng[i] = 0;
  1043. -        }
  1044. -    }
  1045. -}
  1046. -
  1047. *-*-END-of-misc/report.awk-*-*
  1048. echo x - misc/restore.active 1>&2
  1049. sed 's/.//' >misc/restore.active <<'*-*-END-of-misc/restore.active-*-*'
  1050. -: recreate the active file from readers .newsrc files
  1051. -: and from the existing articles
  1052. -
  1053. -lib=${1-/usr/lib/news}
  1054. -tmp=/tmp/$$
  1055. -: Find the highest numbered articles from the .newsrcs
  1056. -cat `sed 's/[^:]*:[^:]*:[^:]*:[^:]*:[^:]*://
  1057. -s/:.*//' /etc/passwd | sort -u | sed 's;$;/.newsrc;' ` 2>/dev/null  | 
  1058. -sed '/:/!d
  1059. -s/:.*[,-]/ /
  1060. -s/: */ /'  >$tmp
  1061. -: in case there are groups no-one reads, look in the list of newsgroups
  1062. -sed 's/[     ].*/ 1/' $lib/newsgroups >>$tmp
  1063. -sort  +0 -1 +1nr  $tmp | sort -m +0u -1 | sed 's/$/ 00001 y/
  1064. -/^fa/s/y$/n/' >$lib/active
  1065. -: finally, scan the spool directory and fix up the active file.
  1066. -$lib/expire -u
  1067. -rm -f $tmp
  1068. *-*-END-of-misc/restore.active-*-*
  1069. echo x - misc/sendnewsmail 1>&2
  1070. sed 's/.//' >misc/sendnewsmail <<'*-*-END-of-misc/sendnewsmail-*-*'
  1071. -From cbosg!ucbvax!decvax!ittvax!swatt Thu Mar 25 07:06:53 1982
  1072. -Date: Wed Mar 24 20:29:56 1982
  1073. -From: cbosg!ucbvax!decvax!ittvax!swatt
  1074. -Subject: sendnewsmail script
  1075. -Via: cbosgd.uucp (V3.73 [1/5/82]); 25-Mar-82 07:06:53-EST (Thu)
  1076. -Mail-From: cbosg received by cbosgd at 25-Mar-82 07:06:51-EST (Thu)
  1077. -To: cbosgd!mark
  1078. -Status: R
  1079. -
  1080. -
  1081. -Mark:
  1082. -
  1083. -I find the following handy as a mail interface to news; you don't have
  1084. -to remake the aliases database everytime a new newsgroup gets formed.
  1085. -
  1086. -    - Alan
  1087. -=======================================================================
  1088. -#! /bin/sh
  1089. -: '/*********************************************************************
  1090. -   program:    sendnewsmail
  1091. -   description:    Send news items from mail
  1092. -   programmer:    Alan S. Watt
  1093. -        (ittvax!swatt)
  1094. -   
  1095. -   Sccsid=@W@
  1096. -
  1097. -   usage:
  1098. -    Not invoked by user: called as program mail alias
  1099. -    News item title and newsgroup(s) are specified on the
  1100. -    mail subject line by:
  1101. -
  1102. -    Subj: <news item title> : <newsgroup> ...
  1103. -
  1104. -    Several (blank separated) newsgroups may be specified;
  1105. -    the news article will be submitted to each.  There is
  1106. -    no way to embed a colon character in the title, so there
  1107. -    can only be one colon on the subject line.
  1108. -
  1109. -   arguments:
  1110. -    None
  1111. -   
  1112. -   notes:
  1113. -    To install this, put it someplace safe from system updates
  1114. -    (I use /usr/lib/news), and put an alias in the system
  1115. -    mail alias file (/usr/lib/aliases) that names this program
  1116. -    as the alias for the use "news":
  1117. -
  1118. -        news:"|/usr/lib/news/sendnewsmail"
  1119. -
  1120. -   history:
  1121. -    11/11/81    original version
  1122. -    11/19/81    fixed to properly handle default newsgroup
  1123. -    03/13/82    changes to work with "B" netnews
  1124. -    03/35/82    Modest documentation changes
  1125. -   *********************************************************************/'
  1126. -
  1127. -PROGRAM_NAME='sendnewsmail'
  1128. -VERSION_NUMBER='@I@'
  1129. -TOOL_LOG='/usr/advanced/logs/testlog'
  1130. -USAGE='mail news'
  1131. -
  1132. -
  1133. -: 'mail alias program to send news items through mail(1)'
  1134. -: 'need to get newsgroup and title from subject line'
  1135. -
  1136. -tempf=/tmp/news$$.tmp
  1137. -errorf=/tmp/news$$.err
  1138. -
  1139. -: 'copy standard input to a temporary file'
  1140. -cat >$tempf
  1141. -
  1142. -: 'read the message and grab title and newsgroups from the
  1143. -   Subject line. Grab the sender from the From line.
  1144. -   Header ends on first blank line (/^$/).
  1145. -  '
  1146. -eval `sed -n '
  1147. -/^Subj/    {
  1148. -    s/^Subj[^ :]*[ :] *\([^:]*\):\(.*\)/title="\1";newsgroup="\2"/p
  1149. -    s/^Subj[^ :]*[ :] *\([^:]*\)$/title="\1"/p
  1150. -}
  1151. -/^From/ {
  1152. -    s/^[fF]rom[: ] *\([^ ]*\).*/sender="\1"/p
  1153. -}
  1154. -/^$/    {
  1155. -    b done
  1156. -}
  1157. -: done
  1158. -' $tempf`
  1159. -
  1160. -: 'default newsgroup to "general" if unspecified'
  1161. -case $newsgroup in
  1162. -'')    newsgroup=general ;;
  1163. -esac
  1164. -
  1165. -: 'make up something if the title unspecified'
  1166. -case $title in
  1167. -'')    title="News from mail" ;;
  1168. -esac
  1169. -
  1170. -: 'Submit the article to news'
  1171. -if sed "1,/^$/d" $tempf | inews -t "$title" -n $newsgroup >$errorf 2>&1
  1172. -then
  1173. -    : 'OK exit, do nothing'
  1174. -else
  1175. -    : 'On errors, return article together with error messages to user'
  1176. -    : 'Change this line if your mailer does not have a -s flag'
  1177. -    mail -s 'Rejected News Article' $sender <<!EOF
  1178. -
  1179. -The news article you submitted could not be accepted for the reasons:
  1180. -`cat $errorf`
  1181. -
  1182. -The text of the article you submitted was:
  1183. -`cat $tempf`
  1184. -!EOF
  1185. -
  1186. -fi
  1187. -
  1188. -: 'clean up'
  1189. -rm -f $tempf $errorf
  1190. -
  1191. -
  1192. -
  1193. -
  1194. -
  1195. *-*-END-of-misc/sendnewsmail-*-*
  1196. echo x - misc/shar 1>&2
  1197. sed 's/.//' >misc/shar <<'*-*-END-of-misc/shar-*-*'
  1198. -for i
  1199. -do
  1200. -    echo "echo x - $i"
  1201. -    echo "sed 's/^X//' >$i <<'*-*-END-of-$i-*-*'"
  1202. -    sed 's/^/X/' $i
  1203. -    echo "*-*-END-of-$i-*-*"
  1204. -done
  1205. -echo exit
  1206. *-*-END-of-misc/shar-*-*
  1207. echo x - misc/trimlib 1>&2
  1208. sed 's/.//' >misc/trimlib <<'*-*-END-of-misc/trimlib-*-*'
  1209. -: if this is run once per day, it will save the last
  1210. -: weeks worth of news log files. You can, of course, comment
  1211. -: out some of the lines to save less
  1212. -cd /usr/lib/news
  1213. -mv log.5 log.6
  1214. -mv log.4 log.5
  1215. -mv log.3 log.4
  1216. -mv log.2 log.3
  1217. -mv log.1 log.2
  1218. -mv log.0 log.1
  1219. -mv log log.0
  1220. -cp /dev/null log
  1221. -/etc/chown news log* history*
  1222. *-*-END-of-misc/trimlib-*-*
  1223. echo x - misc/unshar 1>&2
  1224. sed 's/.//' >misc/unshar <<'*-*-END-of-misc/unshar-*-*'
  1225. -From lee@unmvax.UUCP Sun Oct 28 16:56:42 1984
  1226. -Relay-Version: version B 2.10.2 10/19/84; site seismo.UUCP
  1227. -Posting-Version: version B 2.10.2 9/5/84; site unmvax.UUCP
  1228. -Path: seismo!cmcl2!lanl!unm-cvax!unmvax!lee
  1229. -From: lee@unmvax.UUCP
  1230. -Newsgroups: net.sources
  1231. -Subject: Program to un-shar netmaps without using a shell..
  1232. -Message-ID: <473@unmvax.UUCP>
  1233. -Date: 28 Oct 84 21:56:42 GMT
  1234. -Date-Received: 29 Oct 84 11:14:42 GMT
  1235. -Distribution: net
  1236. -Organization: Univ. of New Mexico, Albuquerque
  1237. -Lines: 336
  1238. -
  1239. -#ifndef    lint
  1240. -char    *Rcsid = "$Header: getmaps.c,v 1.4 84/10/13 18:19:13 lee Exp $";
  1241. -#endif
  1242. -
  1243. -/*
  1244. - * getmaps
  1245. - *
  1246. - * Get the net maps from USENET as published by Karen and Mark Horton, in
  1247. - * "shar" format. Because of paranoia the sh is not used but instead a DFA
  1248. - * recognizing the appropriate commands.
  1249. - *
  1250. - * lee Ward        10/13/84
  1251. - */
  1252. -
  1253. -#include <stdio.h>
  1254. -#include <ctype.h>
  1255. -#include <sys/types.h>
  1256. -#include <sys/stat.h>
  1257. -#include <sys/dir.h>
  1258. -
  1259. -char    *mapgrp = "/usr/spool/news/net/news/map";
  1260. -char    *mapdir = "/usr/lee/netmap/maps";
  1261. -char    *seqfil = "/usr/lee/netmap/.seq";
  1262. -char    *logfil = "/usr/lee/netmap/log";
  1263. -
  1264. -char    *usestr = "[-l logfil] [-g group] [-s seqfile] [-a archiv-dir]";
  1265. -
  1266. -FILE    *logsd = NULL;
  1267. -
  1268. -void    domaps(), myabort(), log(), mkmaps(), getwrd(), logtime();
  1269. -
  1270. -main(argc, argv)
  1271. -    int    argc;
  1272. -    char    *argv[];
  1273. -{
  1274. -    int    x;
  1275. -    FILE    *seqsd;
  1276. -    char    seqbuf[BUFSIZ];
  1277. -
  1278. -    for (x = 1; x < argc; x++) {
  1279. -        if (*argv[x]++ != '-') {
  1280. -            fprintf(stderr, "Bad usage\n");
  1281. -            fprintf(stderr, "Usage: %s %s\n", argv[0], usestr);
  1282. -            exit(-1);
  1283. -        }
  1284. -        switch (*argv[x]) {
  1285. -
  1286. -        case 'l':
  1287. -            logfil = argv[++x];
  1288. -            break;
  1289. -        case 'g':
  1290. -            mapgrp = argv[++x];
  1291. -            break;
  1292. -        case 's':
  1293. -            seqfil = argv[++x];
  1294. -            break;
  1295. -        case 'a':
  1296. -            mapdir = argv[++x];
  1297. -            break;
  1298. -        default:
  1299. -            fprintf(stderr, "Bad switch\n");
  1300. -            fprintf(stderr, "Usage: %s %s\n", argv[0], usestr);
  1301. -            exit(-1);
  1302. -        }
  1303. -    }
  1304. -
  1305. -    logsd = fopen(logfil, "a");
  1306. -
  1307. -    logtime("Start");
  1308. -
  1309. -    if (chdir(mapdir) != 0)
  1310. -        myabort("Could not change directory to %s", mapdir);
  1311. -
  1312. -    seqbuf[0] = NULL;
  1313. -    if ((seqsd = fopen(seqfil, "r")) != NULL) {
  1314. -        if ((x = fread(seqbuf, sizeof(char), sizeof(seqbuf),
  1315. -            seqsd)) != 0)
  1316. -            seqbuf[x - 1] = NULL;
  1317. -        (void )fclose(seqsd);
  1318. -    }
  1319. -    if ((seqsd = fopen(seqfil, "a")) == NULL)
  1320. -        myabort("Could not open seq file for writing");
  1321. -    (void )fseek(seqsd, 0L, 0);
  1322. -
  1323. -    domaps(mapgrp, seqbuf, seqsd);
  1324. -    (void )fclose(seqsd);
  1325. -
  1326. -    logtime("End");
  1327. -}
  1328. -
  1329. -void
  1330. -domaps(grp, seqbuf, seqsd)
  1331. -    char    *grp, *seqbuf;
  1332. -    FILE    *seqsd;
  1333. -{
  1334. -    char    nbuf[BUFSIZ], *nptr, *tptr;
  1335. -    struct direct **filst;
  1336. -    int    nfils, x;
  1337. -    struct stat stbuf;
  1338. -    extern int scandir(), alphasort();
  1339. -    extern char *strcpy(), *strncat();
  1340. -
  1341. -    if ((nfils = scandir(grp, &filst, (int (*)())NULL, alphasort)) == -1)
  1342. -        myabort("scandir failed");
  1343. -
  1344. -    (void )strcpy(nbuf, grp);
  1345. -    nptr = nbuf + strlen(nbuf);
  1346. -    *nptr++ = '/';
  1347. -    *nptr = NULL;
  1348. -    nbuf[BUFSIZ] = NULL;
  1349. -
  1350. -    for (x = 0; x < nfils; x++) {
  1351. -        if (strcmp(".", filst[x]->d_name) == 0 ||
  1352. -            strcmp("..", filst[x]->d_name) == 0)
  1353. -            continue;
  1354. -        tptr = filst[x]->d_name;
  1355. -        while(*tptr && isdigit(*tptr))
  1356. -            tptr++;
  1357. -        if (*tptr != NULL)
  1358. -            continue;
  1359. -        *nptr = NULL;
  1360. -        (void )strncat(nptr, filst[x]->d_name,
  1361. -            BUFSIZ - (nptr - nbuf) - 1);
  1362. -        if (stat(nbuf, &stbuf) != 0) {
  1363. -            log("Could not stat %s", nbuf);
  1364. -            continue;
  1365. -        }
  1366. -        if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
  1367. -            continue;
  1368. -        if (strcmp(seqbuf, filst[x]->d_name) >= 0)
  1369. -            continue;
  1370. -
  1371. -        mkmaps(nbuf);
  1372. -        (void )fseek(seqsd, 0L, 0);
  1373. -        (void )fwrite(filst[x]->d_name, sizeof(char),
  1374. -            strlen(filst[x]->d_name), seqsd);
  1375. -        (void )fputc('\n', seqsd);
  1376. -        (void )fflush(seqsd);
  1377. -    }
  1378. -}
  1379. -
  1380. -void
  1381. -mkmaps(file)
  1382. -    char    *file;
  1383. -{
  1384. -    char    buf[BUFSIZ], tofil[BUFSIZ], delim[BUFSIZ];
  1385. -    int    state, sizdel;
  1386. -    FILE    *isd, *osd;
  1387. -    extern FILE *fopen();
  1388. -
  1389. -#define    SEARCH        1
  1390. -#define    INAMAP        2
  1391. -#define    SKIPPING    3
  1392. -
  1393. -    if ((isd = fopen(file, "r")) == NULL) {
  1394. -        log("Could not open %s. Skipping...", file);
  1395. -        return;
  1396. -    }
  1397. -    log("Unarchive %s", file);
  1398. -
  1399. -    state = SEARCH;
  1400. -    while (fgets(buf, sizeof(buf) - 1, isd) != NULL) {
  1401. -        buf[sizeof(buf)] = NULL;
  1402. -        if (state == SEARCH) {
  1403. -            if (gotcat(buf, tofil, BUFSIZ, delim, BUFSIZ)) {
  1404. -                state = INAMAP;
  1405. -                sizdel = strlen(delim);
  1406. -                if ((osd = fopen(tofil, "w")) == NULL) {
  1407. -                    log("Could not open %s", tofil);
  1408. -                    state = SKIPPING;
  1409. -                }
  1410. -            }
  1411. -            continue;
  1412. -        }
  1413. -        if (strncmp(buf, delim, sizdel) == 0) {
  1414. -            state = SEARCH;
  1415. -            if (osd != NULL)
  1416. -                (void )fclose(osd);
  1417. -            continue;
  1418. -        }
  1419. -        if (state == SKIPPING)
  1420. -            continue;
  1421. -        fputs(buf, osd);
  1422. -    }
  1423. -    if (state != SEARCH)
  1424. -        log("Read/sync error on %s", file);
  1425. -    (void )fclose(isd);
  1426. -
  1427. -#undef    SEARCH
  1428. -#undef    INAMAP
  1429. -#undef    SKIPPING
  1430. -}
  1431. -
  1432. -/*
  1433. - * gotcat
  1434. - *
  1435. - * Use a DFA to recognize
  1436. - *    cat << DELIM > OUT
  1437. - * or
  1438. - *    cat > OUT << DELIM
  1439. - *
  1440. - */
  1441. -
  1442. -/* Transition table for the DFA */
  1443. -int    ttbl[9][4] = {
  1444. -        1,-1,-1,-1,
  1445. -        -1,6,2,-1,
  1446. -        -1,-1,-1,3,
  1447. -        -1,4,-1,-1,
  1448. -        -1,-1,-1,5,
  1449. -        -1,-1,-1,-1,
  1450. -        -1,-1,-1,7,
  1451. -        -1,-1,8,-1,
  1452. -        -1,-1,-1,5,
  1453. -    };
  1454. -
  1455. -gotcat(buf, tofil, tofilln, delim, delimln)
  1456. -    char    *buf,
  1457. -        *tofil,
  1458. -        *delim;
  1459. -    int    tofilln,
  1460. -        delimln;
  1461. -{
  1462. -    int    state;
  1463. -    char    *ptr;
  1464. -
  1465. -    state = 0;            /* Start state */
  1466. -    while (state != -1 && state != 5) {
  1467. -        /* Eat up white */
  1468. -        while (*buf != '\n' && (*buf == ' ' || *buf == '\t'))
  1469. -            buf++;
  1470. -        if (*buf == '>') {
  1471. -            buf++;
  1472. -            state = ttbl[state][1];
  1473. -            continue;
  1474. -        }
  1475. -        if (*buf == '<' && *(buf + 1) == '<') {
  1476. -            buf += 2;
  1477. -            state = ttbl[state][2];
  1478. -            continue;
  1479. -        }
  1480. -        if (*buf == 'c' && *(buf + 1) == 'a' && *(buf + 2) == 't') {
  1481. -            buf += 3;
  1482. -            state = ttbl[state][0];
  1483. -            continue;
  1484. -        }
  1485. -        ptr = buf;
  1486. -        while (*buf != '\n' && *buf != ' ' && *buf != '\t')
  1487. -            buf++;
  1488. -        if (state == 2 || state == 8)
  1489. -            getwrd(ptr, buf, delim, delimln);
  1490. -        else if (state == 6 || state == 4)
  1491. -            getwrd(ptr, buf, tofil, tofilln);
  1492. -        state = ttbl[state][3];
  1493. -    }
  1494. -
  1495. -    if (state == 5)
  1496. -        return(1);
  1497. -    return(0);
  1498. -}
  1499. -
  1500. -void
  1501. -getwrd(fc, lc, buf, maxlen)
  1502. -    char    *fc,
  1503. -        *lc,
  1504. -        *buf;
  1505. -    int    maxlen;
  1506. -{
  1507. -    char    *ptr, *t1ptr, *t2ptr;
  1508. -
  1509. -    maxlen--;
  1510. -    maxlen = lc - fc > maxlen ? maxlen : lc - fc;
  1511. -    ptr = buf;
  1512. -    t1ptr = fc;
  1513. -    while (maxlen-- != 0)
  1514. -        *ptr++ = *t1ptr++;
  1515. -    *ptr = NULL;
  1516. -
  1517. -    /* Strip quotes */
  1518. -    ptr = buf;
  1519. -    while (*ptr != NULL) {
  1520. -        if (*ptr == '\\' && (*(ptr + 1) == '\'' || *(ptr + 1) == '"'))
  1521. -            ptr += 2;
  1522. -        else if (*ptr == '\'' || *ptr == '"') {
  1523. -            t1ptr = ptr;
  1524. -            t2ptr = ptr + 1;
  1525. -            while ((*t1ptr++ = *t2ptr++) != NULL)
  1526. -                ;
  1527. -        } else
  1528. -            ptr++;
  1529. -    }
  1530. -}
  1531. -/*VARARGS1*/
  1532. -void
  1533. -myabort(s, a, b, c, d, e, f, g, h, i, j, k, l)
  1534. -    char    *s;
  1535. -{
  1536. -
  1537. -    if (logsd != NULL) {
  1538. -        fputs("ABORT - ", logsd);
  1539. -        fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l);
  1540. -        (void )fputc('\n', logsd);
  1541. -        logtime("End");
  1542. -    }
  1543. -    exit(-1);
  1544. -}
  1545. -
  1546. -/*VARARGS1*/
  1547. -void
  1548. -log(s, a, b, c, d, e, f, g, h, i, j, k, l)
  1549. -    char    *s;
  1550. -{
  1551. -
  1552. -    if (logsd == NULL)
  1553. -        return;
  1554. -    fprintf(logsd, s, a, b, c, d, e, f, g, h, i, j, k, l);
  1555. -    (void )fputc('\n', logsd);
  1556. -    (void )fflush(logsd);
  1557. -}
  1558. -
  1559. -void
  1560. -logtime(s)
  1561. -    char    *s;
  1562. -{
  1563. -    time_t    clock;
  1564. -    extern char *ctime();
  1565. -
  1566. -    if (logsd == NULL)
  1567. -        return;
  1568. -    (void )time(&clock);
  1569. -    fprintf(logsd, "%s %s", s, ctime(&clock));
  1570. -    (void )fflush(logsd);
  1571. -}
  1572. --- 
  1573. -            --Lee (Ward)
  1574. -            {ucbvax,convex,gatech,pur-ee}!unmvax!lee
  1575. -
  1576. -
  1577. *-*-END-of-misc/unshar-*-*
  1578. exit
  1579.  
  1580.