home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume17 / rkive / part04 < prev    next >
Internet Message Format  |  1991-02-24  |  57KB

  1. From: kent@sparky.imd.sterling.com (Kent Landfield)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i020:  rkive - Usenet sources archiver, Part04/06
  4. Message-ID: <1991Feb24.222536.27087@sparky.IMD.Sterling.COM>
  5. Date: 24 Feb 91 22:25:36 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: c9bf3687 cc294723 b4875ee2 5d8467ba
  8.  
  9. Submitted-by: Kent Landfield <kent@sparky.imd.sterling.com>
  10. Posting-number: Volume 17, Issue 20
  11. Archive-name: rkive/part04
  12.  
  13. #! /bin/sh
  14. # This is a shell archive.  Remove anything before this line, then feed it
  15. # into a shell via "sh file" or similar.  To overwrite existing files,
  16. # type "sh file -c".
  17. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  18. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  19. # If this archive is complete, you will see the following message at the end:
  20. #        "End of archive 4 (of 6)."
  21. # Contents:  rkive/ck_name.c rkive/format.c rkive/match.y
  22. #   rkive/nntpart.c rkive/rkive.5
  23. # Wrapped by kent@sparky on Sun Feb 24 16:11:22 1991
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'rkive/ck_name.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'rkive/ck_name.c'\"
  27. else
  28. echo shar: Extracting \"'rkive/ck_name.c'\" \(2106 characters\)
  29. sed "s/^X//" >'rkive/ck_name.c' <<'END_OF_FILE'
  30. X/*
  31. X** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
  32. X**
  33. X** Permission is hereby granted to copy, distribute or otherwise 
  34. X** use any part of this package as long as you do not try to make 
  35. X** money from it or pretend that you wrote it.  This copyright 
  36. X** notice must be maintained in any copy made.
  37. X**
  38. X*/
  39. X#if !defined(lint) && !defined(SABER)
  40. Xstatic char SID[] = "@(#)ck_name.c    2.2 2/23/91";
  41. X#endif
  42. X
  43. X#include <stdio.h>
  44. X/*
  45. X** check_archive_name
  46. X**
  47. X** Assure the path specified is within the base directory
  48. X** specified by the archive administrator by assuring that
  49. X** a prankster could not have an article archived at a
  50. X**     basedir/../../../etc/passwd
  51. X** location.
  52. X**
  53. X** If an absoulte path is specified in the Archive-name, it
  54. X** is of no concern since a "checked" base directory and
  55. X** volume directory are prefixed.
  56. X*/
  57. X
  58. Xvoid check_archive_name(argstr)
  59. X    char *argstr;
  60. X {
  61. X    int strlen();
  62. X    char *substr();
  63. X    register char *rp;
  64. X    register char *dp;
  65. X
  66. X    /* 
  67. X    ** check to assure that the path specified
  68. X    ** does not contain the '..' sequence.
  69. X    */
  70. X
  71. X    while ((rp = substr(argstr, "..")) != NULL) {
  72. X       dp = rp+2;
  73. X       while(*dp)
  74. X           *rp++ = *dp++;
  75. X       *rp = '\0';
  76. X    }
  77. X
  78. X    /* I know this is not necessary but what the heck.. */
  79. X
  80. X    while ((rp = substr(argstr, "//")) != NULL) {
  81. X       dp = rp+2;
  82. X       ++rp;
  83. X       while(*dp)
  84. X           *rp++ = *dp++;
  85. X       *rp = '\0';
  86. X    }
  87. X
  88. X    /* 
  89. X    ** strip the string of trailing '/'s
  90. X    */
  91. X
  92. X    dp = argstr+(strlen(argstr)-1);
  93. X    while(*dp == '/' && dp > argstr)
  94. X        *dp = '\0';
  95. X
  96. X    /*
  97. X    ** Assure that there is no spaces inside
  98. X    ** the archive-name. This is not that uncommon
  99. X    ** alt.sources postings. "X_list/part 3"
  100. X    */
  101. X
  102. X    rp = argstr;
  103. X    while (*rp) {
  104. X       if (*rp == ' ')
  105. X           *rp = '-';
  106. X       ++rp;
  107. X    }
  108. X
  109. X    /*
  110. X    ** lets get rid of leading blanks so
  111. X    ** that "/dev/null" Archive-name: lines
  112. X    ** work as they should... :-)
  113. X    */
  114. X
  115. X    dp = argstr;
  116. X    rp = argstr;
  117. X
  118. X    while(*dp == '/')
  119. X        ++dp;
  120. X
  121. X    while(*dp)
  122. X      *rp++ = *dp++;
  123. X    *rp = '\0';
  124. X}
  125. END_OF_FILE
  126. if test 2106 -ne `wc -c <'rkive/ck_name.c'`; then
  127.     echo shar: \"'rkive/ck_name.c'\" unpacked with wrong size!
  128. fi
  129. # end of 'rkive/ck_name.c'
  130. fi
  131. if test -f 'rkive/format.c' -a "${1}" != "-c" ; then 
  132.   echo shar: Will not clobber existing file \"'rkive/format.c'\"
  133. else
  134. echo shar: Extracting \"'rkive/format.c'\" \(15279 characters\)
  135. sed "s/^X//" >'rkive/format.c' <<'END_OF_FILE'
  136. X/*
  137. X** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
  138. X**
  139. X** Permission is hereby granted to copy, distribute or otherwise 
  140. X** use any part of this package as long as you do not try to make 
  141. X** money from it or pretend that you wrote it.  This copyright 
  142. X** notice must be maintained in any copy made.
  143. X**
  144. X*/
  145. X#if !defined(lint) && !defined(SABER)
  146. Xstatic char SID[] = "@(#)format.c    2.2 2/23/91";
  147. X#endif
  148. X
  149. X#include <stdio.h>
  150. X#include <sys/types.h>
  151. X#include "article.h"
  152. X#include "rkive.h"
  153. X
  154. Xint strlen();
  155. X
  156. Xextern FILE *errfp;
  157. Xextern struct group_archive *newsgrp;
  158. X
  159. X#ifdef RKIVE
  160. X  extern char *config_file;
  161. X  extern char problems_dir[];
  162. X  extern char spooldir[];
  163. X  extern char compress[];
  164. X  extern char log[];
  165. X  extern char log_format[];
  166. X  extern char mindex[];
  167. X  extern char index_format[];
  168. X  extern char mail[];
  169. X  extern char checkhash[];
  170. X  extern char arch_command[];
  171. X  extern int default_type;
  172. X  extern int default_patch_type;
  173. X  extern int default_owner;
  174. X  extern int default_group;
  175. X  extern int default_modes;
  176. X# ifdef NNTP
  177. X    extern char nntp[];
  178. X# endif /*NNTP*/
  179. X#endif /* RKIVE */
  180. X
  181. X
  182. X/*
  183. X** substr:
  184. X**
  185. X** substr(str, substr) returns a pointer to the first place in
  186. X** str where the substring substr occurs, or NULL if substr does
  187. X** not occur in str.
  188. X**
  189. X** char *substr(str, substr) char *str, *substr; { return (str); }
  190. X*/
  191. X
  192. Xchar *substr(from, find)
  193. X    char *from, *find;
  194. X{
  195. X    int strncmp();
  196. X    char *strchr();
  197. X
  198. X    register char *sp, *np;
  199. X    register int len;
  200. X
  201. X    np = from;
  202. X    len = strlen(find);
  203. X
  204. X    while ((sp = strchr(np,*find)) != NULL) {
  205. X        if (strlen(sp) < len)
  206. X            break;
  207. X        if (strncmp(sp,find,len) == 0) 
  208. X            return(sp);
  209. X        np = sp + 1;
  210. X    }
  211. X    return(NULL);
  212. X}
  213. X
  214. Xchar *itoa(n)
  215. Xint n;
  216. X{
  217. X    static char str[20];
  218. X
  219. X    int i, c, j, sign;
  220. X    
  221. X    if ((sign = n) < 0) 
  222. X    n = -n;
  223. X
  224. X    i = 0;
  225. X    do {
  226. X        str[i++] = n % 10 + '0';
  227. X    } while ((n /= 10) > 0);
  228. X
  229. X    if (sign < 0)
  230. X        str[i++] = '-';
  231. X    str[i] = '\0';
  232. X
  233. X    for (i = 0, j = strlen(str)-1; i < j; i++,j--) {
  234. X        c = str[i];
  235. X        str[i] = str[j];
  236. X        str[j] = c;
  237. X    }
  238. X    return(str);
  239. X}
  240. X
  241. Xchar *add_string(ptr, member_str)
  242. Xchar *ptr, *member_str;
  243. X{
  244. X    while(*member_str)
  245. X        *ptr++ = *member_str++;
  246. X    return(ptr);
  247. X}
  248. X
  249. X
  250. Xchar *basename(name)
  251. X    char *name;
  252. X{
  253. X    char *p;
  254. X    char *strrchr();
  255. X    
  256. X    if ((p = strrchr(name,'/')) == NULL)
  257. X        return(name);
  258. X    return(++p);
  259. X}
  260. X
  261. X
  262. Xchar *format_output(frmptr, filename, called_from)
  263. Xchar *frmptr;          /* Selection Format pointer              */
  264. Xchar *filename;        /* File name the info came from          */
  265. Xint called_from;       /* Where called from, Rkive or Article   */
  266. X{
  267. X    char *basename();
  268. X
  269. X    static char format[4*BUFSIZ];
  270. X    register char *aptr;
  271. X    register char *cp;
  272. X    char c;
  273. X    /* Did the user specify a format to use   */
  274. X    /* or should the default format be used ? */
  275. X
  276. X    if (frmptr == NULL) {
  277. X       if (called_from == ARCHIVE) 
  278. X           (void) sprintf(format,"%-s\t%-s\t%s",
  279. X                 article.newsarticle, header.archive_name,
  280. X                 article.description);
  281. X       else
  282. X           (void) sprintf(format,"%-s\t%-s", filename, header.subject);
  283. X       return(format);
  284. X    }
  285. X
  286. X    for (cp = format; cp < format + sizeof(format); cp++)
  287. X         *cp = '\0';
  288. X    aptr = frmptr;
  289. X    cp = format;
  290. X
  291. X    while ((c = *aptr++)) {
  292. X        if (c == '%') {
  293. X           switch (*aptr++) {
  294. X               case '%':
  295. X                   *cp++ = '%';
  296. X                   continue;
  297. X               case 'A':     /* Approved  */
  298. X                   cp = add_string(cp, header.approved);
  299. X                   continue;
  300. X               case 'B':     /* Base name of the file path  */
  301. X                   cp = add_string(cp, basename(filename));
  302. X                   continue;
  303. X               case 'C':     /* Control  */
  304. X                   cp = add_string(cp, header.ctlmsg);
  305. X                   continue;
  306. X               case 'D':     /* Date */
  307. X                   cp = add_string(cp, header.subdate);
  308. X                   continue;
  309. X               case 'E':     /* Reposted-by */
  310. X                   cp = add_string(cp, header.reposter);
  311. X                   continue;
  312. X               case 'F':     /* From */
  313. X                   cp = add_string(cp, header.from);
  314. X                   continue;
  315. X               case 'G':     /* newGroups disk location */
  316. X                   /*
  317. X                   ** The newsgroup selected and displayed is the first
  318. X                   ** newsgroup encountered unless the calling routine 
  319. X                   ** is rkive. This is necessary to support rkive's
  320. X                   ** needs when the newsgroup is known ahead of time
  321. X                   ** and article's need to display just what the news article
  322. X                   ** contains. If this is not done then the index information
  323. X                   ** mailed to the specified users may display a crossposted
  324. X                   ** newsgroup as an information line. KLUDGE ALERT!!!
  325. X                   */
  326. X                   if (called_from == ARCHIVE) 
  327. X                       cp = add_string(cp, newsgrp->ng_name);
  328. X                   else
  329. X                       cp = add_string(cp, article.newsgroup);
  330. X                   continue;
  331. X               case 'H':     /* Original-posting-by */
  332. X                   cp = add_string(cp, header.orig_poster);
  333. X                   continue;
  334. X               case 'I':     /* Original-subject */
  335. X                   cp = add_string(cp, header.orig_subject);
  336. X                   continue;
  337. X               case 'J':     /* Archive-directory */
  338. X                   cp = add_string(cp, header.archive_dir);
  339. X                   continue;
  340. X               case 'K':     /* Keywords  */
  341. X                   cp = add_string(cp, header.keywords);
  342. X                   continue;
  343. X               case 'L':     /* Lines */
  344. X                   cp = add_string(cp, header.numlines);
  345. X                   continue;
  346. X               case 'M':     /* Message-ID */
  347. X                   cp = add_string(cp, header.ident);
  348. X                   continue;
  349. X               case 'N':     /* Newsgroups */
  350. X                   cp = add_string(cp, header.nbuf);
  351. X                   continue;
  352. X               case 'O':     /* Actual Archived filename */
  353. X                   cp = add_string(cp, filename);
  354. X                   continue;
  355. X               case 'P':     /* Path */
  356. X                   cp = add_string(cp, header.path);
  357. X                   continue;
  358. X               case 'Q':     /* Expires  */
  359. X                   cp = add_string(cp, header.expdate);
  360. X                   continue;
  361. X               case 'R':     /* References */
  362. X                   cp = add_string(cp, header.references);
  363. X                   continue;
  364. X               case 'S':     /* Subject */
  365. X                   cp = add_string(cp, header.subject);
  366. X                   continue;
  367. X               case 'T':     /* Subject Topic */
  368. X                   cp = add_string(cp, article.description);
  369. X                   continue;
  370. X               case 'V':     /* Volume-Issue article filename  */
  371. X                   cp = add_string(cp, article.filename);
  372. X                   continue;
  373. X               case 'W':     /* Architecture */
  374. X                   cp = add_string(cp, header.architecture);
  375. X                   continue;
  376. X               case 'X':     /* Version-number */
  377. X                   cp = add_string(cp, header.version_number);
  378. X                   continue;
  379. X               case 'a':     /* Archive-name */
  380. X                   cp = add_string(cp, header.archive_name);
  381. X                   continue;
  382. X               case 'b':     /* Submitted-by */
  383. X                   cp = add_string(cp, header.submitted_by);
  384. X                   continue;
  385. X               case 'c':     /* Supersedes  */
  386. X                   cp = add_string(cp, header.supersedes);
  387. X                   continue;
  388. X               case 'd':     /* Distribution  */
  389. X                   cp = add_string(cp, header.distribution);
  390. X                   continue;
  391. X               case 'e':     /* Environment  */
  392. X                   cp = add_string(cp, header.environment);
  393. X                   continue;
  394. X               case 'f':     /* Followup-to  */
  395. X                   cp = add_string(cp, header.followup_to);
  396. X                   continue;
  397. X               case 'h':     /* X-Checksum-Snefru  */
  398. X                   cp = add_string(cp, header.x_checksum_snefru);
  399. X                   continue;
  400. X               case 'i':     /* issue (if archive) */
  401. X                   cp = add_string(cp,itoa(article.issue));
  402. X                   continue;
  403. X               case 'l':     /* Author's logon address */
  404. X                   cp = add_string(cp, article.author_signon);
  405. X                   continue;
  406. X               case 'n':     /* Author's name */
  407. X                   cp = add_string(cp, article.author_name);
  408. X                   continue;
  409. X               case 'o':     /* Organization */
  410. X                   cp = add_string(cp, header.organization);
  411. X                   continue;
  412. X               case 'p':     /* Posting-number */
  413. X                   cp = add_string(cp, header.posting_num);
  414. X                   continue;
  415. X               case 'r':     /* Reply-to */
  416. X                   cp = add_string(cp, header.replyto);
  417. X                   continue;
  418. X               case 's':     /* Sender  */
  419. X                   cp = add_string(cp, header.sender);
  420. X                   continue;
  421. X               case 't':     /* Patch-To  */
  422. X                   cp = add_string(cp, header.patch_to);
  423. X                   continue;
  424. X               case 'u':     /* Summary */
  425. X                   cp = add_string(cp, header.summary);
  426. X                   continue;
  427. X               case 'v':     /* volume (if archive) */
  428. X                   cp = add_string(cp,itoa(article.volume));
  429. X                   continue;
  430. X               case 'w':     /* Archive-site */
  431. X                   cp = add_string(cp,header.archive_site);
  432. X                   continue;
  433. X               case 'x':     /* Xref */
  434. X                   cp = add_string(cp, header.xref);
  435. X                   continue;
  436. X           case 'y':     /* Archive */
  437. X           cp = add_string(cp, header.archive);
  438. X           continue;
  439. X               default:
  440. X                  (void) fprintf(errfp, "invalid format - %c\n", *--aptr);
  441. X                  exit(2);
  442. X           }    /* end switch */
  443. X        }
  444. X        else if (c == '\134') {
  445. X           switch (*aptr++) {
  446. X               case 'n':
  447. X                   *cp++ = '\n';
  448. X                   continue;
  449. X               case 't':
  450. X                   *cp++ = '\t';
  451. X                   continue;
  452. X           }
  453. X        }
  454. X
  455. X#ifdef RKIVE
  456. X        else if (c == '$') {
  457. X           switch (*aptr++) {
  458. X               /*
  459. X               **  The GLOBAL information 
  460. X               */
  461. X               case 'B':     /* BASEDIR */
  462. X                   cp = add_string(cp,newsgrp->location);
  463. X                   continue;
  464. X               case 'E':     /* PROBLEMS - errors */
  465. X                   cp = add_string(cp,problems_dir);
  466. X                   continue;
  467. X               case 'I':     /* INDEX */
  468. X                   cp = add_string(cp, mindex);
  469. X                   continue;
  470. X               case 'J':     /* INDEX_FORMAT */
  471. X                   cp = add_string(cp, index_format);
  472. X                   continue;
  473. X               case 'K':     /* LOG_FORMAT */
  474. X                   cp = add_string(cp, log_format);
  475. X                   continue;
  476. X               case 'L':     /* LOG */
  477. X                   cp = add_string(cp, log);
  478. X                   continue;
  479. X               case 'P':     /* actual disk path to file to archive */
  480. X                   cp = add_string(cp,spooldir);
  481. X                   cp = add_string(cp,"/");
  482. X                   cp = add_string(cp,newsgrp->ng_path);
  483. X                   cp = add_string(cp,"/");
  484. X                   cp = add_string(cp, basename(filename));
  485. X                   continue;
  486. X               case 'S':     /* SPOOLDIR */
  487. X                   cp = add_string(cp,spooldir);
  488. X                   continue;
  489. X        case 'U':     /* MAIL - users */
  490. X                   cp = add_string(cp,mail);
  491. X                   continue;
  492. X               /*
  493. X               **  Now the newgroup specific information 
  494. X               */
  495. X               case 'a':     /* newsgroup's .archived file path */
  496. X                   cp = add_string(cp, newsgrp->arc_done);
  497. X                   continue;
  498. X               case 'b':     /* newsgroup's spool directory */
  499. X                   cp = add_string(cp, newsgrp->ng_path);
  500. X                   continue;
  501. X               case 'c':     /* COMPRESS: */
  502. X                   if (*newsgrp->compress)
  503. X                       cp = add_string(cp, newsgrp->compress);
  504. X                   else
  505. X                       cp = add_string(cp, compress);
  506. X                   continue;
  507. X               case 'g':     /* GROUP: */
  508. X                   cp = add_string(cp,itoa(newsgrp->group));
  509. X                   continue;
  510. X               case 'h':     /* CHECKHASH: */
  511. X                   if (*newsgrp->checkhash)
  512. X                       cp = add_string(cp, newsgrp->checkhash);
  513. X                   else
  514. X                       cp = add_string(cp, checkhash);
  515. X                   continue;
  516. X               case 'i':     /* INDEX: */
  517. X                   cp = add_string(cp, newsgrp->index);
  518. X                   continue;
  519. X               case 'j':     /* INDEX_FORMAT: */
  520. X                   cp = add_string(cp, "'");
  521. X                   cp = add_string(cp, newsgrp->indformat);
  522. X                   cp = add_string(cp, "'");
  523. X                   continue;
  524. X               case 'k':     /* LOG_FORMAT: */
  525. X                   cp = add_string(cp, "'");
  526. X                   cp = add_string(cp, newsgrp->logformat);
  527. X                   cp = add_string(cp, "'");
  528. X                   continue;
  529. X               case 'l':     /* LOG: */
  530. X                   cp = add_string(cp, newsgrp->logfile);
  531. X                   continue;
  532. X               case 'm':     /* MODE: */
  533. X                   {
  534. X                     char octal_str[20];
  535. X                     (void) sprintf(octal_str,"%o",newsgrp->modes);
  536. X                     cp = add_string(cp,octal_str);
  537. X                     continue;
  538. X                   }
  539. X               case 'n':     /* $$newsgroup name */
  540. X                   cp = add_string(cp,newsgrp->ng_name);
  541. X                   continue;
  542. X               case 'o':     /* OWNER: */
  543. X                   cp = add_string(cp,itoa(newsgrp->owner));
  544. X                   continue;
  545. X               case 'p':     /* PATCHES: */
  546. X                   if (newsgrp->patch_type == PACKAGE)
  547. X                       cp = add_string(cp, "Package");
  548. X                   else
  549. X                       cp = add_string(cp, "Historical");
  550. X                   continue;
  551. X                case 'u':     /* MAIL: - users */
  552. X                   cp = add_string(cp,newsgrp->mail_list);
  553. X                   continue;
  554. X#ifdef NNTP
  555. X               case 'N':     /* NNTP */
  556. X                   /* print out according to precedence. */
  557. X                   if (*newsgrp->nntp)
  558. X                       cp = add_string(cp,newsgrp->nntp);
  559. X                   else if (*nntp)
  560. X                       cp = add_string(cp,nntp);
  561. X                   continue;
  562. X#endif /* NNTP */
  563. X               default:
  564. X                  (void) fprintf(errfp, "invalid format - %c\n", *--aptr);
  565. X                  exit(2);
  566. X           }
  567. X        }
  568. X#endif /* RKIVE */
  569. X
  570. X        *cp++ = c;
  571. X     }  /* end while */
  572. X     return(format);
  573. X}
  574. END_OF_FILE
  575. if test 15279 -ne `wc -c <'rkive/format.c'`; then
  576.     echo shar: \"'rkive/format.c'\" unpacked with wrong size!
  577. fi
  578. # end of 'rkive/format.c'
  579. fi
  580. if test -f 'rkive/match.y' -a "${1}" != "-c" ; then 
  581.   echo shar: Will not clobber existing file \"'rkive/match.y'\"
  582. else
  583. echo shar: Extracting \"'rkive/match.y'\" \(9346 characters\)
  584. sed "s/^X//" >'rkive/match.y' <<'END_OF_FILE'
  585. X%{
  586. X
  587. X/*
  588. X** Copyright Heikki Suonsivu 1989
  589. X**
  590. X** Kent, you owe me a beer, if you use it and meet me some day. No other
  591. X** limitations. You can use, sell, put your name in it, print it out and
  592. X** eat the printout, or use it any other way. I take no responsibility
  593. X** for the consequences.
  594. X**
  595. X** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
  596. X**
  597. X** Permission is hereby granted to copy, distribute or otherwise 
  598. X** use any part of this package as long as you do not try to make 
  599. X** money from it or pretend that you wrote it.  This copyright 
  600. X** notice must be maintained in any copy made.
  601. X**
  602. X*/
  603. X#if !defined(lint) && !defined(SABER)
  604. Xstatic char SID[] = "@(#)match.y    2.2 2/23/91";
  605. X#endif
  606. X
  607. X#define YYDEBUG 1
  608. X#include <stdio.h>
  609. X#include <sys/types.h>
  610. X#include <ctype.h>
  611. X#include "rkive.h"
  612. X#include "article.h"
  613. X
  614. Xextern FILE *logfp;
  615. Xextern FILE *errfp;
  616. Xextern int yydebug;
  617. Xint parser_return_value;
  618. X
  619. X%}
  620. X
  621. X%union {
  622. X  int integer;
  623. X  char *string;
  624. X  char *header;    /* Must be different for parser, no "" around header names */
  625. X}
  626. X
  627. X%token <string> STRING
  628. X%token <header> HEADER
  629. X%left OR AND
  630. X%left NOT
  631. X%left INCLUDES GLOB_MATCHES
  632. X%type <integer> exp
  633. X  
  634. X/* Tries to understand some expressions. */
  635. X%%
  636. X
  637. Xexpression:    /* Empty */    { return 1; } /* Empty always matches */
  638. X|    exp    { parser_return_value = $1; }
  639. X  
  640. Xexp:    exp OR exp    { $$ = $1 || $3; }
  641. X|    exp AND exp    { $$ = $1 && $3; }
  642. X|    NOT exp    { $$ = ! $2; }
  643. X|    '(' exp ')'    { $$ = $2; }
  644. X|    HEADER INCLUDES STRING    { $<integer>$ = substr($1, $3); }
  645. X|    STRING INCLUDES HEADER    { $<integer>$ = substr($1, $3); }
  646. X|    HEADER GLOB_MATCHES STRING { $<integer>$ = match_str($1, $3); }
  647. X%%
  648. X
  649. Xtypedef struct {
  650. X  char *keyword;
  651. X  int key;
  652. X} KEYWORD;
  653. X
  654. XKEYWORD keys[] = {
  655. X  "and", AND,
  656. X  "or", OR,
  657. X  "includes", INCLUDES,
  658. X  "glob-matches", GLOB_MATCHES,
  659. X  "not", NOT,
  660. X  NULL, 0
  661. X  };
  662. X
  663. XKEYWORD headers[] = {
  664. X  "from", FROM,
  665. X  "path", PATH,
  666. X  "newsgroup", NEWSGROUP,
  667. X  "subject", SUBJECT,
  668. X  "message-id", MSG_ID,
  669. X  "reply-to", REPLY_TO,
  670. X  "references", REFERENCES,
  671. X  "date", DATE,
  672. X  "expire", EXPIRE,
  673. X  "control", CONTROL,
  674. X  "sender", SENDER,
  675. X  "followup-to", FOLLOWUP_TO,
  676. X  "distribution", DISTRIBUTION,
  677. X  "organization", ORGANIZATION,
  678. X  "numlines", NUMLINES,
  679. X  "keywords", KEYWORDS,
  680. X  "summary", SUMMARY,
  681. X  "approved", APPROVED,
  682. X  "supersedes", SUPERSEDES,
  683. X  "xref", XREF,
  684. X  "posting-number", POSTING_NUMBER,
  685. X  "submitted-by", SUBMITTED_BY,
  686. X  "archive-name", ARCH_NAME,
  687. X  "articleid", ARTICLEID,
  688. X  "patch-to", PATCH_TO,
  689. X  "environment", ENVIRONMENT,
  690. X  NULL, 0
  691. X  };
  692. X
  693. X/* Global, copy matching-expression here, then call yyparse */
  694. X
  695. Xchar inputstring[MAXMATCHLEN];
  696. X
  697. X/* Parser for expression */
  698. X
  699. Xyylex()
  700. X{
  701. X  static char input_buffer[MAXMATCHLEN];
  702. X  static char string_buffer[MAXMATCHLEN];
  703. X  static char *p;
  704. X  register char *s, *string;
  705. X  register KEYWORD *keyword;
  706. X  
  707. X  if (*inputstring) {
  708. X      if (strlen(inputstring) >= MAXMATCHLEN) {
  709. X          (void) fprintf(logfp, "Match string too long, max %d characters",
  710. X               MAXMATCHLEN);
  711. X          exit (1);
  712. X      }
  713. X      
  714. X      (void) strcpy(input_buffer, inputstring);
  715. X      p = input_buffer;
  716. X      *inputstring = 0;    /* We got it */
  717. X  }
  718. X
  719. X  /* Skip whitespace separating tokens */
  720. X  
  721. X  while (*p && isspace(*p)) p++;
  722. X  
  723. X  if (!*p) {
  724. X      if (yydebug) 
  725. X          (void) fprintf(logfp, "yylex: return eof\n");
  726. X      return 0; /* Eof */
  727. X  }
  728. X
  729. X  if (*p == '"') {
  730. X      string = string_buffer;
  731. X      
  732. X      /* Collect the string, try to be intelligent with escaped '"'.
  733. X      ** Trailing " is not needed. 
  734. X      */
  735. X      
  736. X      for (p++; *p && *p != '"'; p++) {
  737. X    if (*p == '\\') {
  738. X        *string++ = *p++;
  739. X        if (*p) *string++ = *p; /* Skip the next char, whatever it is */
  740. X    }
  741. X    else
  742. X      *string++ = *p;
  743. X      }
  744. X
  745. X      p++; /* Disgard trailing '"' */
  746. X      
  747. X      *string = 0;
  748. X
  749. X      yylval.string = string_buffer;
  750. X      if (yydebug) 
  751. X         (void) fprintf(logfp, "yylex: return string <%s>\n", string_buffer);
  752. X      return STRING;
  753. X  }
  754. X  else if (isalpha(*p)) {
  755. X      string = string_buffer;
  756. X
  757. X      /* Collect keyword/header */
  758. X
  759. X      for (; *p && (isalpha(*p) || !isspace(*p)); p++)
  760. X    *string++ = isupper(*p) ? tolower(*p) : *p;
  761. X      
  762. X      *string = 0;
  763. X      
  764. X      /* Any of the operands? */
  765. X  
  766. X      for (keyword = keys; keyword->keyword; keyword++) {
  767. X    if (!strcmp(keyword->keyword, string_buffer)) {
  768. X        if (yydebug)
  769. X                (void) fprintf(logfp, "yylex: return keyword %d (%s)\n",
  770. X                 keyword->key, keyword->keyword);
  771. X        return keyword->key;
  772. X    }
  773. X      }
  774. X      
  775. X      /* A header? */
  776. X      
  777. X      for (keyword = headers; keyword->keyword; keyword++)
  778. X    if (!strcmp(keyword->keyword, string_buffer)) {
  779. X        yylval.header = header.header[keyword->key];
  780. X        if (yydebug) 
  781. X                (void) fprintf(logfp, "yylex: return header %s <%s>\n",
  782. X                 keyword->keyword, yylval.header);
  783. X        return HEADER;
  784. X    }
  785. X
  786. X      /* Nope, maybe its a string without "". Note, it converts
  787. X     the string to lower-case. */
  788. X
  789. X      yylval.string = string_buffer;
  790. X      if (yydebug) 
  791. X          (void) fprintf(logfp,"yylex: return unquoted string <%s>\n",string_buffer);
  792. X      return STRING;
  793. X  }
  794. X  else if (strchr("()", *p))
  795. X    return *p++;
  796. X  else {
  797. X      if (yydebug) 
  798. X          (void) fprintf(logfp, "yylex: Bad character '%c'\n", *p);
  799. X      return 0; /* Eof, could be something else, but I'm too tired now */
  800. X  }
  801. X    /* Never here... (?) */
  802. X}
  803. X      
  804. Xyyerror(s)
  805. X     char *s;
  806. X{
  807. X  (void) fprintf(errfp,"Cannot parse match pattern: %s\n",s);
  808. X  exit (1);
  809. X}
  810. X
  811. X/*
  812. X** int match_str( char *string, char *format ) {  return(0); }
  813. X**
  814. X** Search the "string" to see if it matches the format specified.
  815. X** 
  816. X** The characters `[', `]', `*', `?', `^', `-', and `\' are considered
  817. X** special metacharacters and have the following meanings...
  818. X**    `*'   matches any set of characters,
  819. X**    `?'   matches any one character,
  820. X**   [..]   matches any character specified in the brackets,
  821. X**   [^..]  matches any character that is *not* specified in the brackets.
  822. X**          The use of the brackets is suppose to work in much the same
  823. X**          manner as the shell in that you can use [a-z] notation as well.
  824. X** 
  825. X** If there is a need to match one of the special metacharacters characters
  826. X** the character must be prefixed with a backslash (`\') to negate its 
  827. X** special meaning.
  828. X** 
  829. X** This function returns 1 if there is a match and 0 otherwise.
  830. X** 
  831. X*/ 
  832. X
  833. Xint match_str(string, format)
  834. Xchar *string;
  835. Xchar *format;
  836. X{
  837. X   register char *s = string;
  838. X   register char *f = format;
  839. X   register char ch;
  840. X   register char nextch;
  841. X   register int negate;
  842. X
  843. X   while ((ch = *f++)) {
  844. X       switch (ch) {
  845. X           case '*':
  846. X                  /*
  847. X                  ** Now let's match against what is left...
  848. X                  */
  849. X     
  850. X                  while ((ch = *f++) == '?' || ch == '*') {
  851. X                     if (ch == '?' && *s++ == 0)
  852. X                        return 0;
  853. X                  }
  854. X     
  855. X                  if (ch == 0)   /* at the end of the format ? */
  856. X                     return 1;
  857. X     
  858. X                  if (ch == '\\') 
  859. X                      nextch = *f;
  860. X                  else
  861. X                      nextch = ch;
  862. X     
  863. X                  for (;;) {
  864. X                     if ((ch == '[' || *s == nextch)) {
  865. X                         if (match_str (s, f - 1))
  866. X                            return 1;
  867. X                     }
  868. X                     if (*s++ == 0)
  869. X                        return 0;
  870. X                  }
  871. X     
  872. X           case '?':
  873. X              if (!*s)
  874. X                  return 0;
  875. X              else
  876. X                  ++s;
  877. X              break;
  878. X
  879. X           case '\\':
  880. X                 if (*f++ != *s++) 
  881. X                     return 0;
  882. X                 break;
  883. X     
  884. X           case '[':
  885. X                 nextch = *s++;
  886. X     
  887. X                 if (*f == '^') {
  888. X                     negate = 1;
  889. X                     f++;
  890. X                 }
  891. X                 else
  892. X                     negate = 0;
  893. X     
  894. X                 for(ch = *f++;;) {
  895. X                    register char sp = ch, rp = ch;
  896. X
  897. X                    sp = ch;
  898. X                    rp = ch;
  899. X     
  900. X                    if (ch == '\\') {
  901. X                       sp = *f++; 
  902. X                       rp = sp;
  903. X                    }
  904. X     
  905. X                    if (!ch)
  906. X                        return (0);
  907. X     
  908. X                    ch = *f++;
  909. X     
  910. X                    if (ch == '-') {
  911. X                       rp = *f++;
  912. X                       if (rp == '\\')
  913. X                          rp = *f++;
  914. X                       if (!rp)
  915. X                          return (0);
  916. X                       ch = *f++;
  917. X                    }
  918. X                    if (nextch >= sp && nextch <= rp) {
  919. X                       /*
  920. X                       ** Ignore the rest of [...] previously matched.  
  921. X                       */
  922. X                       while (ch != ']') {
  923. X                          if (!ch || !(ch = *f++)) 
  924. X                              return (0);
  925. X                          if (ch == '\\') 
  926. X                              f++;
  927. X                       }
  928. X                       if (negate) 
  929. X                           return 0;
  930. X                    }
  931. X                    if (ch == ']')
  932. X                       break;
  933. X                 }
  934. X                 if (!negate) 
  935. X                    return 0;
  936. X                 break;
  937. X              
  938. X           default:
  939. X              if (ch != *s++)
  940. X                  return 0;
  941. X              break;
  942. X       }
  943. X   }
  944. X   return(*s ? 0 : 1); 
  945. X}
  946. END_OF_FILE
  947. if test 9346 -ne `wc -c <'rkive/match.y'`; then
  948.     echo shar: \"'rkive/match.y'\" unpacked with wrong size!
  949. fi
  950. # end of 'rkive/match.y'
  951. fi
  952. if test -f 'rkive/nntpart.c' -a "${1}" != "-c" ; then 
  953.   echo shar: Will not clobber existing file \"'rkive/nntpart.c'\"
  954. else
  955. echo shar: Extracting \"'rkive/nntpart.c'\" \(8989 characters\)
  956. sed "s/^X//" >'rkive/nntpart.c' <<'END_OF_FILE'
  957. X/*
  958. X** This software is Copyright (c) 1989, 1990, 1991 by Kent Landfield.
  959. X**
  960. X** Permission is hereby granted to copy, distribute or otherwise
  961. X** use any part of this package as long as you do not try to make
  962. X** money from it or pretend that you wrote it.  This copyright
  963. X** notice must be maintained in any copy made.
  964. X**
  965. X*/
  966. X
  967. X#if !defined(lint) && !defined(SABER)
  968. Xstatic char *SID = "@(#)nntpart.c    2.1 2/21/91";
  969. X#endif
  970. X
  971. X/*LINTLIBRARY*/
  972. X#include <stdio.h>
  973. X#include <ctype.h>
  974. X#include <sys/types.h>
  975. X#include <nntp.h>
  976. X#include "cfg.h"
  977. X
  978. X#define TMPDIR "/usr/tmp"
  979. X
  980. Xchar *nntp_server;
  981. X
  982. Xint     server_init();
  983. Xvoid    put_server();
  984. Xint     get_server();
  985. Xvoid    close_server();
  986. X
  987. Xint atoi();
  988. Xint fputs();
  989. X
  990. Xextern int verbose;
  991. X
  992. X/*
  993. X *
  994. X * First digit:
  995. X *
  996. X *    1xx    Informative message
  997. X *    2xx    Command ok
  998. X *    3xx    Command ok so far, continue
  999. X *    4xx    Command was correct, but couldn't be performed
  1000. X *        for some specified reason.
  1001. X *    5xx    Command unimplemented, incorrect, or a
  1002. X *        program error has occured.
  1003. X *
  1004. X * Second digit:
  1005. X *
  1006. X *    x0x    Connection, setup, miscellaneous
  1007. X *    x1x    Newsgroup selection
  1008. X *    x2x    Article selection
  1009. X *    x3x    Distribution
  1010. X *    x4x    Posting
  1011. X */
  1012. X
  1013. Xstruct nntp_resp {
  1014. X    int     resp;
  1015. X    char    *msg;
  1016. X};
  1017. X
  1018. Xstruct nntp_resp resps[] = {
  1019. X{    INF_HELP,    "Help text on way"            },
  1020. X{    INF_DEBUG,    "Debug output"                },
  1021. X{    OK_CANPOST,    "Hello; you can post"            },
  1022. X{    OK_NOPOST,    "Hello; you can't post"            },
  1023. X{    OK_SLAVE,    "Slave status noted"            },
  1024. X{    OK_GOODBYE,    "Closing connection"            },
  1025. X{    OK_GROUP,    "Group selected"            },
  1026. X{    OK_GROUPS,    "Newsgroups follow"            },
  1027. X{    OK_ARTICLE,    "Article (head & body) follows"        },
  1028. X{    OK_HEAD,    "Head follows"                },
  1029. X{    OK_BODY,    "Body follows"                },
  1030. X{    OK_NOTEXT,    "No text sent -- stat, next, last"    },
  1031. X{    OK_NEWNEWS,    "New articles by message-id follow"    },
  1032. X{    OK_NEWGROUPS,    "New newsgroups follow"            },
  1033. X{    OK_XFERED,    "Article transferred successfully"    },
  1034. X{    OK_POSTED,    "Article posted successfully"        },
  1035. X{    CONT_XFER,    "Continue to send article"        },
  1036. X{    CONT_POST,    "Continue to post article"        },
  1037. X{    ERR_GOODBYE,    "Have to hang up for some reason"    },
  1038. X{    ERR_NOGROUP,    "No such newsgroup"            },
  1039. X{    ERR_NCING,    "Not currently in newsgroup"        },
  1040. X{    ERR_NOCRNT,    "No current article selected"        },
  1041. X{    ERR_NONEXT,    "No next article in this group"        },
  1042. X{    ERR_NOPREV,    "No previous article in this group"    },
  1043. X{    ERR_NOARTIG,    "No such article in this group"        },
  1044. X{    ERR_NOART,    "No such article at all"        },
  1045. X{    ERR_GOTIT,    "Already got that article, don't send"    },
  1046. X{    ERR_XFERFAIL,    "Transfer failed"            },
  1047. X{    ERR_XFERRJCT,    "Article rejected, don't resend"    },
  1048. X{    ERR_NOPOST,    "Posting not allowed"            },
  1049. X{    ERR_POSTFAIL,    "Posting failed"            },
  1050. X{    ERR_COMMAND,    "Command not recognized"        },
  1051. X{    ERR_CMDSYN,    "Command syntax error"            },
  1052. X{    ERR_ACCESS,    "Access to server denied"        },
  1053. X{    ERR_FAULT,    "Program fault, command not performed"    },
  1054. X{    -1,            NULL                    },
  1055. X};
  1056. X
  1057. Xchar *get_nntpstr(resp_line,number)
  1058. X    char *resp_line;
  1059. X    int *number;
  1060. X {
  1061. X    struct nntp_resp *ct;
  1062. X
  1063. X    *number = atoi(resp_line);
  1064. X
  1065. X    ct = &resps[0];
  1066. X    while ((ct->resp) != -1) {
  1067. X        if (*number == ct->resp)
  1068. X            return(ct->msg);
  1069. X        ct++;
  1070. X    }
  1071. X    return(NULL);
  1072. X}
  1073. X
  1074. Xvoid print_server_response(line)
  1075. Xchar *line;
  1076. X{
  1077. X    int rrc;
  1078. X    static char *str;
  1079. X
  1080. X        /*
  1081. X        ** Verify the first character as a valid response code.
  1082. X        */
  1083. X        if ((*line != CHAR_INF) && (*line != CHAR_OK) 
  1084. X            && (*line != CHAR_CONT) && (*line != CHAR_ERR)
  1085. X            && (*line != CHAR_FATAL))  {
  1086. X            (void) fprintf(logfp,"[%s]: Xxx : unknown response\n",line);
  1087. X            return;
  1088. X        }
  1089. X
  1090. X        /*
  1091. X        ** Verify the last two characters are 
  1092. X        ** within range of valid responses.
  1093. X        */
  1094. X        
  1095. X        if ((*(line+1) < '0') || (*(line+1) > '9')) {
  1096. X            (void) fprintf(logfp,"[%s]: xXx : unknown response\n",line);
  1097. X            return;
  1098. X        }
  1099. X        if ((*(line+2) < '0') || (*(line+2) > '9')) {
  1100. X            (void) fprintf(logfp,"[%s]: xxX : unknown response\n",line);
  1101. X            return;
  1102. X        }
  1103. X
  1104. X        if ((str = get_nntpstr(line,&rrc)) != NULL) 
  1105. X            (void) fprintf(logfp,"%d: %s\n", rrc, str);
  1106. X        else
  1107. X            (void) fprintf(logfp,"%d: unknown response\n", rrc);
  1108. X
  1109. X        /* If the response in within a range (190-199) it is not handled.. */
  1110. X        /* fix later, I am too lazy now....*/
  1111. X        return;
  1112. X}
  1113. X
  1114. X
  1115. Xint nntp_retrieve_article(filename,which_time)
  1116. Xchar *filename;
  1117. Xint which_time;
  1118. X{
  1119. X     int sscanf();
  1120. X     int fclose();
  1121. X     int chdir();
  1122. X
  1123. X     char buf[256];
  1124. X     char ser_line[512];
  1125. X     int  response;
  1126. X     int  rc;               /* response code */
  1127. X     FILE *tfp;             /* transfer file pointer */ 
  1128. X     static int n;          /* extimated number of articles */
  1129. X     static int f;          /* first article number */
  1130. X     static int l;          /* last article number */
  1131. X   
  1132. X     if (which_time == 1) {
  1133. X         if (chdir(TMPDIR) != 0) {
  1134. X             (void) fprintf(errfp,"can't cd to %s.\n",TMPDIR);
  1135. X             return(ERROR_ENCOUNTERED);
  1136. X         }
  1137. X
  1138. X         /* 
  1139. X         ** Need to establish the connection with the nntp_server.
  1140. X         */
  1141. X
  1142. X         if ((response = server_init(nntp_server)) < 0) {
  1143. X             (void) fprintf(errfp,"can't connect to %s.\n",nntp_server);
  1144. X             return(ERROR_ENCOUNTERED);
  1145. X         }
  1146. X
  1147. X         /* 
  1148. X         ** Assure that the connection succeeded...
  1149. X         */
  1150. X
  1151. X         if (response == ERR_ACCESS) {
  1152. X             (void) fprintf(errfp,
  1153. X                       "Connection permission to the %s news server denied.\n",
  1154. X                       nntp_server);
  1155. X             return(ERROR_ENCOUNTERED);
  1156. X         }
  1157. X         else if ((response != OK_NOPOST) && (response != OK_CANPOST)) {
  1158. X             (void) fprintf(errfp,
  1159. X                       "Unexpected response code from %s news server: %d\n",
  1160. X                       nntp_server, response);
  1161. X             return(ERROR_ENCOUNTERED);
  1162. X         }
  1163. X
  1164. X         /* 
  1165. X         ** Need to tell the server which newsgroup to process.
  1166. X         */
  1167. X
  1168. X         (void) sprintf(buf,"GROUP %s", newsgrp->ng_name);
  1169. X         put_server(buf);    /* tell server we want to select the group */
  1170. X
  1171. X         if (get_server(ser_line, sizeof(ser_line)) < 0) {
  1172. X             (void) fprintf(errfp,
  1173. X               "Unexpected close of %s connection\n", nntp_server);
  1174. X             return(ERROR_ENCOUNTERED);
  1175. X         }
  1176. X
  1177. X         if (*ser_line != CHAR_OK) {      /* and then see if that's ok */
  1178. X             print_server_response(ser_line);
  1179. X             return(ERROR_ENCOUNTERED);
  1180. X         }
  1181. X
  1182. X         /* 
  1183. X         ** Get the newsgroup article information from the returned buffer 
  1184. X         ** 
  1185. X         ** rc    = response code (211 or 411)
  1186. X         **  n    = estimated number of articles in group,
  1187. X         **  f    = first article number in the group,
  1188. X         **  l    = last article number in the group,
  1189. X         **  smsg = name of the group.)
  1190. X         */
  1191. X
  1192. X         (void) sscanf(ser_line,"%d%d%d%d%s",  &rc, &n, &f, &l, buf);
  1193. X         if (verbose) {
  1194. X             print_server_response(ser_line);
  1195. X              (void) fprintf(logfp,"Newsgroup\t%s\n",buf);
  1196. X              (void) fprintf(logfp,"First\t%d\tLast \t%d\n",f,l);
  1197. X              (void) fprintf(logfp,"Est. No. Articles\t%d\n",n);
  1198. X         }
  1199. X     }
  1200. X        
  1201. X     while (f <= l) {
  1202. X        /* 
  1203. X        ** Store the article number as the file name for the
  1204. X        ** temporary file transfer. This is mainly to support
  1205. X        ** the Article-Number form of archiving.
  1206. X        */
  1207. X        (void) sprintf(filename,"%d",f);
  1208. X
  1209. X        /* 
  1210. X        ** Build the nntp command string 
  1211. X        ** designating which article to transfer.
  1212. X        */
  1213. X        (void) sprintf(buf,"ARTICLE %ld", f);
  1214. X        put_server(buf);    /* tell server we want the article */
  1215. X        (void) get_server(ser_line, sizeof(ser_line));
  1216. X        if (verbose)
  1217. X        (void) fprintf(logfp,"Retrieving <%d> from %s\n",f, nntp_server);
  1218. X        ++f;
  1219. X        if (*ser_line != CHAR_OK) {      /* and then see if that's ok */
  1220. X            if ((rc = atoi(ser_line)) != ERR_NOART && rc != ERR_NOARTIG) {
  1221. X               if (verbose)
  1222. X                  print_server_response(ser_line);
  1223. X            }
  1224. X            continue;
  1225. X        }
  1226. X
  1227. X        /* 
  1228. X        ** Here we have a valid article. Create a temporary file
  1229. X        ** to transfer the article from the nntp server to the
  1230. X        ** local system into.
  1231. X        */
  1232. X        if ((tfp = fopen(filename, "w+")) == NULL)
  1233. X             return(ERROR_ENCOUNTERED);
  1234. X
  1235. X        /* 
  1236. X        ** Read a line from the server and write it out to
  1237. X        ** the file to be used for archiving. This file is
  1238. X        ** removed when it is no longer needed.
  1239. X        */
  1240. X        while (get_server(ser_line, sizeof(ser_line)) >= 0) {  /* while */
  1241. X            if (ser_line[0] == '.' && ser_line[1] == '\0')  /* valid input */
  1242. X                break;                          /* get it and write it  */
  1243. X            (void) fputs(ser_line, tfp);        /* to standard output.  */
  1244. X            (void) fputs("\n", tfp);
  1245. X        }
  1246. X        (void) fclose(tfp);
  1247. X        return(RETRIEVED);
  1248. X     }
  1249. X     close_server();
  1250. X     return(DONE);
  1251. X}
  1252. END_OF_FILE
  1253. if test 8989 -ne `wc -c <'rkive/nntpart.c'`; then
  1254.     echo shar: \"'rkive/nntpart.c'\" unpacked with wrong size!
  1255. fi
  1256. # end of 'rkive/nntpart.c'
  1257. fi
  1258. if test -f 'rkive/rkive.5' -a "${1}" != "-c" ; then 
  1259.   echo shar: Will not clobber existing file \"'rkive/rkive.5'\"
  1260. else
  1261. echo shar: Extracting \"'rkive/rkive.5'\" \(15730 characters\)
  1262. sed "s/^X//" >'rkive/rkive.5' <<'END_OF_FILE'
  1263. X'br "@(#)rkive.5    2.3 2/24/91"
  1264. X.TH RKIVE 5
  1265. X.SH NAME
  1266. Xrkive.cf \- USENET Source Archiver Configuration File.
  1267. X.SH DESCRIPTION
  1268. X.I rkive.cf
  1269. Xallows the administrator to configure the way in which USENET sources
  1270. Xare archived.
  1271. X.PP
  1272. XThe configuration file is used to indicate where the archives are
  1273. Xto be located, who will own the archive members, etc. The configuration 
  1274. Xfile is divided into two sections, a global section and the individual 
  1275. Xnewsgroup specifications.
  1276. X.PP
  1277. XThe syntax of the individual line types are as follows:
  1278. X.RS
  1279. X.IP "Global Variable Line"
  1280. XVariable = value
  1281. X.IP "Newsgroup Identifier"
  1282. X$$comp.source.whatever
  1283. X.IP "Newsgroup Variable Line"
  1284. XVariable : value
  1285. X.RE
  1286. X.LP
  1287. XNote that the '=' is used to designate a global variable and
  1288. Xthat the ':' is used to determine a newsgroup variable.
  1289. X.PP
  1290. XThe global variables are divided up into variables that pertain to
  1291. Xall archiving as well as defaults to be used in the event that the
  1292. Xarchive administrator has not set a specific value for a "defaultable"
  1293. Xvariable.
  1294. X.PP
  1295. X.SH "GLOBAL VARIABLES"
  1296. X.PP
  1297. X.IP "SPOOLDIR =" 15
  1298. XThis is the base directory for the news subsystem.
  1299. X.IP "PROBLEMS ="
  1300. XThe name of the base directory used to store any duplicate or "problem"
  1301. Xarticles that rkive(1) cannot deal with. All articles are stored under 
  1302. Xthis directory in a newsgroup / volume directory structure.
  1303. X.IP "LOG ="
  1304. XThe location of the master log in which actions are logged. 
  1305. XIf this variable is not set, no global logging takes place.
  1306. X.IP "LOG_FORMAT ="
  1307. XThe format of the records of the master log file.  This variable only
  1308. Xpertains to the global log file format. The actual format specification
  1309. Xmust be enclosed in "". See article(1) for a discussion of the available 
  1310. Xselection format capabilities.
  1311. X.IP "INDEX =" 
  1312. XThe location of the master index file (if one is to be kept).  The index 
  1313. Xcan be used to interface with the netlib source retrieval software facility.
  1314. X.IP "INDEX_FORMAT ="
  1315. XThe format of the records of the master index file. The actual format
  1316. Xspecification must be enclosed in "".   See article(1) for a
  1317. Xdiscussion of the available selection format capabilities.
  1318. X.IP "MAIL ="
  1319. XIf specified, logged actions are mailed to the users listed. 
  1320. XThe user names are a comma separated list. It is not necessary to
  1321. Xspecify any users. 
  1322. X.PP
  1323. XThe following values are used if the administrator has not
  1324. Xset a value for a corresponding newsgroup configuration item.
  1325. X.IP "TYPE =" 15
  1326. XThis is the default archive type.  There are 7 possible ways
  1327. Xin which to archive USENET sources,
  1328. X.PP
  1329. X                  Volume-Issue, 
  1330. X                  Archive-Name, 
  1331. X                  Chronological, 
  1332. X                  Article Number,
  1333. X                  Comp-Archives,
  1334. X                  External-Command or
  1335. X                  Only-Archive-Name.
  1336. X
  1337. X.IP
  1338. XThese are used to determine if you wish the articles archived in a 
  1339. X.PP
  1340. X           /basedir/amiga/Volume1/v001i22 or
  1341. X           /basedir/amiga/Volume1/sitonit or
  1342. X           /basedir/amiga/Volume89/Jun/890628.01 or
  1343. X           /basedir/amiga/Volume1/44 format.
  1344. X.IP
  1345. XComp-Archives is used only for the comp.archives newsgroup or newsgroups 
  1346. Xthat supply Archive-name: but do not supply a volume number. External-Command 
  1347. Xis used if you want to have an external program/script deal with the article. 
  1348. XThe External-Command type must be accompanied with an ARCHIVE_CMD entry with 
  1349. Xspecifies the external program for rkive to use.
  1350. X.LP
  1351. X.IP "PATCHES =" 15
  1352. XThis variable determines the way in which patches are installed into 
  1353. Xthe archive. If the PATCHES entry is not defined either globally or within
  1354. Xthe newsgroup, the article is handled as a regular article and is stored 
  1355. Xaccording to the specified parameters of the newsgroup. The following are
  1356. Xthe valid possible values for the PATCHES variable:
  1357. X.RS
  1358. X.IP "PATCHES=Historical" 6 
  1359. XThis is the same as if no PATCHES entry existed at all. It is useful 
  1360. Xif Historical patches archiving is the default but there are certain 
  1361. Xnewsgroups that have it specified differently.
  1362. X.IP "PATCHES=Package"
  1363. XPackage patches archiving allows the inbound patch to be placed with 
  1364. Xthe directory with the initially posted articles. In this manner
  1365. Xall parts and fixes of a package are together making it easier for 
  1366. Xsoftware retrieval by uucp requests and mail request facilities
  1367. Xsuch as netlib.
  1368. X.RE
  1369. X.IP "OWNER ="
  1370. XThe owner of the archive files after they are stored in the archive.
  1371. X.IP "GROUP ="
  1372. XThe group ownership of the archive files after they are stored in the archive.
  1373. X.IP "MODE ="
  1374. XThe default modes of the files residing in the archive.
  1375. X.IP "COMPRESS =" 
  1376. XThe location of the compression utility if the files are to be reduced.
  1377. XIf this variable is specified, it must contain the full path to the command
  1378. Xused to perform the compression.
  1379. X.IP "CHECKHASH =" 
  1380. XThe location of the checkhash utility if the files are to be tested for
  1381. Xtransit damage.  Currently, only comp.sources.unix and comp.sources.misc
  1382. Xsupports this test with the X-Checksum-Snerfu: header.  If this variable 
  1383. Xis specified, it must contain the full path to the command used to perform 
  1384. Xthe test.
  1385. X.IP "NNTP =" 
  1386. XThe location of the NNTP server where the articles are to be archived from. 
  1387. XThis can be specified globally if all or most newsgroups are archived
  1388. Xfrom a single NNTP server. 
  1389. X.IP "ARCHIVE_CMD =" 
  1390. XThis is the path to an external command to pass all articles to that are 
  1391. Xin need of archiving.  This is used when with the archive specification
  1392. XTYPE=External-Command.  This command line may be augmented with variables 
  1393. Xspecified in the rkive.cf file. See article.1 for a description of the 
  1394. Xformat specification characters available.
  1395. X.IP "MATCH =" 
  1396. Xrkive allows you to use globbing to determine if an article is to be 
  1397. Xarchived or not. This is the specification by which articles must match 
  1398. Xto be archived. The match specification may span multiple lines. A \ at 
  1399. Xthe end of a line is used to indicate that the specification is continued on 
  1400. Xanother line. 
  1401. X.PP
  1402. XThe following is a sample global variable section.
  1403. X.PP
  1404. XSPOOLDIR=/usr/spool/news      
  1405. X.br
  1406. XPROBLEMS=/usenet/problems
  1407. X.br
  1408. XLOG=/usenet/archive.log
  1409. X.br
  1410. XLOG_FORMAT= "%O %T %l" 
  1411. X.br
  1412. XINDEX= /usenet/index
  1413. X.br
  1414. XINDEX_FORMAT= "%a %T" 
  1415. X.br
  1416. XMAIL=kent,rick,chris
  1417. X.br
  1418. XTYPE= Archive-Name
  1419. X.br
  1420. XPATCHES= Package
  1421. X.br
  1422. XOWNER=src
  1423. X.br
  1424. XGROUP=archive
  1425. X.br
  1426. XMODE=0444
  1427. X.br
  1428. X#COMPRESS=/usr/local/bin/compress
  1429. X.br
  1430. X#CHECKHASH=/usr/local/bin/checkhash -s
  1431. X.br
  1432. X.PP
  1433. XIn the above sample, if any of the individual newsgroups had not
  1434. Xhad the type of the archive specified, the type would have defaulted
  1435. Xto an Archive-Name (if the newsgroup had the auxiliary headers required
  1436. Xto support Archive-Name). By default, no compression was to be done. All
  1437. Xresults would have been mailed to the accounts of kent, rick and chris.
  1438. XIf a newsgroup had not specified the ownership and modes of the destination
  1439. Xarchive members, the values specified in the global OWNER, GROUP, and MODE
  1440. Xwould have been used.
  1441. X.LP
  1442. X.SH "NEWSGROUP SPECIFICATIONS"
  1443. X.PP
  1444. X.PP
  1445. XAn individual newsgroup entry is identified by a $$ as the first two
  1446. Xcharacters of the line. The name of the newsgroup (in newsgroup format)
  1447. Xfollows such as
  1448. X.IP
  1449. X$$comp.sources.unix        
  1450. X.LP
  1451. X.IP "BASEDIR :" 15
  1452. XThis is the base directory for the archive.
  1453. X.IP "LOG :"
  1454. XThe location of the log file in which actions are logged. 
  1455. XIf this variable is not set, no logging takes place.
  1456. X.IP "LOG_FORMAT :"
  1457. XThe format of the records of the log file.  The actual format
  1458. Xspecification must be enclosed in "".  See article(1) for a 
  1459. Xdiscussion of the available selection format capabilities.
  1460. X.IP "INDEX :" 
  1461. XThe location of the index file (if one is to be kept).  The index can be 
  1462. Xused to interface with the netlib source retrieval software facility.
  1463. X.IP "INDEX_FORMAT :"
  1464. XThe format of the records of the index file.  The actual format
  1465. Xspecification must be enclosed in "".  See article(1) for a
  1466. Xdiscussion of the available selection format capabilities.
  1467. X.IP "MAIL :"
  1468. XIf specified, logged actions are mailed to the list of users specified. 
  1469. XThe user names are a comma separated list. It is not necessary to
  1470. Xspecify any users. 
  1471. X.IP "TYPE :" 
  1472. XThis is the archive type.  There are 7 possible ways
  1473. Xin which to archive USENET sources,
  1474. X.PP
  1475. X                  Volume-Issue, 
  1476. X                  Archive-Name, 
  1477. X                  Chronological, 
  1478. X                  Article Number,
  1479. X                  Comp-Archives,
  1480. X                  External-Command or
  1481. X                  Only-Archive-Name.
  1482. X.IP
  1483. XComp-Archives is used only for the comp.archives newsgroup or newsgroups 
  1484. Xthat supply Archive-name: but do not supply a volume number. External-Command 
  1485. Xis used if you want to have an external program/script deal with the article. 
  1486. XThe External-Command type must be accompanied with an ARCHIVE_CMD entry with 
  1487. Xspecifies the external program for rkive to use. Only-Archive-Name is used
  1488. Xwhen the only articles that should be archived are articles that contain
  1489. XArchive-name: lines.  The difference between Comp-Archives and 
  1490. XOnly-Archive-Name is that Comp-Archives expects all articles in the newsgroup
  1491. Xhave valid Archive-name: header lines and those that do not generate an error 
  1492. Xcondition.  Only-Archive-Name usage expects that only a few articles in the 
  1493. Xnewsgroup have Archive-name: headers lines and silently ignores those that
  1494. Xdo not have the header line.
  1495. X.IP "PATCHES :"
  1496. XThis variable determines the way in which patches are installed into 
  1497. Xthe newsgroup's archive. If the PATCHES entry is not defined either 
  1498. Xglobally or within the newsgroup, the article is handled as a regular 
  1499. Xarticle and is stored according to the specified parameters of the 
  1500. Xnewsgroup. The following are the valid possible values for the 
  1501. XPATCHES variable:
  1502. X.RS
  1503. X.IP "PATCHES: Historical" 6 
  1504. XThis is the same as if no PATCHES entry existed at all. It is useful 
  1505. Xif Historical patches archiving is the default but there are certain 
  1506. Xnewsgroups that have it specified differently.
  1507. X.IP "PATCHES: Package"
  1508. XPackage patches archiving allows the inbound patch to be placed with 
  1509. Xthe directory with the initially posted articles. In this manner
  1510. Xall parts and fixes of a package are together making it easier for 
  1511. Xsoftware retrieval by uucp requests and mail request facilities
  1512. Xsuch as netlib.
  1513. X.RE
  1514. X.IP "OWNER :"
  1515. XThe the owner of the files after they are stored in the archive 
  1516. Xdirectory for the newsgroup.
  1517. X.IP "GROUP :"
  1518. XThe group ownership of the archive files after they are stored in the 
  1519. Xarchive directory for the newsgroup.
  1520. X.IP "MODE :"
  1521. XThe default modes of the files residing in the archive directory.
  1522. X.IP "COMPRESS :" 
  1523. XThe location of the compression utility if the files are to be reduced.
  1524. XIf this variable is specified, it must contain the full path to the command
  1525. Xused to perform the compression.
  1526. X.IP "CHECKHASH :" 
  1527. XThe location of the checkhash utility if the files are to be tested for
  1528. Xtransit damage.  Currently, only comp.sources.unix supports this test with
  1529. Xthe X-Checksum-Snerfu: header.  If this variable is specified, it must contain
  1530. Xthe full path to the command used to perform the test.
  1531. X.IP "NNTP :" 
  1532. XThe location of the NNTP server where the articles are to be archived from. 
  1533. XThis can be specified globally if all or most newsgroups are archived
  1534. Xfrom a single NNTP server, or on a by newsgroup basis.  If NNTP is specified 
  1535. Xglobally and you wish to archive a newsgroup from your local system, add the 
  1536. Xfollowing entry to the newsgroup specifications. 
  1537. X.RS
  1538. X.IP "NNTP: local"
  1539. X.RE
  1540. X.IP
  1541. XThis tells rkive to negate the global value. Case does not matter in the 
  1542. Xspecification of local.
  1543. X.IP "ARCHIVED_LOG :"
  1544. Xrkive requires that it be able to determine if an article has been previously 
  1545. Xarchived. By default, rkive uses a file named .archived ($BASEDIR/.archived) 
  1546. Xwhich stores the message-id of the previously archived articles. If it is
  1547. Xinconvient to store the .archived file in the base directory of the archive, 
  1548. Xa alternate path/location can be specified by the use of ARCHIVED_LOG.
  1549. X.IP "PATCHLOG :"
  1550. Xrkive writes an entry to a file called .patchlog when it it encounters a 
  1551. XPatch-To: line.  By default, rkive uses a file named .patchlog 
  1552. X($BASEDIR/.patchlog). If it is inconvient to store the .patchlog file in the 
  1553. Xbase directory of the archive, a alternate path/location can be specified
  1554. Xby the use of PATHLOG.
  1555. X.IP "ARCHIVE_CMD :" 
  1556. XThis is the path to an external command to pass all articles to that are 
  1557. Xin need of archiving.  This is used when with the archive specification
  1558. XTYPE=External-Command.  This command line may be augmented with variables 
  1559. Xspecified in the rkive.cf file. The additional format specification characters 
  1560. Xthat can be used to build a command line with the information that is configured
  1561. Xin the rkive.cf file.  The specification character '$' is used to indicate that
  1562. Xthere is a variable that needs to be filled in.  After the $, a character 
  1563. Xfollows that indicates the type of information that is to supplied.
  1564. XThe indicator characters and their meanings are:
  1565. X.IP
  1566. X
  1567. XGlobal rkive.cf indicator characters:
  1568. X.br
  1569. X   
  1570. XE - PROBLEMS - Path to the problems directory.
  1571. X.br
  1572. XI - INDEX    - Location of the master index.
  1573. X.br
  1574. XJ - INDEX_FORMAT - Format of the master index records.
  1575. X.br
  1576. XK - LOG_FORMAT - Format of the master log file records.
  1577. X.br
  1578. XL - LOG - Disk location of the master log file.
  1579. X.br
  1580. XS - SPOOLDIR - Base location of the news subsystem.
  1581. X.br
  1582. XU - MAIL - List of users to mail messages to.
  1583. X.br
  1584. X                  
  1585. XNewgroup specific indicator characters:
  1586. X.br
  1587. X                  
  1588. Xa - ARCHIVED_LOG - Newsgroup's .archived file path
  1589. X.br
  1590. XB - BASEDIR - Base directory of the archive.
  1591. X.br
  1592. Xc - COMPRESS - Path to compression program to be used.
  1593. X.br
  1594. Xg - GROUP - Group id specified.
  1595. X.br
  1596. Xh - CHECKHASH - Path to the checkhash utility.
  1597. X.br
  1598. Xi - INDEX - Location of the newsgroup index.
  1599. X.br
  1600. Xj - INDEX_FORMAT - Format of newsgroup index records.
  1601. X.br
  1602. Xk - LOG_FORMAT - Format of newsgroup log file records.
  1603. X.br
  1604. Xl - LOG - Disk location of the newsgroup log file.
  1605. X.br
  1606. Xm - MODE - Modes of the archived files.
  1607. X.br
  1608. Xo - OWNER - Owner of the archived files.
  1609. X.br
  1610. Xp - PATCHES - Type of patches archiving to be done.
  1611. X.br
  1612. Xu - MAIL - List of newsgroup users to mail messages to.
  1613. X.br
  1614. XN - NNTP - NNTP Server Host for the newsgroup.
  1615. X.br
  1616. X   
  1617. XGeneral indicator characters:
  1618. X.br
  1619. X   
  1620. Xb - Newsgroup's spool directory path.
  1621. X.br
  1622. Xn - Newsgroup name.
  1623. X.br
  1624. XP - Actual disk path to the file to be archived.
  1625. X.br
  1626. X.IP "MATCH :" 
  1627. Xrkive allows you to use globbing to determine if an article is to be 
  1628. Xarchived or not. This is the specification by which articles must match 
  1629. Xto be archived. The match specification may span multiple lines. A \ at 
  1630. Xthe end of a line is used to indicate that the specification is continued on 
  1631. Xanother line. 
  1632. X.PP
  1633. XA sample entry for comp.sources.unix might look like:
  1634. X.PP
  1635. X$$comp.sources.unix        
  1636. X.br
  1637. X    BASEDIR: /usenet/unix 
  1638. X.br
  1639. X    TYPE: Volume-Issue
  1640. X.br
  1641. X    PATCHES: Historical
  1642. X.br
  1643. X    OWNER: kent
  1644. X.br
  1645. X    GROUP: support
  1646. X.br
  1647. X    MODE: 0664
  1648. X.br
  1649. X    INDEX: /usenet/unix/index
  1650. X.br
  1651. X    INDEX_FORMAT: "%O %a %S" 
  1652. X.br
  1653. X    COMPRESS: /usr/local/bin/compress
  1654. X.br
  1655. X    CHECKHASH: /usr/local/bin/checkhash -s
  1656. X.br
  1657. X    MAIL: kent,bob,sally
  1658. X.br
  1659. X.PP
  1660. XIn the above sample, comp.sources.unix would be archived in /usenet/unix.
  1661. XThe individual volume directories would be created there. All files would
  1662. Xbe owned by kent and the group support. The files would be writable by the
  1663. Xgroup as well as the owner. (Not a smart idea but just for examples sake.)
  1664. XLogging is not being done although an index entry is being generated for
  1665. Xeach article archived. All files stored in the archive for this newsgroup
  1666. Xare to be compressed using the compress program in /usr/local/bin. Mail is
  1667. Xsent to kent, bob and sally when the archiving of comp.sources.unix has been
  1668. Xcompleted. All files are tested with the checkhash command for validity
  1669. Xbefore archiving.
  1670. X.SH "SEE ALSO"
  1671. Xrkive(1), article(1), ckconfig(1), checkhash(1), snefru(1)
  1672. X.LP
  1673. END_OF_FILE
  1674. if test 15730 -ne `wc -c <'rkive/rkive.5'`; then
  1675.     echo shar: \"'rkive/rkive.5'\" unpacked with wrong size!
  1676. fi
  1677. # end of 'rkive/rkive.5'
  1678. fi
  1679. echo shar: End of archive 4 \(of 6\).
  1680. cp /dev/null ark4isdone
  1681. MISSING=""
  1682. for I in 1 2 3 4 5 6 ; do
  1683.     if test ! -f ark${I}isdone ; then
  1684.     MISSING="${MISSING} ${I}"
  1685.     fi
  1686. done
  1687. if test "${MISSING}" = "" ; then
  1688.     echo You have unpacked all 6 archives.
  1689.     rm -f ark[1-9]isdone
  1690. else
  1691.     echo You still need to unpack the following archives:
  1692.     echo "        " ${MISSING}
  1693. fi
  1694. ##  End of shell archive.
  1695. exit 0
  1696. exit 0 # Just in case...
  1697. -- 
  1698. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1699. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1700. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1701. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1702.