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

  1. Subject:  v07i053:  2.11 News Source, Part04/09
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rick (Rick Adams)
  6. Mod.sources: Volume 7, Issue 53
  7. Archive-name: 2.11news/Part14
  8.  
  9. # To extract, sh this file
  10. #
  11. #    news 2.11 source part 4 of 9
  12. #
  13. if test ! -d src
  14. then
  15.     mkdir src
  16. fi
  17. echo x - src/postnews.c 1>&2
  18. sed 's/.//' >src/postnews.c <<'*-*-END-of-src/postnews.c-*-*'
  19. -/*
  20. - * This software is Copyright (c) 1986 by Rick Adams.
  21. - *
  22. - * Permission is hereby granted to copy, reproduce, redistribute or
  23. - * otherwise use this software as long as: there is no monetary
  24. - * profit gained specifically from the use or reproduction or this
  25. - * software, it is not sold, rented, traded or otherwise marketed, and
  26. - * this copyright notice is included prominently in any copy
  27. - * made.
  28. - *
  29. - * The author make no claims as to the fitness or correctness of
  30. - * this software for any use whatsoever, and it is provided as is. 
  31. - * Any use of this software is at the user's own risk.
  32. - *
  33. - * Postnews: post a news message to Usenet.  This C version replaces a shell
  34. - * script, and does more intelligent prompting and filtering than possible
  35. - * in a shell script.
  36. - */
  37. -
  38. -#ifdef SCCSID
  39. -static char    *SccsId = "@(#)postnews.c    1.28    10/23/86";
  40. -#endif /* SCCSID */
  41. -
  42. -#include "params.h"
  43. -
  44. -#define APPEND 1
  45. -#define REPLACE 2
  46. -
  47. -extern char *MAILPARSER;
  48. -
  49. -char tempfname[50];        /* file name used for making article */
  50. -char original[BUFLEN];        /* file name of original, used in followup */
  51. -char homedir[BUFLEN];        /* HOME environment setting */
  52. -char user[SBUFLEN];        /* user name */
  53. -char ccname[BUFLEN];        /* file name for article copy */
  54. -
  55. -/* article header information */
  56. -char subject[BUFLEN];
  57. -char distribution[BUFLEN];
  58. -char references[BUFLEN];
  59. -char newsgroups[BUFLEN];
  60. -char isfrom[BUFLEN];
  61. -char msgid[BUFLEN];
  62. -char keywords[BUFLEN];
  63. -char summary[BUFLEN];
  64. -
  65. -char ngsep[] = { NGDELIM, '\0' };    /* == "," */
  66. -
  67. -char *Progname = "postnews";        /* for xerror */
  68. -
  69. -time_t fmodtime;
  70. -char buf[BUFLEN];
  71. -
  72. -#define MAXDISTR    16
  73. -struct distr {
  74. -    char abbr[24];
  75. -    char descr[128];
  76. -} distr[MAXDISTR];
  77. -
  78. -FILE *xfopen();
  79. -
  80. -main(argc, argv)
  81. -char *argv[];
  82. -{
  83. -    register int c;
  84. -
  85. -    init();
  86. -
  87. -    if (argc == 2) {
  88. -        if (!prefix(argv[1], SPOOL))
  89. -            xerror("Can only followup to articles in %s", SPOOL);
  90. -        followup(argv[1]);
  91. -        (void) strcpy(original, argv[1]);
  92. -    } else
  93. -    if (askyes("Is this message in response to some other message? ","no")) {
  94. -        char ng[BUFLEN], num[BUFLEN];
  95. -        long i, j, lastnum;
  96. -        register char *p;
  97. -        int fd, dir;
  98. -        char canpost;
  99. -
  100. -        getpr("In what newsgroup was the article posted? ",ng);
  101. -        if (!valid_ng(ng, &i, &j, &canpost))
  102. -            if (canpost == 'i' )
  103. -                byebye("There is no such newsgroup.");
  104. -            else if (canpost == 'n')
  105. -                byebye("You are not allowed to post to that group.");
  106. -
  107. -        printf("Valid article numbers are from %ld to %ld\n", j, i);
  108. -        lastnum = i + 1;
  109. -        dir = -1;
  110. -
  111. -        for(;;) {
  112. -            getpr("\nWhat was the article number? ", num);
  113. -            switch(num[0]) {
  114. -            case '+':
  115. -                dir = 1;
  116. -                sprintf(num, "%ld", lastnum + 1);
  117. -                break;
  118. -            case '-':
  119. -                dir = -1;
  120. -                /* no break */
  121. -            case '\0':
  122. -                sprintf(num, "%ld", lastnum + dir);
  123. -                break;
  124. -            }
  125. -            (void) sprintf(original, "%s/%s", SPOOL, ng);
  126. -            for (p=original+strlen(SPOOL)+1; *p ;++p)
  127. -                if (*p == '.')
  128. -                    *p = '/';
  129. -            (void) strcat(original, "/");
  130. -            (void) strcat(original, num);
  131. -
  132. -            if ((fd=open(original,0)) >= 0) {
  133. -                (void) close(fd);
  134. -                printf("\narticle %s\n", original);
  135. -                if (article_line(original, "From: ", buf))
  136. -                    printf("%s\n", buf);
  137. -                if (article_line(original, "Subject: ", buf))
  138. -                    printf("%s\n", buf);
  139. -                if (askyes("Is this the one you want? ", "n"))
  140. -                    break;
  141. -            } else
  142. -                printf("I can't find that article.\n");
  143. -            lastnum = atol(num);
  144. -        }
  145. -
  146. -        followup(original);
  147. -    } else {
  148. -        do {
  149. -            getpr("Subject: ", subject);
  150. -            if (*subject == '?') {
  151. -printf("People read the subject line to learn what your article is about.\n");
  152. -printf("You want it to do the same job as a newspaper headline.\n");
  153. -printf("So type in something both brief and descriptive.\n");
  154. -                *subject = '\0';
  155. -            }
  156. -        } while (*subject == '\0');
  157. -        getpr("Keywords: ", keywords);
  158. -
  159. -        while (!get_newsgroup())
  160. -            ;
  161. -        get_distribution((char *)0);
  162. -    }
  163. -
  164. -    if (pre_checks())
  165. -        exit(1);
  166. -
  167. -    prep_article();
  168. -    c = 'e';
  169. -    for (;;) {
  170. -        if (c == 'e') {
  171. -            edit_article();
  172. -            post_checks();
  173. -        }
  174. -        do {
  175. -            do {
  176. -                getpr("\nWhat now?  [send, edit, list, quit, write] ", buf);
  177. -                c = buf[0];
  178. -            } while (c == '\0');
  179. -            if (isupper(c))
  180. -                c = tolower(c);
  181. -            if (c == 'q') {
  182. -                (void) UNLINK(tempfname);
  183. -                exit(1);
  184. -            }
  185. -            if (c == 'l') {
  186. -                char *pager = getenv("PAGER");
  187. -                char lbuf[BUFLEN];
  188. -                if (pager == NULL || *pager == '\0') {
  189. -#ifdef PAGE
  190. -# ifdef IHCC
  191. -                    (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
  192. -# else /* !IHCC */
  193. -                    (void) strcpy(lbuf, PAGE);
  194. -# endif /* !IHCC */
  195. -                    pager = lbuf;
  196. -#else /* !PAGE */
  197. -                    pager = "cat";
  198. -#endif /* !PAGE */
  199. -                }
  200. -                sprintf(buf, "exec %s %s", pager, tempfname);
  201. -                (void)  system(buf);
  202. -            }
  203. -            if (c == 'w') {
  204. -                register int ifd, ofd, nbytes;
  205. -                char iobuf[BUFSIZ];
  206. -                char fname[BUFLEN];
  207. -                getpr("Filename? ", fname);
  208. -                if (fname[0] == '\0')
  209. -                    continue;
  210. -                ofd = creat(fname, 0666);
  211. -                if (ofd < 0)
  212. -                    perror(fname);
  213. -                else {
  214. -                    ifd = open(tempfname, 0);
  215. -                    if (ifd < 0)
  216. -                        xerror("Can't reopen %s\n", tempfname);
  217. -                    while ((nbytes = read(ifd, iobuf, BUFSIZ)) > 0 )
  218. -                        write(ofd, iobuf, nbytes);
  219. -                    close(ofd);
  220. -                    close(ifd);
  221. -                }
  222. -            }
  223. -        } while (!index("eps", c));
  224. -        if (c != 'e')
  225. -            post_article(); /* will exit if posted successfully */
  226. -    };
  227. -}
  228. -
  229. -/*
  230. - * Find out the topic of interest.
  231. - */
  232. -get_newsgroup()
  233. -{
  234. -    int n;
  235. -    long i;
  236. -    char canpost;
  237. -    static int first = 1;
  238. -
  239. -    printf("Newsgroups (enter one at a time, end with a blank line):\n");
  240. -    if (first) {
  241. -        printf("\nThe most relevant newsgroup should be the first, you should\n");
  242. -        printf("add others only if your article really MUST be read by people\n");
  243. -        printf("who choose not to read the appropriate group for your article.\n");
  244. -        printf("But DO use multiple newsgroups rather than posting many times.\n\n");
  245. -        first = 0;
  246. -    }
  247. -    printf("For a list of newsgroups, type ?\n");
  248. -    n = 0;
  249. -    newsgroups[0] = '\0';
  250. -
  251. -    for(;;) {
  252. -        getpr("> ", buf);
  253. -        if (buf[0] == '\0')
  254. -            if (n == 0)
  255. -                return FALSE;
  256. -            else
  257. -                return TRUE;
  258. -        if (buf[0] == '?'){
  259. -            char *pager = getenv("PAGER");
  260. -            char lbuf[BUFLEN];
  261. -            if (pager == NULL) {
  262. -#ifdef PAGE
  263. -# ifdef IHCC
  264. -                (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
  265. -# else /* !IHCC */
  266. -                (void) strcpy(lbuf, PAGE);
  267. -# endif /* !IHCC */
  268. -                pager = lbuf;
  269. -#else /* !PAGE */
  270. -                pager = "cat";
  271. -#endif /* !PAGE */
  272. -            }
  273. -            printf("These are the currently active groups:\n");
  274. -            sprintf(buf, "exec %s %s/newsgroups", pager, LIB);
  275. -            (void) system(buf);
  276. -            continue;
  277. -        }
  278. -        if (valid_ng(buf, &i, &i, &canpost)) {
  279. -            if (n++ != 0)
  280. -                (void) strcat(newsgroups, ngsep);
  281. -            (void) strcat(newsgroups, buf);
  282. -        } else {
  283. -            if (canpost == 'n')
  284. -                printf("You are not allowed to post to %s\n",
  285. -                    buf);
  286. -            else if (canpost == 'i')
  287. -                printf("%s is not a valid newsgroup.\n", buf);
  288. -        }
  289. -    }
  290. -}
  291. -
  292. -/*
  293. - * Find out how widely the author wants the message distributed.
  294. - */
  295. -get_distribution(deflt)
  296. -    char *deflt;
  297. -{
  298. -    register int i;
  299. -    register char *r;
  300. -    char def[BUFLEN];
  301. -    char *lastgroup;
  302. -
  303. -    lastgroup = newsgroups;
  304. -    (void) strcpy(def, newsgroups);
  305. -    r = index(def, NGDELIM);
  306. -    if (r)
  307. -        *r = '\0';
  308. -    r = index(def, '.');
  309. -    if (r) {
  310. -        *r = '\0';
  311. -        if (strcmp(def, "net") == 0)
  312. -            (void) strcpy(def, "world");
  313. -    } else {
  314. -        distribution[0] = '\0';
  315. -        return;
  316. -    }
  317. -
  318. -    if (strcmp(def, "to") == 0) {
  319. -        /*
  320. -         * This only works if "to.xx" is the first (or only)
  321. -         * newsgroup, but it usually is ..
  322. -         * Perhaps we should make the distribution be "to.xxx" ??
  323. -         */
  324. -        distribution[0] = '\0';
  325. -        return;        /* He's probably testing something */
  326. -    }
  327. -    if (deflt != (char *)0)
  328. -        (void) strcpy(def, deflt);
  329. -    if (ngmatch("net.test", newsgroups))
  330. -        (void) strcpy(def, "local");
  331. -    for(;;) {
  332. -        do {
  333. -            (void) sprintf(buf, "Distribution (default='%s', '?' for help) : ", def);
  334. -            getpr(buf, distribution);
  335. -            if (distribution[0] == '\0') {
  336. -                if (strcmp(def, "*None*") == 0)
  337. -                    printf("You must enter a distribution, '?' for help.\n");
  338. -                (void) strcpy(distribution, def);
  339. -            }
  340. -        } while (strcmp(distribution, "*None*") == 0);
  341. -
  342. -        /* Did the user ask for help? */
  343. -        if (distribution[0] == '?') {
  344. -            printf("How widely should your article be distributed?\n\n");
  345. -            for (i=0; distr[i].abbr[0]; i++)
  346. -                printf("%s\t%s\n", distr[i].abbr, distr[i].descr);
  347. -            printf("\nEnter the word that specifies the distribution that you require.\n");
  348. -            continue;
  349. -        }
  350. -
  351. -        /* Check that it's a proper distribution */
  352. -        for (i=0; distr[i].abbr[0]; i++) {
  353. -            if (strncmp(distr[i].abbr, distribution, sizeof(distr[0].abbr)) == 0) {
  354. -                register int n;
  355. -                /* Found a match. Do any special rewriting. */
  356. -                r = newsgroups;
  357. -                n = strlen(distribution);
  358. -                /*
  359. -                 * A distribution of foo is useless
  360. -                 * if all the newsgroups are in foo.all
  361. -                 */
  362. -                for (;;) {
  363. -                    if (strncmp(r, distribution, n))
  364. -                        return;
  365. -                    if ((r = index(r, NGDELIM)) == NULL)
  366. -                        break;
  367. -                    ++r;
  368. -                }
  369. -                distribution[0] = '\0';
  370. -                return;
  371. -            }
  372. -        }
  373. -        if (strcmp(distribution, def) != 0)
  374. -            printf("Type ? for help.\n");
  375. -        else {
  376. -            int once = TRUE;
  377. -
  378. -            do {
  379. -                r = lastgroup;
  380. -                while (r = index(r, NGDELIM))
  381. -                    if (!prefix(++r, def))
  382. -                        break;
  383. -                if (r == NULL) {
  384. -                    /*
  385. -                     * no newsgroups are distribution
  386. -                     * names, and user simply will
  387. -                     * not type a valid distribution,
  388. -                     * assume that the default is OK.
  389. -                     */
  390. -                    distribution[0] = '\0';
  391. -                    return;
  392. -                }
  393. -                lastgroup = r;
  394. -                if (once)
  395. -                    printf("Sorry, '%s' is an unknown distribution.  Type ? for help.\n", def);
  396. -                once = FALSE;
  397. -                strcpy(def, r);
  398. -                r = index(def, NGDELIM);
  399. -                if (r)
  400. -                    *r = '\0';
  401. -                r = index(def, '.');
  402. -            } while (r == NULL);
  403. -            *r = '\0';
  404. -            if (strcmp(def, "net") == 0)
  405. -                strcpy(def, "world");
  406. -        }
  407. -    }
  408. -}
  409. -
  410. -/*
  411. - * Do sanity checks before the author types in the message.
  412. - */
  413. -pre_checks()
  414. -{
  415. -    if (recording(newsgroups))
  416. -        return 1;
  417. -    return 0;
  418. -}
  419. -
  420. -/*
  421. - * Set up the temp file with headers.
  422. - */
  423. -prep_article()
  424. -{
  425. -    FILE *tf, *of;
  426. -    struct stat stbuf;
  427. -
  428. -    (void) strcpy(tempfname, "/tmp/postXXXXXX");
  429. -    (void) mktemp(tempfname);
  430. -
  431. -    /* insert a header */
  432. -    tf = xfopen(tempfname, "w");
  433. -    fprintf(tf, "Subject: %s\n", subject);
  434. -    fprintf(tf, "Newsgroups: %s\n", newsgroups);
  435. -    if (distribution[0] != '\0' && strcmp(distribution, "world"))
  436. -        fprintf(tf, "Distribution: %s\n", distribution);
  437. -
  438. -    if (keywords[0] != '\0')
  439. -        fprintf(tf, "Keywords: %s\n", keywords);
  440. -    if (summary[0] != '\0')
  441. -        fprintf(tf, "Summary: %s\n", summary);
  442. -
  443. -    if (references[0] != '\0') {
  444. -        fprintf(tf, "References: %s\n\n", references);
  445. -
  446. -        if (askyes("Do you want to include a copy of the article? ", "no")){
  447. -            of = xfopen(original, "r");
  448. -            while (fgets(buf, BUFSIZ, of) != NULL)
  449. -                if (buf[0] == '\n')    /* skip headers */
  450. -                    break;
  451. -            fprintf(tf, "In article %s, %s writes:\n", msgid, isfrom);
  452. -            while (fgets(buf, BUFSIZ, of) != NULL)
  453. -                fprintf(tf, "> %s", buf);
  454. -            (void) fclose(of);
  455. -            printf("OK, but please edit it to suppress unnecessary verbiage, signatures, etc.\n");
  456. -        }
  457. -    }
  458. -
  459. -    fprintf(tf, "\n\n");
  460. -    (void) fflush(tf);
  461. -    (void) fstat(fileno(tf), &stbuf);
  462. -    fmodtime = stbuf.st_mtime;
  463. -    (void) fclose(tf);
  464. -}
  465. -
  466. -edit_article()
  467. -{
  468. -    register char *p;
  469. -    char *editor;
  470. -    char *endflag = "";
  471. -    char *getenv();
  472. -
  473. -    /* edit the file */
  474. -    editor = getenv("EDITOR");
  475. -    if (editor == NULL)
  476. -        editor = DFTEDITOR;
  477. -
  478. -    p = editor + strlen(editor) - 2;
  479. -    if (strcmp(p, "vi") == 0)
  480. -        endflag = "+";
  481. -
  482. -    (void) sprintf(buf, "A=%s;export A;exec %s %s %s",
  483. -        original, editor, endflag, tempfname);
  484. -
  485. -    (void) system(buf);
  486. -}
  487. -
  488. -/*
  489. - * Do sanity checks after the author has typed in the message.
  490. - */
  491. -post_checks()
  492. -{
  493. -    char group[BUFLEN];
  494. -    register char *c, *p;
  495. -    struct stat stbuf;
  496. -
  497. -    if (stat(tempfname, &stbuf) < 0) {
  498. -        printf("File deleted - no message posted.\n");
  499. -        (void) UNLINK(tempfname);
  500. -        exit(1);
  501. -    }
  502. -    if (stbuf.st_size < 5) {
  503. -        printf("File too small (<5 characters) - no message posted.\n");
  504. -        (void) UNLINK(tempfname);
  505. -        exit(1);
  506. -    }
  507. -
  508. -    if (stbuf.st_mtime == fmodtime) {
  509. -        printf("File not modified - no message posted.\n");
  510. -        (void) UNLINK(tempfname);
  511. -        exit(1);
  512. -    }
  513. -
  514. -    /*
  515. -     * Is this the right number?  Most of the headers are yet to be added
  516. -     */
  517. -    if (stbuf.st_size > 64000) {
  518. -        printf("\nYour message will probably be truncated when it\n");
  519. -        printf("passes through a notesfile site, since it is\n");
  520. -        printf("greater than 64000 characters.\n\n");
  521. -        if (!askyes("Do you still want to post it? ","")) {
  522. -            sprintf(ccname, "%s/dead.article", homedir);
  523. -            save_article();
  524. -            (void) UNLINK(tempfname);
  525. -            exit(1);
  526. -        }
  527. -    }
  528. -
  529. -    /*
  530. -     * get the newsgroups from the edited article, in
  531. -     * case they were altered in the editor
  532. -     */
  533. -    if (!article_line(tempfname, "Newsgroups: ", group)) {
  534. -  nogroups:
  535. -        printf("Not sending to any newsgroups - no message posted\n");
  536. -        (void) UNLINK(tempfname);
  537. -        exit(1);
  538. -    }
  539. -    c = &group[11];
  540. -    while (*c == ' ' || *c == '\t')
  541. -        c++;
  542. -    if (*c == '\0')
  543. -        goto nogroups;
  544. -    for (p = newsgroups; *c; c++)    /* copy to newsgroups, w/o blanks */
  545. -        if (*c != ' ' && *c != '\t')
  546. -            *p++ = *c;
  547. -    *p = '\0';
  548. -
  549. -    /* Sanity checks for certain newsgroups */
  550. -    if (ngmatch(newsgroups, "all.wanted") && ngmatch(distribution,"net,na,usa,att,btl,eunet,aus")) {
  551. -        printf("Is your message something that might go in your local\n");
  552. -        printf("newspaper, for example a used car ad, or an apartment\n");
  553. -        printf("for rent? ");
  554. -        if (askyes("","")) {
  555. -            printf("It's pointless to distribute your article widely, since\n");
  556. -            printf("people more than a hundred miles away won't be interested.\n");
  557. -            printf("Please use a more restricted distribution.\n");
  558. -            get_distribution("*None*");
  559. -            modify_article(tempfname, "Distribution: ", distribution,REPLACE);
  560. -        }
  561. -    }
  562. -
  563. -    if (ngmatch(newsgroups, "all.jokes")) {
  564. -        if (askyes("Could this be offensive to anyone? ","")) {
  565. -            getpr("Whom might it offend? ", group);
  566. -            (void) sprintf(buf," - offensive to %s (rot 13)",group);
  567. -            modify_article(tempfname, "Subject: ", buf, APPEND);
  568. -            encode(tempfname);
  569. -        }
  570. -    }
  571. -
  572. -    if (ngmatch(newsgroups, "net.general")) {
  573. -        if (index(newsgroups, NGDELIM)) {
  574. -            printf("Everybody in the world reads net.general, so it doesn't make\n");
  575. -            printf("sense to post to newsgroups in addition to net.general.  If your\n");
  576. -            printf("article belongs in one of these other newsgroups, then you\n");
  577. -            printf("should not post to net.general.    If it is important enough\n");
  578. -            printf("for net.general, then you shouldn't post it in other places\n");
  579. -            printf("as well.    Please reenter the newsgroups.\n");
  580. -            while (!get_newsgroup())
  581. -                ;
  582. -            modify_article(tempfname, "Newsgroups: ", newsgroups,REPLACE);
  583. -        }
  584. -        if (ngmatch(newsgroups, "net.general")) {
  585. -            printf("net.general is for important announcements.\n");
  586. -            printf("It is not for items for which you couldn't think\n");
  587. -            printf("of a better place - those belong in net.misc.\n");
  588. -            if (!askyes("Are you sure your message belongs in net.general? ","")) {
  589. -                while (!get_newsgroup())
  590. -                    ;
  591. -                modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
  592. -            }
  593. -        }
  594. -    }
  595. -
  596. -    if (ngmatch(newsgroups, "net.sources,!net.sources.all")) {
  597. -        if (!article_line(tempfname, "Subject: ", group)) {
  598. -  nosubj:
  599. -            printf("There seems to be no subject for this article.\n");
  600. -            getpr("Subject: ", subject);
  601. -            modify_article(tempfname, "Subject: ", subject, REPLACE);
  602. -        } else {
  603. -            c = &group[8];
  604. -            while (*c == ' ' || *c == '\t')
  605. -                c++;
  606. -            if (*c == '\0')
  607. -                goto nosubj;
  608. -            strcpy(subject, c);
  609. -        }
  610. -        if (ngmatch(newsgroups, "all.wanted") || iswanted(subject)) {
  611. -            printf("Requests for sources should not be posted to any of\n");
  612. -            printf("the net.sources newsgroups, please post such requests\n");
  613. -            printf("to net.wanted.sources only.     Please reenter the newsgroups.\n\n");
  614. -            while (!get_newsgroup())
  615. -                ;
  616. -            modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
  617. -        }
  618. -        if (ngmatch(newsgroups, "net.sources")) {
  619. -            if (!ngmatch(newsgroups, "net.sources.all") &&
  620. -                stbuf.st_size < (4*1024)) {
  621. -                printf("Your article seems rather small to be a source distribution.\n");
  622. -                if (!askyes("Are you certain that this is really source? ", "")) {
  623. -
  624. -                    while (!get_newsgroup())
  625. -                        ;
  626. -                    modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
  627. -                }
  628. -            }
  629. -            if (index(newsgroups, NGDELIM)) {
  630. -                printf("Sources should be posted to one newsgroup only.\n");
  631. -                printf("Please pick the most appropriate group for your article.\n\n");
  632. -                while (!get_newsgroup())
  633. -                    ;
  634. -                modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
  635. -            }
  636. -        }
  637. -    }
  638. -}
  639. -
  640. -iswanted(str)
  641. -register char *str;
  642. -{
  643. -    while (*str == ' ')
  644. -        str++;
  645. -
  646. -    if (prefix(str, "Re:"))
  647. -        return (FALSE);
  648. -
  649. -    if (isin(str, " wanted ") || isin(str, " can any") ||
  650. -        isin(str, " need ") || isin(str, " please ") || isin(str, " help ")
  651. -        || isin(str, " looking ") || index(str, '?'))
  652. -        return (TRUE);
  653. -
  654. -    return (FALSE);
  655. -}
  656. -
  657. -isin(str, words)
  658. -register char *str, *words;
  659. -{
  660. -    register char *p;
  661. -    register sc, wc;
  662. -
  663. -    p = words;
  664. -    while (sc = *str++) {
  665. -        if ((wc = *p++) == '\0')
  666. -            return (TRUE);
  667. -        if (wc == ' ') {
  668. -            if (index(".,!?-; \t\n", sc))
  669. -                continue;
  670. -        } else {
  671. -            if (isupper(wc))
  672. -                wc = tolower(wc);
  673. -            if (isupper(sc))
  674. -                sc = tolower(sc);
  675. -            if (wc == sc)
  676. -                continue;
  677. -        }
  678. -        str -= p - words - 1;
  679. -        p = words;
  680. -    }
  681. -    if (*p == '\0')
  682. -        return (TRUE);
  683. -    return (FALSE);
  684. -}
  685. -
  686. -/*
  687. - * Save a copy of the article in the users NEWSARCHIVE directory.
  688. - */
  689. -save_article()
  690. -{
  691. -    FILE *in, *out;
  692. -    int c;
  693. -    time_t timenow, time();
  694. -    char *today, *ctime();
  695. -    struct stat stbuf;
  696. -    char filename[BUFLEN];
  697. -
  698. -    if (stat(ccname, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) {
  699. -        /*
  700. -         * It would be much nicer here to write articles
  701. -         * in MH format (numbered files, in rfc822 format)
  702. -         *
  703. -         * one day ..
  704. -         */
  705. -        (void) sprintf(filename, "%s/author_copy", ccname);
  706. -        (void) strcpy(ccname, filename);
  707. -    }
  708. -    in = xfopen(tempfname, "r");
  709. -    out = xfopen(ccname, "a");
  710. -    timenow = time((time_t)0);
  711. -    today = ctime(&timenow);
  712. -    fprintf(out,"From postnews %s",today);
  713. -    while ((c=getc(in)) != EOF)
  714. -        putc(c, out);
  715. -    putc('\n', out);
  716. -    (void) fclose(in);
  717. -    (void) fclose(out);
  718. -}
  719. -
  720. -/*
  721. - * Post the article to the net.
  722. - */
  723. -post_article()
  724. -{
  725. -    int status;
  726. -
  727. -    printf("Posting article...\n");
  728. -    fflush(stdout);
  729. -    (void) sprintf(buf, "exec %s/%s -h < %s", LIB, "inews", tempfname);
  730. -    status = system(buf);
  731. -
  732. -    if (status) {
  733. -        printf("Article not posted - exit status %d\n", status);
  734. -        return;
  735. -    } else
  736. -        printf("Article posted successfully.\n");
  737. -
  738. -    if (ccname[0]) {
  739. -        printf("A copy has been saved in %s\n", ccname);
  740. -        save_article();
  741. -    }
  742. -
  743. -    (void) UNLINK(tempfname);
  744. -    exit(0);
  745. -}
  746. -
  747. -/*
  748. - * Initialization.
  749. - */
  750. -init()
  751. -{
  752. -    FILE *fd;
  753. -    register char *p;
  754. -    int i;
  755. -    char *getenv();
  756. -    struct passwd *pw;
  757. -
  758. -    references[0] = '\0';
  759. -    distribution[0] = '\0';
  760. -
  761. -    uid = getuid();
  762. -    pw = getpwuid(uid);
  763. -    if (pw == NULL) {
  764. -        fprintf(stderr,"You're not in /etc/passwd\n");
  765. -        exit(1);
  766. -    }
  767. -    p = getenv("HOME");
  768. -    if (p == NULL) {
  769. -        p = getenv("LOGDIR");
  770. -        if (p == NULL) 
  771. -            p = pw->pw_dir;
  772. -    }
  773. -    (void) strncpy(user, pw->pw_name, SBUFLEN);
  774. -    (void) strcpy(homedir, p);
  775. -
  776. -    p = getenv("NEWSARCHIVE");
  777. -    if (p != NULL) {
  778. -        if (*p == '\0')
  779. -            sprintf(ccname, "%s/author_copy", homedir);
  780. -        else
  781. -            strcpy(ccname, p);
  782. -    }
  783. -
  784. -    pathinit();
  785. -    (void) sprintf(buf, "%s/%s", LIB, "distributions");
  786. -    fd = xfopen(buf, "r");
  787. -    for (i=0; i < MAXDISTR; i++) {
  788. -        if (fscanf(fd, "%s %[^\n]", distr[i].abbr, distr[i].descr)
  789. -            != 2)
  790. -            break;
  791. -    }
  792. -    (void) fclose(fd);
  793. -}
  794. -
  795. -/*
  796. - * Get a yes or no answer to a question.    A default may be used.
  797. - */
  798. -askyes(msg, def)
  799. -char *msg, *def;
  800. -{
  801. -    for(;;) {
  802. -        printf("%s", msg);
  803. -        buf[0] = 0;
  804. -        (void) gets(buf);
  805. -        switch(buf[0]) {
  806. -        case 'y':
  807. -        case 'Y':
  808. -            return TRUE;
  809. -        case 'n':
  810. -        case 'N':
  811. -            return FALSE;
  812. -        case '\0':
  813. -            switch(*def) {
  814. -            case 'y':
  815. -            case 'Y':
  816. -                return TRUE;
  817. -            case 'n':
  818. -            case 'N':
  819. -                return FALSE;
  820. -            }
  821. -        default:
  822. -            printf("Please answer yes or no.\n");
  823. -        }
  824. -    }
  825. -}
  826. -
  827. -/*
  828. - * Get a character string into buf, using prompt msg.
  829. - */
  830. -getpr(msg, bptr)
  831. -char *msg, *bptr;
  832. -{
  833. -    static int numeof = 0;
  834. -    printf("%s", msg);
  835. -    (void) gets(bptr);
  836. -    (void) nstrip(bptr);
  837. -    if (feof(stdin)) {
  838. -        if (numeof++ > 3) {
  839. -            fprintf(stderr,"Too many EOFs\n");
  840. -            exit(1);
  841. -        }
  842. -        clearerr(stdin);
  843. -    }
  844. -}
  845. -
  846. -byebye(mesg)
  847. -char *mesg;
  848. -{
  849. -    printf("%s\n", mesg);
  850. -    exit(1);
  851. -}
  852. -
  853. -/*
  854. - * make a modification to the header of an article
  855. - *
  856. - *     fname -- name of article
  857. - *     field -- header field to modify
  858. - *     line    -- modification line
  859. - *     how     -- APPEND or REPLACE
  860. - *
  861. - * example:
  862. - *     modify_article("/tmp/article" , "Subject:" , "new subject" , REPLACE);
  863. - *
  864. - *
  865. - */
  866. -modify_article(fname, field, line, how)
  867. -char *fname, *field, *line;
  868. -{
  869. -    FILE *fpart, *fptmp;
  870. -    char *temp2fname = "/tmp/postXXXXXX";
  871. -    char lbfr[BUFLEN];
  872. -    register found = FALSE;
  873. -
  874. -    mktemp(temp2fname);
  875. -
  876. -    fptmp = xfopen(temp2fname, "w");
  877. -    fpart = xfopen(fname, "r");
  878. -
  879. -    while (fgets(lbfr, BUFLEN, fpart) != NULL) {
  880. -        if (prefix(lbfr, field)) {
  881. -            found = TRUE;
  882. -            (void) nstrip(lbfr);
  883. -            if (how == APPEND) {
  884. -                /* append to current field */
  885. -                (void) strcat(lbfr, line);
  886. -                (void) strcat(lbfr, "\n");
  887. -            } else
  888. -                /* replace current field */
  889. -                (void) sprintf(lbfr, "%s%s\n", field, line);
  890. -        }
  891. -        (void) fputs(lbfr, fptmp);
  892. -    }
  893. -
  894. -    fclose(fpart);
  895. -    fclose(fptmp);
  896. -
  897. -    fptmp = xfopen(temp2fname, "r");
  898. -    fpart = xfopen(fname, "w");
  899. -
  900. -    if (!found)
  901. -        fprintf(fpart, "%s%s\n", field, line);
  902. -    while (fgets(buf,BUFLEN,fptmp) != NULL)
  903. -        (void) fputs(buf, fpart);
  904. -
  905. -    (void) fclose(fpart);
  906. -    (void) fclose(fptmp);
  907. -    (void) UNLINK(temp2fname);
  908. -}
  909. -
  910. -
  911. -/* verify that newsgroup exists, and get number of entries */
  912. -valid_ng(ng, maxart, minart, canpost)
  913. -char *ng;
  914. -long *maxart, *minart;
  915. -char *canpost;
  916. -{
  917. -    char ng_check[BUFLEN], ng_read[BUFLEN];
  918. -    FILE *fp;
  919. -
  920. -    fp = xfopen(ACTIVE, "r");
  921. -    while (fgets(ng_read, BUFLEN, fp) != NULL) {
  922. -        switch (sscanf(ng_read, "%s %ld %ld %c", ng_check, maxart, minart, canpost)) {
  923. -        case 2:
  924. -            *minart = 1;
  925. -            /* fall through */
  926. -        case 3:
  927. -            *canpost = 'y';
  928. -            /* fall through */
  929. -        case 4:
  930. -            break;
  931. -
  932. -        default:
  933. -            printf("Active file (%s) corrupted. ", ACTIVE);
  934. -            byebye("Seek help!");
  935. -        }
  936. -            
  937. -        if (strcmp(ng_check, ng) == 0) {
  938. -            (void) fclose(fp);
  939. -            if (*canpost != 'n') {
  940. -#ifdef FASCIST
  941. -                if (uid && uid != ROOTID && fascist(user, ng)) {
  942. -                    *canpost = 'n';
  943. -                    return FALSE;
  944. -                }
  945. -#endif FASCIST
  946. -                return TRUE;
  947. -            } else
  948. -                return FALSE;
  949. -        }
  950. -    }
  951. -    *canpost = 'i';
  952. -    *maxart = 0;
  953. -    *minart = 0;
  954. -    (void) fclose(fp);
  955. -    return FALSE;
  956. -}
  957. -
  958. -/* get the line specified by field from an article */
  959. -article_line(article, field, line)
  960. -char *article, *field, *line;
  961. -{
  962. -    FILE *fp;
  963. -    char *c;
  964. -
  965. -    fp = xfopen(article,"r");
  966. -    while ((c=fgets(line,BUFLEN,fp)) != NULL && !prefix(line, field))
  967. -        if (line[0] == '\n') {
  968. -            c = NULL;
  969. -            break;
  970. -        }
  971. -    (void) fclose(fp);
  972. -    if (c != NULL) {
  973. -        (void) nstrip(line);
  974. -        return TRUE;
  975. -    } else {
  976. -        line[0] = '\0';
  977. -        return FALSE;
  978. -    }
  979. -}
  980. -
  981. -/* get the header information for a followup article */
  982. -followup(baseart)
  983. -register char *baseart;
  984. -{
  985. -    register char *p;
  986. -
  987. -    /* subject */
  988. -    if (article_line(baseart, "Subject: ", buf)) {
  989. -        p = buf+9;
  990. -        for ( ; ; ) {
  991. -            while (*p == ' ' || *p == '\t')
  992. -                ++p;
  993. -            if ((*p != 'r' && *p != 'R') ||
  994. -                (p[1] != 'e' && p[1] != 'E') ||
  995. -                (p[2] != ':' && p[2] != ' '))
  996. -                    break;
  997. -            p += 3;
  998. -        }
  999. -        (void) sprintf(subject, "Re: %s", p);
  1000. -    } else {
  1001. -        if (article_line(baseart, "From: ", buf))
  1002. -            (void) sprintf(subject, "Re: orphan response from %s", buf);
  1003. -        else
  1004. -            (void) strcpy(subject, "Re: orphan response");
  1005. -    }
  1006. -
  1007. -    /* newsgroup */
  1008. -    if (article_line(baseart, "Newsgroups: ", buf))
  1009. -        (void) strcpy(newsgroups, buf+12);
  1010. -    if (ngmatch(newsgroups, "net.general"))
  1011. -        (void) strcpy(newsgroups,"net.followup");
  1012. -    if (ngmatch(newsgroups, "net.sources,!net.sources.all"))
  1013. -        (void) strcpy(newsgroups,"net.sources.d");
  1014. -    if (ngmatch(newsgroups, "net.jobs")) {
  1015. -        printf("net.jobs is for the direct posting of job announcements and requests.\n");
  1016. -        printf("it is not for discussion. You followup has been directed to net.misc\n");
  1017. -        (void) strcpy(newsgroups,"net.misc");
  1018. -    }
  1019. -
  1020. -    /* distribution */
  1021. -    if (article_line(baseart, "Distribution: ", buf))
  1022. -        (void) strcpy(distribution, buf+14);
  1023. -
  1024. -    /* references */
  1025. -    if (article_line(baseart, "References: ", buf)) {
  1026. -        register char *rcp;
  1027. -        (void) strcpy(references, buf+12);
  1028. -        (void) strcat(references, " ");
  1029. -        /* keep the number of references to a reasonable number */
  1030. -        rcp = rindex(references, ' '); /* Can not fail */
  1031. -        while ((int)(rcp - references) > 70) {
  1032. -            while (*--rcp != ' ')
  1033. -                ;
  1034. -            rcp[1] = '\0';
  1035. -        }
  1036. -    }
  1037. -    if (article_line(baseart, "Message-ID: ", buf)) {
  1038. -        (void) strcat(references, buf+12);
  1039. -        (void) strcpy(msgid, buf+12);
  1040. -    }
  1041. -
  1042. -    if (article_line(baseart, "From: ", buf))
  1043. -        (void) strcpy(isfrom, buf+6);
  1044. -
  1045. -    if (article_line(baseart, "Keywords: ", buf))
  1046. -        (void) strcpy(keywords, buf+10);
  1047. -
  1048. -    if (article_line(baseart, "Followup-To: ", buf)) {
  1049. -        (void) strcpy(newsgroups, buf+13);
  1050. -        if (strcmp(newsgroups, "poster") == 0)
  1051. -            byebye("Mail followups directly to poster.");
  1052. -    }
  1053. -
  1054. -    get_summary();
  1055. -}
  1056. -
  1057. -get_summary()
  1058. -{
  1059. -    register char *p;
  1060. -    register i;
  1061. -
  1062. -    printf("Please enter a short summary of your contribution to the discussion\n");
  1063. -    printf("Just one or two lines ...   (end with a blank line)\n");
  1064. -    p = summary;
  1065. -    for (i = 0; i < 3; i++) {    /* 3 * 80 < 256, should be safe .. */
  1066. -        getpr(">\t", p);
  1067. -        if (*p == '\0')
  1068. -            break;
  1069. -        p = index(p, '\0');
  1070. -        (void) strcpy(p, "\n\t ");
  1071. -        p += 3;
  1072. -    }
  1073. -    if (p > summary)
  1074. -        p[-3] = '\0';
  1075. -}
  1076. -
  1077. -encode(article)
  1078. -char *article;
  1079. -{
  1080. -    FILE *fpart, *fphead, *fpcoded;
  1081. -    char *headerfile = "/tmp/pheadXXXXXX";
  1082. -    char *codedfile = "/tmp/pcodeXXXXXX";
  1083. -
  1084. -    (void) mktemp(headerfile);
  1085. -    (void) mktemp(codedfile);
  1086. -
  1087. -    fpart = xfopen(article, "r");
  1088. -
  1089. -    /* place article header in "headerfile" file */
  1090. -    fphead = xfopen(headerfile, "w");
  1091. -    while (fgets(buf, BUFLEN, fpart) != NULL) {
  1092. -        (void) fputs(buf, fphead);
  1093. -        if (buf[0] == '\n')
  1094. -            break;
  1095. -    }
  1096. -    (void) fclose(fphead);
  1097. -
  1098. -    /* place article body in "codedfile" file */
  1099. -    fpcoded = xfopen(codedfile, "w");
  1100. -    while (fgets(buf, BUFLEN, fpart) != NULL)
  1101. -        (void) fputs(buf, fpcoded);
  1102. -    (void) fclose(fpcoded);
  1103. -    (void) fclose(fpart);
  1104. -
  1105. -    /* encode body and put back together with header */
  1106. -    (void) rename(headerfile, article);
  1107. -
  1108. -    (void) sprintf(buf,"exec %s/%s 13 < %s >> %s\n", LIB, "caesar", codedfile, article);
  1109. -    printf("Encoding article -- please stand by\n");
  1110. -    if (system(buf)) {
  1111. -        printf("encoding failed");
  1112. -        exit(2);
  1113. -    }
  1114. -    (void) UNLINK(codedfile);
  1115. -}
  1116. -
  1117. -
  1118. -/*
  1119. - * Print a recorded message warning the poor luser what he is doing
  1120. - * and demand that he understands it before proceeding.  Only do
  1121. - * this for newsgroups listed in LIBDIR/recording.
  1122. - */
  1123. -recording(ngrps)
  1124. -char *ngrps;
  1125. -{
  1126. -    char recbuf[BUFLEN];
  1127. -    FILE *fd;
  1128. -    char nglist[BUFLEN], fname[BUFLEN];
  1129. -    int  c, n, yes, retval = 0;
  1130. -
  1131. -    (void) sprintf(recbuf, "%s/%s", LIB, "recording");
  1132. -    fd = fopen(recbuf, "r");
  1133. -    if (fd == NULL)
  1134. -        return 0;
  1135. -    while ((fgets(recbuf, sizeof recbuf, fd)) != NULL) {
  1136. -        (void) sscanf(recbuf, "%s %s", nglist, fname);
  1137. -        if (ngmatch(ngrps, nglist)) {
  1138. -            (void) fclose(fd);
  1139. -            if (fname[0] == '/')
  1140. -                (void) strcpy(recbuf, fname);
  1141. -            else
  1142. -                (void) sprintf(recbuf, "%s/%s", LIB, fname);
  1143. -            fd = fopen(recbuf, "r");
  1144. -            if (fd == NULL)
  1145. -                return 0;
  1146. -            while ((c = getc(fd)) != EOF)
  1147. -                putc(c, stderr);
  1148. -            fprintf(stderr, "Do you understand this?  Hit <return> to proceed, <BREAK> to abort: ");
  1149. -            n = read(2, recbuf, 100);
  1150. -            c = recbuf[0];
  1151. -            yes = (c=='y' || c=='Y' || c=='\n' || c=='\n' || c==0);
  1152. -            if (n <= 0 || !yes)
  1153. -                retval = -1;
  1154. -        }
  1155. -    }
  1156. -    return retval;
  1157. -}
  1158. -
  1159. -xxit(i)
  1160. -{
  1161. -    exit(i);
  1162. -}
  1163. -
  1164. -#if !defined(BSD4_2) && !defined(BSD4_1C)
  1165. -rename(from,to)
  1166. -register char *from, *to;
  1167. -{
  1168. -    (void) unlink(to);
  1169. -    if (link(from, to) < 0)
  1170. -        return -1;
  1171. -
  1172. -    (void) unlink(from);
  1173. -    return 0;
  1174. -}
  1175. -#endif /* !BSD4_2 && ! BSD4_1C */
  1176. *-*-END-of-src/postnews.c-*-*
  1177. echo x - src/control.c 1>&2
  1178. sed 's/.//' >src/control.c <<'*-*-END-of-src/control.c-*-*'
  1179. -/*
  1180. - * This software is Copyright (c) 1986 by Rick Adams.
  1181. - *
  1182. - * Permission is hereby granted to copy, reproduce, redistribute or
  1183. - * otherwise use this software as long as: there is no monetary
  1184. - * profit gained specifically from the use or reproduction or this
  1185. - * software, it is not sold, rented, traded or otherwise marketed, and
  1186. - * this copyright notice is included prominently in any copy
  1187. - * made.
  1188. - *
  1189. - * The author make no claims as to the fitness or correctness of
  1190. - * this software for any use whatsoever, and it is provided as is. 
  1191. - * Any use of this software is at the user's own risk.
  1192. - *
  1193. - * Control message handling code.  Deal with messages which are to be
  1194. - * acted on by netnews itself rather than by people.
  1195. - *
  1196. - * See defs.h "news_version" for the real version of netnews.
  1197. - */
  1198. -
  1199. -#ifdef SCCSID
  1200. -static char    *SccsId = "@(#)control.c    2.48    10/30/86";
  1201. -#endif /* SCCSID */
  1202. -
  1203. -#include "iparams.h"
  1204. -
  1205. -#define eq(msg) (strcmp(msg, cargv[0]) == 0)
  1206. -
  1207. -int cargc;
  1208. -char **cargv;
  1209. -
  1210. -FILE *hfopen();
  1211. -FILE *popen(), *mhopen(), *mailhdr();
  1212. -
  1213. -char *senderof();
  1214. -#ifdef u370
  1215. -static struct hbuf htmp;
  1216. -#endif /* u370 */
  1217. -
  1218. -/*
  1219. - * The global structure is initialized to NOTIFY as the default (if defined)
  1220. - * uid to send mail to for every state.  The following conditions are
  1221. - * dealt with (assumes NOTIFY defined):
  1222. - *
  1223. - * 1) LIB/notify exists and is empty (or contains no recognizable control
  1224. - *    message types).
  1225. - *        Action: force TELLME = "";
  1226. - * 2) LIB/notify contains the control message name "all" and no associated
  1227. - *    address.
  1228. - *    Action: force TELLME = "";
  1229. - * 3) LIB/notify contains the control message name "all" and has an address.
  1230. - *    Action: set TELLME = AlloCpy(address);
  1231. - * 4) LIB/notify contains only some of the known control message types.
  1232. - *    Action: initialize all addresses to "" and set declared addresses
  1233. - *        to listed address.
  1234. - */
  1235. -
  1236. -control(h)
  1237. -struct hbuf *h;
  1238. -{
  1239. -    register char *ctlmsgtext;
  1240. -    register struct msgtype *mp;
  1241. -
  1242. -    if (strncmp(h->title, "cmsg ", 5) == 0) {
  1243. -        register char *cp1, *cp2;
  1244. -        cp1 = h->title;
  1245. -        cp2 = h->title + 5;
  1246. -        while (*cp1++ = *cp2++)
  1247. -            ;
  1248. -    }
  1249. -
  1250. -    if (*h->ctlmsg)
  1251. -        ctlmsgtext = h->ctlmsg;
  1252. -    else
  1253. -        ctlmsgtext = h->title;
  1254. -    log("Ctl Msg %s from %s: %s", h->nbuf, h->path, ctlmsgtext);
  1255. -    /*
  1256. -     * Control messages have the standard format
  1257. -     *    command [args]
  1258. -     * much like shell commands.  Each site has the option
  1259. -     * of customizing this code to deal with control messages
  1260. -     * as they see fit, but we would like to buy back the
  1261. -     * code, ifdeffed or otherwise parameterized, to simplify
  1262. -     * the maintenence issues.
  1263. -     */
  1264. -    argparse(ctlmsgtext);
  1265. -    
  1266. -    /*
  1267. -     * We look for a match of the control message name and then
  1268. -     * set TELLME to the value parsed from the LIB/notify file
  1269. -     * (if any).
  1270. -     */
  1271. -    for(mp=msgtype; mp->m_name; mp++) {
  1272. -        if(eq(mp->m_name) ) {        /* hit */
  1273. -#ifdef NOTIFY
  1274. -            TELLME = mp->m_who_to;    /* reset whom to tell */
  1275. -#endif /* NOTIFY */
  1276. -            if(strcmp(mp->m_name, "cancel") == 0) /* special case */
  1277. -                return (*mp->m_func)(cargc, cargv);
  1278. -            (*mp->m_func)(cargc, cargv); /* do the function */
  1279. -            break;
  1280. -        }
  1281. -    }
  1282. -    if( !mp->m_name ) {
  1283. -#ifdef NOTIFY
  1284. -        TELLME = NOTIFY;
  1285. -#endif /* NOTIFY */
  1286. -        c_unknown(h, ctlmsgtext);
  1287. -    }
  1288. -    return 0;
  1289. -}
  1290. -
  1291. -/*
  1292. - * Parse the string str into separate words in cargc and cargv
  1293. - * as per the usual UNIX convention.  Nothing fancy here, just
  1294. - * blanks and tabs separating words.
  1295. - */
  1296. -argparse(str)
  1297. -char *str;
  1298. -{
  1299. -    static char *cavpbuf[20];
  1300. -    static char cavbuf[256];
  1301. -    char *nextfree = cavbuf;
  1302. -
  1303. -    if (str == '\0')
  1304. -        error("Control message %s has no title", header.ident);
  1305. -    cargc = (*str != '\0');
  1306. -    cargv = cavpbuf;
  1307. -    cargv[0] = cavbuf;
  1308. -
  1309. -    while (*str) {
  1310. -        if (*str <= ' ') {
  1311. -            *nextfree++ = 0;
  1312. -            cargv[cargc] = nextfree;
  1313. -            cargc++;
  1314. -            /* skip over white space */
  1315. -            while (*str != '\0' && *str <= ' ')
  1316. -                str++;
  1317. -            if (*str == '\0')    /* line ends in white space */
  1318. -                return;
  1319. -        } else
  1320. -            *nextfree++ = *str++;
  1321. -    }
  1322. -}
  1323. -
  1324. -/*
  1325. - * ihave <artid> ... <remotesys>
  1326. - *    or
  1327. - * ihave <remotesys>
  1328. - *    with <artid>s in message body.
  1329. - *
  1330. - * The other system is telling you it has article <artid>, in case
  1331. - * you decide you want it to transmit it to you.
  1332. - * The assumption is that the other system only tells you about articles
  1333. - * in newsgroups you subscribe to.
  1334. - *
  1335. - * We turn the incoming ihave into an outgoing sendme on the fly.
  1336. - * It then gets saved in the SPOOL directory and transmitted to the
  1337. - * remote system.  (This way the sendme messages can be batched.)
  1338. - */
  1339. -c_ihave(argc, argv)
  1340. -register char **    argv;
  1341. -{
  1342. -    register int    i;
  1343. -    char        list[sizeof header.title];
  1344. -    extern char *    findhist();
  1345. -
  1346. -    if (argc < 2)
  1347. -        error("ihave: Too few arguments.");
  1348. -    if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
  1349. -        return;
  1350. -    list[0] = '\0';
  1351. -    if (argc > 2) {
  1352. -        for (i = 1; i < (argc - 1); ++i)
  1353. -            if (findhist(argv[i]) == NULL) {
  1354. -                (void) strcat(list, " ");
  1355. -                (void) strcat(list, argv[i]);
  1356. -            }
  1357. -        if (list[0] == '\0')
  1358. -            return;
  1359. -    } else {
  1360. -        register FILE *    outfp;
  1361. -        register long    outpos, inpos;
  1362. -        char        myid[256];
  1363. -
  1364. -        outfp = xfopen(INFILE, "a");
  1365. -        outpos = ftell(outfp);
  1366. -        inpos = ftell(infp);
  1367. -        while (ftell(infp) < outpos) {
  1368. -            if (fgets(myid, sizeof myid, infp) != myid)
  1369. -                error("iline: Can't rerear article");
  1370. -            myid[strlen(myid) - 1] = '\0';
  1371. -            if (findhist(myid) == NULL)
  1372. -                (void) fprintf(outfp, "%s\n", myid);
  1373. -        }
  1374. -        if (outpos == ftell(outfp)) {    /* if nothing is wanted */
  1375. -            (void) fclose(outfp);
  1376. -            (void) fseek(infp, inpos, 0);
  1377. -            return;
  1378. -        }
  1379. -        (void) fclose(outfp);
  1380. -        /*
  1381. -        ** The close and open may just be paranoia.
  1382. -        */
  1383. -        (void) fclose(infp);
  1384. -        infp = xfopen(INFILE, "r");
  1385. -        (void) fseek(infp, outpos, 0);
  1386. -    }
  1387. -    /*
  1388. -    ** Turn the ihave into a sendme.
  1389. -    */
  1390. -    (void) sprintf(header.nbuf, "to.%s.ctl", argv[argc - 1]);
  1391. -    (void) sprintf(header.title, "sendme%s %s", list, FULLSYSNAME);
  1392. -    (void) strcpy(header.ctlmsg, header.title);
  1393. -    getident(&header);
  1394. -    (void) sprintf(header.from, "%s@%s%s", "usenet", FULLSYSNAME, MYDOMAIN);
  1395. -    (void) strcpy(header.path, NEWSUSR);
  1396. -    header.subdate[0] = header.expdate[0] = '\0';
  1397. -    dates(&header);
  1398. -    /*
  1399. -    ** What else of this kind should be done?
  1400. -    */
  1401. -    header.organization[0] = header.distribution[0] = '\0';
  1402. -    for (i = 0; i < NUNREC && header.unrec[i] != NULL; ++i) {
  1403. -        free(header.unrec[i]);
  1404. -        header.unrec[i] = NULL;
  1405. -    }
  1406. -    /*
  1407. -    ** Note that we do *not* change the history line
  1408. -    ** so that if the "ihave" message comes in again it gets rejected.
  1409. -    */
  1410. -}
  1411. -
  1412. -/*
  1413. - * sendme <artid> ... <remotesys>
  1414. - *    or
  1415. - * sendme <remotesys>
  1416. - *    with <artid>s in message body.
  1417. - * The other system wants me to send out article <artid>.
  1418. - * Give it to them with no fuss.
  1419. - */
  1420. -c_sendme(argc, argv)
  1421. -register char **    argv;
  1422. -{
  1423. -    struct srec    srec;
  1424. -
  1425. -    if (argc < 2)
  1426. -        error("sendme: Too few arguments.");
  1427. -    if (strncmp(FULLSYSNAME, argv[argc - 1], SNLN) == 0)
  1428. -        return;
  1429. -    if (s_find(&srec, argv[argc - 1]) != TRUE)
  1430. -        error("sendme: Can't find sys record for %s", argv[argc - 1]);
  1431. -    /* Send the articles. */
  1432. -    if (argc == 2) {
  1433. -        register FILE *    fp;
  1434. -        char        buf[256];
  1435. -
  1436. -        fp = xfopen(INFILE, "r");
  1437. -        while (fgets(buf, sizeof buf, fp) == buf) {
  1438. -            buf[strlen(buf) - 1] = '\0';    /* zap trailing '\n' */
  1439. -            sendmefunc(buf, &srec);
  1440. -        }
  1441. -        (void) fclose(fp);
  1442. -    } else {     /* argc > 2 */
  1443. -        register int    i;
  1444. -
  1445. -        for (i = 1; i < (argc - 1); ++i)
  1446. -            sendmefunc(argv[i], &srec);
  1447. -    }
  1448. -}
  1449. -
  1450. -static
  1451. -sendmefunc(id, sp)
  1452. -register char *        id;
  1453. -register struct srec *    sp;
  1454. -{
  1455. -    register FILE *    fp;
  1456. -    register char *    cp;
  1457. -    char        savedbufname[256];
  1458. -    extern char    firstbufname[];
  1459. -    extern char *    dirname();
  1460. -    extern char *    findfname();
  1461. -
  1462. -    cp = findfname(id);
  1463. -    if (cp == NULL) {
  1464. -        logerr("System %s wants unavailable article %s.",
  1465. -            sp->s_name, id);
  1466. -        return;
  1467. -    }
  1468. -    cp = dirname(cp);
  1469. -    fp = fopen(cp, "r");
  1470. -    if (fp == NULL) {
  1471. -        logerr("Article %s unopenable as %s.", id, cp);
  1472. -        return;
  1473. -    }
  1474. -    (void) strcpy(savedbufname, firstbufname);
  1475. -    (void) strcpy(firstbufname, cp);
  1476. -    transmit(sp, fp, FALSE, (char **) NULL, FALSE);
  1477. -    /* transmit closes fp */
  1478. -    (void) strcpy(firstbufname, savedbufname);
  1479. -}
  1480. -
  1481. -/*
  1482. - * newgroup <groupname>
  1483. - * A new newsgroup has been created.
  1484. - * The body of the article, if present, is a description of the
  1485. - * purpose of the newsgroup.
  1486. - *
  1487. - */
  1488. -c_newgroup(argc, argv)
  1489. -char **argv;
  1490. -{
  1491. -    FILE *fd;
  1492. -    char abuf[BUFLEN], subjline[BUFLEN];
  1493. -    int didcreate = 0;
  1494. -    register char *p, *q;
  1495. -# ifdef NONEWGROUPS
  1496. -#  ifdef ORGDISTRIB
  1497. -    /* local or ORGDISTRIB */
  1498. -    int can_change = (strcmp(header.distribution, "local") == 0) ||
  1499. -                (strcmp(header.distribution, ORGDISTRIB) == 0);
  1500. -#  else /* ! ORGDISTRIB */
  1501. -    /* local only */
  1502. -    int can_change = strcmp(header.distribution, "local") == 0;
  1503. -#  endif /* ORGDISTRIB */
  1504. -# else /* ! NONEWGROUPS */
  1505. -    int can_change = 1;    /* allow changes for all distributions */
  1506. -# endif /* NONEWGROUPS */
  1507. -
  1508. -    if (argc < 2)
  1509. -        error("newgroup: Too few arguments.");
  1510. -
  1511. -    if (header.approved[0] == '\0')
  1512. -        error("newgroup: %s not approved", argv[1]);
  1513. -
  1514. -    /* see if it already exists */
  1515. -    (void) rewind(actfp); clearerr(actfp);
  1516. -    while(fgets(abuf, BUFLEN, actfp) != NULL) {
  1517. -        p = abuf;
  1518. -        q = argv[1];
  1519. -        while (*p++ == *q++)
  1520. -            ;
  1521. -        if (*--q == '\0' && *--p == ' ') {
  1522. -            int modified = 0;
  1523. -            /* Now check if it's correctly moderated/unmoderated */
  1524. -            while (*p++)
  1525. -                ;
  1526. -            p -= 3;
  1527. -            if (argc > 2 && strcmp(argv[2], "moderated") == 0) {
  1528. -                if (*p == 'm')
  1529. -                    return;
  1530. -# ifdef NONEWGROUPS
  1531. -                if(can_change) {
  1532. -                    *p = 'm';
  1533. -                    modified = 1;
  1534. -                }
  1535. -# else /* ! NONEWGROUPS */
  1536. -                *p = 'm';
  1537. -                modified = 1;
  1538. -#endif /* NONEWGROUPS */
  1539. -            } else {
  1540. -                if (*p != 'm')
  1541. -                    return;
  1542. -# ifdef NONEWGROUPS
  1543. -                if(can_change)  {
  1544. -                    *p = 'y';
  1545. -                    modified = 1;
  1546. -                }
  1547. -# else /* ! NONEWGROUPS */
  1548. -                *p = 'y';
  1549. -                modified = 1;
  1550. -# endif /* NONEWGROUPS */
  1551. -            }
  1552. -# ifdef NOTIFY
  1553. -            (void) sprintf(subjline,
  1554. -            "Newsgroup %s change from %smoderated to %smoderated",
  1555. -                argv[1], *p=='y' ? "" : "un",
  1556. -                *p=='y' ? "un" : "");
  1557. -            fd = mailhdr((struct hbuf *)NULL, subjline);
  1558. -            if (fd != NULL) {
  1559. -                if(modified)
  1560. -                    fprintf(fd,
  1561. -"%s has been changed from %smoderated to %smoderated as requested by\n%s\n",
  1562. -                        argv[1], *p=='y' ? "" : "un", 
  1563. -                        *p=='y' ? "un":"", header.path);
  1564. -                else {
  1565. -                    fprintf(fd,
  1566. -"%s\nhas requested that %s be changed from %smoderated to %smoderated\n",
  1567. -                        header.path, argv[1], 
  1568. -                        *p=='y' ? "un" : "",
  1569. -                        *p=='y' ? "" : "un");
  1570. -#ifdef ORGDISTRIB
  1571. -                    fprintf(fd,
  1572. -"You can accomplish this by re-creating the newsgroup with a distribution\n");
  1573. -                    fprintf(fd,
  1574. -"of '%s' by executing the command:\n", ORGDISTRIB);
  1575. -                    fprintf(fd,
  1576. -                "%s/inews -d %s -C %s moderated\n",
  1577. -                        LIB, ORGDISTRIB, argv[1]);
  1578. -#else /* !ORGDISTRIB */
  1579. -                    fprintf(fd,
  1580. -"You can accomplish this by re-creating the newsgroup by executing the command:\n");
  1581. -                    fprintf(fd, "%s/inews -C %s moderated\n",
  1582. -                        LIB, argv[1]);
  1583. -#endif /* !ORGDISTRIB */
  1584. -                }
  1585. -                (void) mclose(fd);
  1586. -            }
  1587. -# endif /* NOTIFY */
  1588. -# ifdef NONEWGROUPS
  1589. -            /*
  1590. -             * No permission to change
  1591. -             */
  1592. -            if(!can_change)
  1593. -                return;
  1594. -# endif /* NONEWGROUPS */
  1595. -            /* The active file was wrong about the state of the
  1596. -             * group. Rewrite the active file
  1597. -             */
  1598. -            (void) fseek(actfp, -2L, 1); /* back up 2 characters */
  1599. -#ifdef USG
  1600. -            /*
  1601. -             * U G L Y   K L U D G E
  1602. -             * This utter piece of tripe is the only way I know of
  1603. -             * to get around the fact that ATT BROKE standard IO
  1604. -             * in System 5.2. Basically, you can't open a file for
  1605. -             * "r+" and then try and write to it. This hack works
  1606. -             * on all "real" USG Unix systems, It will probably
  1607. -             * break on some obscure look alike that doesnt use the
  1608. -             * real ATT stdio.h
  1609. -             * Don't blame me, blame ATT. stdio should have
  1610. -             * already done the following line for us, but it didn't
  1611. -             */
  1612. -            actfp->_flag |= _IOWRT;
  1613. -#endif /* USG */
  1614. -            putc(*p, actfp);
  1615. -            fflush(actfp);
  1616. -            if (*p != 'm')
  1617. -                logerr("Newsgroup %s changed from moderated to unmoderated",
  1618. -                argv[1]);
  1619. -            else
  1620. -                logerr("Newsgroup %s changed from unmoderated to moderated",
  1621. -                argv[1]);
  1622. -            return;
  1623. -        }
  1624. -    }
  1625. -
  1626. -    /* It doesn't already exist, we must create it */
  1627. -
  1628. -    if(can_change) {
  1629. -        didcreate++;
  1630. -        (void) fseek(actfp, 0L, 2); clearerr(actfp);
  1631. -        fprintf(actfp, "%s 00000 00001 %c\n", argv[1],
  1632. -            (argc > 2 && strcmp(argv[2], "moderated") == 0) 
  1633. -                ? 'm' : 'y');
  1634. -        fflush(actfp);
  1635. -    }
  1636. -
  1637. -# ifdef NOTIFY
  1638. -    (void) sprintf(subjline, "Newsgroup %s created", argv[1]);
  1639. -    fd = mailhdr((struct hbuf *)NULL, subjline);
  1640. -    if (fd != NULL) {
  1641. -        if (didcreate) 
  1642. -            fprintf(fd, 
  1643. -        "A new newsgroup called '%s' has been created by %s.\n",
  1644. -                            argv[1], header.path);
  1645. -        else {
  1646. -            fprintf(fd, 
  1647. -        "%s requested that a new newsgroup called '%s' be created.\n",
  1648. -            header.path, argv[1]);
  1649. -            fprintf(fd,"It was approved by %s\n\n",header.approved);
  1650. -            fprintf(fd, 
  1651. -        "You can accomplish this by creating the newgroup yourself\n");
  1652. -#  ifdef ORGDISTRIB
  1653. -            fprintf(fd,"with a distribution of '%s'.\n",
  1654. -                ORGDISTRIB);
  1655. -            fprintf(fd,
  1656. -                "In other words, by executing the command:\n");
  1657. -            fprintf(fd, "%s/inews -d %s -C %s\n", LIB, 
  1658. -                            ORGDISTRIB, argv[1]);
  1659. -#  else /* !ORGDISTRIB */
  1660. -            fprintf(fd, "In other words, by executing the command:\n");
  1661. -            fprintf(fd, "%s/inews -C %s\n", LIB, argv[1]);
  1662. -#  endif /* !ORGDISTRIB */
  1663. -        }
  1664. -        (void) mclose(fd);
  1665. -    }
  1666. -# endif /* NOTIFY */
  1667. -}
  1668. -
  1669. -/*
  1670. - * rmgroup <groupname>
  1671. - * An old newsgroup is being cancelled on a network wide basis.
  1672. - */
  1673. -c_rmgroup(argc, argv)
  1674. -char **argv;
  1675. -{
  1676. -    FILE *fd;
  1677. -    int shouldremove = 0;
  1678. -#ifdef NOTIFY
  1679. -    char subjline[BUFLEN];
  1680. -#endif    /* NOTIFY */
  1681. -
  1682. -    if (argc < 2)
  1683. -        error("rmgroup: Too few arguments.");
  1684. -    if (!validng(argv[1]))
  1685. -        return;
  1686. -    if (header.approved[0] == '\0')
  1687. -        error("rmgroup: %s not approved", argv[1]);
  1688. -
  1689. -#ifndef MANUALLY
  1690. -#ifdef ORGDISTRIB
  1691. -    /*
  1692. -     * Allow local as well as organizational removals
  1693. -     */
  1694. -    if (!strcmp(ORGDISTRIB, header.distribution)
  1695. -       || !strcmp("local", header.distribution))
  1696. -#else    /* !ORGDISTRIB */        
  1697. -    if (!strcmp("local", header.distribution))
  1698. -#endif    /* !ORGDISTRIB */        
  1699. -        shouldremove++;
  1700. -#endif /* !MANUALLY */
  1701. -#ifdef NOTIFY
  1702. -    sprintf(subjline, "Recevied rmgroup for %s", argv[1]);
  1703. -    fd = mailhdr((struct hbuf *)NULL, subjline);
  1704. -    if (fd != NULL) {
  1705. -        if (shouldremove) {
  1706. -            fprintf(fd, "Newsgroup '%s' has been removed by %s.\n\n",
  1707. -                argv[1], header.path);
  1708. -#  ifdef USG
  1709. -            fprintf(fd, "You may need to remove the directory %s by hand\n",
  1710. -                dirname(argv[1]));
  1711. -#  endif
  1712. -        } else {
  1713. -            fprintf(fd, "%s requested that newsgroup %s be removed.\n",
  1714. -                header.path, argv[1]);
  1715. -            fprintf(fd, "You should remove it by hand\n");
  1716. -            fprintf(fd, "To do this, execute the command\n");
  1717. -            fprintf(fd, "\t%s/rmgroup %s\n", LIB, argv[1]);
  1718. -        }
  1719. -        (void) mclose(fd);
  1720. -    }
  1721. -#endif /* NOTIFY */
  1722. -
  1723. -    if (shouldremove) {
  1724. -        int rc;
  1725. -        /* We let the shell do all the work.
  1726. -         * See the rmgrp shell script. */
  1727. -        (void) setuid(geteuid()); /* otherwise it won't rmdir the dir */
  1728. -        (void) sprintf(bfr, "exec %s/rmgroup %s", LIB, argv[1]);
  1729. -        rc = system(bfr);
  1730. -        log("system(%s) status %d", bfr, rc);
  1731. -    }
  1732. -}
  1733. -
  1734. -/*
  1735. - * cancel <artid>
  1736. - * Cancel the named article
  1737. - */
  1738. -c_cancel(argc, argv)
  1739. -char **argv;
  1740. -{
  1741. -    char *line, *p, *q, *r, *poster;
  1742. -    char *findhist();
  1743. -    register FILE *fp;
  1744. -    char whatsisname[BUFLEN], nfilename[BUFLEN];
  1745. -    time_t t;
  1746. -    int su = 0;
  1747. -#ifndef u370
  1748. -    struct hbuf htmp;
  1749. -#endif /* !u370 */
  1750. -
  1751. -    if (argc < 2)
  1752. -        error("cancel: Too few arguments.");
  1753. -    (void) strcpy(whatsisname, senderof(&header));
  1754. -    line = findhist(argv[1]);
  1755. -    if (line == NULL) {
  1756. -        struct tm *tm;
  1757. -        log("Can't cancel %s:  non-existent", argv[1]);
  1758. -        (void) time(&t);
  1759. -        tm = localtime(&t);
  1760. -#ifdef USG
  1761. -        sprintf(bfr,"%s\t%2.2d/%2.2d/%d %2.2d:%2.2d\tcancelled",
  1762. -#else /* !USG */
  1763. -        sprintf(bfr,"%s\t%02d/%02d/%d %02d:%02d\tcancelled",
  1764. -#endif /* !USG */
  1765. -           argv[1], tm->tm_mon+1, tm->tm_mday, tm->tm_year, tm->tm_hour,
  1766. -           tm->tm_min);
  1767. -        savehist(bfr);
  1768. -        return 1;
  1769. -    }
  1770. -
  1771. -    q = index(line, '\t');
  1772. -    p = index(q+1, '\t');
  1773. -    if (p == NULL || *++p == '\0' || *p == '\n') {
  1774. -        *q = '\0';
  1775. -        log("Expired article %s", line);
  1776. -        return 1;
  1777. -    }
  1778. -    if (strcmp(p, "cancelled") == 0) {
  1779. -        *q = '\0';
  1780. -        log("Already Cancelled %s", line);
  1781. -        return 1;
  1782. -    } else
  1783. -        log("Cancelling %s", line);
  1784. -    if ((uid == ROOTID||uid == 0) && strcmp(header.distribution, "local") == 0)
  1785. -        su = 1;
  1786. -    while (*p) {
  1787. -        q = index(p, ' ');
  1788. -        if (q)
  1789. -            *q = '\0';
  1790. -        (void) strcpy(nfilename, dirname(p));
  1791. -        fp = fopen(nfilename, "r");
  1792. -        if (fp == NULL) {
  1793. -            log("Already Cancelled %s", line);
  1794. -            return 1;
  1795. -        }
  1796. -        htmp.unrec[0] = NULL;
  1797. -        if (hread(&htmp, fp, TRUE) == NULL) {
  1798. -            if (bfr[0] == '/') {
  1799. -                fp = fopen(bfr, "r");
  1800. -                if (fp == NULL
  1801. -                    || hread(&htmp, fp, TRUE) == NULL)
  1802. -                    error("Article is garbled.");
  1803. -            } else 
  1804. -                error("Article is garbled.");
  1805. -        }
  1806. -        (void) fclose(fp);
  1807. -        poster = senderof(&htmp);
  1808. -        /* only compare up to '.' or ' ' */
  1809. -        r = index(poster,'.');
  1810. -        if (r == NULL)
  1811. -            r = index(poster,' ');
  1812. -        if (r != NULL)
  1813. -            *r = '\0';
  1814. -        if (!su && strncmp(whatsisname, poster,strlen(poster))) {
  1815. -            error("Not contributor: posted by %s, and you are %s", poster, whatsisname);
  1816. -        }
  1817. -
  1818. -        (void) unlink(nfilename);
  1819. -        p = q+1;
  1820. -    }
  1821. -    return 0;
  1822. -}
  1823. -
  1824. -/*
  1825. - * sendsys    (no arguments)
  1826. - *
  1827. - * Mail the sys file to the person submitting the article.
  1828. - * POLICY: the contents of your sys file are public information
  1829. - * and as such, you should not change this code.  You may feel
  1830. - * free to arrange for it to manually notify you, in the event
  1831. - * that you want to do something to clean it up before it goes out.
  1832. - * Secret sites on the net are expressly frowned on.
  1833. - * 
  1834. - * The purpose of this command is for making a network map.  The
  1835. - * details of your link and which newsgroups are forwarded are not
  1836. - * important, in case you want to sanitize them.  Since the definition
  1837. - * of USENET is those sites getting net.announce, you can disable this
  1838. - * on sites not getting net articles, but if you take out the list of
  1839. - * forwarded newsgroups, and you have sites that only get local newsgroups,
  1840. - * you should make this clear, or remove those sites from what you send out.
  1841. - */
  1842. -/* ARGSUSED */
  1843. -c_sendsys(argc, argv)
  1844. -char **argv;
  1845. -{
  1846. -    register FILE *f, *u;
  1847. -    int c;
  1848. -
  1849. -#ifdef NOTIFY
  1850. -    f = mailhdr((struct hbuf *)NULL, "sendsys control message");
  1851. -    if (f != NULL) {
  1852. -        fprintf(f, "%s requested your %s/sys file.\n", header.path, LIB);
  1853. -        fprintf(f, "It has been sent.\n");
  1854. -        (void) mclose(f);
  1855. -    }
  1856. -#endif /* NOTIFY */
  1857. -    f = mailhdr(&header, "response to your sendsys request");
  1858. -    u = fopen(SUBFILE, "r");
  1859. -    if (f != NULL && u != NULL) {
  1860. -        while ((c=getc(u)) != EOF)
  1861. -            putc(c, f);
  1862. -        (void) fclose(u);
  1863. -        (void) mclose(f);
  1864. -    }
  1865. -}
  1866. -
  1867. -/*
  1868. - * senduuname    (no arguments)
  1869. - *
  1870. - * Run the "uuname" command and send it back to the person who submitted
  1871. - * the article.  The purpose of this control message is for attempting to
  1872. - * make a uucp net map.
  1873. - *
  1874. - * POLICY: If you view this information as not public (because you have
  1875. - * a connection you consider secret, or know a site that considers itself
  1876. - * secret) you can feel free to change this code in whatever way is
  1877. - * appropriate, so long as it sends some response back to the sender.  If
  1878. - * you don't run uucp, this code does not make sense, and so an error
  1879. - * message (or garbage, such as "research") will be mailed back.
  1880. - *
  1881. - * If you wish to add or remove sites from the output of uuname, you
  1882. - * may wish to use the euuname.sh shell script here.
  1883. - */
  1884. -/* ARGSUSED */
  1885. -c_senduuname(argc, argv)
  1886. -char **argv;
  1887. -{
  1888. -    char buf[256];
  1889. -    FILE *fd, *u;
  1890. -    int c;
  1891. -
  1892. -#ifdef NOTIFY
  1893. -    fd = mailhdr((struct hbuf *)NULL, "uuname control message");
  1894. -    fprintf(fd, "%s requested your uuname output\n", header.path);
  1895. -    (void) mclose(fd);
  1896. -#endif /* NOTIFY */
  1897. -    fd = mailhdr(&header, "response to your senduuname request");
  1898. -#ifdef UUPROG
  1899. -    if (UUPROG[0] == '/')
  1900. -        (void) strcpy(buf, UUPROG);
  1901. -    else
  1902. -        (void) sprintf(buf, "%s/%s", LIB, UUPROG);
  1903. -#else
  1904. -    (void) strcpy(buf, "uuname");
  1905. -#endif
  1906. -    u = popen(buf, "r");
  1907. -    if (fd != NULL && u != NULL) {
  1908. -        while ((c=getc(u)) != EOF)
  1909. -            putc(c, fd);
  1910. -        (void) pclose(u);
  1911. -        (void) mclose(fd);
  1912. -    }
  1913. -}
  1914. -
  1915. -/*
  1916. - * Send the version number to the right person.
  1917. - */
  1918. -/* ARGSUSED */
  1919. -c_version(argc, argv)
  1920. -char **argv;
  1921. -{
  1922. -    register FILE *f;
  1923. -
  1924. -    f = mailhdr(&header, "Our news version");
  1925. -    if (f == NULL)
  1926. -        error("Cannot send back error message");
  1927. -    fprintf(f, "Currently running news version %s.\n\n", news_version);
  1928. -    fprintf(f, "The header of your message follows:\n\n");
  1929. -    (void) hwrite(&header, f);
  1930. -    (void) mclose(f);
  1931. -}
  1932. -
  1933. -/*
  1934. - * Check the active file for old or missing newsgroups
  1935. - * Body of article is list of valid groups
  1936. - */
  1937. -/* ARGSUSED */
  1938. -c_checkgroups(argc, argv)
  1939. -char **argv;
  1940. -{
  1941. -    int rc;
  1942. -
  1943. -    (void) setuid(geteuid());
  1944. -    /* dont change the cat %s| to < %s, it breaks some "unix" systems */
  1945. -    (void) sprintf(bfr, "cat %s | %s/checkgroups %s", INFILE, LIB,
  1946. -#ifdef NOTIFY
  1947. -        (TELLME && *TELLME) ? TELLME : NEWSUSR );
  1948. -#else /* !NOTIFY */
  1949. -        NEWSUSR);
  1950. -#endif /* !NOTIFY */
  1951. -    rc = system(bfr);
  1952. -    log("system(%s) status %d", bfr, rc);
  1953. -}
  1954. -
  1955. -/*
  1956. - * An unknown control message has been received.
  1957. - */
  1958. -c_unknown(h, ctlmsgtext)
  1959. -struct hbuf *h;
  1960. -char *ctlmsgtext;
  1961. -{
  1962. -    register FILE *f;
  1963. -
  1964. -    log("UNKNOWN Ctl Msg %s from %s", ctlmsgtext, h->path);
  1965. -#ifdef NOTIFY
  1966. -    f = mailhdr((struct hbuf *)NULL, "Unrecognized Control Message");
  1967. -    if (f != NULL) {
  1968. -        fprintf(f, "Currently running news version %s.\n\n", news_version);
  1969. -        fprintf(f, "The header of the message follows:\n\n");
  1970. -        (void) hwrite(h, f);
  1971. -        (void) mclose(f);
  1972. -    }
  1973. -#endif /* NOTIFY */
  1974. -}
  1975. -
  1976. -/* ARGSUSED */
  1977. -c_unimp(argc, argv)
  1978. -char **argv;
  1979. -{
  1980. -    register FILE *f;
  1981. -
  1982. -#ifdef NOTIFY
  1983. -    f = mailhdr((struct hbuf*)NULL, "Unimplemented Control Message");
  1984. -    if (f != NULL) {
  1985. -        fprintf(f, "Currently running news version B %s.\n\n", news_version);
  1986. -        fprintf(f, "The header of the message follows:\n\n");
  1987. -        (void) hwrite(&header, f);
  1988. -        (void) mclose(f);
  1989. -    }
  1990. -#endif /* NOTIFY */
  1991. -}
  1992. -
  1993. -/*
  1994. - * This is a modified version of popen, made more secure.  Rather than
  1995. - * forking off a shell, you get a bare process.  You must have exactly
  1996. - * one argument, and the command must be mail (or sendmail if you have it).
  1997. - */
  1998. -#define    RDR    0
  1999. -#define    WTR    1
  2000. -static    int    mopen_pid[20];
  2001. -char *replyname();
  2002. -
  2003. -FILE *
  2004. -mhopen(hptr)
  2005. -struct hbuf *hptr;
  2006. -{
  2007. -    int p[2];
  2008. -    register myside, hisside, pid;
  2009. -    char *sendto = "usenet";
  2010. -
  2011. -    if (hptr)
  2012. -        sendto = replyname(hptr);
  2013. -    else {
  2014. -#ifdef NOTIFY
  2015. -        if (TELLME)
  2016. -            sendto = TELLME;
  2017. -#endif /* NOTIFY */
  2018. -        if (sendto == NULL || *sendto == NULL)
  2019. -            return NULL;
  2020. -    }
  2021. -    verifyname(sendto);
  2022. -    if(pipe(p) < 0)
  2023. -        return NULL;
  2024. -    myside = p[WTR];
  2025. -    hisside = p[RDR];
  2026. -    if((pid = vfork()) == 0) {
  2027. -        /* myside and hisside reverse roles in child */
  2028. -        (void) close(myside);
  2029. -        (void) close(0);
  2030. -        (void) dup(hisside);
  2031. -        (void) close(hisside);
  2032. -        (void) setgid(gid);
  2033. -        (void) setuid(uid);
  2034. -#ifdef SENDMAIL
  2035. -        execl(SENDMAIL, "sendmail", "-oi", "-oeq", sendto, (char *)NULL);
  2036. -#endif /* SENDMAIL */
  2037. -#ifdef MMDF
  2038. -        execl(MMDF, "inews-mail", "-smuxto,cc*", (char *)NULL);
  2039. -#endif /* MMDF */
  2040. -        execl("/bin/mail", "mail", sendto, (char *)NULL);
  2041. -        execl("/usr/bin/mail", "mail", sendto, (char *)NULL);
  2042. -        execl("/usr/ucb/mail", "mail", sendto, (char *)NULL);
  2043. -        _exit(1);
  2044. -    }
  2045. -    if(pid == -1)
  2046. -        return NULL;
  2047. -    mopen_pid[myside] = pid;
  2048. -    (void) close(hisside);
  2049. -    return(fdopen(myside, "w"));
  2050. -}
  2051. -
  2052. -mclose(ptr)
  2053. -FILE *ptr;
  2054. -{
  2055. -    register f, r, (*hstat)(), (*istat)(), (*qstat)();
  2056. -    int status;
  2057. -
  2058. -    f = fileno(ptr);
  2059. -    (void) fclose(ptr);
  2060. -    istat = signal(SIGINT, SIG_IGN);
  2061. -    qstat = signal(SIGQUIT, SIG_IGN);
  2062. -    hstat = signal(SIGHUP, SIG_IGN);
  2063. -    while((r = wait(&status)) != mopen_pid[f] && r != -1)
  2064. -        ;
  2065. -    if(r == -1)
  2066. -        status = -1;
  2067. -    signal(SIGINT, istat);
  2068. -    signal(SIGQUIT, qstat);
  2069. -    signal(SIGHUP, hstat);
  2070. -    return status;
  2071. -}
  2072. -
  2073. -/*
  2074. - * mhopen a pipe to mail, write out a std header, and return the file ptr.
  2075. - *
  2076. - * We don't include a From: field because this is probably uucp, i.e.
  2077. - * explicitly routed.  Leave it up to the recipient's mailer.
  2078. - * Always include the To: field because if we ge back failed mail, we
  2079. - * might be able to deliver it by hand if we know to wom it was addressed.
  2080. - * By convention, hptr==NULL means to send the message to the local contact person.
  2081. - */
  2082. -FILE *
  2083. -mailhdr(hptr, subject)
  2084. -struct hbuf *hptr;
  2085. -char  *subject;
  2086. -{
  2087. -    FILE *fp;
  2088. -    time_t now;
  2089. -    char *to = "usenet";
  2090. -
  2091. -#ifdef NOTIFY
  2092. -    if (TELLME && *TELLME)
  2093. -        to = TELLME;
  2094. -#endif /* NOTIFY */
  2095. -    if (hptr)
  2096. -        to = replyname(hptr);
  2097. -
  2098. -    if ((fp = mhopen(hptr)) != NULL) {
  2099. -        (void) time(&now);
  2100. -        fprintf(fp, "Date: %s\n", arpadate(&now));
  2101. -#ifdef MMDF
  2102. -        fprintf(fp, "From: The News System <usenet@%s%s>\n",
  2103. -                FULLSYSNAME, MYDOMAIN);
  2104. -#endif /* MMDF */
  2105. -        fprintf(fp, "To: %s\n", to);
  2106. -        fprintf(fp, "Subject: %s\n", subject);
  2107. -#ifdef HIDDENNET
  2108. -        if (strcmp(LOCALSYSNAME, FULLSYSNAME))
  2109. -            fprintf(fp, "Responding-System: %s.%s%s\n\n",
  2110. -                LOCALSYSNAME, FULLSYSNAME, MYDOMAIN);
  2111. -        else
  2112. -#endif /* !HIDDENNET */
  2113. -            fprintf(fp, "Responding-System: %s%s\n\n",
  2114. -                FULLSYSNAME, MYDOMAIN);
  2115. -    }
  2116. -    return fp;
  2117. -}
  2118. -
  2119. -/*
  2120. - * verify that the name mail is being sent to does not contain any
  2121. - * nasty hooks to invoke funny functions from the shell or the like.
  2122. - */
  2123. -verifyname(sendto)
  2124. -char *sendto;
  2125. -{
  2126. -    /* Be sure we DO allow alphabetics, !, :, ., -, @. *. */
  2127. -    char *nasty = "\"'\\`^|;& <>/~";
  2128. -    register char *p;
  2129. -
  2130. -    if (sendto[0] <= ' ') {
  2131. -        log("nasty mail name %s from %s", sendto, header.path);
  2132. -        xxit(1);
  2133. -    }
  2134. -    for (p=sendto; *p; p++) {
  2135. -        if (*p == ' ') {
  2136. -            *p = 0;
  2137. -            break;
  2138. -        }
  2139. -    }
  2140. -    if (strpbrk(sendto, nasty) != NULL)
  2141. -        error("nasty mail name %s from %s", sendto, header.path);
  2142. -
  2143. -    for (nasty = sendto; (nasty = index(nasty, '.')) != NULL; ) {
  2144. -        if (*++nasty == '.')    /* check for .. */
  2145. -            error("nasty mail name %s from %s", sendto, header.path);
  2146. -    }
  2147. -}
  2148. -
  2149. -/*
  2150. - * Checks to make sure the control message is OK to post.
  2151. - */
  2152. -ctlcheck()
  2153. -{
  2154. -    char msg[BUFLEN];
  2155. -    char *p;
  2156. -
  2157. -    if (!is_ctl)
  2158. -        return;
  2159. -
  2160. -    if (header.ctlmsg[0])
  2161. -        (void) strcpy(msg, header.ctlmsg);
  2162. -    else
  2163. -        (void) strcpy(msg, header.title);
  2164. -
  2165. -    p = index(msg, ' ');
  2166. -    if (p)
  2167. -        *p = 0;
  2168. -    
  2169. -    if (strcmp(msg, "ihave") == 0 || strcmp(msg, "sendbad") == 0 ||
  2170. -        strcmp(msg, "sendme") == 0) {
  2171. -        return;    /* no restrictions */
  2172. -    } else if (strcmp(msg, "newgroup") == 0) {
  2173. -        suser();
  2174. -    } else if (strcmp(msg, "rmgroup") == 0) {
  2175. -        suser();
  2176. -    } else if (strcmp(msg, "sendsys") == 0) {
  2177. -        suser();
  2178. -    } else if (strcmp(msg, "senduuname") == 0) {
  2179. -        suser();
  2180. -    } else if (strcmp(msg, "checkgroups") == 0) {
  2181. -        suser();
  2182. -    } else if (strcmp(msg, "version") == 0) {
  2183. -        return;    /* no restrictions */
  2184. -    } else if (strcmp(msg, "cancel") == 0) {
  2185. -        return;    /* no restrictions at this level */
  2186. -    } else if (strcmp(msg, "delsub") == 0) {
  2187. -        if (!prefix(header.nbuf, "to.")) {
  2188. -            printf("Must be in a 'to.system' newsgroup.");
  2189. -            xxit(0);
  2190. -        }
  2191. -        return;
  2192. -    } else {
  2193. -        printf("Unrecognized control message - %s\n", msg);
  2194. -        xxit(0);
  2195. -    }
  2196. -}
  2197. -
  2198. -/* Make sure this guy is special. */
  2199. -suser()
  2200. -{
  2201. -    if (uid == 0 || uid == ROOTID)
  2202. -        return;
  2203. -    /*
  2204. -     * We assume that since our real uid is the same as NEWSUSR
  2205. -     * (the euid) we were run by rootid and it did a setuid.
  2206. -     * Too bad we can't set just the effective uid like suid does.
  2207. -     */
  2208. -    if (uid == geteuid())
  2209. -        return;
  2210. -#ifdef IHCC
  2211. -    printf("Please use the command:\n\ttoolnews providers\n");
  2212. -    printf("then call one of the news people.\n");
  2213. -#else
  2214. -    printf("Get your local netnews contact to do it for you.\n");
  2215. -#endif
  2216. -    xxit(0);
  2217. -}
  2218. *-*-END-of-src/control.c-*-*
  2219. echo x - src/unbatch.c 1>&2
  2220. sed 's/.//' >src/unbatch.c <<'*-*-END-of-src/unbatch.c-*-*'
  2221. -/*
  2222. - * unbatchnews: extract news in batched format and process it one article
  2223. - * at a time.  The format looks like
  2224. - *    #! rnews 1234
  2225. - *    article containing 1234 characters
  2226. - *    #! rnews 4321
  2227. - *    article containing 4321 characters
  2228. - *
  2229. - *    or
  2230. - *
  2231. - *    #! command [args]
  2232. - *    calls LIBDIR/command [args] to process the news
  2233. - */
  2234. -
  2235. -#ifdef SCCSID
  2236. -static char    *SccsId = "@(#)unbatch.c    1.22    10/23/86";
  2237. -#endif /* SCCSID */
  2238. -
  2239. -#define    MAXARGS        20
  2240. -
  2241. -#include "defs.h"
  2242. -#include <stdio.h>
  2243. -#include <ctype.h>
  2244. -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
  2245. -#include <fcntl.h>
  2246. -#endif /* USG */
  2247. -
  2248. -char buf[BUFSIZ];
  2249. -char sibuf[BUFSIZ];
  2250. -
  2251. -main()
  2252. -{
  2253. -    register int c;
  2254. -    register FILE *pfn;
  2255. -    register long size;
  2256. -    char *filename;
  2257. -    int pid, wpid, exstat;
  2258. -    char *mktemp(), *gets();
  2259. -    long atol();
  2260. -
  2261. -    filename = mktemp("/tmp/unbnewsXXXXXX");
  2262. -    setbuf(stdin, (char *)NULL);    /* only for the first line */
  2263. -    if (gets(buf) == NULL) {
  2264. -        (void) unlink(filename);
  2265. -        exit(0);
  2266. -    }
  2267. -    if (strncmp(buf, "#! rnews ", 9) != 0) {
  2268. -        docmd(buf);
  2269. -        /* should not return */
  2270. -        logerr("unbatch: docmd returned!");
  2271. -        exit(1);
  2272. -    }
  2273. -
  2274. -    setbuf(stdin, sibuf);    /* buffer the rest of the file */
  2275. -
  2276. -    do {
  2277. -        while (strncmp(buf, "#! rnews ", 9) 
  2278. -            && strncmp(buf, "! rnews ", 8)) { /* kludge for bug */
  2279. -            register char *cp;
  2280. -            for (cp = buf; *cp != '\0'; ++cp)
  2281. -                if (!isascii(*cp) ||
  2282. -                    (!isprint(*cp) && !isspace(*cp)))
  2283. -                        *cp = '?';
  2284. -            logerr("out of sync, skipping %s", buf);
  2285. -            if (gets(buf) == NULL)
  2286. -                exit(0);
  2287. -        }
  2288. -        size = atol(buf + (buf[0] == '#' ? 9 : 8));
  2289. -        if(size <= 0) {
  2290. -            logerr("nonsense size %ld", size);
  2291. -            continue;
  2292. -        }
  2293. -#ifdef VMS
  2294. -/* The loop is to delete all versions. */
  2295. -        while (unlink(filename) == 0)
  2296. -            ;
  2297. -#endif /* VMS */
  2298. -        pfn = fopen(filename, "w");
  2299. -        while(--size >= 0 && (c = getc(stdin)) != EOF)
  2300. -            putc(c, pfn);
  2301. -        if (ferror(pfn) || fclose(pfn)) {    /* disk full? */
  2302. -            logerr("error writing temporary file");
  2303. -            break;
  2304. -        }
  2305. -
  2306. -        /*
  2307. -         * If we got a truncated batch, don't process the
  2308. -         * last article; it will probably be received again.
  2309. -         */
  2310. -        if (size > 0) {
  2311. -            logerr("truncated batch");
  2312. -            break;
  2313. -        }
  2314. -
  2315. -        /*
  2316. -         * rnews < filename
  2317. -         */
  2318. -        while ((pid = vfork()) == -1) {
  2319. -            logerr("fork failed, waiting...\n");
  2320. -            sleep(60);
  2321. -        }
  2322. -        if (pid == 0) {
  2323. -            (void) close(0);
  2324. -            (void) open(filename, 0);
  2325. -#ifdef IHCC
  2326. -            (void) sprintf(buf, "%s/%s/rnews", logdir(HOME), LIBDIR);
  2327. -#else
  2328. -            (void) sprintf(buf, "%s/rnews", BINDIR);
  2329. -#endif
  2330. -#ifdef SPOOLNEWS
  2331. -            execlp(buf, "rnews", "-S", (char *)0);
  2332. -#else /* !SPOOLNEWS */
  2333. -            execlp(buf, "rnews", (char *)0);
  2334. -#endif /* !SPOOLNEWS */
  2335. -            perror("rnews");
  2336. -            exit(1);
  2337. -        }
  2338. -        while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
  2339. -            ;
  2340. -    } while (gets(buf) != NULL);
  2341. -    (void) unlink(filename);
  2342. -    exit(0);
  2343. -}
  2344. -
  2345. -docmd(p)
  2346. -register char *p;
  2347. -{
  2348. -    char *args[MAXARGS];
  2349. -    register char **ap = args;
  2350. -    char path[BUFSIZ];
  2351. -    char *rindex(), *cp;
  2352. -
  2353. -    while (*p && !isspace(*p))        /* skip leading #! crud */
  2354. -        p++;
  2355. -
  2356. -    while (isspace(*p))
  2357. -        p++;
  2358. -
  2359. -    while (*p != '\0') {
  2360. -        *ap++ = p;
  2361. -        if (ap >= &args[MAXARGS]) {
  2362. -            logerr("unbatch: Too many args to %s", args[0]);
  2363. -            exit(2);
  2364. -        }
  2365. -        while (*p && !isspace(*p))
  2366. -            p++;
  2367. -        if (*p)
  2368. -            *p++ = '\0';
  2369. -        while (isspace(*p))
  2370. -            p++;
  2371. -    }
  2372. -    *ap = (char *)0;
  2373. -
  2374. -    if (ap == args) {
  2375. -        logerr("unbatch: no command to execute");
  2376. -        exit(2);
  2377. -    }
  2378. -
  2379. -    /* strip off any leading pathname in case someone gets tricky */
  2380. -    cp = rindex(args[0], '/');
  2381. -    if (cp++ == NULL)
  2382. -        cp = args[0];
  2383. -
  2384. -    sprintf(path, "%s/%s", LIBDIR, cp);
  2385. -
  2386. -    /*
  2387. -     * "path" is absolute, no searching is needed,  we use
  2388. -     * 'execvp' solely so that sh scripts will be handled
  2389. -     */
  2390. -    (void) execvp(path, args);
  2391. -    perror(path);
  2392. -    exit(2);
  2393. -}
  2394. -
  2395. -/*
  2396. - * Log the given message, with printf strings and parameters allowed,
  2397. - * on the log file, if it can be written.
  2398. - */
  2399. -/* VARARGS1 */
  2400. -logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  2401. -char *fmt;
  2402. -{
  2403. -    FILE *logfile;
  2404. -    char lfname[BUFSIZ];        /* the log file */
  2405. -    char bfr[BUFSIZ];
  2406. -    char *logtime, *ctime(); 
  2407. -    long t;
  2408. -
  2409. -    (void) time(&t);
  2410. -    logtime = ctime(&t);
  2411. -    logtime[16] = 0;
  2412. -    logtime += 4;
  2413. -
  2414. -#ifdef IHCC
  2415. -    (void) sprintf(lfname, "%s/%s/errlog", logdir(HOME), LIBDIR);
  2416. -#else
  2417. -    (void) sprintf(lfname, "%s/errlog", LIBDIR);
  2418. -#endif
  2419. -
  2420. -    (void) sprintf(bfr, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  2421. -    (void) fprintf(stderr, "%s\n", bfr);
  2422. -    if (access(lfname, 0) == 0 && (logfile = fopen(lfname, "a")) != NULL) {
  2423. -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
  2424. -        int flags;
  2425. -        flags = fcntl(fileno(logfile), F_GETFL, 0);
  2426. -        (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
  2427. -#else /* v7 */
  2428. -        (void) lseek(fileno(logfile), 0L, 2);
  2429. -#endif /* v7 */
  2430. -        fprintf(logfile, "%s\tbatch\t%s\n", logtime, bfr);
  2431. -        (void) fclose(logfile);
  2432. -    }
  2433. -}
  2434. *-*-END-of-src/unbatch.c-*-*
  2435. echo x - src/euninstal.com 1>&2
  2436. sed 's/.//' >src/euninstal.com <<'*-*-END-of-src/euninstal.com-*-*'
  2437. -$ ! @(#)euninstal.com    1.2    10/28/86
  2438. -$ ! This DCL script installs inews and rnews with the necessary
  2439. -$ ! privileges in a Eunice system.
  2440. -$ SET PROCESS/PRIV=CMKRNL
  2441. -$ RUN SYS$SYSTEM:INSTALL
  2442. -EUN_USR:[USR.BIN]RNEWS. /OPEN/SHARED/PRIV=SYSPRV
  2443. -EUN_USR:[USR.LIB.NEWS]INEWS. /OPEN/SHARED/PRIV=SYSPRV
  2444. -$ EXIT
  2445. *-*-END-of-src/euninstal.com-*-*
  2446. exit
  2447.  
  2448.