Annotation of 43BSDTahoe/new/news/src/postnews.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This software is Copyright (c) 1986 by Rick Adams.
                      3:  *
                      4:  * Permission is hereby granted to copy, reproduce, redistribute or
                      5:  * otherwise use this software as long as: there is no monetary
                      6:  * profit gained specifically from the use or reproduction or this
                      7:  * software, it is not sold, rented, traded or otherwise marketed, and
                      8:  * this copyright notice is included prominently in any copy
                      9:  * made.
                     10:  *
                     11:  * The author make no claims as to the fitness or correctness of
                     12:  * this software for any use whatsoever, and it is provided as is. 
                     13:  * Any use of this software is at the user's own risk.
                     14:  *
                     15:  * Postnews: post a news message to Usenet.  This C version replaces a shell
                     16:  * script, and does more intelligent prompting and filtering than possible
                     17:  * in a shell script.
                     18:  */
                     19: #ifdef SCCSID
                     20: static char    *SccsId = "@(#)postnews.c       1.33    10/15/87";
                     21: #endif /* SCCSID */
                     22: 
                     23: #include "params.h"
                     24: 
                     25: # ifndef ROOTID
                     26: extern int ROOTID;
                     27: # endif
                     28: #define APPEND 1
                     29: #define REPLACE 2
                     30: 
                     31: extern char *MAILPARSER;
                     32: 
                     33: char tempfname[50];            /* file name used for making article */
                     34: char original[BUFLEN];         /* file name of original, used in followup */
                     35: char homedir[BUFLEN];          /* HOME environment setting */
                     36: char user[SBUFLEN];            /* user name */
                     37: char ccname[BUFLEN];           /* file name for article copy */
                     38: 
                     39: /* article header information */
                     40: char subject[BUFLEN];
                     41: char distribution[BUFLEN];
                     42: char references[BUFLEN];
                     43: char newsgroups[BUFLEN];
                     44: char isfrom[BUFLEN];
                     45: char msgid[BUFLEN];
                     46: char keywords[BUFLEN];
                     47: char summary[BUFLEN];
                     48: 
                     49: char ngsep[] = { NGDELIM, '\0' };      /* == "," */
                     50: 
                     51: char *Progname = "postnews";           /* for xerror */
                     52: 
                     53: time_t fmodtime;
                     54: char buf[BUFLEN];
                     55: 
                     56: #define MAXDISTR       16
                     57: struct distr {
                     58:        char abbr[24];
                     59:        char descr[128];
                     60: } distr[MAXDISTR];
                     61: 
                     62: char def_distr[24] = "";       /* default distribution */
                     63: FILE *xfopen();
                     64: 
                     65: main(argc, argv)
                     66: char *argv[];
                     67: {
                     68:        register int c;
                     69: 
                     70:        init();
                     71: 
                     72:        if (argc == 2) {
                     73:                if (!PREFIX(argv[1], SPOOL))
                     74:                        xerror("Can only followup to articles in %s", SPOOL);
                     75:                followup(argv[1]);
                     76:                (void) strcpy(original, argv[1]);
                     77:        } else
                     78:        if (askyes("Is this message in response to some other message? ","no")) {
                     79:                char ng[BUFLEN], num[BUFLEN];
                     80:                long i, j, lastnum;
                     81:                register char *p;
                     82:                int fd, dir;
                     83:                char canpost;
                     84: 
                     85:                getpr("In what newsgroup was the article posted? ",ng);
                     86:                if (!valid_ng(ng, &i, &j, &canpost))
                     87:                        if (canpost == 'i' )
                     88:                                byebye("There is no such newsgroup.");
                     89:                        else if (canpost == 'n')
                     90:                                byebye("You are not allowed to post to that group.");
                     91: 
                     92:                printf("Valid article numbers are from %ld to %ld\n", j, i);
                     93:                lastnum = i + 1;
                     94:                dir = -1;
                     95: 
                     96:                for(;;) {
                     97:                        getpr("\nWhat was the article number? ", num);
                     98:                        switch(num[0]) {
                     99:                        case '+':
                    100:                                dir = 1;
                    101:                                sprintf(num, "%ld", lastnum + 1);
                    102:                                break;
                    103:                        case '-':
                    104:                                dir = -1;
                    105:                                /* no break */
                    106:                        case '\0':
                    107:                                sprintf(num, "%ld", lastnum + dir);
                    108:                                break;
                    109:                        }
                    110: #ifdef SERVER
                    111:                        if (getarticle(ng, num, "ARTICLE") == NULL)
                    112:                                        goto nothere;
                    113:                        strcpy(original, article_name());
                    114: #else  /* !SERVER */
                    115:                        (void) sprintf(original, "%s/%s", SPOOL, ng);
                    116:                        for (p=original+strlen(SPOOL)+1; *p ;++p)
                    117:                                if (*p == '.')
                    118:                                        *p = '/';
                    119:                        (void) strcat(original, "/");
                    120:                        (void) strcat(original, num);
                    121: #endif /* !SERVER */
                    122:                        if ((fd=open(original,0)) >= 0) {
                    123:                                (void) close(fd);
                    124:                                printf("\narticle %s\n", original);
                    125:                                if (article_line(original, "From: ", buf))
                    126:                                        printf("%s\n", buf);
                    127:                                if (article_line(original, "Subject: ", buf))
                    128:                                        printf("%s\n", buf);
                    129:                                if (askyes("Is this the one you want? ", "n"))
                    130:                                        break;
                    131:                        } else
                    132: #ifdef SERVER
                    133: nothere:
                    134: #endif /* !SERVER */
                    135:                                printf("I can't find that article.\n");
                    136:                        lastnum = atol(num);
                    137:                }
                    138: 
                    139:                followup(original);
                    140:        } else {
                    141:                do {
                    142:                        getpr("Subject: ", subject);
                    143:                        if (*subject == '?') {
                    144: printf("People read the subject line to learn what your article is about.\n");
                    145: printf("You want it to do the same job as a newspaper headline.\n");
                    146: printf("So type in something both brief and descriptive.\n");
                    147:                                *subject = '\0';
                    148:                        }
                    149:                } while (*subject == '\0');
                    150:                getpr("Keywords: ", keywords);
                    151: 
                    152:                while (!get_newsgroup())
                    153:                        ;
                    154:                get_distribution((char *)0);
                    155:        }
                    156: 
                    157:        if (pre_checks())
                    158:                exit(1);
                    159: 
                    160:        prep_article();
                    161:        c = 'e';
                    162:        for (;;) {
                    163:                if (c == 'e') {
                    164:                        edit_article();
                    165:                        post_checks();
                    166:                }
                    167:                do {
                    168:                        do {
                    169:                                getpr("\nWhat now?  [send, edit, list, quit, write, append] ", buf);
                    170:                                c = buf[0];
                    171:                        } while (c == '\0');
                    172:                        if (isupper(c))
                    173:                                c = tolower(c);
                    174:                        if (c == 'q') {
                    175:                                (void) UNLINK(tempfname);
                    176:                                exit(1);
                    177:                        }
                    178:                        if (c == 'l') {
                    179:                                char *pager = getenv("PAGER");
                    180:                                char lbuf[BUFLEN];
                    181:                                if (pager == NULL || *pager == '\0') {
                    182: #ifdef PAGE
                    183: # ifdef LOGDIR
                    184:                                        (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
                    185: # else /* !LOGDIR */
                    186:                                        (void) strcpy(lbuf, PAGE);
                    187: # endif /* !LOGDIR */
                    188:                                        pager = lbuf;
                    189: #else /* !PAGE */
                    190:                                        pager = "cat";
                    191: #endif /* !PAGE */
                    192:                                }
                    193:                                sprintf(buf, "exec %s %s", pager, tempfname);
                    194:                                (void)  system(buf);
                    195:                        }
                    196:                        if (c == 'w' || c == 'a') {
                    197:                                register int ifd, ofd, nbytes;
                    198:                                char iobuf[BUFSIZ];
                    199:                                char fname[BUFLEN];
                    200:                                getpr("Filename? ", fname);
                    201:                                if (fname[0] == '\0')
                    202:                                        continue;
                    203:                                ofd = (c == 'w') ? creat(fname, 0666)
                    204:                                                 : open(fname, 2);
                    205:                                if (ofd < 0)
                    206:                                        perror(fname);
                    207:                                else {
                    208:                                        if (c == 'a')
                    209:                                                (void) lseek(ofd, 0L, 2);
                    210:                                        ifd = open(tempfname, 0);
                    211:                                        if (ifd < 0)
                    212:                                                xerror("Can't reopen %s\n", tempfname);
                    213:                                        while ((nbytes = read(ifd, iobuf, BUFSIZ)) > 0 )
                    214:                                                write(ofd, iobuf, nbytes);
                    215:                                        close(ofd);
                    216:                                        close(ifd);
                    217:                                }
                    218:                        }
                    219:                } while (!index("eps", c));
                    220:                if (c != 'e')
                    221:                        post_article(); /* will exit if posted successfully */
                    222:        };
                    223: }
                    224: 
                    225: /*
                    226:  * Find out the topic of interest.
                    227:  */
                    228: get_newsgroup()
                    229: {
                    230:        int n;
                    231:        long i;
                    232:        char canpost;
                    233:        static int first = 1;
                    234: 
                    235:        printf("Newsgroups (enter one at a time, end with a blank line):\n");
                    236:        if (first) {
                    237:                printf("\nThe most relevant newsgroup should be the first, you should\n");
                    238:                printf("add others only if your article really MUST be read by people\n");
                    239:                printf("who choose not to read the appropriate group for your article.\n");
                    240:                printf("But DO use multiple newsgroups rather than posting many times.\n\n");
                    241:                first = 0;
                    242:        }
                    243: #ifndef SERVER
                    244:        printf("For a list of newsgroups, type ?\n");
                    245: #endif /* !SERVER */
                    246:        n = 0;
                    247:        newsgroups[0] = '\0';
                    248: 
                    249:        for(;;) {
                    250:                getpr("> ", buf);
                    251:                if (buf[0] == '\0')
                    252:                        if (n == 0)
                    253:                                return FALSE;
                    254:                        else
                    255:                                return TRUE;
                    256: #ifndef SERVER
                    257:                if (buf[0] == '?'){
                    258:                        char *pager = getenv("PAGER");
                    259:                        char lbuf[BUFLEN];
                    260:                        if (pager == NULL) {
                    261: #ifdef PAGE
                    262: # ifdef LOGDIR
                    263:                                (void) sprintf(lbuf,"%s/bin/%s", logdir(HOME), PAGE);
                    264: # else /* !LOGDIR */
                    265:                                (void) strcpy(lbuf, PAGE);
                    266: # endif /* !LOGDIR */
                    267:                                pager = lbuf;
                    268: #else /* !PAGE */
                    269:                                pager = "cat";
                    270: #endif /* !PAGE */
                    271:                        }
                    272:                        printf("These are the currently active groups:\n");
                    273:                        (void) fflush(stdout);
                    274:                        sprintf(buf, "exec %s %s/newsgroups", pager, LIB);
                    275:                        (void) system(buf);
                    276:                        continue;
                    277:                }
                    278: #endif /* !SERVER */
                    279:                if (valid_ng(buf, &i, &i, &canpost)) {
                    280:                        if (n++ != 0)
                    281:                                (void) strcat(newsgroups, ngsep);
                    282:                        (void) strcat(newsgroups, buf);
                    283:                } else {
                    284:                        if (canpost == 'n')
                    285:                                printf("You are not allowed to post to %s\n",
                    286:                                        buf);
                    287:                        else if (canpost == 'i')
                    288:                                printf("%s is not a valid newsgroup.\n", buf);
                    289:                }
                    290:        }
                    291: }
                    292: 
                    293: /*
                    294:  * Find out how widely the author wants the message distributed.
                    295:  */
                    296: get_distribution(deflt)
                    297:        char *deflt;
                    298: {
                    299:        register int i;
                    300:        register char *r;
                    301:        char def[BUFLEN];
                    302:        char *lastgroup;
                    303: 
                    304:        lastgroup = newsgroups;
                    305:        (void) strcpy(def, newsgroups);
                    306:        r = index(def, NGDELIM);
                    307:        if (r)
                    308:                *r = '\0';
                    309:        r = index(def, '.');
                    310:        if (r) {
                    311:                *r = '\0';
                    312:                if (STRCMP(def, "net") == 0)
                    313:                        (void) strcpy(def, "world");
                    314:        } else {
                    315:                distribution[0] = '\0';
                    316:                return;
                    317:        }
                    318: 
                    319:        if (STRCMP(def, "to") == 0) {
                    320:                /*
                    321:                 * This only works if "to.xx" is the first (or only)
                    322:                 * newsgroup, but it usually is ..
                    323:                 * Perhaps we should make the distribution be "to.xxx" ??
                    324:                 */
                    325:                distribution[0] = '\0';
                    326:                return;         /* He's probably testing something */
                    327:        }
                    328:        if (deflt != (char *)0)
                    329:                (void) strcpy(def, deflt);
                    330:        if (ngmatch("misc.test", newsgroups))
                    331:                (void) strcpy(def, "local");
                    332:        for (i=0; distr[i].abbr[0]; i++) {
                    333:                if (STRCMP(distr[i].abbr, def) == 0)
                    334:                        break;
                    335:        }
                    336:        if (distr[i].abbr[0] == '\0')
                    337:                strcpy(def, def_distr);
                    338:        for(;;) {
                    339:                do {
                    340:                        (void) sprintf(buf, "Distribution (default='%s', '?' for help) : ", def);
                    341:                        getpr(buf, distribution);
                    342:                        if (distribution[0] == '\0') {
                    343:                                if (STRCMP(def, "*None*") == 0)
                    344:                                        printf("You must enter a distribution, '?' for help.\n");
                    345:                                (void) strcpy(distribution, def);
                    346:                        }
                    347:                } while (STRCMP(distribution, "*None*") == 0);
                    348: 
                    349:                /* Did the user ask for help? */
                    350:                if (distribution[0] == '?') {
                    351:                        printf("How widely should your article be distributed?\n\n");
                    352:                        for (i=0; distr[i].abbr[0]; i++)
                    353:                                printf("%s\t%s\n", distr[i].abbr, distr[i].descr);
                    354:                        printf("\nEnter the word that specifies the distribution that you require.\n");
                    355:                        continue;
                    356:                }
                    357: 
                    358: #ifdef SERVER
                    359:                return;         /* can't do this yet */
                    360: #else  /* !SERVER */
                    361:                /* Check that it's a proper distribution */
                    362:                for (i=0; distr[i].abbr[0]; i++) {
                    363:                        if (strncmp(distr[i].abbr, distribution, sizeof(distr[0].abbr)) == 0) {
                    364:                                return;
                    365:                        }
                    366:                }
                    367:                if (STRCMP(distribution, def) != 0)
                    368:                        printf("Type ? for help.\n");
                    369:                else {
                    370:                        int once = TRUE;
                    371: 
                    372:                        do {
                    373:                                r = lastgroup;
                    374:                                while (r = index(r, NGDELIM))
                    375:                                        if (!PREFIX(++r, def))
                    376:                                                break;
                    377:                                if (r == NULL) {
                    378:                                        /*
                    379:                                         * no newsgroups are distribution
                    380:                                         * names, and user simply will
                    381:                                         * not type a valid distribution,
                    382:                                         * assume that the default is OK.
                    383:                                         */
                    384:                                        distribution[0] = '\0';
                    385:                                        return;
                    386:                                }
                    387:                                lastgroup = r;
                    388:                                if (once)
                    389:                                        printf("Sorry, '%s' is an unknown distribution.  Type ? for help.\n", def);
                    390:                                once = FALSE;
                    391:                                strcpy(def, r);
                    392:                                r = index(def, NGDELIM);
                    393:                                if (r)
                    394:                                        *r = '\0';
                    395:                                r = index(def, '.');
                    396:                        } while (r == NULL);
                    397:                        *r = '\0';
                    398:                        if (STRCMP(def, "net") == 0)
                    399:                                strcpy(def, "world");
                    400:                }
                    401: #endif /* !SERVER */
                    402:        }
                    403: }
                    404: 
                    405: /*
                    406:  * Do sanity checks before the author types in the message.
                    407:  */
                    408: pre_checks()
                    409: {
                    410:        if (recording(newsgroups))
                    411:                return 1;
                    412:        return 0;
                    413: }
                    414: 
                    415: /*
                    416:  * Set up the temp file with headers.
                    417:  */
                    418: prep_article()
                    419: {
                    420:        FILE *tf, *of;
                    421:        struct stat stbuf;
                    422: 
                    423:        (void) strcpy(tempfname, "/tmp/postXXXXXX");
                    424:        (void) mktemp(tempfname);
                    425: 
                    426:        /* insert a header */
                    427:        tf = xfopen(tempfname, "w");
                    428:        fprintf(tf, "Subject: %s\n", subject);
                    429:        fprintf(tf, "Newsgroups: %s\n", newsgroups);
                    430:        if (distribution[0] != '\0' && STRCMP(distribution, "world"))
                    431:                fprintf(tf, "Distribution: %s\n", distribution);
                    432: 
                    433:        if (keywords[0] != '\0')
                    434:                fprintf(tf, "Keywords: %s\n", keywords);
                    435:        if (summary[0] != '\0')
                    436:                fprintf(tf, "Summary: %s\n", summary);
                    437: 
                    438:        if (references[0] != '\0') {
                    439:                fprintf(tf, "References: %s\n\n", references);
                    440: 
                    441:                if (askyes("Do you want to include a copy of the article? ", "no")){
                    442:                        of = xfopen(original, "r");
                    443:                        while (fgets(buf, BUFSIZ, of) != NULL)
                    444:                                if (buf[0] == '\n')     /* skip headers */
                    445:                                        break;
                    446:                        fprintf(tf, "In article %s, %s writes:\n", msgid, isfrom);
                    447:                        while (fgets(buf, BUFSIZ, of) != NULL)
                    448:                                fprintf(tf, "> %s", buf);
                    449:                        (void) fclose(of);
                    450:                        printf("OK, but please edit it to suppress unnecessary verbiage, signatures, etc.\n");
                    451:                        (void) fflush(stdout);
                    452:                }
                    453:        }
                    454: 
                    455:        fprintf(tf, "\n\n");
                    456:        (void) fflush(tf);
                    457:        (void) fstat(fileno(tf), &stbuf);
                    458:        fmodtime = stbuf.st_mtime;
                    459:        (void) fclose(tf);
                    460: }
                    461: 
                    462: edit_article()
                    463: {
                    464:        register char *p;
                    465:        char *editor;
                    466:        char *endflag = "";
                    467:        char *getenv();
                    468: 
                    469:        /* edit the file */
                    470:        editor = getenv("EDITOR");
                    471:        if (editor == NULL)
                    472:                editor = DFTEDITOR;
                    473: 
                    474:        p = editor + strlen(editor) - 2;
                    475:        if (STRCMP(p, "vi") == 0)
                    476:                endflag = "+";
                    477: 
                    478:        (void) sprintf(buf, "A=%s;export A;exec %s %s %s",
                    479:                original, editor, endflag, tempfname);
                    480: 
                    481:        (void) system(buf);
                    482: }
                    483: 
                    484: /*
                    485:  * Do sanity checks after the author has typed in the message.
                    486:  */
                    487: post_checks()
                    488: {
                    489:        char group[BUFLEN];
                    490:        register char *c, *p;
                    491:        struct stat stbuf;
                    492: 
                    493:        if (stat(tempfname, &stbuf) < 0) {
                    494:                printf("File deleted - no message posted.\n");
                    495:                (void) UNLINK(tempfname);
                    496:                exit(1);
                    497:        }
                    498:        if (stbuf.st_size < 5) {
                    499:                printf("File too small (<5 characters) - no message posted.\n");
                    500:                (void) UNLINK(tempfname);
                    501:                exit(1);
                    502:        }
                    503: 
                    504:        if (stbuf.st_mtime == fmodtime) {
                    505:                printf("File not modified - no message posted.\n");
                    506:                (void) UNLINK(tempfname);
                    507:                exit(1);
                    508:        }
                    509: 
                    510:        /*
                    511:         * Is this the right number?  Most of the headers are yet to be added
                    512:         */
                    513:        if (stbuf.st_size > 64000) {
                    514:                printf("\nYour message will probably be truncated when it\n");
                    515:                printf("passes through a notesfile site, since it is\n");
                    516:                printf("greater than 64000 characters.\n\n");
                    517:                if (!askyes("Do you still want to post it? ","")) {
                    518:                        sprintf(ccname, "%s/dead.article", homedir);
                    519:                        save_article();
                    520:                        (void) UNLINK(tempfname);
                    521:                        exit(1);
                    522:                }
                    523:        }
                    524: 
                    525:        /*
                    526:         * get the newsgroups from the edited article, in
                    527:         * case they were altered in the editor
                    528:         */
                    529:        if (!article_line(tempfname, "Newsgroups: ", group)) {
                    530:   nogroups:
                    531:                printf("Not sending to any newsgroups - no message posted\n");
                    532:                sprintf(ccname, "%s/dead.article", homedir);
                    533:                save_article();
                    534:                (void) UNLINK(tempfname);
                    535:                exit(1);
                    536:        }
                    537:        c = &group[11];
                    538:        while (*c == ' ' || *c == '\t')
                    539:                c++;
                    540:        if (*c == '\0')
                    541:                goto nogroups;
                    542:        for (p = newsgroups; *c; c++)   /* copy to newsgroups, w/o blanks */
                    543:                if (*c != ' ' && *c != '\t')
                    544:                        *p++ = *c;
                    545:        *p = '\0';
                    546: 
                    547:        /* Sanity checks for certain newsgroups */
                    548:        if (ngmatch(newsgroups, "all.wanted") && ngmatch(distribution,"world,na,usa,att,btl,eunet,aus")) {
                    549:                printf("Is your message something that might go in your local\n");
                    550:                printf("newspaper, for example a used car ad, or an apartment\n");
                    551:                printf("for rent? ");
                    552:                if (askyes("","")) {
                    553:                        printf("It's pointless to distribute your article widely, since\n");
                    554:                        printf("people more than a hundred miles away won't be interested.\n");
                    555:                        printf("Please use a more restricted distribution.\n");
                    556:                        get_distribution("*None*");
                    557:                        modify_article(tempfname, "Distribution: ", distribution,REPLACE);
                    558:                }
                    559:        }
                    560: 
                    561:        if (ngmatch(newsgroups, "rec.humor,!rec.humor.all")) {
                    562:                if (askyes("Could this be offensive to anyone? ","")) {
                    563:                        getpr("Whom might it offend? ", group);
                    564:                        (void) sprintf(buf," - offensive to %s (rot 13)",group);
                    565:                        modify_article(tempfname, "Subject: ", buf, APPEND);
                    566:                        encode(tempfname);
                    567:                }
                    568:        }
                    569: 
                    570:        if (ngmatch(newsgroups, "comp.sources.all,!comp.sources.wanted,!comp.sources.d")) {
                    571:                if (!article_line(tempfname, "Subject: ", group)) {
                    572:   nosubj:
                    573:                        printf("There seems to be no subject for this article.\n");
                    574:                        getpr("Subject: ", subject);
                    575:                        modify_article(tempfname, "Subject: ", subject, REPLACE);
                    576:                } else {
                    577:                        c = &group[8];
                    578:                        while (*c == ' ' || *c == '\t')
                    579:                                c++;
                    580:                        if (*c == '\0')
                    581:                                goto nosubj;
                    582:                        strcpy(subject, c);
                    583:                }
                    584:                if (ngmatch(newsgroups, "all.wanted") || iswanted(subject)) {
                    585:                        printf("Requests for sources should not be posted to any of\n");
                    586:                        printf("the comp.sources newsgroups, please post such requests\n");
                    587:                        printf("to comp.sources.wanted only.     Please reenter the newsgroups.\n\n");
                    588:                        while (!get_newsgroup())
                    589:                                ;
                    590:                        modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
                    591:                }
                    592:                if (ngmatch(newsgroups, "comp.sources.all")) {
                    593:                        if (!ngmatch(newsgroups, "comp.sources.wanted") &&
                    594:                            stbuf.st_size < (4*1024)) {
                    595:                                printf("Your article seems rather small to be a source distribution.\n");
                    596:                                if (!askyes("Are you certain that this is really source? ", "")) {
                    597: 
                    598:                                        while (!get_newsgroup())
                    599:                                                ;
                    600:                                        modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
                    601:                                }
                    602:                        }
                    603:                        if (index(newsgroups, NGDELIM)) {
                    604:                                printf("Sources should be posted to one newsgroup only.\n");
                    605:                                printf("Please pick the most appropriate group for your article.\n\n");
                    606:                                while (!get_newsgroup())
                    607:                                        ;
                    608:                                modify_article(tempfname, "Newsgroups: ", newsgroups, REPLACE);
                    609:                        }
                    610:                }
                    611:        }
                    612: }
                    613: 
                    614: iswanted(str)
                    615: register char *str;
                    616: {
                    617:        while (*str == ' ')
                    618:                str++;
                    619: 
                    620:        if (PREFIX(str, "Re:"))
                    621:                return (FALSE);
                    622: 
                    623:        if (isin(str, " wanted ") || isin(str, " can any") ||
                    624:            isin(str, " need ") || isin(str, " please ") || isin(str, " help ")
                    625:            || isin(str, " looking ") || index(str, '?'))
                    626:                return (TRUE);
                    627: 
                    628:        return (FALSE);
                    629: }
                    630: 
                    631: isin(str, words)
                    632: register char *str, *words;
                    633: {
                    634:        register char *p;
                    635:        register sc, wc;
                    636: 
                    637:        p = words;
                    638:        while (sc = *str++) {
                    639:                if ((wc = *p++) == '\0')
                    640:                        return (TRUE);
                    641:                if (wc == ' ') {
                    642:                        if (index(".,!?-; \t\n", sc))
                    643:                                continue;
                    644:                } else {
                    645:                        if (isupper(wc))
                    646:                                wc = tolower(wc);
                    647:                        if (isupper(sc))
                    648:                                sc = tolower(sc);
                    649:                        if (wc == sc)
                    650:                                continue;
                    651:                }
                    652:                str -= p - words - 1;
                    653:                p = words;
                    654:        }
                    655:        if (*p == '\0')
                    656:                return (TRUE);
                    657:        return (FALSE);
                    658: }
                    659: 
                    660: /*
                    661:  * Save a copy of the article in the users NEWSARCHIVE directory.
                    662:  */
                    663: save_article()
                    664: {
                    665:        FILE *in, *out;
                    666:        int c;
                    667:        time_t timenow, time();
                    668:        char *today, *ctime();
                    669:        struct stat stbuf;
                    670:        char filename[BUFLEN];
                    671: 
                    672:        if (stat(ccname, &stbuf) == 0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) {
                    673:                /*
                    674:                 * It would be much nicer here to write articles
                    675:                 * in MH format (numbered files, in rfc822 format)
                    676:                 *
                    677:                 * one day ..
                    678:                 */
                    679:                (void) sprintf(filename, "%s/author_copy", ccname);
                    680:                (void) strcpy(ccname, filename);
                    681:        }
                    682:        in = xfopen(tempfname, "r");
                    683:        out = xfopen(ccname, "a");
                    684:        timenow = time((time_t)0);
                    685:        today = ctime(&timenow);
                    686:        fprintf(out,"From postnews %s",today);
                    687:        while ((c=getc(in)) != EOF)
                    688:                putc(c, out);
                    689:        putc('\n', out);
                    690:        (void) fclose(in);
                    691:        (void) fclose(out);
                    692: }
                    693: 
                    694: /*
                    695:  * Post the article to the net.
                    696:  */
                    697: post_article()
                    698: {
                    699:        int status;
                    700: 
                    701:        printf("Posting article...\n");
                    702:        fflush(stdout);
                    703:        (void) sprintf(buf, "exec %s/%s -h < %s", LIB, "inews", tempfname);
                    704:        status = system(buf);
                    705: 
                    706:        if (status) {
                    707:                printf("Article not posted - exit status %d\n", status);
                    708:                return;
                    709:        } else
                    710:                printf("Article posted successfully.\n");
                    711: 
                    712:        if (ccname[0]) {
                    713:                printf("A copy has been saved in %s\n", ccname);
                    714:                save_article();
                    715:        }
                    716: 
                    717:        (void) UNLINK(tempfname);
                    718:        exit(0);
                    719: }
                    720: 
                    721: /*
                    722:  * Initialization.
                    723:  */
                    724: init()
                    725: {
                    726:        FILE *fd;
                    727:        register char *p;
                    728:        int i;
                    729:        char *getenv();
                    730:        struct passwd *pw;
                    731: 
                    732:        references[0] = '\0';
                    733:        distribution[0] = '\0';
                    734: 
                    735:        uid = getuid();
                    736:        pw = getpwuid(uid);
                    737:        if (pw == NULL) {
                    738:                fprintf(stderr,"You're not in /etc/passwd\n");
                    739:                exit(1);
                    740:        }
                    741:        p = getenv("HOME");
                    742:        if (p == NULL) {
                    743:                p = getenv("LOGDIR");
                    744:                if (p == NULL) 
                    745:                        p = pw->pw_dir;
                    746:        }
                    747:        (void) strncpy(user, pw->pw_name, SBUFLEN);
                    748:        (void) strcpy(homedir, p);
                    749: 
                    750:        p = getenv("NEWSARCHIVE");
                    751:        if (p != NULL) {
                    752:                if (*p == '\0')
                    753:                        sprintf(ccname, "%s/author_copy", homedir);
                    754:                else
                    755:                        strcpy(ccname, p);
                    756:        }
                    757: 
                    758:        pathinit();
                    759: #ifdef SERVER
                    760:        if (open_server() < 0) 
                    761:                xerror("Server error");
                    762:                        /* do something to some up with distributions */
                    763:        if ((fd = open_active()) == NULL)
                    764:                xerror("Server error");
                    765:        strcpy(ACTIVE,active_name());
                    766: #else  /* !SERVER */
                    767:        (void) sprintf(buf, "%s/%s", LIB, "distributions");
                    768: 
                    769:        fd = xfopen(buf, "r");
                    770:        for (i=0; i < MAXDISTR; i++) {
                    771:                if (fscanf(fd, "%s %[^\n]", distr[i].abbr, distr[i].descr)
                    772:                        != 2)
                    773:                        break;
                    774:                if (STRCMP(distr[i].abbr, "default") == 0)
                    775:                        strcpy(def_distr, distr[i--].descr);
                    776:        }
                    777: #endif /* !SERVER */
                    778:        (void) fclose(fd);
                    779:        distr[i].abbr[0] = '\0';
                    780:        if (def_distr[0] == '\0')
                    781:                strcpy(def_distr, "world");     /* maybe "local" is better? */
                    782: }
                    783: 
                    784: /*
                    785:  * Get a yes or no answer to a question.       A default may be used.
                    786:  */
                    787: askyes(msg, def)
                    788: char *msg, *def;
                    789: {
                    790:        for(;;) {
                    791:                printf("%s", msg);
                    792:                buf[0] = 0;
                    793:                (void) gets(buf);
                    794:                switch(buf[0]) {
                    795:                case 'y':
                    796:                case 'Y':
                    797:                        return TRUE;
                    798:                case 'n':
                    799:                case 'N':
                    800:                        return FALSE;
                    801:                case '\0':
                    802:                        switch(*def) {
                    803:                        case 'y':
                    804:                        case 'Y':
                    805:                                return TRUE;
                    806:                        case 'n':
                    807:                        case 'N':
                    808:                                return FALSE;
                    809:                        }
                    810:                default:
                    811:                        printf("Please answer yes or no.\n");
                    812:                }
                    813:        }
                    814: }
                    815: 
                    816: /*
                    817:  * Get a character string into buf, using prompt msg.
                    818:  */
                    819: getpr(msg, bptr)
                    820: char *msg, *bptr;
                    821: {
                    822:        static int numeof = 0;
                    823:        printf("%s", msg);
                    824:        (void) gets(bptr);
                    825:        (void) nstrip(bptr);
                    826:        if (feof(stdin)) {
                    827:                if (numeof++ > 3) {
                    828:                        fprintf(stderr,"Too many EOFs\n");
                    829:                        exit(1);
                    830:                }
                    831:                clearerr(stdin);
                    832:        }
                    833: }
                    834: 
                    835: byebye(mesg)
                    836: char *mesg;
                    837: {
                    838:        printf("%s\n", mesg);
                    839:        exit(1);
                    840: }
                    841: 
                    842: /*
                    843:  * make a modification to the header of an article
                    844:  *
                    845:  *      fname -- name of article
                    846:  *      field -- header field to modify
                    847:  *      line   -- modification line
                    848:  *      how     -- APPEND or REPLACE
                    849:  *
                    850:  * example:
                    851:  *      modify_article("/tmp/article" , "Subject:" , "new subject" , REPLACE);
                    852:  *
                    853:  *
                    854:  */
                    855: modify_article(fname, field, line, how)
                    856: char *fname, *field, *line;
                    857: {
                    858:        FILE *fpart, *fptmp;
                    859:        char *temp2fname = "/tmp/postXXXXXX";
                    860:        char lbfr[BUFLEN];
                    861:        register found = FALSE;
                    862: 
                    863:        mktemp(temp2fname);
                    864: 
                    865:        fptmp = xfopen(temp2fname, "w");
                    866:        fpart = xfopen(fname, "r");
                    867: 
                    868:        while (fgets(lbfr, BUFLEN, fpart) != NULL) {
                    869:                if (PREFIX(lbfr, field)) {
                    870:                        found = TRUE;
                    871:                        (void) nstrip(lbfr);
                    872:                        if (how == APPEND) {
                    873:                                /* append to current field */
                    874:                                (void) strcat(lbfr, line);
                    875:                                (void) strcat(lbfr, "\n");
                    876:                        } else
                    877:                                /* replace current field */
                    878:                                (void) sprintf(lbfr, "%s%s\n", field, line);
                    879:                }
                    880:                (void) fputs(lbfr, fptmp);
                    881:        }
                    882: 
                    883:        fclose(fpart);
                    884:        fclose(fptmp);
                    885: 
                    886:        fptmp = xfopen(temp2fname, "r");
                    887:        fpart = xfopen(fname, "w");
                    888: 
                    889:        if (!found)
                    890:                fprintf(fpart, "%s%s\n", field, line);
                    891:        while (fgets(buf,BUFLEN,fptmp) != NULL)
                    892:                (void) fputs(buf, fpart);
                    893: 
                    894:        (void) fclose(fpart);
                    895:        (void) fclose(fptmp);
                    896:        (void) UNLINK(temp2fname);
                    897: }
                    898: 
                    899: 
                    900: /* verify that newsgroup exists, and get number of entries */
                    901: valid_ng(ng, maxart, minart, canpost)
                    902: char *ng;
                    903: long *maxart, *minart;
                    904: char *canpost;
                    905: {
                    906:        char ng_check[BUFLEN], ng_read[BUFLEN];
                    907:        FILE *fp;
                    908: 
                    909:        fp = xfopen(ACTIVE, "r");
                    910:        while (fgets(ng_read, BUFLEN, fp) != NULL) {
                    911:                switch (sscanf(ng_read, "%s %ld %ld %c", ng_check, maxart, minart, canpost)) {
                    912:                case 2:
                    913:                        *minart = 1;
                    914:                        /* fall through */
                    915:                case 3:
                    916:                        *canpost = 'y';
                    917:                        /* fall through */
                    918:                case 4:
                    919:                        break;
                    920: 
                    921:                default:
                    922:                        printf("Active file (%s) corrupted. ", ACTIVE);
                    923:                        byebye("Seek help!");
                    924:                }
                    925:                        
                    926:                if (STRCMP(ng_check, ng) == 0) {
                    927:                        (void) fclose(fp);
                    928:                        if (*canpost != 'n') {
                    929: #ifdef FASCIST
                    930:                                if (uid && uid != ROOTID && fascist(user, ng)) {
                    931:                                        *canpost = 'n';
                    932:                                        return FALSE;
                    933:                                }
                    934: #endif /* FASCIST */
                    935:                                return TRUE;
                    936:                        } else
                    937:                                return FALSE;
                    938:                }
                    939:        }
                    940:        *canpost = 'i';
                    941:        *maxart = 0;
                    942:        *minart = 0;
                    943:        (void) fclose(fp);
                    944:        return FALSE;
                    945: }
                    946: 
                    947: /* get the line specified by field from an article */
                    948: article_line(article, field, line)
                    949: char *article, *field, *line;
                    950: {
                    951:        FILE *fp;
                    952:        char *c;
                    953: 
                    954:        fp = xfopen(article,"r");
                    955:        while ((c=fgets(line,BUFLEN,fp)) != NULL && !PREFIX(line, field))
                    956:                if (line[0] == '\n') {
                    957:                        c = NULL;
                    958:                        break;
                    959:                }
                    960:        (void) fclose(fp);
                    961:        if (c != NULL) {
                    962:                (void) nstrip(line);
                    963:                return TRUE;
                    964:        } else {
                    965:                line[0] = '\0';
                    966:                return FALSE;
                    967:        }
                    968: }
                    969: 
                    970: /* get the header information for a followup article */
                    971: followup(baseart)
                    972: register char *baseart;
                    973: {
                    974:        register char *p;
                    975: 
                    976:        /* subject */
                    977:        if (article_line(baseart, "Subject: ", buf)) {
                    978:                p = buf+9;
                    979:                for ( ; ; ) {
                    980:                        while (*p == ' ' || *p == '\t')
                    981:                                ++p;
                    982:                        if ((*p != 'r' && *p != 'R') ||
                    983:                                (p[1] != 'e' && p[1] != 'E') ||
                    984:                                (p[2] != ':' && p[2] != ' '))
                    985:                                        break;
                    986:                        p += 3;
                    987:                }
                    988:                (void) sprintf(subject, "Re: %s", p);
                    989:        } else {
                    990:                if (article_line(baseart, "From: ", buf))
                    991:                        (void) sprintf(subject, "Re: orphan response from %s", buf);
                    992:                else
                    993:                        (void) strcpy(subject, "Re: orphan response");
                    994:        }
                    995: 
                    996:        /* newsgroup */
                    997:        if (article_line(baseart, "Newsgroups: ", buf))
                    998:                (void) strcpy(newsgroups, buf+12);
                    999:        if (ngmatch(newsgroups, "misc.jobs.all,!misc.jobs.misc")) {
                   1000:                printf("Your followup has been directed to misc.jobs.misc\n");
                   1001:                printf("It is the proper place for followup discussions\n");
                   1002:                (void) strcpy(newsgroups,"misc.jobs.misc");
                   1003:        }
                   1004: 
                   1005:        /* distribution */
                   1006:        if (article_line(baseart, "Distribution: ", buf))
                   1007:                (void) strcpy(distribution, buf+14);
                   1008: 
                   1009:        /* references */
                   1010:        if (article_line(baseart, "References: ", buf)) {
                   1011:                register char *rcp;
                   1012:                (void) strcpy(references, buf+12);
                   1013:                (void) strcat(references, " ");
                   1014:                /* keep the number of references to a reasonable number */
                   1015:                rcp = rindex(references, ' '); /* Can not fail */
                   1016:                while ((int)(rcp - references) > 70) {
                   1017:                        while (*--rcp != ' ')
                   1018:                                ;
                   1019:                        rcp[1] = '\0';
                   1020:                }
                   1021:        }
                   1022:        if (article_line(baseart, "Message-ID: ", buf)) {
                   1023:                (void) strcat(references, buf+12);
                   1024:                (void) strcpy(msgid, buf+12);
                   1025:        }
                   1026: 
                   1027:        if (article_line(baseart, "From: ", buf))
                   1028:                (void) strcpy(isfrom, buf+6);
                   1029: 
                   1030:        if (article_line(baseart, "Keywords: ", buf))
                   1031:                (void) strcpy(keywords, buf+10);
                   1032: 
                   1033:        if (article_line(baseart, "Followup-To: ", buf)) {
                   1034:                (void) strcpy(newsgroups, buf+13);
                   1035:                if (STRCMP(newsgroups, "poster") == 0)
                   1036:                        byebye("Mail followups directly to poster.");
                   1037:        }
                   1038: 
                   1039:        get_summary();
                   1040: }
                   1041: 
                   1042: get_summary()
                   1043: {
                   1044:        register char *p;
                   1045:        register i;
                   1046: 
                   1047:        printf("Please enter a short summary of your contribution to the discussion\n");
                   1048:        printf("Just one or two lines ...   (end with a blank line)\n");
                   1049:        p = summary;
                   1050:        for (i = 0; i < 3; i++) {       /* 3 * 80 < 256, should be safe .. */
                   1051:                getpr(">\t", p);
                   1052:                if (*p == '\0')
                   1053:                        break;
                   1054:                p = index(p, '\0');
                   1055:                (void) strcpy(p, "\n\t ");
                   1056:                p += 3;
                   1057:        }
                   1058:        if (p > summary)
                   1059:                p[-3] = '\0';
                   1060: }
                   1061: 
                   1062: encode(article)
                   1063: char *article;
                   1064: {
                   1065:        FILE *fpart, *fphead, *fpcoded;
                   1066:        char *headerfile = "/tmp/pheadXXXXXX";
                   1067:        char *codedfile = "/tmp/pcodeXXXXXX";
                   1068: 
                   1069:        (void) mktemp(headerfile);
                   1070:        (void) mktemp(codedfile);
                   1071: 
                   1072:        fpart = xfopen(article, "r");
                   1073: 
                   1074:        /* place article header in "headerfile" file */
                   1075:        fphead = xfopen(headerfile, "w");
                   1076:        while (fgets(buf, BUFLEN, fpart) != NULL) {
                   1077:                (void) fputs(buf, fphead);
                   1078:                if (buf[0] == '\n')
                   1079:                        break;
                   1080:        }
                   1081:        (void) fclose(fphead);
                   1082: 
                   1083:        /* place article body in "codedfile" file */
                   1084:        fpcoded = xfopen(codedfile, "w");
                   1085:        while (fgets(buf, BUFLEN, fpart) != NULL)
                   1086:                (void) fputs(buf, fpcoded);
                   1087:        (void) fclose(fpcoded);
                   1088:        (void) fclose(fpart);
                   1089: 
                   1090:        /* encode body and put back together with header */
                   1091:        (void) rename(headerfile, article);
                   1092: 
                   1093:        (void) sprintf(buf,"exec %s/%s 13 < %s >> %s\n", LIB, "caesar", codedfile, article);
                   1094:        printf("Encoding article -- please stand by\n");
                   1095:        (void) fflush(stdout);
                   1096:        if (system(buf)) {
                   1097:                printf("encoding failed");
                   1098:                exit(2);
                   1099:        }
                   1100:        (void) UNLINK(codedfile);
                   1101: }
                   1102: 
                   1103: 
                   1104: /*
                   1105:  * Print a recorded message warning the poor luser what he is doing
                   1106:  * and demand that he understands it before proceeding.  Only do
                   1107:  * this for newsgroups listed in LIBDIR/recording.
                   1108:  */
                   1109: recording(ngrps)
                   1110: char *ngrps;
                   1111: {
                   1112:        char recbuf[BUFLEN];
                   1113:        FILE *fd;
                   1114:        char nglist[BUFLEN], fname[BUFLEN];
                   1115:        int  c, n, yes, retval = 0;
                   1116: 
                   1117:        (void) sprintf(recbuf, "%s/%s", LIB, "recording");
                   1118:        fd = fopen(recbuf, "r");
                   1119:        if (fd == NULL)
                   1120:                return 0;
                   1121:        while ((fgets(recbuf, sizeof recbuf, fd)) != NULL) {
                   1122:                (void) sscanf(recbuf, "%s %s", nglist, fname);
                   1123:                if (ngmatch(ngrps, nglist)) {
                   1124:                        (void) fclose(fd);
                   1125:                        if (fname[0] == '/')
                   1126:                                (void) strcpy(recbuf, fname);
                   1127:                        else
                   1128:                                (void) sprintf(recbuf, "%s/%s", LIB, fname);
                   1129:                        fd = fopen(recbuf, "r");
                   1130:                        if (fd == NULL)
                   1131:                                return 0;
                   1132:                        while ((c = getc(fd)) != EOF)
                   1133:                                putc(c, stderr);
                   1134:                        fclose(fd);
                   1135:                        fprintf(stderr, "Do you understand this?  Hit <return> to proceed, <BREAK> to abort: ");
                   1136:                        fflush(stderr);
                   1137:                        n = read(0, recbuf, 100);
                   1138:                        c = recbuf[0];
                   1139:                        yes = (c=='y' || c=='Y' || c=='\n' || c=='\n' || c==0);
                   1140:                        if (n <= 0 || !yes)
                   1141:                                retval = -1;
                   1142:                }
                   1143:        }
                   1144:        return retval;
                   1145: }
                   1146: 
                   1147: xxit(i)
                   1148: {
                   1149:        exit(i);
                   1150: }
                   1151: 
                   1152: #if !defined(BSD4_2)
                   1153: rename(from,to)
                   1154: register char *from, *to;
                   1155: {
                   1156:        (void) unlink(to);
                   1157:        if (link(from, to) < 0)
                   1158:                return -1;
                   1159: 
                   1160:        (void) unlink(from);
                   1161:        return 0;
                   1162: }
                   1163: #endif /* !BSD4_2 && ! BSD4_1C */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.