xref: /original-bsd/libexec/bugfiler/gethead.c (revision da818fbb)
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.7 (Berkeley) 05/11/89";
20 #endif /* not lint */
21 
22 #include <bug.h>
23 #include <sys/stat.h>
24 #include <stdio.h>
25 #include "pathnames.h"
26 
27 static int	chk1(), pbuf();
28 
29 #define ENT(X)	sizeof(X) - 1, X
30 HEADER	mailhead[] = {				/* mail headers */
31 	{ NO, YES,  NULL, ENT("Date:"), },
32 	{ NO,  NO,  NULL, ENT("From "), },
33 	{ NO, YES,  NULL, ENT("From:"), },
34 	{ NO,  NO,  chk1, ENT("Index:"), },
35 	{ NO, YES,  NULL, ENT("Message-Id:"), },
36 	{ NO, YES,  NULL, ENT("Reply-To:"), },
37 	{ NO, YES,  NULL, ENT("Return-Path:"), },
38 	{ NO,  NO,  pbuf, ENT("Subject:"), },
39 	{ NO, YES,  NULL, ENT("To:"), },
40 	{ NO,  NO,  NULL, ENT("Apparently-To:"), },
41 	{ ERR, }
42 };
43 
44 FILE	*dfp;				/* distf file pointer */
45 char	dir[MAXNAMLEN],			/* subject and folder */
46 	folder[MAXNAMLEN];
47 
48 /*
49  * gethead --
50  *	read mail and bug headers from bug report, construct redist headers
51  */
52 gethead(redist)
53 	int	redist;
54 {
55 	register HEADER	*hp;		/* mail header pointer */
56 	char	*strcpy(), *malloc();
57 
58 	if (redist) {
59 		int	fd;
60 		char	*distf;
61 
62 		distf = _PATH_TMP;
63 		if (!(fd = mkstemp(distf)) || !(dfp = fdopen(fd, "w+")))
64 			error("can't create redistribution file %s.", distf);
65 		/* disappear after last reference is closed */
66 		(void)unlink(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 = malloc((u_int)(strlen(bfr) + 1))))
78 						error("malloc failed.", CHN);
79 					(void)strcpy(hp->line, bfr);
80 					hp->found = YES;
81 					break;
82 				}
83 		if ((hp->found == ERR || hp->redist) && redist)
84 			fputs(bfr, dfp);
85 	}
86 
87 	if (!mailhead[INDX_TAG].found)
88 		error("no readable \"Index:\" header in bug report.", CHN);
89 }
90 
91 /*
92  * chk1 --
93  *	parse the "Index:" line into folder and directory
94  */
95 static
96 chk1(line)
97 	char	*line;
98 {
99 	register char	*C;		/* tmp pointer */
100 	struct stat	sbuf;		/* existence check */
101 	char	*index();
102 
103 	if (sscanf(line, " Index: %s %s ", folder, dir) != 2)
104 		return(NO);
105 	if (C = index(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
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