xref: /original-bsd/libexec/bugfiler/gethead.c (revision 4092c5cc)
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
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
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
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