Annotation of 42BSD/ucb/sendbug/bugfiler.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)bugfiler.c 4.11 (Berkeley) 9/14/83";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Bug report processing program.
                      7:  * It is designed to be invoked by alias(5)
                      8:  * and to be compatible with mh.
                      9:  */
                     10: 
                     11: #include <stdio.h>
                     12: #include <ctype.h>
                     13: #include <signal.h>
                     14: #include <pwd.h>
                     15: 
                     16: #include <sys/types.h>
                     17: #include <sys/stat.h>
                     18: #include <sys/dir.h>
                     19: 
                     20: #define        BUGS_NAME       "4bsd-bugs"
                     21: #define        BUGS_HOME       "%ucbarpa@BERKELEY"
                     22: #define        MAILCMD         "/usr/lib/sendmail -i -t"
                     23: 
                     24: char   unixtomh[] = "/usr/new/lib/mh/unixtomh";
                     25: char   *bugperson = "bugs";
                     26: char   *maildir = "mail";
                     27: char   ackfile[] = ".ack";
                     28: char   errfile[] = ".format";
                     29: char   sumfile[] = "summary";
                     30: char   logfile[] = "errors/log";
                     31: char   redistfile[] = ".redist";
                     32: char   tmpname[] = "BfXXXXXX";
                     33: char   draft[] = "RpXXXXXX";
                     34: char   disttmp[] = "RcXXXXXX";
                     35: 
                     36: char   buf[8192];
                     37: char   folder[MAXNAMLEN];
                     38: int    num;
                     39: int    msg_prot = 0664;
                     40: 
                     41: int    debug;
                     42: 
                     43: char   *index();
                     44: char   *rindex();
                     45: char   *fixaddr();
                     46: char   *any();
                     47: 
                     48: main(argc, argv)
                     49:        char *argv[];
                     50: {
                     51:        register char *cp;
                     52:        register int n;
                     53:        int pfd[2];
                     54: 
                     55:        if (argc > 3) {
                     56:        usage:
                     57:                fprintf(stderr, "Usage: bugfiler [-d] [-mmsg_mode] [maildir]\n");
                     58:                exit(1);
                     59:        }
                     60:        while (--argc > 0) {
                     61:                cp = *++argv;
                     62:                if (*cp == '-')
                     63:                        switch (cp[1]) {
                     64:                        case 'd':
                     65:                                debug++;
                     66:                                break;
                     67: 
                     68:                        case 'm':       /* set message protection */
                     69:                                n = 0;
                     70:                                for (cp += 2; *cp >= '0' && *cp <= '7'; )
                     71:                                        n = (n << 3) + (*cp++ - '0');
                     72:                                msg_prot = n & 0777;
                     73:                                break;
                     74: 
                     75:                        default:
                     76:                                goto usage;
                     77:                        }
                     78:                else
                     79:                        maildir = cp;
                     80:        }
                     81:        if (!debug)
                     82:                freopen(logfile, "a", stderr);
                     83: 
                     84:        if (bugperson) {
                     85:                struct passwd *pwd = getpwnam(bugperson);
                     86: 
                     87:                if (pwd == NULL) {
                     88:                        fprintf(stderr, "%s: bugs person is unknown\n",
                     89:                            bugperson);
                     90:                        exit(1);
                     91:                }
                     92:                if (chdir(pwd->pw_dir) < 0) {
                     93:                        fprintf(stderr, "can't chdir to %s\n", pwd->pw_dir);
                     94:                        exit(1);
                     95:                }
                     96:        }
                     97:        if (chdir(maildir) < 0) {
                     98:                fprintf(stderr, "can't chdir to %s\n", maildir);
                     99:                exit(1);
                    100:        }
                    101:        umask(0);
                    102: 
                    103: #ifdef UNIXCOMP
                    104:        /*
                    105:         * Convert UNIX style mail to mh style by filtering stdin through
                    106:         * unixtomh.
                    107:         */
                    108:        if (pipe(pfd) >= 0) {
                    109:                while ((n = fork()) == -1)
                    110:                        sleep(5);
                    111:                if (n == 0) {
                    112:                        close(pfd[0]);
                    113:                        dup2(pfd[1], 1);
                    114:                        close(pfd[1]);
                    115:                        execl(unixtomh, "unixtomh", 0);
                    116:                        _exit(127);
                    117:                }
                    118:                close(pfd[1]);
                    119:                dup2(pfd[0], 0);
                    120:                close(pfd[0]);
                    121:        }
                    122: #endif
                    123:        while (process())
                    124:                ;
                    125:        exit(0);
                    126: }
                    127: 
                    128: /* states */
                    129: 
                    130: #define EOM    0       /* End of message seen */
                    131: #define FLD    1       /* Looking for header lines */
                    132: #define BODY   2       /* Looking for message body lines */
                    133: 
                    134: /* defines used for tag attributes */
                    135: 
                    136: #define H_REQ 01
                    137: #define H_SAV 02
                    138: #define H_HDR 04
                    139: #define H_FND 010
                    140: 
                    141: #define FROM_I headers[0].h_info
                    142: #define SUBJECT_I headers[1].h_info
                    143: #define INDEX &headers[2]
                    144: #define INDEX_I headers[2].h_info
                    145: #define DATE_I headers[3].h_info
                    146: #define MSGID_I headers[4].h_info
                    147: #define REPLYTO_I headers[5].h_info
                    148: #define TO_I headers[6].h_info
                    149: #define CC_I headers[7].h_info
                    150: #define FIX headers[10]
                    151: 
                    152: struct header {
                    153:        char    *h_tag;
                    154:        int     h_flags;
                    155:        char    *h_info;
                    156: } headers[] = {
                    157:        "From",         H_REQ|H_SAV|H_HDR, 0,
                    158:        "Subject",      H_REQ|H_SAV, 0,
                    159:        "Index",        H_REQ|H_SAV, 0,
                    160:        "Date",         H_SAV|H_HDR, 0,
                    161:        "Message-Id",   H_SAV|H_HDR, 0,
                    162:        "Reply-To",     H_SAV|H_HDR, 0,
                    163:        "To",           H_SAV|H_HDR, 0,
                    164:        "Cc",           H_SAV|H_HDR, 0,
                    165:        "Description",  H_REQ,       0,
                    166:        "Repeat-By",    0,           0,
                    167:        "Fix",          0,           0,
                    168:        0,      0,      0,
                    169: };
                    170: 
                    171: struct header *findheader();
                    172: 
                    173: process()
                    174: {
                    175:        register struct header *hp;
                    176:        register char *cp;
                    177:        register int c;
                    178:        char *info;
                    179:        int state, tmp;
                    180:        FILE *tfp, *fs;
                    181: 
                    182:        /*
                    183:         * Insure all headers are in a consistent
                    184:         * state.  Anything left there is free'd.
                    185:         */
                    186:        for (hp = headers; hp->h_tag; hp++) {
                    187:                hp->h_flags &= ~H_FND;
                    188:                if (hp->h_info) {
                    189:                        free(hp->h_info);
                    190:                        hp->h_info = 0;
                    191:                }
                    192:        }
                    193:        /*
                    194:         * Read the report and make a copy.  Must conform to RFC822 and
                    195:         * be of the form... <tag>: <info>
                    196:         * Note that the input is expected to be in mh mail format
                    197:         * (i.e., messages are separated by lines of ^A's).
                    198:         */
                    199:        while ((c = getchar()) == '\001' && peekc(stdin) == '\001')
                    200:                while (getchar() != '\n')
                    201:                        ;
                    202:        if (c == EOF)
                    203:                return(0);      /* all done */
                    204: 
                    205:        mktemp(tmpname);
                    206:        if ((tmp = creat(tmpname, msg_prot)) < 0) {
                    207:                fprintf(stderr, "cannont create %s\n", tmpname);
                    208:                exit(1);
                    209:        }
                    210:        if ((tfp = fdopen(tmp, "w")) == NULL) {
                    211:                fprintf(stderr, "cannot fdopen temp file\n");
                    212:                exit(1);
                    213:        }
                    214: 
                    215:        for (state = FLD; state != EOF && state != EOM; c = getchar()) {
                    216:                switch (state) {
                    217:                case FLD:
                    218:                        if (c == '\n' || c == '-')
                    219:                                goto body;
                    220:                        for (cp = buf; c != ':'; c = getchar()) {
                    221:                                if (cp < buf+sizeof(buf)-1 && c != '\n' && c != EOF) {
                    222:                                        *cp++ = c;
                    223:                                        continue;
                    224:                                }
                    225:                                *cp = '\0';
                    226:                                fputs(buf, tfp);
                    227:                                state = EOF;
                    228:                                while (c != EOF) {
                    229:                                        if (c == '\n')
                    230:                                                if ((tmp = peekc(stdin)) == EOF)
                    231:                                                        break;
                    232:                                                else if (tmp == '\001') {
                    233:                                                        state = EOM;
                    234:                                                        break;
                    235:                                                }
                    236:                                        putc(c, tfp);
                    237:                                        c = getchar();
                    238:                                }
                    239:                                fclose(tfp);
                    240:                                goto badfmt;
                    241:                        }
                    242:                        *cp = '\0';
                    243:                        fprintf(tfp, "%s:", buf);
                    244:                        hp = findheader(buf, state);
                    245: 
                    246:                        for (cp = buf; ; ) {
                    247:                                if (cp >= buf+sizeof(buf)-1) {
                    248:                                        fprintf(stderr, "field truncated\n");
                    249:                                        while ((c = getchar()) != EOF && c != '\n')
                    250:                                                putc(c, tfp);
                    251:                                }
                    252:                                if ((c = getchar()) == EOF) {
                    253:                                        state = EOF;
                    254:                                        break;
                    255:                                }
                    256:                                putc(c, tfp);
                    257:                                *cp++ = c;
                    258:                                if (c == '\n')
                    259:                                        if ((c = peekc(stdin)) != ' ' && c != '\t') {
                    260:                                                if (c == EOF)
                    261:                                                        state = EOF;
                    262:                                                else if (c == '\001')
                    263:                                                        state = EOM;
                    264:                                                break;
                    265:                                        }
                    266:                        }
                    267:                        *cp = '\0';
                    268:                        cp = buf;
                    269:                        break;
                    270: 
                    271:                body:
                    272:                        state = BODY;
                    273:                case BODY:
                    274:                        for (cp = buf; ; c = getchar()) {
                    275:                                if (c == EOF) {
                    276:                                        state = EOF;
                    277:                                        break;
                    278:                                }
                    279:                                if (c == '\001' && peekc(stdin) == '\001') {
                    280:                                        state = EOM;
                    281:                                        break;
                    282:                                }
                    283:                                putc(c, tfp);
                    284:                                *cp++ = c;
                    285:                                if (cp >= buf+sizeof(buf)-1 || c == '\n')
                    286:                                        break;
                    287:                        }
                    288:                        *cp = '\0';
                    289:                        if ((cp = index(buf, ':')) == NULL)
                    290:                                continue;
                    291:                        *cp++ = '\0';
                    292:                        hp = findheader(buf, state);
                    293:                }
                    294: 
                    295:                /*
                    296:                 * Don't save the info if the header wasn't found, we don't
                    297:                 * care about the info, or the header is repeated.
                    298:                 */
                    299:                if (hp == NULL || !(hp->h_flags & H_SAV) || hp->h_info)
                    300:                        continue;
                    301:                while (isspace(*cp))
                    302:                        cp++;
                    303:                if (*cp) {
                    304:                        info = cp;
                    305:                        while (*cp++);
                    306:                        cp--;
                    307:                        while (isspace(cp[-1]))
                    308:                                *--cp = '\0';
                    309:                        hp->h_info = (char *) malloc(strlen(info) + 1);
                    310:                        if (hp->h_info == NULL) {
                    311:                                fprintf(stderr, "ran out of memory\n");
                    312:                                continue;
                    313:                        }
                    314:                        strcpy(hp->h_info, info);
                    315:                        if (hp == INDEX)
                    316:                                chkindex(hp);
                    317:                }
                    318:        }
                    319:        fclose(tfp);
                    320:        /*
                    321:         * Verify all the required pieces of information
                    322:         * are present.
                    323:         */
                    324:        for (hp = headers; hp->h_tag; hp++) {
                    325:                /*
                    326:                 * Mail the bug report back to the sender with a note
                    327:                 * explaining they must conform to the specification.
                    328:                 */
                    329:                if ((hp->h_flags & H_REQ) && !(hp->h_flags & H_FND)) {
                    330:                        if (debug)
                    331:                                printf("Missing %s\n", hp->h_tag);
                    332:                badfmt:
                    333:                        reply(FROM_I, errfile, tmpname);
                    334:                        file(tmpname, "errors");
                    335:                        return(state == EOM);
                    336:                }
                    337:        }
                    338:        /*
                    339:         * Acknowledge receipt.
                    340:         */
                    341:        reply(FROM_I, ackfile, (char *)0);
                    342:        file(tmpname, folder);
                    343:        /*
                    344:         * Append information about the new bug report
                    345:         * to the summary file.
                    346:         */
                    347:        if ((fs = fopen(sumfile, "a")) == NULL)
                    348:                fprintf(stderr, "Can't open %s\n", sumfile);
                    349:        else {
                    350:                fprintf(fs, "%14.14s/%-3d  ", folder, num);
                    351:                fprintf(fs, "%-51.51s Recv\n", INDEX_I);
                    352:                fprintf(fs, "\t\t    %-51.51s\n", SUBJECT_I);
                    353:        }
                    354:        fclose(fs);
                    355:        /*
                    356:         * Check redistribution list and, if members,
                    357:         * mail a copy of the bug report to these people.
                    358:         */
                    359:        redistribute(folder, num);
                    360:        return(state == EOM);
                    361: }
                    362: 
                    363: /*
                    364:  * Lookup the string in the list of headers and return a pointer
                    365:  * to the entry or NULL.
                    366:  */
                    367: 
                    368: struct header *
                    369: findheader(name, state)
                    370:        char *name;
                    371:        int state;
                    372: {
                    373:        register struct header *hp;
                    374: 
                    375:        if (debug)
                    376:                printf("findheader(%s, %d)\n", name, state);
                    377: 
                    378:        for (hp = headers; hp->h_tag; hp++) {
                    379:                if (!streq(hp->h_tag, buf))
                    380:                        continue;
                    381:                if ((hp->h_flags & H_HDR) && state != FLD)
                    382:                        continue;
                    383:                hp->h_flags |= H_FND;
                    384:                return(hp);
                    385:        }
                    386:        return(NULL);
                    387: }
                    388: 
                    389: /*
                    390:  * Check the format of the Index information.
                    391:  * A side effect is to set the name of the folder if all is well.
                    392:  */
                    393: 
                    394: chkindex(hp)
                    395:        struct header *hp;
                    396: {
                    397:        register char *cp1, *cp2;
                    398:        register char c;
                    399:        struct stat stbuf;
                    400: 
                    401:        if (debug)
                    402:                printf("chkindex(%s)\n", hp->h_info);
                    403:        /*
                    404:         * Strip of leading "/", "usr/", or "src/".
                    405:         */
                    406:        cp1 = hp->h_info;
                    407:        while (*cp1 == '/')
                    408:                cp1++;
                    409:        while (substr(cp1, "usr/") || substr(cp1, "src/"))
                    410:                cp1 += 4;
                    411:        /*
                    412:         * Read the folder name and remove it from the index line.
                    413:         */
                    414:        for (cp2 = folder; ;) {
                    415:                switch (c = *cp1++) {
                    416:                case '/':
                    417:                        if (cp2 == folder)
                    418:                                continue;
                    419:                        break;
                    420:                case '\0':
                    421:                        cp1--;
                    422:                        break;
                    423:                case ' ':
                    424:                case '\t':
                    425:                        while (isspace(*cp1))
                    426:                                cp1++;
                    427:                        break;
                    428:                default:
                    429:                        if (cp2 < folder+sizeof(folder)-1)
                    430:                                *cp2++ = c;
                    431:                        continue;
                    432:                }
                    433:                *cp2 = '\0';
                    434:                for (cp2 = hp->h_info; *cp2++ = *cp1++; )
                    435:                        ;
                    436:                break;
                    437:        }
                    438:        if (debug)
                    439:                printf("folder = %s\n", folder);
                    440:        /*
                    441:         * Check to make sure we have a valid folder name
                    442:         */
                    443:        if (stat(folder, &stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFDIR)
                    444:                return;
                    445:        /*
                    446:         * The Index line is not in the correct format so clear
                    447:         * the H_FND flag to mail back the correct format.
                    448:         */
                    449:        hp->h_flags &= ~H_FND;
                    450: }
                    451: 
                    452: /*
                    453:  * Move or copy the file msg to the folder (directory).
                    454:  * As a side effect, num is set to the number under which
                    455:  * the message is filed in folder.
                    456:  */
                    457: 
                    458: file(fname, folder)
                    459:        char *fname, *folder;
                    460: {
                    461:        register char *cp, n;
                    462:        char msgname[MAXNAMLEN*2+2];
                    463:        struct stat stbuf;
                    464:        DIR *dirp;
                    465:        struct direct *d;
                    466: 
                    467:        if (debug)
                    468:                printf("file(%s, %s)\n", fname, folder);
                    469:        /*
                    470:         * Get the next number to use by finding the last message number
                    471:         * in folder and adding one.
                    472:         */
                    473:        if ((dirp = opendir(folder)) == NULL) {
                    474:                fprintf(stderr, "Cannot open %s/%s\n", maildir, folder);
                    475:                return;
                    476:        }
                    477:        num = 0;
                    478:        while ((d = readdir(dirp)) != NULL) {
                    479:                cp = d->d_name;
                    480:                n = 0;
                    481:                while (isdigit(*cp))
                    482:                        n = n * 10 + (*cp++ - '0');
                    483:                if (*cp == '\0' && n > num)
                    484:                        num = n;
                    485:        }
                    486:        closedir(dirp);
                    487:        num++;
                    488:        /*
                    489:         * Create the destination file "folder/num" and copy fname to it.
                    490:         */
                    491:        sprintf(msgname, "%s/%d", folder, num);
                    492:        if (link(fname, msgname) < 0) {
                    493:                int fin, fout;
                    494: 
                    495:                if ((fin = open(fname, 0)) < 0) {
                    496:                        fprintf(stderr, "cannot open %s\n", fname);
                    497:                        return;
                    498:                }
                    499:                if ((fout = creat(msgname, msg_prot)) < 0) {
                    500:                        fprintf(stderr, "cannot create %s\n", msgname);
                    501:                        return;
                    502:                }
                    503:                while ((n = read(fin, buf, sizeof(buf))) > 0)
                    504:                        write(fout, buf, n);
                    505:                close(fin);
                    506:                close(fout);
                    507:        }
                    508:        unlink(fname);
                    509: }
                    510: 
                    511: /*
                    512:  * Redistribute a bug report to those people indicated
                    513:  * in the redistribution list file.  Perhaps should also
                    514:  * annotate bug report with this information for future
                    515:  * reference?
                    516:  */
                    517: redistribute(folder, num)
                    518:        char *folder;
                    519:        int num;
                    520: {
                    521:        FILE *fredist, *fbug, *ftemp;
                    522:        char line[BUFSIZ], bug[2 * MAXNAMLEN + 1];
                    523:        register char *cp;
                    524:        int redistcnt, continuation, first;
                    525: 
                    526:        fredist = fopen(redistfile, "r");
                    527:        if (fredist == NULL) {
                    528:                if (debug)
                    529:                        printf("redistribute(%s, %d), no distribution list\n",
                    530:                            folder, num);
                    531:                return;
                    532:        }
                    533:        continuation = 0;
                    534:        first = 1;
                    535:        redistcnt = 0;
                    536:        while (fgets(line, sizeof (line) - 1, fredist) != NULL) {
                    537:                if (debug)
                    538:                        printf("%s: %s", redistfile, line);
                    539:                if (continuation && index(line, '\\'))
                    540:                        continue;
                    541:                continuation = 0;
                    542:                cp = any(line, " \t");
                    543:                if (cp == NULL)
                    544:                        continue;
                    545:                *cp++ = '\0';
                    546:                if (strcmp(folder, line) == 0)
                    547:                        goto found;
                    548:                if (index(cp, '\\'))
                    549:                        continuation = 1;
                    550:        }
                    551:        if (debug)
                    552:                printf("no redistribution list found\n");
                    553:        fclose(fredist);
                    554:        return;
                    555: found:
                    556:        mktemp(disttmp);
                    557:        ftemp = fopen(disttmp, "w+r");
                    558:        if (ftemp == NULL) {
                    559:                if (debug)
                    560:                        printf("%s: couldn't create\n", disttmp);
                    561:                return;
                    562:        }
                    563: again:
                    564:        if (debug)
                    565:                printf("redistribution list %s", cp);
                    566:        while (cp) {
                    567:                char *user, terminator;
                    568: 
                    569:                while (*cp && (*cp == ' ' || *cp == '\t' || *cp == ','))
                    570:                        cp++;
                    571:                user = cp, cp = any(cp, ", \t\n\\");
                    572:                if (cp) {
                    573:                        terminator = *cp;
                    574:                        *cp++ = '\0';
                    575:                        if (terminator == '\n')
                    576:                                cp = 0;
                    577:                        if (terminator == '\\')
                    578:                                continuation++;
                    579:                }
                    580:                if (*user == '\0')
                    581:                        continue;
                    582:                if (debug)
                    583:                        printf("copy to %s\n", user);
                    584:                if (first) {
                    585:                        fprintf(ftemp, "To: %s", user);
                    586:                        first = 0;
                    587:                } else
                    588:                        fprintf(ftemp, ", %s", user);
                    589:                redistcnt++;
                    590:        }
                    591:        if (!first)
                    592:                putc('\n', ftemp);
                    593:        if (continuation) {
                    594:                first = 1;
                    595:                continuation = 0;
                    596:                cp = line;
                    597:                if (fgets(line, sizeof (line) - 1, fredist))
                    598:                        goto again;
                    599:        }
                    600:        fclose(fredist);
                    601:        if (redistcnt == 0)
                    602:                goto cleanup;
                    603:        fprintf(ftemp, "Subject: ");
                    604:        if (SUBJECT_I)
                    605:                fprintf(ftemp, "%s\n", SUBJECT_I);
                    606:        else
                    607:                fprintf(ftemp, "Untitled bug report\n");
                    608:        fprintf(ftemp, "\nRedistributed-by: %s%s\n", BUGS_NAME, BUGS_HOME);
                    609:        /*
                    610:         * Create copy of bug report.  Perhaps we should
                    611:         * truncate large messages and just give people
                    612:         * a pointer to the original?
                    613:         */
                    614:        sprintf(bug, "%s/%d", folder, num);
                    615:        fbug = fopen(bug, "r");
                    616:        if (fbug == NULL) {
                    617:                if (debug)
                    618:                        printf("%s: disappeared?\n", bug);
                    619:                goto cleanup;
                    620:        }
                    621:        first = 1;
                    622:        while (fgets(line, sizeof (line) - 1, fbug)) {
                    623:                /* first blank line indicates start of mesg */
                    624:                if (first && line[0] == '\n') {
                    625:                        first = 0;
                    626:                        continue;
                    627:                }
                    628:                fputs(line, ftemp);
                    629:        }
                    630:        fclose(fbug);
                    631:        if (first) {
                    632:                if (debug)
                    633:                        printf("empty bug report?\n");
                    634:                goto cleanup;
                    635:        }
                    636:        if (dodeliver(ftemp))
                    637:                unlink(disttmp);
                    638:        fclose(ftemp);
                    639:        return;
                    640: cleanup:
                    641:        fclose(ftemp);
                    642:        unlink(disttmp);
                    643: }
                    644: 
                    645: dodeliver(fd)
                    646:        FILE *fd;
                    647: {
                    648:        char buf[BUFSIZ], cmd[BUFSIZ];
                    649:        FILE *pf, *popen();
                    650: 
                    651:        strcpy(cmd, MAILCMD);
                    652:        if (debug) {
                    653:                strcat(cmd, " -v");
                    654:                printf("dodeliver \"%s\"\n", cmd);
                    655:        }
                    656:        pf = popen(cmd, "w");
                    657:        if (pf == NULL) {
                    658:                if (debug)
                    659:                        printf("dodeliver, \"%s\" failed\n", cmd);
                    660:                return (0);
                    661:        }
                    662:        rewind(fd);
                    663:        while (fgets(buf, sizeof (buf) - 1, fd)) {
                    664:                if (debug)
                    665:                        printf("%s", buf);
                    666:                (void) fputs(buf, pf);
                    667:        }
                    668:        if (debug)
                    669:                printf("EOF\n");
                    670:        (void) pclose(pf);
                    671:        return (1);
                    672: }
                    673: 
                    674: /*
                    675:  * Mail file1 and file2 back to the sender.
                    676:  */
                    677: 
                    678: reply(to, file1, file2)
                    679:        char    *to, *file1, *file2;
                    680: {
                    681:        int pfd[2], in, w;
                    682:        FILE *fout;
                    683: 
                    684:        if (debug)
                    685:                printf("reply(%s, %s, %s)\n", to, file1, file2);
                    686: 
                    687:        /*
                    688:         * Create a temporary file to put the message in.
                    689:         */
                    690:        mktemp(draft);
                    691:        if ((fout = fopen(draft, "w+r")) == NULL) {
                    692:                fprintf(stderr, "Can't create %s\n", draft);
                    693:                return;
                    694:        }
                    695:        /*
                    696:         * Output the proper header information.
                    697:         */
                    698:        fprintf(fout, "Reply-To: %s%s\n", BUGS_NAME, BUGS_HOME);
                    699:        fprintf(fout, "From: %s%s (Bugs Bunny)\n", BUGS_NAME, BUGS_HOME);
                    700:        if (REPLYTO_I != NULL)
                    701:                to = REPLYTO_I;
                    702:        if ((to = fixaddr(to)) == 0) {
                    703:                fprintf(stderr, "No one to reply to\n");
                    704:                return;
                    705:        }
                    706:        fprintf(fout, "To: %s\n", to);
                    707:        if (SUBJECT_I) {
                    708:                fprintf(fout, "Subject: ");
                    709:                if ((SUBJECT_I[0] != 'R' && SUBJECT_I[0] != 'r') ||
                    710:                    (SUBJECT_I[1] != 'E' && SUBJECT_I[1] != 'e') ||
                    711:                    SUBJECT_I[2] != ':')
                    712:                        fprintf(fout, "Re: ");
                    713:                fprintf(fout, "%s\n", SUBJECT_I);
                    714:        }
                    715:        if (DATE_I) {
                    716:                fprintf(fout, "In-Acknowledgement-Of: Your message of ");
                    717:                fprintf(fout, "%s.\n", DATE_I);
                    718:                if (MSGID_I)
                    719:                        fprintf(fout, "             %s\n", MSGID_I);
                    720:        }
                    721:        fprintf(fout, "\n");
                    722:        if ((in = open(file1, 0)) >= 0) {
                    723:                while ((w = read(in, buf, sizeof(buf))) > 0)
                    724:                        fwrite(buf, 1, w, fout);
                    725:                close(in);
                    726:        }
                    727:        if (file2 && (in = open(file2, 0)) >= 0) {
                    728:                while ((w = read(in, buf, sizeof(buf))) > 0)
                    729:                        fwrite(buf, 1, w, fout);
                    730:                close(in);
                    731:        }
                    732:        if (dodeliver(fout))
                    733:                unlink(draft);
                    734:        fclose(fout);
                    735: }
                    736: 
                    737: /*
                    738:  * fix names like "xxx (something)" to "xxx" and
                    739:  * "xxx <something>" to "something".
                    740:  */
                    741: 
                    742: char *
                    743: fixaddr(text)
                    744:        char *text;
                    745: {
                    746:        register char *cp, *lp, c;
                    747:        char *tp;
                    748: 
                    749:        if (!text)
                    750:                return(0);
                    751:        for (lp = cp = text; ; ) {
                    752:                switch (c = *cp++) {
                    753:                case '(':
                    754:                        while (*cp && *cp++ != ')');
                    755:                        continue;
                    756:                case '<':
                    757:                        lp = text;
                    758:                case '>':
                    759:                        continue;
                    760:                case '\0':
                    761:                        while (lp != text && (*lp == ' ' || *lp == '\t'))
                    762:                                lp--;
                    763:                        *lp = c;
                    764:                        return(text);
                    765:                }
                    766:                *lp++ = c;
                    767:        }
                    768: }
                    769: 
                    770: /*
                    771:  * Compare two strings and convert any upper case letters to lower case.
                    772:  */
                    773: 
                    774: streq(s1, s2)
                    775:        register char *s1, *s2;
                    776: {
                    777:        register int c;
                    778: 
                    779:        while (c = *s1++)
                    780:                if ((c | 040) != (*s2++ | 040))
                    781:                        return(0);
                    782:        return(*s2 == '\0');
                    783: }
                    784: 
                    785: /*
                    786:  * Return true if string s2 matches the first part of s1.
                    787:  */
                    788: 
                    789: substr(s1, s2)
                    790:        register char *s1, *s2;
                    791: {
                    792:        register int c;
                    793: 
                    794:        while (c = *s2++)
                    795:                if (c != *s1++)
                    796:                        return(0);
                    797:        return(1);
                    798: }
                    799: 
                    800: char *
                    801: any(cp, set)
                    802:        register char *cp;
                    803:        char *set;
                    804: {
                    805:        register char *sp;
                    806: 
                    807:        if (cp == 0 || set == 0)
                    808:                return (0);
                    809:        while (*cp) {
                    810:                for (sp = set; *sp; sp++)
                    811:                        if (*cp == *sp)
                    812:                                return (cp);
                    813:                cp++;
                    814:        }
                    815:        return ((char *)0);
                    816: }
                    817: 
                    818: peekc(fp)
                    819: FILE *fp;
                    820: {
                    821:        register c;
                    822: 
                    823:        c = getc(fp);
                    824:        ungetc(c, fp);
                    825:        return(c);
                    826: }

unix.superglobalmegacorp.com

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