- register char *cp;
- register int n;
- int pfd[2];
-
- if (argc > 4) {
- usage:
- fprintf(stderr, "Usage: bugfiler [-d] [-mmsg_mode] [maildir]\n");
- exit(1);
- }
- while (--argc > 0) {
- cp = *++argv;
- if (*cp == '-')
- switch (cp[1]) {
- case 'd':
- debug++;
- break;
-
- case 'm': /* set message protection */
- n = 0;
- for (cp += 2; *cp >= '0' && *cp <= '7'; )
- n = (n << 3) + (*cp++ - '0');
- msg_prot = n & 0777;
- break;
-
- default:
- goto usage;
- }
- else
- maildir = cp;
- }
- if (!debug)
- freopen(logfile, "a", stderr);
-
- if (bugperson) {
- struct passwd *pwd = getpwnam(bugperson);
-
- if (pwd == NULL) {
- fprintf(stderr, "%s: bugs person is unknown\n",
- bugperson);
- exit(1);
- }
- if (chdir(pwd->pw_dir) < 0) {
- fprintf(stderr, "can't chdir to %s\n", pwd->pw_dir);
- exit(1);
- }
- setuid(pwd->pw_uid);
- }
- if (chdir(maildir) < 0) {
- fprintf(stderr, "can't chdir to %s\n", maildir);
- exit(1);
- }
- umask(0);
-
-#ifdef UNIXCOMP
- /*
- * Convert UNIX style mail to mh style by filtering stdin through
- * unixtomh.
- */
- if (pipe(pfd) >= 0) {
- while ((n = fork()) == -1)
- sleep(5);
- if (n == 0) {
- close(pfd[0]);
- dup2(pfd[1], 1);
- close(pfd[1]);
- execl(UNIXTOMH, "unixtomh", 0);
- _exit(127);
- }
- close(pfd[1]);
- dup2(pfd[0], 0);
- close(pfd[0]);
- }
-#endif
- while (process())
- ;
- exit(0);
-}
-
-/* states */
-
-#define EOM 0 /* End of message seen */
-#define FLD 1 /* Looking for header lines */
-#define BODY 2 /* Looking for message body lines */
-
-/* defines used for tag attributes */
-
-#define H_REQ 01
-#define H_SAV 02
-#define H_HDR 04
-#define H_FND 010
-
-#define FROM &headers[0]
-#define FROM_I headers[0].h_info
-#define SUBJECT_I headers[1].h_info
-#define INDEX &headers[2]
-#define INDEX_I headers[2].h_info
-#define DATE_I headers[3].h_info
-#define MSGID_I headers[4].h_info
-#define REPLYTO_I headers[5].h_info
-#define TO_I headers[6].h_info
-#define CC_I headers[7].h_info
-#define FIX headers[10]
-
-struct header {
- char *h_tag;
- int h_flags;
- char *h_info;
-} headers[] = {
- "From", H_REQ|H_SAV|H_HDR, 0,
- "Subject", H_REQ|H_SAV, 0,
- "Index", H_REQ|H_SAV, 0,
- "Date", H_SAV|H_HDR, 0,
- "Message-Id", H_SAV|H_HDR, 0,
- "Reply-To", H_SAV|H_HDR, 0,
- "To", H_SAV|H_HDR, 0,
- "Cc", H_SAV|H_HDR, 0,
- "Description", H_REQ, 0,
- "Repeat-By", 0, 0,
- "Fix", 0, 0,
- 0, 0, 0,
-};
-
-struct header *findheader();
-
-process()
-{
- register struct header *hp;
- register char *cp;
- register int c;
- char *info;
- int state, tmp, no_reply = 0;
- FILE *tfp, *fs;
-
- /*
- * Insure all headers are in a consistent
- * state. Anything left there is free'd.
- */
- for (hp = headers; hp->h_tag; hp++) {
- hp->h_flags &= ~H_FND;
- if (hp->h_info) {
- free(hp->h_info);
- hp->h_info = 0;
- }
- }
- /*
- * Read the report and make a copy. Must conform to RFC822 and
- * be of the form... <tag>: <info>
- * Note that the input is expected to be in mh mail format
- * (i.e., messages are separated by lines of ^A's).
- */
- while ((c = getchar()) == '\001' && peekc(stdin) == '\001')
- while (getchar() != '\n')
- ;
- if (c == EOF)
- return(0); /* all done */
-
- mktemp(tmpname);
- if ((tmp = creat(tmpname, msg_prot)) < 0) {
- fprintf(stderr, "cannont create %s\n", tmpname);
- exit(1);
- }
- if ((tfp = fdopen(tmp, "w")) == NULL) {
- fprintf(stderr, "cannot fdopen temp file\n");
- exit(1);
- }
-
- for (state = FLD; state != EOF && state != EOM; c = getchar()) {
- switch (state) {
- case FLD:
- if (c == '\n' || c == '-')
- goto body;
- for (cp = buf; c != ':'; c = getchar()) {
- if (cp < buf+sizeof(buf)-1 && c != '\n' && c != EOF) {
- *cp++ = c;
- continue;
- }
- *cp = '\0';
- fputs(buf, tfp);
- state = EOF;
- while (c != EOF) {
- if (c == '\n')
- if ((tmp = peekc(stdin)) == EOF)
- break;
- else if (tmp == '\001') {
- state = EOM;
- break;
- }
- putc(c, tfp);
- c = getchar();
- }
- fclose(tfp);
- goto badfmt;
- }
- *cp = '\0';
- fprintf(tfp, "%s:", buf);
- hp = findheader(buf, state);
-
- for (cp = buf; ; ) {
- if (cp >= buf+sizeof(buf)-1) {
- fprintf(stderr, "field truncated\n");
- while ((c = getchar()) != EOF && c != '\n')
- putc(c, tfp);
- }
- if ((c = getchar()) == EOF) {
- state = EOF;
- break;
- }
- putc(c, tfp);
- *cp++ = c;
- if (c == '\n')
- if ((c = peekc(stdin)) != ' ' && c != '\t') {
- if (c == EOF)
- state = EOF;
- else if (c == '\001')
- state = EOM;
- break;
- }
- }
- *cp = '\0';
- cp = buf;