2 * Another stupid program, this one parsing the headers of an
3 * email to figure out authorship and subject
10 static FILE *cmitmsg, *patchfile, *filelist;
12 static char line[1000];
13 static char name[1000];
14 static char email[1000];
15 static char subject[1000];
17 static char *sanity_check(char *name, char *email)
19 int len = strlen(name);
20 if (len < 3 || len > 60)
22 if (strchr(name, '@') || strchr(name, '<') || strchr(name, '>'))
27 static int handle_from(char *line)
29 char *at = strchr(line, '@');
36 * If we already have one email, don't take any confusing lines
38 if (*email && strchr(at+1, '@'))
43 if (isspace(c) || c == '<')
49 unsigned char c = *at;
50 if (!c || c == '>' || isspace(c))
57 at = line + strlen(line);
59 unsigned char c = *--at;
67 unsigned char c = *at;
75 at = sanity_check(at, email);
81 static void handle_subject(char *line)
83 strcpy(subject, line);
86 static void add_subject_line(char *line)
88 while (isspace(*line))
91 strcat(subject, line);
94 static void check_line(char *line, int len)
97 if (!memcmp(line, "From:", 5) && isspace(line[5])) {
102 if (!memcmp(line, "Subject:", 8) && isspace(line[8])) {
103 handle_subject(line+9);
107 if (isspace(*line)) {
110 fprintf(stderr, "I don't do 'From:' line continuations\n");
113 add_subject_line(line);
122 static char * cleanup_subject(char *subject)
129 if (!memcmp("e:", subject+1, 2)) {
134 case ' ': case '\t': case ':':
139 p = strchr(subject, ']');
145 remove = p - subject;
146 if (remove <= len *2) {
156 static void cleanup_space(char *buf)
159 while ((c = *buf) != 0) {
165 int len = strlen(buf);
166 memmove(buf, buf+1, len);
174 * Hacky hacky. This depends not only on -p1, but on
175 * filenames not having some special characters in them,
178 static void show_filename(char *line)
181 char *name = strchr(line, '/');
183 if (!name || !isspace(*line))
188 unsigned char c = name[len];
195 case '\t': case '\n':
198 /* patch tends to special-case these things.. */
204 /* remove ".orig" from the end - common patch behaviour */
205 if (len > 5 && !memcmp(name+len-5, ".orig", 5))
209 fprintf(filelist, "%.*s\n", len, name);
212 static void handle_rest(void)
214 char *sub = cleanup_subject(subject);
216 cleanup_space(email);
218 printf("Author: %s\nEmail: %s\nSubject: %s\n\n", name, email, sub);
222 /* Track filename information from the patch.. */
223 if (!memcmp("---", line, 3)) {
225 show_filename(line+3);
228 if (!memcmp("+++", line, 3))
229 show_filename(line+3);
232 } while (fgets(line, sizeof(line), stdin) != NULL);
234 if (out == cmitmsg) {
235 fprintf(stderr, "No patch found\n");
243 static int eatspace(char *line)
245 int len = strlen(line);
246 while (len > 0 && isspace(line[len-1]))
251 static void handle_body(void)
255 /* First line of body can be a From: */
256 while (fgets(line, sizeof(line), stdin) != NULL) {
257 int len = eatspace(line);
260 if (!memcmp("From:", line, 5) && isspace(line[5])) {
261 if (!has_from && handle_from(line+6)) {
272 static void usage(void)
274 fprintf(stderr, "mailinfo msg-file path-file filelist-file < email\n");
278 int main(int argc, char ** argv)
282 cmitmsg = fopen(argv[1], "w");
287 patchfile = fopen(argv[2], "w");
292 filelist = fopen(argv[3], "w");
297 while (fgets(line, sizeof(line), stdin) != NULL) {
298 int len = eatspace(line);
303 check_line(line, len);