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