]> diplodocus.org Git - nmh/blob - uip/scan.c
Cope with sasl_decode64() returning SASL_CONTINUE as well as SASL_OK.
[nmh] / uip / scan.c
1
2 /*
3 * scan.c -- display a one-line "scan" listing of folder or messages
4 *
5 * $Id$
6 *
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
10 */
11
12 #include <h/mh.h>
13 #include <h/fmt_scan.h>
14 #include <h/scansbr.h>
15 #include <h/tws.h>
16 #include <h/mts.h>
17 #include <h/utils.h>
18 #include <errno.h>
19
20 static struct swit switches[] = {
21 #define CLRSW 0
22 { "clear", 0 },
23 #define NCLRSW 1
24 { "noclear", 0 },
25 #define FORMSW 2
26 { "form formatfile", 0 },
27 #define FMTSW 3
28 { "format string", 5 },
29 #define HEADSW 4
30 { "header", 0 },
31 #define NHEADSW 5
32 { "noheader", 0 },
33 #define WIDTHSW 6
34 { "width columns", 0 },
35 #define REVSW 7
36 { "reverse", 0 },
37 #define NREVSW 8
38 { "noreverse", 0 },
39 #define FILESW 9
40 { "file file", 4 },
41 #define VERSIONSW 10
42 { "version", 0 },
43 #define HELPSW 11
44 { "help", 0 },
45 { NULL, 0 }
46 };
47
48
49 /*
50 * global for sbr/formatsbr.c - yech!
51 */
52 #ifdef LBL
53 extern struct msgs *fmt_current_folder;
54 #endif
55
56 /*
57 * prototypes
58 */
59 void clear_screen(void); /* from termsbr.c */
60
61
62 int
63 main (int argc, char **argv)
64 {
65 int clearflag = 0, hdrflag = 0, ontty;
66 int width = 0, revflag = 0;
67 int i, state, msgnum;
68 int seqnum[NUMATTRS], unseen, num_unseen_seq = 0;
69 char *cp, *maildir, *file = NULL, *folder = NULL;
70 char *form = NULL, *format = NULL, buf[BUFSIZ];
71 char **argp, *nfs, **arguments;
72 struct msgs_array msgs = { 0, 0, NULL };
73 struct msgs *mp;
74 FILE *in;
75
76 #ifdef LOCALE
77 setlocale(LC_ALL, "");
78 #endif
79 invo_name = r1bindex (argv[0], '/');
80
81 /* read user profile/context */
82 context_read();
83
84 mts_init (invo_name);
85 arguments = getarguments (invo_name, argc, argv, 1);
86 argp = arguments;
87
88 /*
89 * Parse arguments
90 */
91 while ((cp = *argp++)) {
92 if (*cp == '-') {
93 switch (smatch (++cp, switches)) {
94 case AMBIGSW:
95 ambigsw (cp, switches);
96 done (1);
97 case UNKWNSW:
98 adios (NULL, "-%s unknown", cp);
99
100 case HELPSW:
101 snprintf (buf, sizeof(buf), "%s [+folder] [msgs] [switches]",
102 invo_name);
103 print_help (buf, switches, 1);
104 done (1);
105 case VERSIONSW:
106 print_version(invo_name);
107 done (1);
108
109 case CLRSW:
110 clearflag++;
111 continue;
112 case NCLRSW:
113 clearflag = 0;
114 continue;
115
116 case FORMSW:
117 if (!(form = *argp++) || *form == '-')
118 adios (NULL, "missing argument to %s", argp[-2]);
119 format = NULL;
120 continue;
121 case FMTSW:
122 if (!(format = *argp++) || *format == '-')
123 adios (NULL, "missing argument to %s", argp[-2]);
124 form = NULL;
125 continue;
126
127 case HEADSW:
128 hdrflag++;
129 continue;
130 case NHEADSW:
131 hdrflag = 0;
132 continue;
133
134 case WIDTHSW:
135 if (!(cp = *argp++) || *cp == '-')
136 adios (NULL, "missing argument to %s", argp[-2]);
137 width = atoi (cp);
138 continue;
139 case REVSW:
140 revflag++;
141 continue;
142 case NREVSW:
143 revflag = 0;
144 continue;
145
146 case FILESW:
147 if (!(cp = *argp++) || (cp[0] == '-' && cp[1]))
148 adios (NULL, "missing argument to %s", argp[-2]);
149 if (strcmp (file = cp, "-"))
150 file = path (cp, TFILE);
151 continue;
152 }
153 }
154 if (*cp == '+' || *cp == '@') {
155 if (folder)
156 adios (NULL, "only one folder at a time!");
157 else
158 folder = pluspath (cp);
159 } else
160 app_msgarg(&msgs, cp);
161 }
162
163 if (!context_find ("path"))
164 free (path ("./", TFOLDER));
165
166 /*
167 * Get new format string. Must be before chdir().
168 */
169 nfs = new_fs (form, format, FORMAT);
170
171 /*
172 * We are scanning a maildrop file
173 */
174 if (file) {
175 if (msgs.size)
176 adios (NULL, "\"msgs\" not allowed with -file");
177 if (folder)
178 adios (NULL, "\"+folder\" not allowed with -file");
179
180 /* check if "file" is really stdin */
181 if (strcmp (file, "-") == 0) {
182 in = stdin;
183 file = "stdin";
184 } else {
185 if ((in = fopen (file, "r")) == NULL)
186 adios (file, "unable to open");
187 }
188
189 #ifndef JLR
190 if (hdrflag) {
191 printf ("FOLDER %s\t%s\n", file, dtimenow (1));
192 }
193 #endif /* JLR */
194
195 m_unknown (in);
196 for (msgnum = 1; ; ++msgnum) {
197 state = scan (in, msgnum, -1, nfs, width, 0, 0,
198 hdrflag ? file : NULL, 0L, 1);
199 if (state != SCNMSG && state != SCNENC)
200 break;
201 }
202 fclose (in);
203 done (0);
204 }
205
206 /*
207 * We are scanning a folder
208 */
209
210 if (!msgs.size)
211 app_msgarg(&msgs, "all");
212 if (!folder)
213 folder = getfolder (1);
214 maildir = m_maildir (folder);
215
216 if (chdir (maildir) == NOTOK)
217 adios (maildir, "unable to change directory to");
218
219 /* read folder and create message structure */
220 if (!(mp = folder_read (folder)))
221 adios (NULL, "unable to read folder %s", folder);
222
223 /* check for empty folder */
224 if (mp->nummsg == 0)
225 adios (NULL, "no messages in %s", folder);
226
227 /* parse all the message ranges/sequences and set SELECTED */
228 for (msgnum = 0; msgnum < msgs.size; msgnum++)
229 if (!m_convert (mp, msgs.msgs[msgnum]))
230 done(1);
231 seq_setprev (mp); /* set the Previous-Sequence */
232
233 context_replace (pfolder, folder); /* update current folder */
234 seq_save (mp); /* synchronize message sequences */
235 context_save (); /* save the context file */
236
237 /*
238 * Get the sequence number for each sequence
239 * specified by Unseen-Sequence
240 */
241 if ((cp = context_find (usequence)) && *cp) {
242 char **ap, *dp;
243
244 dp = getcpy(cp);
245 ap = brkstring (dp, " ", "\n");
246 for (i = 0; ap && *ap; i++, ap++)
247 seqnum[i] = seq_getnum (mp, *ap);
248
249 num_unseen_seq = i;
250 if (dp)
251 free(dp);
252 }
253
254 ontty = isatty (fileno (stdout));
255
256 #ifdef LBL
257 else
258 fmt_current_folder = mp;
259 #endif
260
261 for (msgnum = revflag ? mp->hghsel : mp->lowsel;
262 (revflag ? msgnum >= mp->lowsel : msgnum <= mp->hghsel);
263 msgnum += (revflag ? -1 : 1)) {
264 if (is_selected(mp, msgnum)) {
265 if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
266 #if 0
267 if (errno != EACCES)
268 #endif
269 admonish (cp, "unable to open message");
270 #if 0
271 else
272 printf ("%*d unreadable\n", DMAXFOLDER, msgnum);
273 #endif
274 continue;
275 }
276
277 #ifndef JLR
278 if (hdrflag) {
279 printf ("FOLDER %s\t%s\n", folder, dtimenow(1));
280 }
281 #endif /* JLR */
282
283 /*
284 * Check if message is in any sequence given
285 * by Unseen-Sequence profile entry.
286 */
287 unseen = 0;
288 for (i = 0; i < num_unseen_seq; i++) {
289 if (in_sequence(mp, seqnum[i], msgnum)) {
290 unseen = 1;
291 break;
292 }
293 }
294
295 switch (state = scan (in, msgnum, 0, nfs, width,
296 msgnum == mp->curmsg, unseen,
297 folder, 0L, 1)) {
298 case SCNMSG:
299 case SCNENC:
300 case SCNERR:
301 break;
302
303 default:
304 adios (NULL, "scan() botch (%d)", state);
305
306 case SCNEOF:
307 #if 0
308 printf ("%*d empty\n", DMAXFOLDER, msgnum);
309 #else
310 advise (NULL, "message %d: empty", msgnum);
311 #endif
312 break;
313 }
314 hdrflag = 0;
315 fclose (in);
316 if (ontty)
317 fflush (stdout);
318 }
319 }
320
321 #ifdef LBL
322 seq_save (mp); /* because formatsbr might have made changes */
323 #endif
324
325 folder_free (mp); /* free folder/message structure */
326 if (clearflag)
327 clear_screen ();
328
329 done (0);
330 return 1;
331 }