Annotation of researchv10no/cmd/netnews/src/rfuncs2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * rfuncs2 - more routines needed by readr.
                      3:  */
                      4: static char *sccsid = "@(#)rfuncs2.c   1.9     4/25/83";
                      5: 
                      6: #include "rparams.h"
                      7: 
                      8: static char    lbuf[BUFLEN*2];
                      9: 
                     10: FILE *popen();
                     11: 
                     12: /*
                     13:  * nglist is the list of newsgroups in an article we want to follow up.
                     14:  * Do any special fascist processing to prevent certain kinds of followups.
                     15:  * In this case, there are two things we want to do:
                     16:  *     All followups to "net.general" are fed to "net.followup".
                     17:  *     However, if "net.general" is mentioned along with "net.news.group",
                     18:  *             just remove the net.general.
                     19:  */
                     20: launder(nglist)
                     21: char   *nglist;
                     22: {
                     23:        char    *cp, *op;
                     24:        char    outbuf[128];
                     25:        int     seen_group = 0;
                     26: 
                     27:        for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n'))
                     28:                if (strncmp("news.group", cp, 10) == 0)
                     29:                        seen_group++;
                     30:        for (cp = index(nglist, 'n'); cp; cp = index(cp + 1, 'n'))
                     31:                if (strncmp("net.general", cp, 11) == 0) {
                     32:                        /* 11 = strlen("net.general") */
                     33:                        strcpy(outbuf, cp + 11);
                     34:                        if (!seen_group) {
                     35:                                strcpy(cp, "net.followup");
                     36:                                cp += 12;  /* 12 = strlen("net.followup") */
                     37:                        }
                     38:                        if (cp[-1] == ',' && outbuf[0] == ',')
                     39:                                cp--;
                     40:                        strcpy(cp, outbuf);
                     41:                }
                     42: }
                     43: 
                     44: 
                     45: /*
                     46:  * Match title.
                     47:  */
                     48: titmat(h, titlist)
                     49: register struct hbuf *h;
                     50: register char  *titlist;
                     51: {
                     52:        register char   *p;
                     53:        register int    titlen;
                     54: 
                     55:        while (*titlist != '\0') {
                     56:                titlen = strlen(titlist);
                     57:                for (p = h->title; *p != '\0'; p++)
                     58:                        if (strncmp(p, titlist, titlen) == 0) {
                     59:                                return(TRUE);
                     60:                        }
                     61:                titlist += titlen + 1;
                     62:        }
                     63:        return(FALSE);
                     64: }
                     65: 
                     66: 
                     67: /*
                     68:  * Save the news item in the user's file.
                     69:  * Fri Mar 12 20:04:43 EST 1982: (ittvax!swatt)
                     70:  *     Allow files with first character as '|' to write article
                     71:  *     to program across a pipe.
                     72:  */
                     73: 
                     74: #define PIPECHAR '|'
                     75: 
                     76: save(file, to)
                     77: register char  *file, *to;
                     78: {
                     79:        register FILE *ufp, *hfp;
                     80:        struct hbuf hh;
                     81:        int     isprogram = 0;
                     82:        int     isnew = 1;
                     83: 
                     84:        if ((hfp = fopen(file, "r")) == NULL) {
                     85:                printf("Can't get article.\n");
                     86:                return;
                     87:        }
                     88:        if (hread(&hh, hfp, TRUE) == NULL) {
                     89:                printf("Article is garbled.\n");
                     90:                return;
                     91:        }
                     92:        ufp = fopen(to, "r");
                     93:        if (ufp != NULL) {
                     94:                fclose(ufp);
                     95:                isnew = 0;
                     96:        }
                     97:        setgid(gid);
                     98:        setuid(uid);
                     99:        umask(savmask);
                    100: 
                    101:        if (*to == PIPECHAR) {
                    102:                if ((ufp = popen (&to[1], "w")) == NULL) {
                    103:                        printf ("Cannot execute %s\n", &to[1]);
                    104:                        return;
                    105:                }
                    106:                isprogram++;
                    107:        } else if ((ufp = fopen(to, "a")) == NULL) {
                    108:                printf("Cannot append to %s.\n", to);
                    109:                return;
                    110:        }
                    111:        /*
                    112:         * V7MAIL code is here to conform to V7 mail format.
                    113:         * If you need a different format to be able to
                    114:         * use your local mail command (such as four ^A's
                    115:         * on the end of articles) substitute it here.
                    116:         */
                    117: #ifdef V7MAIL
                    118:        fprintf(ufp, "From %s %s",
                    119: #ifdef INTERNET
                    120:                                hh.from,
                    121: #else
                    122:                                hh.path,
                    123: #endif
                    124:                                        ctime(&hh.subtime));
                    125: #endif
                    126:        hprint(&hh, ufp, 2);
                    127: #ifdef V7MAIL
                    128:        tprint(hfp, ufp, TRUE);
                    129:        putc('\n', ufp);        /* force blank line at end (ugh) */
                    130: #else
                    131:        tprint(hfp, ufp, FALSE);
                    132: #endif
                    133:        fclose(hfp);
                    134:        if (isprogram)
                    135:                pclose (ufp);
                    136:        else
                    137:                fclose(ufp);
                    138:        if (!isprogram)
                    139:                printf("%s: %s\n", to, isnew ? "New file" : "Appended");
                    140: }
                    141: 
                    142: 
                    143: /*
                    144:  * Print out the rest of the article.
                    145:  */
                    146: tprint(ifp, ofp, checkfrom)
                    147: register FILE *ifp, *ofp;
                    148: int checkfrom;
                    149: {
                    150:        register int    c;
                    151: 
                    152:        while ((fgets(bfr, sizeof bfr, ifp)) != NULL && !sigtrap) {
                    153:                if (checkfrom && strncmp(bfr, "From ", 5) == 0)
                    154:                        putc('>', ofp);
                    155:                fputs(bfr, ofp);
                    156:        }
                    157:        if (sigtrap)
                    158:                qfflush(ofp);
                    159:        fflush(ofp);
                    160:        fprintf(ofp, (sigtrap ? "\n\n" : "\n"));
                    161:        sigtrap = FALSE;
                    162: }
                    163: 
                    164: 
                    165: /*
                    166:  * Print the file header.
                    167:  */
                    168: hprint(hp, ofp, verbose)
                    169: register struct hbuf *hp;
                    170: int    verbose;
                    171: register FILE *ofp;
                    172: {
                    173:        register char   *p1, *p2;
                    174:        char    fname[BUFLEN];
                    175:        char *tailpath();
                    176: 
                    177:        fname[0] = '\0';                /* init name holder */
                    178: 
                    179:        if (verbose == 2) {
                    180:                lhwrite(hp, ofp);
                    181:                return;
                    182:        }
                    183: 
                    184:        if (lflag || eflag) {
                    185:                char buf1[80], buf2[200];
                    186:                char *cp;
                    187: 
                    188:                strcpy(bfr, groupdir);
                    189:                for (cp=bfr; *cp; cp++)
                    190:                        if (*cp == '/')
                    191:                                *cp = '.';
                    192:                sprintf(buf1, "%s/%d", bfr, bit);
                    193:                sprintf(buf2, "%-20s %s", buf1, hp->title);
                    194:                fprintf(ofp, "%.76s\n", buf2);
                    195:                return;
                    196:        }
                    197: 
                    198:        p1 = index(hp->from, '(');      /* Find the sender's full name. */
                    199:        if (p1 == NULL && hp->path[0])
                    200:                p1 = index(hp->path, '(');
                    201:        if (p1 != NULL) {
                    202:                strcpy(fname, p1+1);
                    203:                p2 = index(fname, ')');
                    204:                if (p2 != NULL)
                    205:                        *p2 = '\0';
                    206:        }
                    207: 
                    208:        fprintf(ofp, "Subject: %s\n", hp->title);
                    209:        if (!hflag && hp->keywords[0])
                    210:                fprintf(ofp, "Keywords: %s\n", hp->keywords);
                    211:        if (verbose) {
                    212:                fprintf(ofp, "From: %s\n", hp->from);
                    213:                fprintf(ofp, "Path: %s\n", hp->path);
                    214:                if (hp->organization[0])
                    215:                        fprintf(ofp, "Organization: %s\n", hp->organization);
                    216:        }
                    217:        else {
                    218:                if (p1 != NULL)
                    219:                        *--p1 = '\0';           /* bump over the '(' */
                    220: #ifdef INTERNET
                    221:                /*
                    222:                 * Prefer Path line if it's in internet format, or if we don't
                    223:                 * understand internet format here, or if there is no reply-to.
                    224:                 */
                    225:                fprintf(ofp, "From: %s", hp->from);
                    226: #else
                    227:                fprintf(ofp, "Path: %s", tailpath(hp));
                    228: #endif
                    229:                if (fname[0] != '\0') {
                    230:                        fprintf(ofp, " (%s", fname);
                    231:                        if (hp->organization[0] && !hflag)
                    232:                                fprintf(ofp, " @ %s", hp->organization);
                    233:                        fprintf(ofp, ")");
                    234:                }
                    235:                fprintf(ofp, "\n");
                    236:                if (p1 != NULL)
                    237:                        *p1 = ' ';
                    238:        }
                    239: 
                    240:        ngdel(strcpy(bfr, hp->nbuf));
                    241:        if (verbose) {
                    242:                fprintf(ofp, "Newsgroups: %s\n", bfr);
                    243:                fprintf(ofp, "Date: %s\n", hp->subdate);
                    244:                if (hp->sender[0])
                    245:                        fprintf(ofp, "Sender: %s\n", hp->sender);
                    246:                if (hp->replyto[0])
                    247:                        fprintf(ofp, "Reply-To: %s\n", hp->replyto);
                    248:                if (hp->followto[0])
                    249:                        fprintf(ofp, "Followup-To: %s\n", hp->followto);
                    250:        }
                    251:        else if (index(bfr, ',') || strcmp(groupdir, "junk") == 0)
                    252:                fprintf(ofp, "Newsgroups: %s\n", bfr);
                    253: 
                    254:        if (pflag || ofp != stdout)
                    255:                putc('\n', ofp);
                    256: }
                    257: 
                    258: 
                    259: /*
                    260:  * If ofp != stdout, close it and run the script in coptbuf.
                    261:  */
                    262: cout(ofp)
                    263: FILE *ofp;
                    264: {
                    265:        register char   *p, *q, *r;
                    266: 
                    267:        if (ofp == stdout)
                    268:                return;
                    269:        fclose(ofp);
                    270:        p = coptbuf;
                    271:        q = lbuf;
                    272:        while ((*q = *p++) != '\0')
                    273:                if (*q++ == FMETA) {
                    274:                        q--;
                    275:                        r = outfile;
                    276:                        while ((*q++ = *r++) != '\0')
                    277:                                ;
                    278:                        q--;
                    279:                }
                    280:        fwait(fsubr(ushell, lbuf, (char *)NULL));
                    281:        unlink(outfile);
                    282: }
                    283: 
                    284: 
                    285: cdump(ofp)
                    286: register FILE *ofp;
                    287: {
                    288:        if (ofp == stdout)
                    289:                return;
                    290:        fclose(ofp);
                    291:        unlink(outfile);
                    292: }
                    293: 
                    294: 
                    295: /*
                    296:  * Quiet 'flush'.
                    297:  * Empty (without fflush()) the buffer for stream fp.
                    298:  */
                    299: /* ARGSUSED */
                    300: qfflush(fp)
                    301: FILE *fp;
                    302: {
                    303:        /* Alas, stdio does not permit this */
                    304: }
                    305: 
                    306: 
                    307: /*
                    308:  * Count the number of remaining lines in file fp.
                    309:  * Do not move the file pointer.
                    310:  */
                    311: linecnt(fp)
                    312: FILE *fp;
                    313: {
                    314:        long    curpos;
                    315:        register int    nlines = 0;
                    316:        register int    c;
                    317: 
                    318:        if (fp == NULL)
                    319:                return 0;
                    320:        curpos = ftell(fp);
                    321:        while ((c = getc(fp)) != EOF)
                    322:                if (c == '\n')
                    323:                        nlines++;
                    324:        fseek(fp, curpos, 0);
                    325:        return nlines;
                    326: }
                    327: 
                    328: 
                    329: /*
                    330:  * Transmit file to system.
                    331:  */
                    332: transmit(sp, file)
                    333: register struct srec *sp;
                    334: char   *file;
                    335: {
                    336:        register FILE *ifp, *ofp;
                    337:        register int    c;
                    338:        struct hbuf hh;
                    339:        char    TRANS[BUFLEN];
                    340: 
                    341: #ifdef DEBUG
                    342:        fprintf(stderr, "xmit %s to %s using %s\n", file, sp->s_name, sp->s_xmit);
                    343: #endif
                    344:        ifp = xfopen(file, "r");
                    345:        if (hread(&hh, ifp, TRUE) == NULL)
                    346:                return;
                    347:        strcpy(TRANS, "/tmp/trXXXXXX");
                    348:        ofp = xfopen(mktemp(TRANS), "w");
                    349:        if (index(sp->s_flags, 'A') == NULL)
                    350:                hwrite(&hh, ofp);
                    351:        else
                    352:                ohwrite(&hh, ofp);
                    353:        while ((c = getc(ifp)) != EOF)
                    354:                putc(c, ofp);
                    355:        fclose(ifp);
                    356:        fclose(ofp);
                    357:        if (*sp->s_xmit == '\0' || index(sp->s_flags, 'F') || index(sp->s_flags, 'U'))
                    358:                sprintf(bfr, DFTXMIT, sp->s_name, TRANS);
                    359:        else
                    360:                sprintf(bfr, "(%s) < %s", sp->s_xmit, TRANS);
                    361: #ifdef DEBUG
                    362:        fprintf(stderr, "%s\n", bfr);
                    363: #endif
                    364:        fwait(fsubr(pshell, bfr, (char *)NULL));
                    365:        unlink(TRANS);
                    366: }
                    367: 
                    368: 
                    369: /*
                    370:  * Cancel the article whose header is in hp, by posting a control message
                    371:  * to cancel it.  The scope of the control message depends on who would
                    372:  * really be willing to cancel it.  It is sent as far as it will do any good.
                    373:  * notauthor is true iff the person posting this article is not the
                    374:  * real author of the article being cancelled.
                    375:  */
                    376: cancel(ofp, hp, notauthor)
                    377: FILE *ofp;
                    378: struct hbuf *hp;
                    379: int    notauthor;
                    380: {
                    381:        FILE    *inews;
                    382:        struct utsname me;
                    383:        char    *p;
                    384:        char    distgroup[64];
                    385:        int     pid;
                    386: 
                    387:        fflush(stdout);
                    388:        pid = fork();
                    389:        if (pid > 0)
                    390:                return 0;
                    391:        uname(&me);
                    392:        strcpy(distgroup, hp->nbuf);
                    393:        p = index(distgroup, '.');
                    394:        if (notauthor)
                    395:                sprintf(distgroup, "to.%s", me.nodename);
                    396:        else
                    397:                sprintf(distgroup, "%s", hp->nbuf);
                    398:        sprintf(bfr, "%s -t 'cmsg cancel %s' -n %s < /dev/null",
                    399:            INEWS, hp->ident, distgroup);
                    400:        if ((inews = popen(bfr, "w")) == NULL)
                    401:                fprintf(ofp, "Can't fork %s\n", INEWS);
                    402:        else
                    403:                pclose(inews);
                    404:        if (pid == 0)
                    405:                exit(0);
                    406:        return 0;
                    407: }
                    408: 
                    409: 
                    410: dash(num, ofp)
                    411: register int   num;
                    412: register FILE *ofp;
                    413: {
                    414:        register int    i;
                    415: 
                    416:        for (i = 0; i < num; i++)
                    417:                putc('-', ofp);
                    418:        putc('\n', ofp);
                    419: }
                    420: 
                    421: 
                    422: help(ofp)
                    423: register FILE *ofp;
                    424: {
                    425:        register FILE *fp;
                    426:        register int    c;
                    427: 
                    428:        if (cflag) {
                    429: oneline:
                    430:                fprintf(ofp, "(n)ext re(p)rint (w)rite (q)uit (r)eply\
                    431:  (c)ancel -[n] +[n] (f)ollowup (N)ext (U)nsubscribe (v)ersion\n");
                    432:                return;
                    433:        }
                    434:        if ((fp = fopen(HELPFILE, "r")) == NULL) {
                    435:                fprintf(ofp, "No help file.\n");
                    436:                goto oneline;
                    437:        }
                    438:        while ((c = getc(fp)) != EOF && !sigtrap)
                    439:                putc(c, ofp);
                    440:        fclose(fp);
                    441: }
                    442: 
                    443: 
                    444: pout(ofp)
                    445: FILE *ofp;
                    446: {
                    447:        register char   *p, *q, *r;
                    448: 
                    449:        p = PAGER;
                    450:        q = lbuf;
                    451:        while ((*q = *p++) != '\0')
                    452:                if (*q++ == FMETA) {
                    453:                        q--;
                    454:                        r = filename;
                    455:                        while ((*q++ = *r++) != '\0')
                    456:                                ;
                    457:                        q--;
                    458:                }
                    459:        fwait(fsubr(ushell, lbuf, (char *)NULL));
                    460:        fprintf(ofp, "\n");
                    461: }
                    462: 
                    463: 
                    464: /*
                    465:  * like strcat but be careful with quotes.  since there appears to be no way
                    466:  * to quote an apostrophe in sh, we change them to double quotes.
                    467:  */
                    468: strqcat(dest, src)
                    469: register char  *dest, *src;
                    470: {
                    471:        while (*dest++)
                    472:                ;
                    473:        dest--;
                    474:        while (*src) {
                    475:                if (*src == '\'')
                    476:                        *dest++ = '"', src++;
                    477:                else
                    478:                        *dest++ = *src++;
                    479:        }
                    480:        *dest++ = 0;
                    481: }
                    482: 
                    483: /*
                    484:  * Print a very brief version of the date in question.
                    485:  */
                    486: char *
                    487: briefdate(datestr)
                    488: char *datestr;
                    489: {
                    490:        long dt, now;
                    491:        char *tmstr;
                    492:        char *wkday, *monthdate, *timeofday;
                    493:        static char rbuf[20];
                    494: 
                    495:        dt = cgtdate(datestr);
                    496:        tmstr = ctime(&dt);
                    497: 
                    498:        wkday = tmstr; tmstr[3] = '\0';
                    499:        monthdate = tmstr+4; tmstr[10] = '\0';
                    500:        timeofday = tmstr+11; tmstr[16] = '\0';
                    501: 
                    502:        time(&now);
                    503:        if (now - dt < 7 * DAYS)
                    504:                strcpy(rbuf, wkday);
                    505:        else
                    506:                strcpy(rbuf, monthdate);
                    507:        strcat(rbuf, " ");
                    508:        strcat(rbuf, timeofday);
                    509:        return rbuf;
                    510: }
                    511: 
                    512: /*
                    513:  * Return TRUE iff stdout is /dev/null.
                    514:  */
                    515: ignoring()
                    516: {
                    517:        struct stat ss, ns;
                    518: 
                    519:        fstat(1, &ss);
                    520:        stat("/dev/null", &ns);
                    521:        if (ss.st_dev == ns.st_dev && ss.st_rdev == ns.st_rdev)
                    522:                return TRUE;
                    523:        return FALSE;
                    524: }

unix.superglobalmegacorp.com

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