2 * Another stupid program, this one parsing the headers of an
3 * email to figure out authorship and subject
10 static FILE *cmitmsg
, *patchfile
;
12 static int keep_subject
= 0;
13 static char line
[1000];
14 static char date
[1000];
15 static char name
[1000];
16 static char email
[1000];
17 static char subject
[1000];
19 static char *sanity_check(char *name
, char *email
)
21 int len
= strlen(name
);
22 if (len
< 3 || len
> 60)
24 if (strchr(name
, '@') || strchr(name
, '<') || strchr(name
, '>'))
29 static int handle_from(char *line
)
31 char *at
= strchr(line
, '@');
38 * If we already have one email, don't take any confusing lines
40 if (*email
&& strchr(at
+1, '@'))
45 if (isspace(c
) || c
== '<')
51 unsigned char c
= *at
;
52 if (!c
|| c
== '>' || isspace(c
))
59 at
= line
+ strlen(line
);
61 unsigned char c
= *--at
;
69 unsigned char c
= *at
;
77 at
= sanity_check(at
, email
);
83 static void handle_date(char *line
)
88 static void handle_subject(char *line
)
90 strcpy(subject
, line
);
93 static void check_line(char *line
, int len
)
95 if (!memcmp(line
, "From:", 5) && isspace(line
[5]))
97 else if (!memcmp(line
, "Date:", 5) && isspace(line
[5]))
99 else if (!memcmp(line
, "Subject:", 8) && isspace(line
[8]))
100 handle_subject(line
+9);
103 static char * cleanup_subject(char *subject
)
112 if (!memcmp("e:", subject
+1, 2)) {
117 case ' ': case '\t': case ':':
122 p
= strchr(subject
, ']');
128 remove
= p
- subject
;
129 if (remove
<= len
*2) {
139 static void cleanup_space(char *buf
)
142 while ((c
= *buf
) != 0) {
148 int len
= strlen(buf
);
149 memmove(buf
, buf
+1, len
);
156 static void handle_rest(void)
159 char *sub
= cleanup_subject(subject
);
162 cleanup_space(email
);
164 printf("Author: %s\nEmail: %s\nSubject: %s\nDate: %s\n\n", name
, email
, sub
, date
);
167 if (!memcmp("diff -", line
, 6) ||
168 !memcmp("---", line
, 3) ||
169 !memcmp("Index: ", line
, 7))
173 } while (fgets(line
, sizeof(line
), stdin
) != NULL
);
175 if (out
== cmitmsg
) {
176 fprintf(stderr
, "No patch found\n");
184 static int eatspace(char *line
)
186 int len
= strlen(line
);
187 while (len
> 0 && isspace(line
[len
-1]))
192 static void handle_body(void)
197 /* First lines of body can have From: and Date: */
198 while (fgets(line
, sizeof(line
), stdin
) != NULL
) {
199 int len
= eatspace(line
);
202 if (!memcmp("From:", line
, 5) && isspace(line
[5])) {
203 if (!has_from
&& handle_from(line
+6)) {
208 if (!memcmp("Date:", line
, 5) && isspace(line
[5])) {
221 static int read_one_header_line(char *line
, int sz
, FILE *in
)
226 if (fgets(line
+ ofs
, sz
- ofs
, in
) == NULL
)
228 len
= eatspace(line
+ ofs
);
231 peek
= fgetc(in
); ungetc(peek
, in
);
232 if (peek
== ' ' || peek
== '\t') {
233 /* Yuck, 2822 header "folding" */
242 static void usage(void)
244 fprintf(stderr
, "mailinfo msg-file patch-file < email\n");
248 static const char mailinfo_usage
[] =
249 "git-mailinfo [-k] msg patch <mail >info";
250 int main(int argc
, char ** argv
)
252 while (1 < argc
&& argv
[1][0] == '-') {
253 if (!strcmp(argv
[1], "-k"))
256 fprintf(stderr
, "usage: %s\n", mailinfo_usage
);
264 cmitmsg
= fopen(argv
[1], "w");
269 patchfile
= fopen(argv
[2], "w");
275 int len
= read_one_header_line(line
, sizeof(line
), stdin
);
280 check_line(line
, len
);