Annotation of 43BSD/ucb/sendbug/bugfiler.c, revision 1.1

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

unix.superglobalmegacorp.com

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