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