]> diplodocus.org Git - mdfrm/blob - mdfrm.c
23d95071a835f22ea23a94c4bd55113c3d3af1d3
[mdfrm] / mdfrm.c
1 /* mdfrm.c -- mdfrm(1) for maildir.
2 *
3 * $Id$
4 *
5 * This program is in the public domain.
6 */
7
8 #include <sys/types.h>
9
10 #include <dirent.h>
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sysexits.h>
16 #include <unistd.h>
17
18 /* Note that PATH_MAX is supposed to include the terminating null. */
19 #ifndef PATH_MAX
20 #ifndef MAXPATHLEN
21 #define PATH_MAX 65
22 #else
23 #define PATH_MAX MAXPATHLEN
24 #endif
25 #endif
26
27 enum {
28 FROMLEN = 6, /* "From: " */
29 SUBJLEN = 9, /* "Subject: " */
30
31 /* Number of characters for each field we actually output. This
32 * must also be changed in the printf functions at the end of the
33 * frm function.
34 */
35 FROMCOUNT = 24,
36 SUBJCOUNT = 53
37 };
38
39 static char ident[] = "$Id$";
40
41 static void
42 scan_message(char *filename, char *fromheader, char *subjheader)
43 {
44 FILE *file;
45 char *line;
46 size_t len, fromcount, subjcount;
47
48 if (!(file = fopen(filename, "r"))) {
49 err(EX_OSERR, "Failed fopen(%s)", filename);
50 }
51
52 fromcount = subjcount = 0;
53 fromheader[0] = subjheader[0] = '\0';
54 while ((line = fgetln(file, &len))) {
55 if (len <= 1) {
56 break;
57 }
58 --len;
59
60 if (len > FROMLEN && strncmp(line, "From: ", FROMLEN) == 0) {
61 line += FROMLEN;
62 len -= FROMLEN;
63 if (len < FROMCOUNT) {
64 fromcount = len;
65 } else {
66 fromcount = FROMCOUNT;
67 }
68 strncpy(fromheader, line, fromcount);
69 fromheader[fromcount] = '\0';
70 } else if (len > SUBJLEN && strncmp(line, "Subject: ", SUBJLEN) == 0) {
71 line += SUBJLEN;
72 len -= SUBJLEN;
73 if (len < SUBJCOUNT) {
74 subjcount = len;
75 } else {
76 subjcount = SUBJCOUNT;
77 }
78 strncpy(subjheader, line, subjcount);
79 subjheader[subjcount] = '\0';
80 }
81 }
82
83 fclose(file);
84 }
85
86 static void
87 frm(char *dirname)
88 {
89 DIR *dir;
90 struct dirent *dirent;
91 char *filename;
92 char fromheader[FROMCOUNT + 1] = { '\0' };
93 char subjheader[SUBJCOUNT + 1] = { '\0' };
94
95 if (chdir(dirname) != 0) {
96 err(EX_OSERR, "Failed chdir(%s)", dirname);
97 }
98
99 if (chdir("new") != 0) {
100 err(EX_OSERR, "Failed chdir(%s/new)", dirname);
101 }
102
103 dir = opendir(".");
104 if (!dir) {
105 err(EX_OSERR, "Failed opendir(%s/new)", dirname);
106 }
107
108 for (dirent = readdir(dir); dirent; dirent = readdir(dir)) {
109 filename = dirent->d_name;
110 if (filename[0] == '.') {
111 continue;
112 }
113
114 scan_message(filename, fromheader, subjheader);
115
116 printf("%-24s ", fromheader);
117 printf("%-53s\n", subjheader);
118 }
119 }
120
121 int
122 main(int argc, char *argv[])
123 {
124 char *dirname;
125 char buf[PATH_MAX];
126
127 if (argv[1] && argv[1][0] == '-' && argv[1][1] == 'v') {
128 puts(ident);
129 return 0;
130 }
131
132 if (!(dirname = argv[1])) {
133 if (!(dirname = getenv("MAILDIR"))) {
134 if (!(dirname = getenv("HOME"))) {
135 errx(EX_UNAVAILABLE, "Could not find maildir.");
136 } else {
137 snprintf(buf, PATH_MAX, "%s/Maildir", dirname);
138 dirname = buf;
139 }
140 }
141 }
142
143 frm(dirname);
144
145 return 0;
146 }