home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / 2.11news / patch05 < prev    next >
Text File  |  1987-03-10  |  45KB  |  1,709 lines

  1. Path: mirror!adelie!necntc!husc6!seismo!rick
  2. From: rick@seismo.CSS.GOV (Rick Adams)
  3. Newsgroups: news.software.b
  4. Subject: patch #5 for 2.11 news src
  5. Message-ID: <43143@beno.seismo.CSS.GOV>
  6. Date: 10 Mar 87 20:58:51 GMT
  7. Sender: rick@seismo.CSS.GOV
  8. Organization: Center for Seismic Studies, Arlington, VA
  9. Lines: 1698
  10.  
  11. Description:
  12.     This is patch #5 for news 2.11 source. It addresses the following
  13.     problems:
  14.  
  15.     The locking seems to work completely now. Various obscure
  16.     interactions have all been fixed.
  17.     Mail sent to moderators no longer contains the suggested news header.
  18.     If HIDDENNET is defined, you can now use your local hostname instead
  19.     of the HIDDENNET name in the sys file.
  20.     The senduuname control message has been removed. It wasn't used
  21.     anymore and many people felt it was a security hole.
  22.     ihave/sendme now works with multicasting.
  23.     expire -R will just rebuild the dbm history files without actually
  24.     expiring anything.
  25.     If LIBDIR/localdomain is present, it is used instead of MYDOMAIN.
  26.     "unbatch" has been moved into rnews to avoid execing a separate process.
  27.     Processing batches of news is much faster (but still not fast). This
  28.     is done by recognizing that the parent process IS rnews (since
  29.     the unbatcher was moved into it), so it only need fork and not exec.
  30.  
  31. Fix:
  32.     cd to the src directory and apply the following patch
  33.  
  34. Index: patchlevel.h
  35. Prereq: 4
  36. *** .d/patchlevel.h    Tue Feb 24 17:55:57 1987
  37. --- patchlevel.h    Tue Mar 10 15:06:47 1987
  38. ***************
  39. *** 1,3 ****
  40. ! #define    PATCHLEVEL    4
  41.   
  42. ! #define NEWS_VERSION   "B 2.11 2/22/87"
  43. --- 1,3 ----
  44. ! #define    PATCHLEVEL    5
  45.   
  46. ! #define NEWS_VERSION   "B 2.11 3/10/87"
  47.  
  48. Index: inews.c
  49. Prereq: 2.74
  50. *** .d/inews.c    Tue Feb 24 17:55:56 1987
  51. --- inews.c    Tue Mar 10 15:06:14 1987
  52. ***************
  53. *** 17,27 ****
  54.    */
  55.   
  56.   #ifdef SCCSID
  57. ! static char    *SccsId = "@(#)inews.c    2.74    2/22/87";
  58.   #endif /* SCCSID */
  59.   
  60.   #include "iparams.h"
  61.   
  62.   #ifdef BSD4_2
  63.   # include <sys/dir.h>
  64.   # include <sys/file.h>
  65. --- 17,31 ----
  66.    */
  67.   
  68.   #ifdef SCCSID
  69. ! static char    *SccsId = "@(#)inews.c    2.76    3/10/87";
  70.   #endif /* SCCSID */
  71.   
  72.   #include "iparams.h"
  73.   
  74. + # ifdef LOCKF
  75. + # include <unistd.h>
  76. + # endif /* LOCKF */
  77.   #ifdef BSD4_2
  78.   # include <sys/dir.h>
  79.   # include <sys/file.h>
  80. ***************
  81. *** 30,38 ****
  82.   # ifdef USG
  83.   # include <fcntl.h>
  84.   # endif /* USG */
  85. - # ifdef LOCKF
  86. - # include <unistd.h>
  87. - # endif /* LOCKF */
  88.   #endif /* !BSD4_2 */
  89.   /* local defines for inews */
  90.   
  91. --- 34,39 ----
  92. ***************
  93. *** 86,91 ****
  94. --- 87,93 ----
  95.   };
  96.   
  97.   FILE *mailhdr();
  98. + extern char *mydomain();
  99.   extern int errno;
  100.   
  101.   struct timeb Now;
  102. ***************
  103. *** 126,138 ****
  104.       if (!ptr)
  105.           ptr = *argv - 1;
  106.       actfp = xfopen(ACTIVE, "r+");
  107. - #ifdef BSD4_2
  108. -     if (flock(fileno(actfp), LOCK_SH|LOCK_NB) < 0 && errno == EWOULDBLOCK)
  109. - #else    /* !BSD4_2 */
  110.   #ifdef    LOCKF
  111.       if (lockf(fileno(actfp), F_TLOCK, 0) < 0 &&
  112.           (errno == EAGAIN || errno == EACCES))
  113.   #else    /* !LOCKF */
  114.       sprintf(bfr, "%s.lock", ACTIVE);
  115.       if (LINK(ACTIVE,bfr) < 0 && errno == EEXIST)
  116.   #endif /* V7 */
  117. --- 128,140 ----
  118.       if (!ptr)
  119.           ptr = *argv - 1;
  120.       actfp = xfopen(ACTIVE, "r+");
  121.   #ifdef    LOCKF
  122.       if (lockf(fileno(actfp), F_TLOCK, 0) < 0 &&
  123.           (errno == EAGAIN || errno == EACCES))
  124.   #else    /* !LOCKF */
  125. + #ifdef BSD4_2
  126. +     if (flock(fileno(actfp), LOCK_SH|LOCK_NB) < 0 && errno == EWOULDBLOCK)
  127. + #else    /* !BSD4_2 */
  128.       sprintf(bfr, "%s.lock", ACTIVE);
  129.       if (LINK(ACTIVE,bfr) < 0 && errno == EEXIST)
  130.   #endif /* V7 */
  131. ***************
  132. *** 148,162 ****
  133.   
  134.   #endif /* SPOOLNEWS */
  135.       }
  136. ! #ifdef BSD4_2
  137. !     flock(fileno(actfp), LOCK_UN);
  138. ! #else    /* !BSD4_2 */
  139.   #ifdef    LOCKF
  140. !     lockf(fileno(actfp), F_ULOCK, 0);
  141.   #else    /* !LOCKF */
  142. !     UNLINK(bfr);
  143. ! #endif /* V7 */
  144.   #endif    /* !BSD4_2 */
  145.       if (argc > 1 && !strcmp(*(argv+1), "-U")) {
  146.           if (spool_news > 1) /* can't unspool while things are locked */
  147.               xxit(0);
  148. --- 150,170 ----
  149.   
  150.   #endif /* SPOOLNEWS */
  151.       }
  152. !     if (spool_news != 2) {
  153. !         /* only unlock if we locked */
  154.   #ifdef    LOCKF
  155. !         lockf(fileno(actfp), F_ULOCK, 0);
  156.   #else    /* !LOCKF */
  157. ! #ifdef     BSD4_2
  158. !         flock(fileno(actfp), LOCK_UN);
  159. ! #else    /* !BSD4_2 */
  160. !         UNLINK(bfr);
  161. ! #endif     /* V7 */
  162.   #endif    /* !BSD4_2 */
  163. +     } else {    /* expire is running */
  164. +         if (argc > 1 && !strcmp(*(argv+1), "-S"))
  165. +             exit(42);    /* inform rnews -U by exit status */
  166. +     }
  167.       if (argc > 1 && !strcmp(*(argv+1), "-U")) {
  168.           if (spool_news > 1) /* can't unspool while things are locked */
  169.               xxit(0);
  170. ***************
  171. *** 357,368 ****
  172.               }
  173.               if (!Mflag && !strpbrk(forgedname, "@ (<"))
  174.                   (void) sprintf(header.from,"%s@%s%s",
  175. !                     forgedname, FULLSYSNAME, MYDOMAIN);
  176.               else
  177.                   (void) strncpy(header.from, forgedname, BUFLEN);
  178.   
  179.               (void) sprintf(header.sender, "%s@%s%s",
  180. !                 username, FULLSYSNAME, MYDOMAIN);
  181.           } else {
  182.               gensender(&header, username);
  183.           }
  184. --- 365,376 ----
  185.               }
  186.               if (!Mflag && !strpbrk(forgedname, "@ (<"))
  187.                   (void) sprintf(header.from,"%s@%s%s",
  188. !                     forgedname, FULLSYSNAME, mydomain());
  189.               else
  190.                   (void) strncpy(header.from, forgedname, BUFLEN);
  191.   
  192.               (void) sprintf(header.sender, "%s@%s%s",
  193. !                 username, FULLSYSNAME, mydomain());
  194.           } else {
  195.               gensender(&header, username);
  196.           }
  197. ***************
  198. *** 407,413 ****
  199.           (void) signal(SIGQUIT, SIG_IGN);
  200.           header.ident[0] = '\0';
  201.           if (hread(&header, infp, TRUE) == NULL)
  202. !             error("Inbound news is garbled");
  203.           input();
  204.       }
  205.       /* always check history */
  206. --- 415,421 ----
  207.           (void) signal(SIGQUIT, SIG_IGN);
  208.           header.ident[0] = '\0';
  209.           if (hread(&header, infp, TRUE) == NULL)
  210. !             xerror("%s: Inbound news is garbled", filename);
  211.           input();
  212.       }
  213.       /* always check history */
  214. ***************
  215. *** 470,475 ****
  216. --- 478,484 ----
  217.       if (!rwaccess(f)) {
  218.           mfd = mailhdr((struct hbuf *)NULL, exists(f) ? "Unwritable files!" : "Missing files!");
  219.           if (mfd != NULL) {
  220. +             putc('\n', mfd);
  221.   #ifdef HIDDENNET
  222.               fprintf(mfd, "System: %s.%s\n\nThere was a problem with %s!!\n", LOCALSYSNAME, FULLSYSNAME, f);
  223.   #else /* !HIDDENNET */
  224. ***************
  225. *** 498,503 ****
  226. --- 507,513 ----
  227.       if (eaccess(dir, 07) != 0) {
  228.           mfd = mailhdr((struct hbuf *)NULL, exists(dir) ? "Unwritable diretories!" : "Missing directories!");
  229.           if (mfd != NULL) {
  230. +             putc('\n', mfd);
  231.   #ifdef HIDDENNET
  232.               fprintf(mfd, "System: %s.%s\n\nThere was a problem with %s!!\n", LOCALSYSNAME, FULLSYSNAME, dir);
  233.   #else /* !HIDDENNET */
  234. ***************
  235. *** 566,574 ****
  236.       register FILE *sp;
  237.       register struct tm *tp;
  238.       time_t t;
  239. !     char buf[BUFLEN];
  240.       extern struct tm *gmtime();
  241.   
  242.       (void) time(&t);
  243.       tp = gmtime(&t);
  244.       /* This file name "has to" be unique  (right?) */
  245. --- 576,596 ----
  246.       register FILE *sp;
  247.       register struct tm *tp;
  248.       time_t t;
  249. !     char buf[BUFLEN], *mktemp();
  250.       extern struct tm *gmtime();
  251.   
  252. +     sp = xfopen(mktemp(INFILE), "w");
  253. +     if (batchcmd != NULL)
  254. +         fprintf(sp, "%s\n", batchcmd);
  255. +     else
  256. +         if (not_here[0] != '\0')
  257. +             fprintf(sp, "#! inews -x %s -p\n", not_here);
  258. +     if (dolhwrite)
  259. +         lhwrite(&header, sp);
  260. +     while ((c = getc(infp)) != EOF)
  261. +         putc(c, sp);
  262. +     fclose(sp);
  263.       (void) time(&t);
  264.       tp = gmtime(&t);
  265.       /* This file name "has to" be unique  (right?) */
  266. ***************
  267. *** 585,592 ****
  268.           SPOOL,
  269.           tp->tm_year, tp->tm_mon+1, tp->tm_mday,
  270.           tp->tm_hour, tp->tm_min, getpid());
  271. !     sp = fopen(buf, "w");
  272. !     if (sp == NULL) {
  273.           char dbuf[BUFLEN];
  274.   #ifdef VMS
  275.           sprintf(dbuf, "%s/+rnews", SPOOL);
  276. --- 607,613 ----
  277.           SPOOL,
  278.           tp->tm_year, tp->tm_mon+1, tp->tm_mday,
  279.           tp->tm_hour, tp->tm_min, getpid());
  280. !     if (LINK(INFILE, buf) < 0) {
  281.           char dbuf[BUFLEN];
  282.   #ifdef VMS
  283.           sprintf(dbuf, "%s/+rnews", SPOOL);
  284. ***************
  285. *** 595,612 ****
  286.   #endif /* !VMS */
  287.           if (mkdir(dbuf, 0777&~N_UMASK) < 0)
  288.               xerror("Cannot mkdir %s: %s", dbuf, errmsg(errno));
  289. !         sp = xfopen(buf, "w");
  290.       }
  291. !     if (batchcmd != NULL)
  292. !         fprintf(sp, "%s\n", batchcmd);
  293. !     else
  294. !         if (not_here[0] != '\0')
  295. !             fprintf(sp, "#! inews -x %s -p\n", not_here);
  296. !     if (dolhwrite)
  297. !         lhwrite(&header, sp);
  298. !     while ((c = getc(infp)) != EOF)
  299. !         putc(c, sp);
  300. !     fclose(sp);
  301.       xxit(0);
  302.       /* NOTREACHED */
  303.   }
  304. --- 616,626 ----
  305.   #endif /* !VMS */
  306.           if (mkdir(dbuf, 0777&~N_UMASK) < 0)
  307.               xerror("Cannot mkdir %s: %s", dbuf, errmsg(errno));
  308. !         if (LINK(INFILE, buf) < 0) 
  309. !             xerror("Cannot link(%s,%s): %s", INFILE, buf,
  310. !                 errmsg(errno));
  311.       }
  312. !     (void) UNLINK(INFILE);
  313.       xxit(0);
  314.       /* NOTREACHED */
  315.   }
  316. ***************
  317. *** 638,644 ****
  318.   
  319.       if (header.approved[0] == '\0')
  320.           (void) sprintf(header.approved, "%s@%s%s",
  321. !                 username, FULLSYSNAME, MYDOMAIN);
  322.       (void) sprintf(bfr, "%s/inews -n %s.ctl -c newgroup %s -d %s -a \"%s\"",
  323.           LIB, header.nbuf, header.ctlmsg, header.distribution,
  324.           header.approved);
  325. --- 652,658 ----
  326.   
  327.       if (header.approved[0] == '\0')
  328.           (void) sprintf(header.approved, "%s@%s%s",
  329. !                 username, FULLSYSNAME, mydomain());
  330.       (void) sprintf(bfr, "%s/inews -n %s.ctl -c newgroup %s -d %s -a \"%s\"",
  331.           LIB, header.nbuf, header.ctlmsg, header.distribution,
  332.           header.approved);
  333. ***************
  334. *** 839,847 ****
  335.       if (is_mod[0] != '\0'     /* one of the groups is moderated */
  336.           && header.approved[0] == '\0') { /* and unapproved */
  337.           struct hbuf mhdr;
  338. !         FILE *mfd;
  339.           register char *p;
  340. !         char modadd[BUFLEN];
  341.   #ifdef DONTFOWARD
  342.           if(mode == PROC) {
  343.               logerr("Unapproved article in moderated group %s",
  344. --- 853,861 ----
  345.       if (is_mod[0] != '\0'     /* one of the groups is moderated */
  346.           && header.approved[0] == '\0') { /* and unapproved */
  347.           struct hbuf mhdr;
  348. !         FILE *mfd, *mhopen();
  349.           register char *p;
  350. !         char modadd[BUFLEN], *replyname();
  351.   #ifdef DONTFOWARD
  352.           if(mode == PROC) {
  353.               logerr("Unapproved article in moderated group %s",
  354. ***************
  355. *** 871,882 ****
  356.           while (*++p)
  357.               if (*p == '.')
  358.                   *p = '-';
  359. -         sprintf(bfr, "Submission for %s", is_mod);
  360.           sprintf(mhdr.path, modadd, is_mod);
  361. !         mfd = mailhdr(&mhdr, bfr);
  362.           if (mfd == NULL)
  363.               xerror("Can't send mail to %s", mhdr.path);
  364.           lhwrite(&header, mfd);
  365.           while ((c = getc(infp)) != EOF)
  366.               putc(c, mfd);
  367.           mclose(mfd);
  368. --- 885,897 ----
  369.           while (*++p)
  370.               if (*p == '.')
  371.                   *p = '-';
  372.           sprintf(mhdr.path, modadd, is_mod);
  373. !         mfd = mhopen(&mhdr);
  374.           if (mfd == NULL)
  375.               xerror("Can't send mail to %s", mhdr.path);
  376. +         fprintf(mfd, "To: %s\n", replyname(mhdr.path));
  377.           lhwrite(&header, mfd);
  378. +         putc('\n', mfd);
  379.           while ((c = getc(infp)) != EOF)
  380.               putc(c, mfd);
  381.           mclose(mfd);
  382. ***************
  383. *** 891,901 ****
  384.       }
  385.   
  386.       if (is_ctl) {
  387. !         exitcode = control(&header);
  388.           if (localize("control") && exitcode != 0)
  389.               savehist(histline);
  390.       } else {
  391.           if (s_find(&srec, FULLSYSNAME) == FALSE) {
  392.               logerr("Cannot find my name '%s' in %s", FULLSYSNAME, SUBFILE);
  393.               srec = dummy_srec;
  394.           }
  395. --- 906,920 ----
  396.       }
  397.   
  398.       if (is_ctl) {
  399. !         exitcode = control(&header, mode == PROC);
  400.           if (localize("control") && exitcode != 0)
  401.               savehist(histline);
  402.       } else {
  403. + #ifdef HIDDENNET
  404. +         if (s_find(&srec, LOCALSYSNAME) == FALSE) {
  405. + #else /* !HIDDENNET */
  406.           if (s_find(&srec, FULLSYSNAME) == FALSE) {
  407. + #endif /* !HIDDENNET */
  408.               logerr("Cannot find my name '%s' in %s", FULLSYSNAME, SUBFILE);
  409.               srec = dummy_srec;
  410.           }
  411. ***************
  412. *** 1193,1212 ****
  413.       register struct direct *dir;
  414.       register int foundsome;
  415.       int pid, status, ret;
  416.   #ifdef VMS
  417. !     sprintf(bfr, "%s/+rnews", SPOOL);
  418.   #else /* !VMS */
  419. !     sprintf(bfr, "%s/.rnews", SPOOL);
  420.   #endif /* !VMS */
  421.   
  422. !     if (chdir(bfr) < 0)
  423. !         xerror("chdir(%s):%s", bfr, errmsg(errno));
  424.   
  425.       do {
  426.           foundsome = 0;
  427. -         dirp = opendir(".");
  428. -         if (dirp == NULL)    /* Boy are things screwed up */
  429. -             xerror("opendir can't open .:%s", errmsg(errno));
  430.   
  431.           while ((dir=readdir(dirp)) != NULL) {
  432.               if (dir->d_name[0] == '.')
  433. --- 1212,1253 ----
  434.       register struct direct *dir;
  435.       register int foundsome;
  436.       int pid, status, ret;
  437. +     char spbuf[BUFLEN];
  438.   #ifdef VMS
  439. !     sprintf(spbuf, "%s/+rnews", SPOOL);
  440.   #else /* !VMS */
  441. !     sprintf(spbuf, "%s/.rnews", SPOOL);
  442.   #endif /* !VMS */
  443.   
  444. !     if (chdir(spbuf) < 0)
  445. !         xerror("chdir(%s):%s", spbuf, errmsg(errno));
  446.   
  447. +     dirp = opendir(".");
  448. +     if (dirp == NULL)    /* Boy are things screwed up */
  449. +         xerror("opendir can't open .:%s", errmsg(errno));
  450. + #ifdef    LOCKF
  451. +     if (lockf(dirp->dd_fd, F_TLOCK, 0) < 0 &&
  452. +         (errno == EAGAIN || errno == EACCES)) {
  453. + #else    /* !LOCKF */
  454. + #ifdef BSD4_2
  455. +     if (flock(dirp->dd_fd, LOCK_EX|LOCK_NB) < 0 &&
  456. +         errno == EWOULDBLOCK) {
  457. + #else    /* V7 */
  458. +     strcat(spbuf, ".lock");
  459. +     sprintf(bfr, "%s.tmp", spbuf);
  460. +     (void) close(creat(bfr, 0666));
  461. +     if (LINK(bfr, spbuf) < 0) {
  462. +         (void) UNLINK(bfr);
  463. +         if (errno != EEXIST)
  464. +             xerror("Can't lock %s: %s", spbuf, errmsg(errno));
  465. +         else
  466. + #endif /* V7 */
  467. + #endif    /* !LOCKF */
  468. +         xxit(3); /* another rnews -U is running */
  469. +     }
  470.       do {
  471.           foundsome = 0;
  472.   
  473.           while ((dir=readdir(dirp)) != NULL) {
  474.               if (dir->d_name[0] == '.')
  475. ***************
  476. *** 1222,1227 ****
  477. --- 1263,1273 ----
  478.               while ((ret=wait(&status)) != pid && ret != -1)
  479.                   /* continue */;
  480.   
  481. +             if (((status>>8)&0177) == 42) {
  482. +                 /* expire has started up, shutdown rnews -U */
  483. +                 break;
  484. +             }
  485.               if (status != 0) {
  486.                   sprintf(bfr, "../%s", dir->d_name);
  487.                   (void) LINK(dir->d_name, bfr);
  488. ***************
  489. *** 1231,1238 ****
  490.               (void) unlink(dir->d_name);
  491.               foundsome++;
  492.           }
  493. !         closedir(dirp);
  494.       } while (foundsome); /* keep rereading the directory until it's empty */
  495.   
  496.       xxit(0);
  497.   }
  498. --- 1277,1286 ----
  499.               (void) unlink(dir->d_name);
  500.               foundsome++;
  501.           }
  502. !         rewinddir(dirp);
  503.       } while (foundsome); /* keep rereading the directory until it's empty */
  504. +     closedir(dirp);
  505. +     (void) UNLINK(spbuf);
  506.   
  507.       xxit(0);
  508.   }
  509.  
  510. Index: control.c
  511. Prereq: 2.51
  512. *** .d/control.c    Tue Feb 24 17:55:44 1987
  513. --- control.c    Mon Mar  9 22:59:58 1987
  514. ***************
  515. *** 19,25 ****
  516.    */
  517.   
  518.   #ifdef SCCSID
  519. ! static char    *SccsId = "@(#)control.c    2.51    2/22/87";
  520.   #endif /* SCCSID */
  521.   
  522.   #include "iparams.h"
  523. --- 19,25 ----
  524.    */
  525.   
  526.   #ifdef SCCSID
  527. ! static char    *SccsId = "@(#)control.c    2.52    3/9/87";
  528.   #endif /* SCCSID */
  529.   
  530.   #include "iparams.h"
  531. ***************
  532. *** 55,66 ****
  533.    *        to listed address.
  534.    */
  535.   
  536. ! control(h)
  537.   struct hbuf *h;
  538.   {
  539.       register char *ctlmsgtext;
  540.       register struct msgtype *mp;
  541.   
  542.       if (strncmp(h->title, "cmsg ", 5) == 0) {
  543.           register char *cp1, *cp2;
  544.           cp1 = h->title;
  545. --- 55,70 ----
  546.    *        to listed address.
  547.    */
  548.   
  549. ! static int is_proc;
  550. ! control(h, isproc)
  551.   struct hbuf *h;
  552. + int isproc;
  553.   {
  554.       register char *ctlmsgtext;
  555.       register struct msgtype *mp;
  556.   
  557. +     is_proc = isproc;
  558.       if (strncmp(h->title, "cmsg ", 5) == 0) {
  559.           register char *cp1, *cp2;
  560.           cp1 = h->title;
  561. ***************
  562. *** 161,166 ****
  563. --- 165,171 ----
  564.       register int    i;
  565.       char        list[sizeof header.title];
  566.       extern char *    findhist();
  567. +     extern char *    mydomain();
  568.   
  569.       if (argc < 2)
  570.           error("ihave: Too few arguments.");
  571. ***************
  572. *** 210,216 ****
  573.       (void) sprintf(header.title, "sendme%s %s", list, FULLSYSNAME);
  574.       (void) strcpy(header.ctlmsg, header.title);
  575.       getident(&header);
  576. !     (void) sprintf(header.from, "%s@%s%s", "usenet", FULLSYSNAME, MYDOMAIN);
  577.       (void) strcpy(header.path, NEWSUSR);
  578.       header.subdate[0] = header.expdate[0] = '\0';
  579.       dates(&header);
  580. --- 215,221 ----
  581.       (void) sprintf(header.title, "sendme%s %s", list, FULLSYSNAME);
  582.       (void) strcpy(header.ctlmsg, header.title);
  583.       getident(&header);
  584. !     (void) sprintf(header.from, "%s@%s%s", "usenet", FULLSYSNAME, mydomain());
  585.       (void) strcpy(header.path, NEWSUSR);
  586.       header.subdate[0] = header.expdate[0] = '\0';
  587.       dates(&header);
  588. ***************
  589. *** 238,243 ****
  590. --- 243,252 ----
  591.    * The other system wants me to send out article <artid>.
  592.    * Give it to them with no fuss.
  593.    */
  594. + #ifdef MULTICAST
  595. + static int    c_mc;
  596. + static char **    c_sysnames;
  597. + #endif /* MULTICAST */
  598.   c_sendme(argc, argv)
  599.   register char **argv;
  600.   {
  601. ***************
  602. *** 249,254 ****
  603. --- 258,275 ----
  604.           return 0;
  605.       if (s_find(&srec, argv[argc - 1]) != TRUE)
  606.           error("sendme: Can't find sys record for %s", argv[argc - 1]);
  607. + #ifdef MULTICAST
  608. +     c_mc = index(srec.s_flags, 'M') != 0;
  609. +     if (c_mc) {
  610. +         struct srec    trec;
  611. +         c_sysnames = &argv[argc - 1];
  612. +         if (s_find(&trec, srec.s_xmit) != TRUE)
  613. +             error("sendme: Can't find sys record for %s for %s",
  614. +                 srec.s_xmit, argv[argc - 1]);
  615. +         srec = trec;
  616. +     } else    c_sysnames = NULL;
  617. + #endif /* MULTICAST */
  618.       /* Send the articles. */
  619.       if (argc == 2) {
  620.           register FILE *    fp;
  621. ***************
  622. *** 284,290 ****
  623. --- 305,315 ----
  624.       cp = findfname(id);
  625.       if (cp == NULL) {
  626.           logerr("System %s wants unavailable article %s.",
  627. + #ifdef MULTICAST
  628. +             (c_mc ? c_sysnames[0] : sp->s_name), id);
  629. + #else /* !MULTICAST */
  630.               sp->s_name, id);
  631. + #endif /* !MULTICAST */
  632.           return;
  633.       }
  634.       cp = dirname(cp);
  635. ***************
  636. *** 295,301 ****
  637.       }
  638.       (void) strcpy(savedbufname, firstbufname);
  639.       (void) strcpy(firstbufname, cp);
  640. !     transmit(sp, fp, FALSE, (char **) NULL, FALSE);
  641.       /* transmit closes fp */
  642.       (void) strcpy(firstbufname, savedbufname);
  643.   }
  644. --- 320,330 ----
  645.       }
  646.       (void) strcpy(savedbufname, firstbufname);
  647.       (void) strcpy(firstbufname, cp);
  648. ! #ifdef MULTICAST
  649. !     transmit(sp, fp, FALSE, c_sysnames, c_mc);
  650. ! #else /* !MULTICAST */
  651. !     transmit(sp, fp, FALSE, (char **) NULL, 0);
  652. ! #endif /* !MULTICAST */
  653.       /* transmit closes fp */
  654.       (void) strcpy(firstbufname, savedbufname);
  655.   }
  656. ***************
  657. *** 389,396 ****
  658.                       fprintf(fd,
  659.   "%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
  660.                           header.path, argv[1], 
  661. !                         *p=='y' ? "un" : "",
  662. !                         *p=='y' ? "" : "un");
  663.   #ifdef ORGDISTRIB
  664.                       fprintf(fd,
  665.   "You can accomplish this by re-creating the newsgroup with a distribution\n");
  666. --- 418,425 ----
  667.                       fprintf(fd,
  668.   "%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
  669.                           header.path, argv[1], 
  670. !                         *p=='y' ? "" : "un",
  671. !                         *p=='y' ? "un" : "");
  672.   #ifdef ORGDISTRIB
  673.                       fprintf(fd,
  674.   "You can accomplish this by re-creating the newsgroup with a distribution\n");
  675. ***************
  676. *** 595,601 ****
  677.              argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
  678.              tm->tm_min);
  679.           savehist(bfr);
  680. !         return 1;
  681.       }
  682.   
  683.       q = index(line, '\t');
  684. --- 624,630 ----
  685.              argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
  686.              tm->tm_min);
  687.           savehist(bfr);
  688. !         return is_proc ? 0 : 1;
  689.       }
  690.   
  691.       q = index(line, '\t');
  692. ***************
  693. *** 603,614 ****
  694.       if (p == NULL || *++p == '\0' || *p == '\n') {
  695.           *q = '\0';
  696.           log("Expired article %s", line);
  697. !         return 1;
  698.       }
  699.       if (strcmp(p, "cancelled") == 0) {
  700.           *q = '\0';
  701.           log("Already Cancelled %s", line);
  702. !         return 1;
  703.       } else
  704.           log("Cancelling %s", line);
  705.       if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
  706. --- 632,643 ----
  707.       if (p == NULL || *++p == '\0' || *p == '\n') {
  708.           *q = '\0';
  709.           log("Expired article %s", line);
  710. !         return is_proc ? 0 : 1;
  711.       }
  712.       if (strcmp(p, "cancelled") == 0) {
  713.           *q = '\0';
  714.           log("Already Cancelled %s", line);
  715. !         return is_proc ? 0 : 1;
  716.       } else
  717.           log("Cancelling %s", line);
  718.       if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
  719. ***************
  720. *** 696,750 ****
  721.   }
  722.   
  723.   /*
  724. -  * senduuname    (no arguments)
  725. -  *
  726. -  * Run the "uuname" command and send it back to the person who submitted
  727. -  * the article.  The purpose of this control message is for attempting to
  728. -  * make a uucp net map.
  729. -  *
  730. -  * POLICY: If you view this information as not public (because you have
  731. -  * a connection you consider secret, or know a site that considers itself
  732. -  * secret) you can feel free to change this code in whatever way is
  733. -  * appropriate, so long as it sends some response back to the sender.  If
  734. -  * you don't run uucp, this code does not make sense, and so an error
  735. -  * message (or garbage, such as "research") will be mailed back.
  736. -  *
  737. -  * If you wish to add or remove sites from the output of uuname, you
  738. -  * may wish to use the euuname.sh shell script here.
  739. -  */
  740. - /* ARGSUSED */
  741. - c_senduuname(argc, argv)
  742. - char **argv;
  743. - {
  744. -     char buf[256];
  745. -     FILE *fd, *u;
  746. -     int c;
  747. - #ifdef NOTIFY
  748. -     fd = mailhdr((struct hbuf *)NULL, "uuname control message");
  749. -     fprintf(fd, "%s requested your uuname output\n", header.path);
  750. -     (void) mclose(fd);
  751. - #endif /* NOTIFY */
  752. -     fd = mailhdr(&header, "response to your senduuname request");
  753. - #ifdef UUPROG
  754. -     if (UUPROG[0] == '/')
  755. -         (void) strcpy(buf, UUPROG);
  756. -     else
  757. -         (void) sprintf(buf, "%s/%s", LIB, UUPROG);
  758. - #else
  759. -     (void) strcpy(buf, "uuname");
  760. - #endif
  761. -     u = popen(buf, "r");
  762. -     if (fd != NULL && u != NULL) {
  763. -         while ((c=getc(u)) != EOF)
  764. -             putc(c, fd);
  765. -         (void) pclose(u);
  766. -         (void) mclose(fd);
  767. -     }
  768. -     return 0;
  769. - }
  770. - /*
  771.    * Send the version number to the right person.
  772.    */
  773.   /* ARGSUSED */
  774. --- 725,730 ----
  775. ***************
  776. *** 923,928 ****
  777. --- 903,909 ----
  778.       FILE *fp;
  779.       time_t now;
  780.       char *to = "usenet";
  781. +     extern char *mydomain();
  782.   
  783.   #ifdef NOTIFY
  784.       if (TELLME && *TELLME)
  785. ***************
  786. *** 936,942 ****
  787.           fprintf(fp, "Date: %s\n", arpadate(&now));
  788.   #ifdef MMDF
  789.           fprintf(fp, "From: The News System <usenet@%s%s>\n",
  790. !                 FULLSYSNAME, MYDOMAIN);
  791.   #endif /* MMDF */
  792.           fprintf(fp, "To: %s\n", to);
  793.           fprintf(fp, "Subject: %s\n", subject);
  794. --- 917,923 ----
  795.           fprintf(fp, "Date: %s\n", arpadate(&now));
  796.   #ifdef MMDF
  797.           fprintf(fp, "From: The News System <usenet@%s%s>\n",
  798. !                 FULLSYSNAME, mydomain());
  799.   #endif /* MMDF */
  800.           fprintf(fp, "To: %s\n", to);
  801.           fprintf(fp, "Subject: %s\n", subject);
  802. ***************
  803. *** 943,953 ****
  804.   #ifdef HIDDENNET
  805.           if (strcmp(LOCALSYSNAME, FULLSYSNAME))
  806.               fprintf(fp, "Responding-System: %s.%s%s\n\n",
  807. !                 LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
  808.           else
  809.   #endif /* !HIDDENNET */
  810.               fprintf(fp, "Responding-System: %s%s\n\n",
  811. !                 FULLSYSNAME, MYDOMAIN);
  812.       }
  813.       return fp;
  814.   }
  815. --- 924,934 ----
  816.   #ifdef HIDDENNET
  817.           if (strcmp(LOCALSYSNAME, FULLSYSNAME))
  818.               fprintf(fp, "Responding-System: %s.%s%s\n\n",
  819. !                 LOCALSYSNAME, FULLSYSNAME, mydomain());
  820.           else
  821.   #endif /* !HIDDENNET */
  822.               fprintf(fp, "Responding-System: %s%s\n\n",
  823. !                 FULLSYSNAME, mydomain());
  824.       }
  825.       return fp;
  826.   }
  827. ***************
  828. *** 1009,1016 ****
  829.       } else if (strcmp(msg, "rmgroup") == 0) {
  830.           suser();
  831.       } else if (strcmp(msg, "sendsys") == 0) {
  832. -         suser();
  833. -     } else if (strcmp(msg, "senduuname") == 0) {
  834.           suser();
  835.       } else if (strcmp(msg, "checkgroups") == 0) {
  836.           suser();
  837. --- 990,995 ----
  838.  
  839. Index: expire.c
  840. Prereq: 2.50
  841. *** .d/expire.c    Tue Feb 24 17:55:47 1987
  842. --- expire.c    Mon Mar  9 22:59:59 1987
  843. ***************
  844. *** 17,23 ****
  845.    */
  846.   
  847.   #ifdef SCCSID
  848. ! static char    *SccsId = "@(#)expire.c    2.50    2/22/87";
  849.   #endif /* SCCSID */
  850.   
  851.   #include "params.h"
  852. --- 17,23 ----
  853.    */
  854.   
  855.   #ifdef SCCSID
  856. ! static char    *SccsId = "@(#)expire.c    2.51    3/9/87";
  857.   #endif /* SCCSID */
  858.   
  859.   #include "params.h"
  860. ***************
  861. *** 230,235 ****
  862. --- 230,244 ----
  863.               dorebuild++;
  864.               nohistory++;
  865.               break;
  866. +         case 'R':    /* just rebuild the dbm files */
  867. + #ifdef DBM
  868. +             rebuilddbm();
  869. +             xxit(0);
  870. + #else /* !DBM */
  871. +             fprintf(stderr, "You have not compiled expire with DBM, so -R is meaningless\n");
  872. +             xxit(1);
  873. + #endif /* !DBM */
  874.           case 'p':    /* use posting date to expire */
  875.               usepost++;
  876.               break;
  877. ***************
  878. *** 1171,1177 ****
  879.           (void) mkdir(fn, 0755);
  880.       (void) sprintf(fn, "%s.d", ARTFILE);
  881.       if (verbose)
  882. !         printf("Rebuilding history subfile directory %d.\n", fn);
  883.       if (access(fn,0) != 0)
  884.           (void) mkdir(fn, 0755);
  885.       for (i = 0; i < 10; i++) {
  886. --- 1180,1186 ----
  887.           (void) mkdir(fn, 0755);
  888.       (void) sprintf(fn, "%s.d", ARTFILE);
  889.       if (verbose)
  890. !         printf("Rebuilding history subfile directory %s.\n", fn);
  891.       if (access(fn,0) != 0)
  892.           (void) mkdir(fn, 0755);
  893.       for (i = 0; i < 10; i++) {
  894.  
  895. Index: header.c
  896. Prereq: 2.46
  897. *** .d/header.c    Wed Dec 17 18:23:40 1986
  898. --- header.c    Mon Mar  9 22:59:59 1987
  899. ***************
  900. *** 16,22 ****
  901.    */
  902.   
  903.   #ifdef SCCSID
  904. ! static char    *SccsId = "@(#)header.c    2.46    12/17/86";
  905.   #endif /* SCCSID */
  906.   
  907.   #include <stdio.h>
  908. --- 16,22 ----
  909.    */
  910.   
  911.   #ifdef SCCSID
  912. ! static char    *SccsId = "@(#)header.c    2.47    3/9/87";
  913.   #endif /* SCCSID */
  914.   
  915.   #include <stdio.h>
  916. ***************
  917. *** 284,289 ****
  918. --- 284,290 ----
  919.       char *at, *dot;
  920.       char pathbuf[PATHLEN];
  921.       char fullname[BUFLEN];
  922. +     extern char *mydomain();
  923.   
  924.       tp = tailpath(hp);
  925.       user = rindex(tp, '!');
  926. ***************
  927. *** 314,320 ****
  928.       tp = index(host, '@');
  929.       if (tp != NULL)
  930.           *tp = 0;
  931. !     (void) sprintf(hp->from, "%s@%s%s", user, host, MYDOMAIN);
  932.   
  933.       skin(pathbuf, fullname, hp->path);    /* remove RFC822-style comments */
  934.       if (fullname[0] != '\0') {
  935. --- 315,321 ----
  936.       tp = index(host, '@');
  937.       if (tp != NULL)
  938.           *tp = 0;
  939. !     (void) sprintf(hp->from, "%s@%s%s", user, host, mydomain());
  940.   
  941.       skin(pathbuf, fullname, hp->path);    /* remove RFC822-style comments */
  942.       if (fullname[0] != '\0') {
  943.  
  944. Index: pathinit.c
  945. Prereq: 1.19
  946. *** .d/pathinit.c    Wed Dec 17 18:23:22 1986
  947. --- pathinit.c    Mon Mar  9 23:00:02 1987
  948. ***************
  949. *** 34,40 ****
  950.    */
  951.   
  952.   #ifdef SCCSID
  953. ! static char    *SccsId = "@(#)pathinit.c    1.19    12/16/86";
  954.   #endif /* SCCSID */
  955.   
  956.   #if defined(INEW) || defined(EXP)
  957. --- 34,40 ----
  958.    */
  959.   
  960.   #ifdef SCCSID
  961. ! static char    *SccsId = "@(#)pathinit.c    1.20    3/9/87";
  962.   #endif /* SCCSID */
  963.   
  964.   #if defined(INEW) || defined(EXP)
  965. ***************
  966. *** 57,63 ****
  967.   char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
  968.   
  969.   int c_cancel(), c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
  970. !     c_sendsys(), c_senduuname(), c_version(), c_checkgroups(), c_unimp();
  971.   
  972.   struct msgtype msgtype[] = {
  973.       "cancel", NULL, c_cancel,
  974. --- 57,63 ----
  975.   char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
  976.   
  977.   int c_cancel(), c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
  978. !     c_sendsys(), c_version(), c_checkgroups(), c_unimp();
  979.   
  980.   struct msgtype msgtype[] = {
  981.       "cancel", NULL, c_cancel,
  982. ***************
  983. *** 67,73 ****
  984.       "sendbad", NULL, c_sendme,
  985.       "rmgroup", NULL, c_rmgroup,
  986.       "sendsys", NULL, c_sendsys,
  987. -     "senduuname", NULL, c_senduuname,
  988.       "version", NULL, c_version,
  989.       "checkgroups", NULL, c_checkgroups,
  990.       "delsub", NULL, c_unimp,
  991. --- 67,72 ----
  992.  
  993. Index: uname.c
  994. Prereq: 2.13
  995. *** .d/uname.c    Wed Dec 17 18:23:29 1986
  996. --- uname.c    Mon Mar  9 23:00:02 1987
  997. ***************
  998. *** 21,27 ****
  999.    */
  1000.   
  1001.   #ifdef SCCSID
  1002. ! static char    *SccsId = "@(#)uname.c    2.13    12/16/86";
  1003.   #endif /* SCCSID */
  1004.   
  1005.   #include "params.h"
  1006. --- 21,27 ----
  1007.    */
  1008.   
  1009.   #ifdef SCCSID
  1010. ! static char    *SccsId = "@(#)uname.c    2.14    3/9/87";
  1011.   #endif /* SCCSID */
  1012.   
  1013.   #include "params.h"
  1014. ***************
  1015. *** 35,42 ****
  1016.   struct utsname *uptr;
  1017.   {
  1018.       char *cp;
  1019.       gethostname(uptr->nodename, sizeof (uptr->nodename));
  1020. !     cp = MYDOMAIN;    /* Gould compiler can't handle ""[0] */
  1021.       if (*cp == '\0') /* get domain name from hostname */
  1022.           return;
  1023.       cp = index(uptr->nodename, '.');
  1024. --- 35,43 ----
  1025.   struct utsname *uptr;
  1026.   {
  1027.       char *cp;
  1028. +     extern char *mydomain();
  1029.       gethostname(uptr->nodename, sizeof (uptr->nodename));
  1030. !     cp = mydomain();
  1031.       if (*cp == '\0') /* get domain name from hostname */
  1032.           return;
  1033.       cp = index(uptr->nodename, '.');
  1034. ***************
  1035. *** 96,98 ****
  1036. --- 97,157 ----
  1037.       }
  1038.   }
  1039.   #endif
  1040. + /*
  1041. +  * At sites where the are many mail domains within the support area of a single
  1042. +  * news administrator, it is much nicer to be able to read the local domain of
  1043. +  * a machine from a file.  What we do here is:
  1044. +  * 1)    Check for the presence of a LIBDIR/localdomain file.  If it doesn't 
  1045. +  *     exist,assume that MYDOMAIN should be used instead.
  1046. +  * 2)    If it does exist, we make the following assumptions:
  1047. +  *    a)  If it is empty, has only comments, or only blank lines; we assume
  1048. +  *        the domain is desired to be a zero length string ( ie "").  (this
  1049. +  *        implies that the domain name is contained in the hostname.)
  1050. +  *    b)  If it is not empty, we assume the first line not beginning with a
  1051. +  *        '#', blank/tab, or newline is the desired domain name.
  1052. +  *        A like '.UUCP' or '.TEK.COM' should be used.  We could insure that
  1053. +  *        the line begin with a '.' to be a valid domain name, but I don't 
  1054. +  *        think it is necessary to put that restriction on it.
  1055. +  */
  1056. + char *
  1057. + mydomain()
  1058. + {
  1059. +     static char *md = NULL;
  1060. +     register char *cp;
  1061. +     FILE *fp = NULL;
  1062. +     char fbuf[BUFLEN];
  1063. +     extern char *malloc(), *strcpy(), *index();
  1064. +     if(md)    /* we've been here before, so just return what we found */
  1065. +         return(md);
  1066. +     (void) sprintf(fbuf,"%s/localdomain", LIBDIR);
  1067. +     if ( (fp = fopen(fbuf,"r")) == NULL) {
  1068. +         md = MYDOMAIN;    /* No localdomain file, use MYDOMAIN instead */
  1069. +     } else {
  1070. +         while(fgets(fbuf, sizeof(fbuf), fp) ) {
  1071. +             if( *fbuf == '\n' || *fbuf == '#' 
  1072. +                 || *fbuf == ' ' || *fbuf == '\t')
  1073. +                 continue;
  1074. +     
  1075. +             if( cp = index(fbuf, '\n') )
  1076. +                 *cp = '\0';
  1077. +     
  1078. +             if ( (md = malloc(strlen(fbuf) + 1)) == NULL)
  1079. +                 md = MYDOMAIN;    /* punt here */
  1080. +             else
  1081. +                 (void)strcpy(md, fbuf);
  1082. +             break;
  1083. +         }
  1084. +     }
  1085. +     if(fp)
  1086. +         (void)fclose(fp);
  1087. +     if( md == NULL)
  1088. +         md = "";
  1089. +     
  1090. +     return(md);
  1091. + }
  1092.  
  1093. Index: ndir.c
  1094. Prereq: 1.9
  1095. *** .d/ndir.c    Wed Dec 17 18:23:21 1986
  1096. --- ndir.c    Mon Mar  9 23:00:01 1987
  1097. ***************
  1098. *** 1,10 ****
  1099.   #include "defs.h"
  1100. ! #if !defined(BSD4_2) && !defined(BSD4_1C)
  1101.   #include <sys/param.h>
  1102.   #include "ndir.h"
  1103.   
  1104.   #ifdef SCCSID
  1105. ! static char    *SccsId = "@(#)ndir.c    1.9    12/16/86";
  1106.   #endif /* SCCSID */
  1107.   
  1108.   /*
  1109. --- 1,10 ----
  1110.   #include "defs.h"
  1111. ! #if !defined(BSD4_2) && !defined(BSD4_1C) && !defined(HP9K5)
  1112.   #include <sys/param.h>
  1113.   #include "ndir.h"
  1114.   
  1115.   #ifdef SCCSID
  1116. ! static char    *SccsId = "@(#)ndir.c    1.10    3/9/87";
  1117.   #endif /* SCCSID */
  1118.   
  1119.   /*
  1120. ***************
  1121. *** 48,67 ****
  1122.   #else /* V7 file system */
  1123.   #define    ODIRSIZ    14
  1124.   
  1125. - #if HP9K5
  1126. - /* HP 9000/500 has a weird directory format */
  1127. - struct olddirect {
  1128. -     char    od_name[DIRSIZ+2];    /* filename */
  1129. -     short    od_object_type;
  1130. -     short    od_file_code;
  1131. -     short    od_ino;         /* inode */
  1132. - };
  1133. - #else /* normal V7 */
  1134.   struct    olddirect {
  1135.       short    od_ino;
  1136.       char    od_name[ODIRSIZ];
  1137.   };
  1138. - #endif /* V7 */
  1139.   #endif /* !pyr */
  1140.   
  1141.   /*
  1142. --- 48,57 ----
  1143. ***************
  1144. *** 110,113 ****
  1145.       dirp->dd_loc = 0;
  1146.       free((char *)dirp);
  1147.   }
  1148. ! #endif /* !BSD4_2 && !BSD4_1C */
  1149. --- 100,140 ----
  1150.       dirp->dd_loc = 0;
  1151.       free((char *)dirp);
  1152.   }
  1153. ! /*
  1154. !  * seek to an entry in a directory.
  1155. !  * Only values returned by "telldir" should be passed to seekdir.
  1156. !  */
  1157. ! void
  1158. ! seekdir(dirp, loc)
  1159. ! register DIR *dirp;
  1160. ! long loc;
  1161. ! {
  1162. !     long curloc, base, offset;
  1163. !     struct direct *dp;
  1164. !     extern long lseek();
  1165. !     curloc = telldir(dirp);
  1166. !     if (loc == curloc)
  1167. !         return;
  1168. !     base = loc & ~(DIRBLKSIZ - 1);
  1169. !     offset = loc & (DIRBLKSIZ - 1);
  1170. !     (void) lseek(dirp->dd_fd, base, 0);
  1171. !     dirp->dd_loc = 0;
  1172. !     while (dirp->dd_loc < offset) {
  1173. !         dp = readdir(dirp);
  1174. !         if (dp == NULL)
  1175. !             return;
  1176. !     }
  1177. ! }
  1178. ! /*
  1179. !  * return a pointer into a directory
  1180. !  */
  1181. ! long
  1182. ! telldir(dirp)
  1183. ! DIR *dirp;
  1184. ! {
  1185. !     return lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc;
  1186. ! }
  1187. ! #endif /* !BSD4_2 && !BSD4_1C && !HP9K5 */
  1188.  
  1189. Index: ndir.h
  1190. Prereq: 1.4
  1191. *** .d/ndir.h    Thu Oct 30 16:12:09 1986
  1192. --- ndir.h    Mon Mar  9 23:00:01 1987
  1193. ***************
  1194. *** 1,4 ****
  1195. ! /* @(#)ndir.h    1.4    4/16/85 */
  1196.   #ifndef DEV_BSIZE
  1197.   #define    DEV_BSIZE    512
  1198.   #endif
  1199. --- 1,8 ----
  1200. ! /* @(#)ndir.h    1.6    3/9/87    */
  1201. ! #if defined(HP9K5)
  1202. ! /* He should have included it instead of this, but prevent confusion */
  1203. ! #include <sys/ndir.h>
  1204. ! #else /* other */
  1205.   #ifndef DEV_BSIZE
  1206.   #define    DEV_BSIZE    512
  1207.   #endif
  1208. ***************
  1209. *** 40,42 ****
  1210. --- 44,49 ----
  1211.   extern    DIR *opendir();
  1212.   extern    struct direct *readdir();
  1213.   extern    void closedir();
  1214. + #define rewinddir(dirp)    seekdir((dirp), (long)0)
  1215. + #endif /* other */
  1216.  
  1217. Index: ifuncs.c
  1218. Prereq: 2.60
  1219. *** .d/ifuncs.c    Tue Feb 24 17:55:52 1987
  1220. --- ifuncs.c    Mon Mar  9 23:00:00 1987
  1221. ***************
  1222. *** 16,22 ****
  1223.    */
  1224.   
  1225.   #ifdef SCCSID
  1226. ! static char    *SccsId = "@(#)ifuncs.c    2.60    2/22/87";
  1227.   #endif /* SCCSID */
  1228.   
  1229.   #include "iparams.h"
  1230. --- 16,22 ----
  1231.    */
  1232.   
  1233.   #ifdef SCCSID
  1234. ! static char    *SccsId = "@(#)ifuncs.c    2.61    3/9/87";
  1235.   #endif /* SCCSID */
  1236.   
  1237.   #include "iparams.h"
  1238. ***************
  1239. *** 712,719 ****
  1240.       extern int errno;
  1241.   #ifdef    VMS
  1242.       int fd;
  1243. !     (void) sprintf(lockname, "/tmp/%s.l.1", str);
  1244.       while ((fd = creat(lockname, 0444)) < 0) {
  1245.   #else /* !VMS */
  1246.       (void) strcpy(tempname, "/tmp/LTMP.XXXXXX");
  1247. --- 712,723 ----
  1248.       extern int errno;
  1249.   #ifdef    VMS
  1250.       int fd;
  1251. ! /* The name here is because of the peculiar properties of version numbers
  1252. !  * in Eunice.  We eliminate any troublesome characters also.
  1253. !  */
  1254. !     (void) sprintf(lockname, "/tmp/%.10s.l.1", str);
  1255. !     for (cp = lockname; *cp; cp++)
  1256. !         if (*cp == '/' || *cp == '[' || *cp == ']') *cp = '.';
  1257.       while ((fd = creat(lockname, 0444)) < 0) {
  1258.   #else /* !VMS */
  1259.       (void) strcpy(tempname, "/tmp/LTMP.XXXXXX");
  1260. ***************
  1261. *** 768,773 ****
  1262. --- 772,778 ----
  1263.   {
  1264.       long seqn;
  1265.       register FILE *fp;
  1266. +     extern char *mydomain();
  1267.   
  1268.       lock();
  1269.       fp = xfopen(SEQFILE, "r");
  1270. ***************
  1271. *** 784,793 ****
  1272.   #ifdef HIDDENNET
  1273.       if (strcmp(LOCALSYSNAME, FULLSYSNAME))
  1274.           (void) sprintf(hp->ident, "<%ld@%s.%s%s>", seqn, LOCALSYSNAME, FULLSYSNAME,
  1275. !         MYDOMAIN);
  1276.       else
  1277.   #endif /* !HIDDENNET */
  1278. !     (void) sprintf(hp->ident, "<%ld@%s%s>", seqn, FULLSYSNAME, MYDOMAIN);
  1279.   }
  1280.   
  1281.   /*
  1282. --- 789,798 ----
  1283.   #ifdef HIDDENNET
  1284.       if (strcmp(LOCALSYSNAME, FULLSYSNAME))
  1285.           (void) sprintf(hp->ident, "<%ld@%s.%s%s>", seqn, LOCALSYSNAME, FULLSYSNAME,
  1286. !         mydomain());
  1287.       else
  1288.   #endif /* !HIDDENNET */
  1289. !     (void) sprintf(hp->ident, "<%ld@%s%s>", seqn, FULLSYSNAME, mydomain());
  1290.   }
  1291.   
  1292.   /*
  1293. ***************
  1294. *** 989,994 ****
  1295. --- 994,1000 ----
  1296.       char buf[BUFLEN];
  1297.       char *fullname(), *getenv();
  1298.       int fd, n;
  1299. +     extern char *mydomain();
  1300.   
  1301.       if ((fn = getenv("NAME")) == NULL) {
  1302.           (void) sprintf(buf, "%s/%s", userhome, ".name");
  1303. ***************
  1304. *** 1007,1013 ****
  1305.           fn = fullname(logname);
  1306.   
  1307.       (void) sprintf(hp->path, "%s", logname);
  1308. !     (void) sprintf(hp->from, "%s@%s%s (%s)", logname, FULLSYSNAME, MYDOMAIN, fn);
  1309.   }
  1310.   
  1311.   /*
  1312. --- 1013,1019 ----
  1313.           fn = fullname(logname);
  1314.   
  1315.       (void) sprintf(hp->path, "%s", logname);
  1316. !     (void) sprintf(hp->from, "%s@%s%s (%s)", logname, FULLSYSNAME, mydomain(), fn);
  1317.   }
  1318.   
  1319.   /*
  1320. ***************
  1321. *** 1032,1104 ****
  1322.   
  1323.   #ifdef BATCH
  1324.   /*
  1325. !  * If the stdin begins with "#", we assume we have been fed a batched
  1326. !  * shell script which looks like this:
  1327.    *    #! rnews 1234
  1328.    *    article with 1234 chars
  1329.    *    #! rnews 4321
  1330.    *    article with 4321 chars
  1331. !  *
  1332. !  * In this case we just exec the unbatcher and let it unpack and call us back.
  1333. !  *
  1334. !  * Note that there is a potential security hole here.  If the batcher is
  1335. !  * /bin/sh, someone could ship you arbitrary stuff to run as shell commands.
  1336. !  * The main protection you have is that the effective uid will be news, not
  1337. !  * uucp and not the super user.  (That, plus the fact that BATCH is set to
  1338. !  * "unbatch" as the system is distributed.)  If you want to run a batched link
  1339. !  * and you are security conscious, do not use /bin/sh as the unbatcher.
  1340. !  * the thing to do is to change BATCH in your localize.sh file from /bin/sh
  1341. !  * to some restricted shell which can only run rnews.
  1342.    */
  1343.   checkbatch()
  1344.   {
  1345.       int c;
  1346.   
  1347. !     c = getc(infp);
  1348.       if (c != EOF)
  1349.           (void) ungetc(c, infp);
  1350.       clearerr(infp);
  1351. !     if (c == '#') {
  1352. !         char cmd[BUFLEN], unbatcher[BUFLEN], arg1[BUFLEN], arg2[BUFLEN];
  1353. !         register char *cp;
  1354. !         int n;
  1355.   
  1356. !         reset_infp();
  1357.           /*
  1358. !          * For efficiency, try and recognize the most common
  1359. !          * forms of batching and exec them directly
  1360.            */
  1361. !         n = read(0, cmd, BUFLEN-1);
  1362. !         if (n <= 0)    /* Can't happen */
  1363. !             xerror("can't read stdin to unbatch");
  1364. !         cmd[n] = '\0';
  1365. !         cp = index(cmd, '\n');
  1366. !         if (cp)
  1367. !             *cp = '\0';
  1368. !         /* now put stdin at the "right" place for the exec */
  1369. !         (void) lseek(0,1L+(long)(cp - cmd), 0);
  1370. !         if( strncmp(cmd, "#! cunbatch", 11) == 0) {
  1371. !             (void) strcpy(unbatcher, "/bin/sh");
  1372. !             (void) strcpy(arg1, "-c");
  1373. !             (void) sprintf(arg2, "%s/compress -d | %s/%s",
  1374. !                 LIB, LIB, BATCH);
  1375. !         } else if (strncmp(cmd, "#! c7unbatch", 12) == 0) {
  1376. !             (void) strcpy(unbatcher, "/bin/sh");
  1377. !             (void) strcpy(arg1, "-c");
  1378. !             (void) sprintf(arg2,
  1379. !                 "%s/decode | %s/compress -d | %s/%s",
  1380. !                 LIB, LIB, LIB, BATCH);
  1381. !         } else {
  1382. !             (void) lseek(0, 0L, 0);
  1383. !             (void) sprintf(unbatcher, "%s/%s", LIB, BATCH);
  1384. !             arg1[0] = '\0';
  1385. !             arg2[0] = '\0';
  1386. !         }
  1387. !         execl(unbatcher, "news-unpack", arg1, arg2, (char *)0);
  1388. !         xerror("Unable to exec %s to unpack news.", unbatcher);
  1389.       }
  1390.   }
  1391.   
  1392.   /*
  1393.    * We've already done a read on stdin, and we want to seek back to the
  1394.    * beginning.  We want the real file descriptor (beyond buffers) to
  1395. --- 1038,1330 ----
  1396.   
  1397.   #ifdef BATCH
  1398.   /*
  1399. !  * If the stdin begins with "#" the input is some kind of batch.  if
  1400. !  * the first line is:
  1401. !  *    #!cunbatch
  1402. !  * or
  1403. !  *    #!c7unbatch
  1404. !  * then fork off a pipe to do the either a
  1405. !  *    "compress -d"
  1406. !  * or a
  1407. !  *    "decode | compress -d"
  1408. !  * and check their output for more batch headers.  They probably
  1409. !  * contain a batch format that looks like this:
  1410.    *    #! rnews 1234
  1411.    *    article with 1234 chars
  1412.    *    #! rnews 4321
  1413.    *    article with 4321 chars
  1414. !  * If so, then for each article, copy the indicated number of chars into
  1415. !  * a temp file, fork a copy of ourselves, make its input the temp file,
  1416. !  * and allow the copy to process the article.  This avoids an exec of
  1417. !  * rnews for each article.
  1418.    */
  1419.   checkbatch()
  1420.   {
  1421.       int c;
  1422.   
  1423. !     while ((c = getc(infp)) == '#') {
  1424. !         /* some kind of batch, investigate further */
  1425. !         int i;
  1426. !         char cmd[BUFLEN];
  1427. !         cmd[0] = c;
  1428. !         fgets(cmd + 1, BUFLEN, infp);
  1429. !         if (strncmp(cmd, "#! cunbatch", 11) == 0) {
  1430. !             reset_infp();
  1431. !             i = strlen(cmd);
  1432. !             (void) lseek(0, (long) i, 0);    /* position STDIN for
  1433. !                              * exec */
  1434. !             (void) sprintf(cmd, "%s/compress", LIB);
  1435. !             input_pipe(cmd, "compress", "-d", (char *) 0);
  1436. !             continue;    /* look for the #! rnews */
  1437. !         } else if (strncmp(cmd, "#! c7unbatch", 12) == 0) {
  1438. !             reset_infp();
  1439. !             i = strlen(cmd);
  1440. !             (void) lseek(0, (long) i, 0);    /* position STDIN for
  1441. !                              * exec */
  1442. !             (void) sprintf(cmd, "%s/decode | %s/compress -d", LIB, LIB);
  1443. !             input_pipe("/bin/sh", "news-unpack", "-c", cmd);
  1444. !             continue;    /* look for the #! rnews */
  1445. !         } else if (strncmp(cmd, "#! rnews", 8) == 0) {
  1446. !             /* instead of execing unbatch do it ourselves */
  1447. !             register int fd, rc, wc;
  1448. !             int piped[2];
  1449. !             register long size, asize;
  1450. !             char *filename;
  1451. !             int pid, wpid, exstat;
  1452. !             char *mktemp();
  1453. !             long atol();
  1454. ! #define CPBFSZ 8192
  1455. !             char buf[CPBFSZ];
  1456. !             filename = 0;
  1457. !             do {
  1458. !                 while (strncmp(cmd, "#! rnews ", 9)) {
  1459. !                     fprintf(stderr, "out of sync, skipping %s\n", cmd);
  1460. !                     if (fgets(cmd, BUFLEN, infp) == NULL)
  1461. !                         exit(0);
  1462. !                 }
  1463. !                 asize = atol(cmd + 9);
  1464. !                 if (asize <= 0)
  1465. !                     xerror("checkbatch: bad batch count %ld", asize);
  1466. !                 fd = -1;
  1467. !                 size = asize;
  1468. !                 do {
  1469. !                     if (size > CPBFSZ)
  1470. !                         rc = CPBFSZ;
  1471. !                     else
  1472. !                         rc = size;
  1473. !                     rc = fread(buf, 1, rc, infp);
  1474. !                     if (rc <= 0)
  1475. !                         break;
  1476. !                     if (fd < 0) {
  1477. !                         if (rc == asize)
  1478. !                             break;    /* fits in buffer */
  1479. !                         if (!filename)
  1480. !                             filename = mktemp("/tmp/unbnewsXXXXXX");
  1481. !                         if ((fd = creat(filename, 0666)) < 0) {
  1482. !                             fprintf(stderr, "rnews: creat of \"%s\" failed",
  1483. !                                 filename);
  1484. !                             perror(" ");
  1485. !                             exit(1);
  1486. !                         }
  1487. !                     }
  1488. !                     wc = write(fd, buf, rc);    /* write to temp file */
  1489. !                     if (wc != rc) {
  1490. !                         fprintf(stderr, "write of %d to \"%s\" returned %d",
  1491. !                             rc, filename, wc);
  1492. !                         perror(" ");
  1493. !                         exit(1);
  1494. !                     }
  1495. !                     size -= rc;
  1496. !                 } while (size > 0);
  1497. !                 if (fd >= 0)
  1498. !                     (void) close(fd);
  1499. !                 /*
  1500. !                  * If we got a truncated batch, don't process
  1501. !                  * the last article; it will probably be
  1502. !                  * received again. 
  1503. !                  */
  1504. !                 if ((rc < asize) && (size > 0))
  1505. !                     break;
  1506. !                 /*
  1507. !                  * This differs from the old unbatcher in
  1508. !                  * that we don't exec rnews, mainly because
  1509. !                  * we ARE rnews.  Instead we fork off a copy
  1510. !                  * of ourselves for each article and allow it
  1511. !                  * to process. 
  1512. !                  */
  1513. !                 if (rc == asize) {
  1514. !                     /*
  1515. !                      * article fits in buffer, use a pipe
  1516. !                      * instead of a temporary file. 
  1517. !                      */
  1518. !                     if (pipe(piped) != 0) {
  1519. !                         perror("checkbatch: pipe() failed");
  1520. !                         exit(1);
  1521. !                     }
  1522. !                 }
  1523. !                 while ((pid = fork()) == -1) {
  1524. !                     fprintf(stderr, "fork failed, waiting...\r\n");
  1525. !                     sleep(60);
  1526. !                 }
  1527. !                 if (pid == 0) {
  1528. !                     if (rc == asize) {
  1529. !                         /* article fits in buffer
  1530. !                          * make the output of the
  1531. !                          * pipe for STDIN 
  1532. !                          */
  1533. !                         (void) fclose(infp);
  1534. !                         /* redundant but why not */
  1535. !                         (void) close(0);
  1536. !                         if ((i = dup(piped[0])) != 0)
  1537. !                             xerror("dup() returned %d, should be 0", i);
  1538. !                         (void) close(piped[0]);
  1539. !                         (void) close(piped[1]);
  1540. !                         infp = fdopen(0, "r");
  1541. !                     } else    /* supstitute temp file as
  1542. !                          * input */
  1543. !                         freopen(filename, "r", infp);
  1544. !                     return;    /* from checkbatch as if
  1545. !                          * normal article */
  1546. !                 }
  1547. !                 /* parent of fork */
  1548. !                 if (rc == asize) {
  1549. !                     /* article fits in buffer */
  1550. !                     wc = write(piped[1], buf, rc);
  1551. !                     if (wc != rc) {
  1552. !                         fprintf(stderr, "write of %d to pipe returned %d",
  1553. !                             rc, wc);
  1554. !                         perror("rnews: write");
  1555. !                         exit(1);
  1556. !                     }
  1557. !                     (void) close(piped[0]);
  1558. !                     (void) close(piped[1]);
  1559. !                 }
  1560. !                 while ((wpid = wait(&exstat)) >= 0 && wpid != pid);
  1561. !             } while (fgets(cmd, BUFLEN, infp) != NULL);
  1562. !             (void) unlink(filename);
  1563. !             exit(0);/* all done */
  1564. !         } else {
  1565. !             reset_infp();
  1566. !             i = strlen(cmd);
  1567. !             (void) lseek(0, (long)i, 0);
  1568. !             docmd(cmd);
  1569. !             xxit(0);
  1570. !         }
  1571. !     }            /* while a batch */
  1572.       if (c != EOF)
  1573.           (void) ungetc(c, infp);
  1574.       clearerr(infp);
  1575. ! }
  1576.   
  1577. ! /*
  1578. !  * The input requires some processing so fork and exec the indicated command
  1579. !  * with its output piped to our input. 
  1580. !  */
  1581. ! static 
  1582. ! input_pipe(cmd, arg0, arg1, arg2)
  1583. ! char *cmd, *arg0, *arg1, *arg2;
  1584. ! {
  1585. !     int i, pid;
  1586. !     int piped[2];
  1587. !     if (pipe(piped) != 0) {
  1588. !         perror("checkbatch: pipe() failed");
  1589. !         exit(1);
  1590. !     }
  1591. !     fflush(stdout);
  1592. !     while ((pid = fork()) == -1) {
  1593. !         perror("checkbatch: fork failed, waiting");
  1594. !         sleep(60);
  1595. !     }
  1596. !     if (pid == 0) {        /* child process */
  1597.           /*
  1598. !          * setup a pipe such that the exec'ed process will read our
  1599. !          * input file and write to the pipe 
  1600.            */
  1601. !         (void) close(1);
  1602. !         if ((i = dup(piped[1])) != 1)
  1603. !             xerror("dup() returned %d, should be 1", i);
  1604. !         (void) close(piped[0]);
  1605. !         (void) close(piped[1]);
  1606. !         execl(cmd, arg0, arg1, arg2, (char *) 0);
  1607. !         perror("checkbatch");
  1608. !         xerror("Unable to exec %s to unpack news.", cmd);
  1609. !     } else {        /* parent process */
  1610. !         /* make the output of the pipe for STDIN */
  1611. !         (void) fclose(infp);
  1612. !         (void) close(0);
  1613. !         if ((i = dup(piped[0])) != 0)
  1614. !             xerror("dup() returned %d, should be 0", i);
  1615. !         (void) close(piped[0]);
  1616. !         (void) close(piped[1]);
  1617. !         /*
  1618. !          * there should be a way to clear any buffered input and just
  1619. !          * replace file descriptor 0 but I can't find a portable way. 
  1620. !          */
  1621. !         infp = fdopen(0, "r");
  1622.       }
  1623.   }
  1624.   
  1625. + #define MAXARGS 32
  1626. + docmd(p)
  1627. + register char *p;
  1628. + {
  1629. +     char *args[MAXARGS];
  1630. +     register char **ap = args;
  1631. +     char path[BUFSIZ];
  1632. +     char *rindex(), *cp;
  1633. +     while (*p && !isspace(*p))        /* skip leading #! crud */
  1634. +         p++;
  1635. +     while (isspace(*p))
  1636. +         p++;
  1637. +     while (*p != '\0') {
  1638. +         *ap++ = p;
  1639. +         if (ap >= &args[MAXARGS]) {
  1640. +             logerr("inews: unbatch: Too many args to %s", args[0]);
  1641. +             exit(2);
  1642. +         }
  1643. +         while (*p && !isspace(*p))
  1644. +             p++;
  1645. +         if (*p)
  1646. +             *p++ = '\0';
  1647. +         while (isspace(*p))
  1648. +             p++;
  1649. +     }
  1650. +     *ap = (char *)0;
  1651. +     if (ap == args) {
  1652. +         logerr("inews: unbatch: no command to execute");
  1653. +         exit(2);
  1654. +     }
  1655. +     /* strip off any leading pathname in case someone gets tricky */
  1656. +     cp = rindex(args[0], '/');
  1657. +     if (cp++ == NULL)
  1658. +         cp = args[0];
  1659. + # ifdef HOME
  1660. +     sprintf(path, "%s/%s/%s", logdir(HOME), LIBDIR, cp);
  1661. + # else /* !HOME */
  1662. +     sprintf(path, "%s/%s", LIBDIR, cp);
  1663. + # endif /* HOME */
  1664. +     /*
  1665. +      * "path" is absolute, no searching is needed,  we use
  1666. +      * 'execvp' solely so that sh scripts will be handled
  1667. +      */
  1668. +     (void) execvp(path, args);
  1669. +     perror(path);
  1670. +     xxit(2);
  1671. + }
  1672.   /*
  1673.    * We've already done a read on stdin, and we want to seek back to the
  1674.    * beginning.  We want the real file descriptor (beyond buffers) to
  1675.