Annotation of 42BSD/ucb/sendbug/bugfiler.c, revision 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.