xref: /original-bsd/libexec/bugfiler/gethead.c (revision c02b9ad6)
1 /*
2  * Copyright (c) 1986, 1987 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)gethead.c	5.6 (Berkeley) 06/29/88";
20 #endif /* not lint */
21 
22 #include <bug.h>
23 #include <sys/stat.h>
24 #include <stdio.h>
25 
26 static int	chk1(), pbuf();
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 gethead(redist)
52 	int	redist;
53 {
54 	register HEADER	*hp;		/* mail header pointer */
55 	char	*strcpy(), *malloc();
56 
57 	if (redist) {
58 		int	fd;
59 		char	*distf;
60 
61 		distf = "/tmp/BUG_XXXXXX";
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 	}
67 	if (!freopen(tmpname, "r", stdin))
68 		error("can't read temporary bug file %s.", tmpname);
69 
70 	while (fgets(bfr, sizeof(bfr), stdin)) {
71 		for (hp = mailhead; hp->found != ERR; ++hp)
72 			if (!hp->found)
73 				if (!strncmp(hp->tag, bfr, hp->len)) {
74 					if (hp->valid && !((*(hp->valid))(bfr)))
75 						break;
76 					if (!(hp->line = malloc((u_int)(strlen(bfr) + 1))))
77 						error("malloc failed.", CHN);
78 					(void)strcpy(hp->line, bfr);
79 					hp->found = YES;
80 					break;
81 				}
82 		if ((hp->found == ERR || hp->redist) && redist)
83 			fputs(bfr, dfp);
84 	}
85 
86 	if (!mailhead[INDX_TAG].found)
87 		error("no readable \"Index:\" header in bug report.", CHN);
88 }
89 
90 /*
91  * chk1 --
92  *	parse the "Index:" line into folder and directory
93  */
94 static
95 chk1(line)
96 	char	*line;
97 {
98 	register char	*C;		/* tmp pointer */
99 	struct stat	sbuf;		/* existence check */
100 	char	*index();
101 
102 	if (sscanf(line, " Index: %s %s ", folder, dir) != 2)
103 		return(NO);
104 	if (C = index(folder, '/')) {	/* deal with "bin/from.c" */
105 		if (C == folder)
106 			return(NO);
107 		*C = EOS;
108 	}
109 	if (stat(dir, &sbuf) || (sbuf.st_mode & S_IFMT) != S_IFDIR)
110 		return(NO);
111 	(void)pbuf(line);
112 	return(YES);
113 }
114 
115 /*
116  * pbuf --
117  *	kludge so that summary file looks pretty
118  */
119 static
120 pbuf(line)
121 	char	*line;
122 {
123 	register char	*rp,			/* tmp pointers */
124 			*wp;
125 
126 	for (rp = line; *rp == ' ' || *rp == '\t'; ++rp);
127 	for (wp = line; *rp; ++wp) {
128 		if ((*wp = *rp++) != ' ' && *wp != '\t')
129 			continue;
130 		*wp = ' ';
131 		while (*rp == ' ' || *rp == '\t')
132 			++rp;
133 	}
134 	if (wp[-1] == ' ')			/* wp can't == line */
135 		--wp;
136 	*wp = EOS;
137 	return(YES);
138 }
139