1 /*
2 * Copyright (c) 1986, 1987, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)gethead.c 8.1 (Berkeley) 06/04/93";
10 #endif /* not lint */
11
12 #include <sys/param.h>
13 #include <sys/stat.h>
14
15 #include <dirent.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20
21 #include "pathnames.h"
22 #include "bug.h"
23 #include "extern.h"
24
25 static int chk1 __P((char *));
26 static int pbuf __P((char *));
27
28 #define ENT(X) sizeof(X) - 1, X
29 HEADER mailhead[] = { /* mail headers */
30 { NO, YES, NULL, ENT("Date:"), },
31 { NO, NO, NULL, ENT("From "), },
32 { NO, YES, NULL, ENT("From:"), },
33 { NO, NO, chk1, ENT("Index:"), },
34 { NO, YES, NULL, ENT("Message-Id:"), },
35 { NO, YES, NULL, ENT("Reply-To:"), },
36 { NO, YES, NULL, ENT("Return-Path:"), },
37 { NO, NO, pbuf, ENT("Subject:"), },
38 { NO, YES, NULL, ENT("To:"), },
39 { NO, NO, NULL, ENT("Apparently-To:"), },
40 { ERR, }
41 };
42
43 FILE *dfp; /* distf file pointer */
44 char dir[MAXNAMLEN], /* subject and folder */
45 folder[MAXNAMLEN];
46
47 /*
48 * gethead --
49 * read mail and bug headers from bug report, construct redist headers
50 */
51 void
gethead(redist)52 gethead(redist)
53 int redist;
54 {
55 register HEADER *hp; /* mail header pointer */
56
57 if (redist) {
58 int fd;
59 char *distf;
60
61 distf = strdup(_PATH_TMP);
62 if (!(fd = mkstemp(distf)) || !(dfp = fdopen(fd, "w+")))
63 error("can't create redistribution file %s.", distf);
64 /* disappear after last reference is closed */
65 (void)unlink(distf);
66 free(distf);
67 }
68 if (!freopen(tmpname, "r", stdin))
69 error("can't read temporary bug file %s.", tmpname);
70
71 while (fgets(bfr, sizeof(bfr), stdin)) {
72 for (hp = mailhead; hp->found != ERR; ++hp)
73 if (!hp->found)
74 if (!strncmp(hp->tag, bfr, hp->len)) {
75 if (hp->valid && !((*(hp->valid))(bfr)))
76 break;
77 if (!(hp->line =
78 malloc((u_int)(strlen(bfr) + 1))))
79 error("malloc failed.", CHN);
80 (void)strcpy(hp->line, bfr);
81 hp->found = YES;
82 break;
83 }
84 if ((hp->found == ERR || hp->redist) && redist)
85 fputs(bfr, dfp);
86 }
87
88 if (!mailhead[INDX_TAG].found)
89 error("no readable \"Index:\" header in bug report.", CHN);
90 }
91
92 /*
93 * chk1 --
94 * parse the "Index:" line into folder and directory
95 */
96 static int
chk1(line)97 chk1(line)
98 char *line;
99 {
100 register char *C; /* tmp pointer */
101 struct stat sbuf; /* existence check */
102
103 if (sscanf(line, " Index: %s %s ", folder, dir) != 2)
104 return(NO);
105 if (C = strchr(folder, '/')) { /* deal with "bin/from.c" */
106 if (C == folder)
107 return(NO);
108 *C = EOS;
109 }
110 if (stat(dir, &sbuf) || (sbuf.st_mode & S_IFMT) != S_IFDIR)
111 return(NO);
112 (void)pbuf(line);
113 return(YES);
114 }
115
116 /*
117 * pbuf --
118 * kludge so that summary file looks pretty
119 */
120 static int
pbuf(line)121 pbuf(line)
122 char *line;
123 {
124 register char *rp, /* tmp pointers */
125 *wp;
126
127 for (rp = line; *rp == ' ' || *rp == '\t'; ++rp);
128 for (wp = line; *rp; ++wp) {
129 if ((*wp = *rp++) != ' ' && *wp != '\t')
130 continue;
131 *wp = ' ';
132 while (*rp == ' ' || *rp == '\t')
133 ++rp;
134 }
135 if (wp[-1] == ' ') /* wp can't == line */
136 --wp;
137 *wp = EOS;
138 return(YES);
139 }
140