130162Sbostic /*
2*61420Sbostic * Copyright (c) 1986, 1987, 1993
3*61420Sbostic * The Regents of the University of California. All rights reserved.
433416Sbostic *
542663Sbostic * %sccs.include.redist.c%
630162Sbostic */
730162Sbostic
830162Sbostic #ifndef lint
9*61420Sbostic static char sccsid[] = "@(#)gethead.c 8.1 (Berkeley) 06/04/93";
1033416Sbostic #endif /* not lint */
1130162Sbostic
1246667Sbostic #include <sys/param.h>
1330162Sbostic #include <sys/stat.h>
1460083Sbostic
1546667Sbostic #include <dirent.h>
1630162Sbostic #include <stdio.h>
1746667Sbostic #include <stdlib.h>
1846667Sbostic #include <string.h>
1960083Sbostic #include <unistd.h>
2060083Sbostic
2137887Sbostic #include "pathnames.h"
2246667Sbostic #include "bug.h"
2360083Sbostic #include "extern.h"
2430162Sbostic
2560083Sbostic static int chk1 __P((char *));
2660083Sbostic static int pbuf __P((char *));
2730162Sbostic
2830162Sbostic #define ENT(X) sizeof(X) - 1, X
2930162Sbostic HEADER mailhead[] = { /* mail headers */
3030162Sbostic { NO, YES, NULL, ENT("Date:"), },
3130162Sbostic { NO, NO, NULL, ENT("From "), },
3230162Sbostic { NO, YES, NULL, ENT("From:"), },
3330162Sbostic { NO, NO, chk1, ENT("Index:"), },
3430162Sbostic { NO, YES, NULL, ENT("Message-Id:"), },
3532093Skarels { NO, YES, NULL, ENT("Reply-To:"), },
3632093Skarels { NO, YES, NULL, ENT("Return-Path:"), },
3731011Sbostic { NO, NO, pbuf, ENT("Subject:"), },
3832093Skarels { NO, YES, NULL, ENT("To:"), },
3932093Skarels { NO, NO, NULL, ENT("Apparently-To:"), },
4030162Sbostic { ERR, }
4130162Sbostic };
4230162Sbostic
4330890Sbostic FILE *dfp; /* distf file pointer */
4430890Sbostic char dir[MAXNAMLEN], /* subject and folder */
4530162Sbostic folder[MAXNAMLEN];
4630162Sbostic
4730162Sbostic /*
4830162Sbostic * gethead --
4930162Sbostic * read mail and bug headers from bug report, construct redist headers
5030162Sbostic */
5160083Sbostic void
gethead(redist)5230890Sbostic gethead(redist)
5330890Sbostic int redist;
5430162Sbostic {
5530162Sbostic register HEADER *hp; /* mail header pointer */
5630162Sbostic
5730890Sbostic if (redist) {
5830890Sbostic int fd;
5930890Sbostic char *distf;
6030162Sbostic
6147077Sdonn distf = strdup(_PATH_TMP);
6230890Sbostic if (!(fd = mkstemp(distf)) || !(dfp = fdopen(fd, "w+")))
6330890Sbostic error("can't create redistribution file %s.", distf);
6430890Sbostic /* disappear after last reference is closed */
6530890Sbostic (void)unlink(distf);
6647077Sdonn free(distf);
6730890Sbostic }
6830890Sbostic if (!freopen(tmpname, "r", stdin))
6930890Sbostic error("can't read temporary bug file %s.", tmpname);
7030890Sbostic
7130890Sbostic while (fgets(bfr, sizeof(bfr), stdin)) {
7230890Sbostic for (hp = mailhead; hp->found != ERR; ++hp)
7330162Sbostic if (!hp->found)
7430890Sbostic if (!strncmp(hp->tag, bfr, hp->len)) {
7530162Sbostic if (hp->valid && !((*(hp->valid))(bfr)))
7630162Sbostic break;
7760083Sbostic if (!(hp->line =
7860083Sbostic malloc((u_int)(strlen(bfr) + 1))))
7930890Sbostic error("malloc failed.", CHN);
8030890Sbostic (void)strcpy(hp->line, bfr);
8130162Sbostic hp->found = YES;
8230162Sbostic break;
8330162Sbostic }
8430890Sbostic if ((hp->found == ERR || hp->redist) && redist)
8530890Sbostic fputs(bfr, dfp);
8630162Sbostic }
8730162Sbostic
8830162Sbostic if (!mailhead[INDX_TAG].found)
8930890Sbostic error("no readable \"Index:\" header in bug report.", CHN);
9030162Sbostic }
9130162Sbostic
9230162Sbostic /*
9330162Sbostic * chk1 --
9430162Sbostic * parse the "Index:" line into folder and directory
9530162Sbostic */
9660083Sbostic static int
chk1(line)9730162Sbostic chk1(line)
9830890Sbostic char *line;
9930162Sbostic {
10030162Sbostic register char *C; /* tmp pointer */
10130162Sbostic struct stat sbuf; /* existence check */
10230162Sbostic
10330890Sbostic if (sscanf(line, " Index: %s %s ", folder, dir) != 2)
10430162Sbostic return(NO);
10560083Sbostic if (C = strchr(folder, '/')) { /* deal with "bin/from.c" */
10630162Sbostic if (C == folder)
10730162Sbostic return(NO);
10830162Sbostic *C = EOS;
10930162Sbostic }
11030890Sbostic if (stat(dir, &sbuf) || (sbuf.st_mode & S_IFMT) != S_IFDIR)
11130162Sbostic return(NO);
11231011Sbostic (void)pbuf(line);
11330162Sbostic return(YES);
11430162Sbostic }
11531011Sbostic
11631011Sbostic /*
11731011Sbostic * pbuf --
11831011Sbostic * kludge so that summary file looks pretty
11931011Sbostic */
12060083Sbostic static int
pbuf(line)12131011Sbostic pbuf(line)
12231011Sbostic char *line;
12331011Sbostic {
12431011Sbostic register char *rp, /* tmp pointers */
12531011Sbostic *wp;
12631011Sbostic
12731011Sbostic for (rp = line; *rp == ' ' || *rp == '\t'; ++rp);
12831011Sbostic for (wp = line; *rp; ++wp) {
12931011Sbostic if ((*wp = *rp++) != ' ' && *wp != '\t')
13031011Sbostic continue;
13131011Sbostic *wp = ' ';
13231011Sbostic while (*rp == ' ' || *rp == '\t')
13331011Sbostic ++rp;
13431011Sbostic }
13531011Sbostic if (wp[-1] == ' ') /* wp can't == line */
13631011Sbostic --wp;
13731011Sbostic *wp = EOS;
13831011Sbostic return(YES);
13931011Sbostic }
140