2 * Mailbox and Maildir Parser (so far very primitive)
4 * (c) 2010--2018 Martin Mares <mj@ucw.cz>
17 const char progname[] = "mparse";
18 static char **field_names;
19 static int num_fields;
24 static char buf[BUFSIZE];
25 static char *bpos, *bend;
27 static void reset_buf(void)
33 static char *get_line(void)
40 int remains = bend - bpos;
43 char *nl = memchr(bpos, '\n', remains);
47 if (nl > p && nl[-1] == '\r')
53 memmove(buf, bpos, remains);
58 int space = BUFSIZE - remains;
61 int len = read(mbox_fd, bend, space);
63 die("Read error: %m");
78 static int want_header(char *line)
83 for (int i=0; i<num_fields; i++)
85 int len = strlen(field_names[i]);
86 if (!strncasecmp(line, field_names[i], len))
99 static void parse_mbox(void)
102 enum state state = S_INITIAL;
106 while (c = get_line())
108 // printf("<%s>\n", c);
109 if (state == S_INITIAL || state == S_BODY)
111 if (!strncmp(c, "From ", 5))
124 else if (*c == ' ' || *c == '\t')
128 while (*c == ' ' || *c == '\t')
136 want = want_header(c);
146 if (state == S_HEADER)
147 printf("\nX-Warning: Incomplete mail\n\n");
150 static void parse_maildir_file(void)
156 while (c = get_line())
158 // printf("<%s>\n", c);
164 else if (*c == ' ' || *c == '\t')
168 while (*c == ' ' || *c == '\t')
176 want = want_header(c);
185 printf("\nX-Warning: Incomplete mail\n\n");
188 static void parse_maildir(char *dir, char *subdir)
191 snprintf(buf, sizeof(buf), "%s/%s", dir, subdir);
193 DIR *d = opendir(buf);
198 while (e = readdir(d))
200 if (e->d_name[0] == '.')
202 snprintf(buf, sizeof(buf), "%s/%s/%s", dir, subdir, e->d_name);
203 mbox_fd = open(buf, O_RDONLY);
206 parse_maildir_file();
213 static void usage(void)
215 fprintf(stderr, "Usage: mparse [-f <mailbox>] <header-field> ...\n");
220 main(int argc, char **argv)
225 while ((opt = getopt(argc, argv, "f:")) >= 0)
235 field_names = argv + optind;
236 num_fields = argc - optind;
245 if (stat(folder, &st) < 0)
246 die("Cannot stat %s: %m", folder);
248 if (st.st_mode & S_IFDIR)
250 parse_maildir(folder, "cur");
251 parse_maildir(folder, "new");
255 mbox_fd = open(folder, O_RDONLY);
257 die("Cannot open %s: %m", folder);