scan.c - rohrpost - A commandline mail client to change the world as we see it.
(HTM) git clone git://r-36.net/rohrpost
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
scan.c (4377B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <time.h>
10 #include <string.h>
11
12 #include "ind.h"
13 #include "arg.h"
14 #include "cfg.h"
15 #include "llist.h"
16 #include "folder.h"
17 #include "imap.h"
18 #include "pager.h"
19 #include "mime.h"
20 #include "scan.h"
21
22 void
23 scan_print(char *id, char *date, char *from, char *subject)
24 {
25 printf("%s\t%s\t%s\t%s\n", id, date, from, subject);
26 }
27
28 void
29 scanusage(char *argv0)
30 {
31 die("usage: %s [-h] [-c cfg] [-m folder] msgs\n", argv0);
32 }
33
34 int
35 scanmain(int argc, char *argv[])
36 {
37 config_t *cfg;
38 imap_t *imap;
39 int filelen;
40 char *user, *pass, *netspec, *selected, *date, *subject, *from,
41 *id, *filec, *cfgn, *argv0;
42 llist_t *ids, *msgs;
43 llistelem_t *elem, *msg, *datee, *subjecte, *frome, *ide;
44 mime_t *mime;
45 struct tm *tim;
46
47 selected = NULL;
48 cfgn = NULL;
49
50 ARGBEGIN(argv0) {
51 case 'c':
52 cfgn = EARGF(scanusage(argv0));
53 break;
54 case 'm':
55 selected = EARGF(scanusage(argv0));
56 break;
57 default:
58 scanusage(argv0);
59 } ARGEND;
60
61 filelen = 0;
62 if (argc < 1) {
63 filec = readtoeoffd(0, &filelen);
64 if (filec == NULL)
65 edie("readtoeoffd");
66 } else {
67 filec = NULL;
68 }
69
70 cfg = config_init(cfgn);
71 if (filec == NULL) {
72 user = config_checkgetstr(cfg, "imapuser");
73 pass = config_checkgetstr(cfg, "imappass");
74 netspec = config_checkgetstr(cfg, "imapnet");
75 if (selected == NULL) {
76 selected = config_checkgetstr(cfg, "selected");
77 } else {
78 selected = memdup(selected, strlen(selected)+1);
79 }
80 }
81 if (cfg->name != NULL) {
82 cfgn = memdup(cfg->name, strlen(cfg->name)+1);
83 } else {
84 cfgn = memdup(cfgn, strlen(cfgn)+1);
85 }
86
87 config_free(cfg);
88
89 if (filec != NULL) {
90 scan_print("ID", "Date", "From", "Subject");
91
92 mime = mime_parsebuf(filec, filelen);
93 free(filec);
94 if (mime == NULL)
95 die("Input does not seem to be valid MIME.\n");
96
97 subjecte = llist_ciget(mime->hdrs, "subject");
98 datee = llist_ciget(mime->hdrs, "date");
99 frome = llist_ciget(mime->hdrs, "from");
100
101 if (subjecte != NULL) {
102 subject = mime_guessheader((char *)subjecte->data);
103 } else {
104 subject = "<empty>";
105 }
106
107 if (datee != NULL) {
108 tim = mime_parsedate((char *)datee->data);
109 if (tim != NULL)
110 date = smftime("%F/%H:%M", tim);
111 else
112 date = smprintf("invalid");
113 free(tim);
114 } else {
115 date = "<empty>";
116 }
117
118 if (frome != NULL) {
119 from = mime_guessheader((char *)frome->data);
120 } else {
121 from = "<empty>";
122 }
123
124 scan_print("", date, from, subject);
125
126 if (subjecte != NULL)
127 free(subject);
128 if (datee != NULL)
129 free(date);
130 if (frome != NULL)
131 free(from);
132
133 mime_free(mime);
134
135 goto scancleanup;
136 }
137
138 imap = imap_new(netspec, user, pass);
139 free(user);
140 free(pass);
141 free(netspec);
142
143 if (imap_init(imap))
144 imap_die(imap, "imap_init");
145 if (imap_select(imap, selected))
146 imap_die(imap, "imap_select");
147
148 ids = imap_argv2ids(cfgn, selected, argc, argv);
149 if (ids == NULL)
150 die("No msgids selected. Aborting.\n");
151
152 msgs = imap_fetchheaders(imap, ids);
153 if (msgs == NULL)
154 imap_die(imap, "imap_fetchheaders");
155 llist_free(ids);
156
157 scan_print("ID", "Date", "From", "Subject");
158 forllist(msgs, msg) {
159 elem = llist_get((llist_t *)msg->data, "literal");
160 if (elem == NULL)
161 continue;
162 mime = mime_parsebuf((char *)elem->data, elem->datalen);
163 if (mime == NULL)
164 continue;
165
166 ide = llist_get((llist_t *)msg->data, "id");
167 subjecte = llist_ciget(mime->hdrs, "subject");
168 datee = llist_ciget(mime->hdrs, "date");
169 frome = llist_ciget(mime->hdrs, "from");
170
171 if (subjecte != NULL) {
172 subject = mime_guessheader((char *)subjecte->data);
173 } else {
174 subject = "<empty>";
175 }
176
177 if (datee != NULL) {
178 tim = mime_parsedate((char *)datee->data);
179 if (tim != NULL)
180 date = smftime("%F/%H:%M", tim);
181 else
182 date = smprintf("invalid");
183 free(tim);
184 } else {
185 date = "<empty>";
186 }
187
188 if (frome != NULL) {
189 from = mime_guessheader((char *)frome->data);
190 } else {
191 from = "<empty>";
192 }
193
194 id = smprintf("rp:/%s/%s/%s",
195 (!strcmp(cfgn, "default")? "" : cfgn),
196 selected,
197 (char *)ide->data);
198
199 scan_print(id, date, from, subject);
200
201 free(id);
202
203 if (subjecte != NULL)
204 free(subject);
205 if (datee != NULL)
206 free(date);
207 if (frome != NULL)
208 free(from);
209
210 mime_free(mime);
211 }
212 llist_efree(msgs);
213
214 scancleanup:
215 free(cfgn);
216 if (filec == NULL) {
217 free(selected);
218 imap_close(imap);
219 imap_free(imap);
220 }
221 return 0;
222 }
223