]> diplodocus.org Git - nmh/blob - uip/scan.c
Started revising m_getfld() code to replace direct buffer
[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 (0);
103 case VERSIONSW:
104 print_version(invo_name);
105 done (0);
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 if (hdrflag) {
188 printf ("FOLDER %s\t%s\n", file, dtimenow (1));
189 }
190
191 m_unknown (in);
192 for (msgnum = 1; ; ++msgnum) {
193 state = scan (in, msgnum, -1, nfs, width, 0, 0,
194 hdrflag ? file : NULL, 0L, 1);
195 if (state != SCNMSG && state != SCNENC)
196 break;
197 }
198 fclose (in);
199 done (0);
200 }
201
202 /*
203 * We are scanning a folder
204 */
205
206 if (!msgs.size)
207 app_msgarg(&msgs, "all");
208 if (!folder)
209 folder = getfolder (1);
210 maildir = m_maildir (folder);
211
212 if (chdir (maildir) == NOTOK)
213 adios (maildir, "unable to change directory to");
214
215 /* read folder and create message structure */
216 if (!(mp = folder_read (folder)))
217 adios (NULL, "unable to read folder %s", folder);
218
219 /* check for empty folder */
220 if (mp->nummsg == 0)
221 adios (NULL, "no messages in %s", folder);
222
223 /* parse all the message ranges/sequences and set SELECTED */
224 for (msgnum = 0; msgnum < msgs.size; msgnum++)
225 if (!m_convert (mp, msgs.msgs[msgnum]))
226 done(1);
227 seq_setprev (mp); /* set the Previous-Sequence */
228
229 context_replace (pfolder, folder); /* update current folder */
230 seq_save (mp); /* synchronize message sequences */
231 context_save (); /* save the context file */
232
233 /*
234 * Get the sequence number for each sequence
235 * specified by Unseen-Sequence
236 */
237 if ((cp = context_find (usequence)) && *cp) {
238 char **ap, *dp;
239
240 dp = getcpy(cp);
241 ap = brkstring (dp, " ", "\n");
242 for (i = 0; ap && *ap; i++, ap++)
243 seqnum[i] = seq_getnum (mp, *ap);
244
245 num_unseen_seq = i;
246 if (dp)
247 free(dp);
248 }
249
250 ontty = isatty (fileno (stdout));
251
252 #ifdef LBL
253 else
254 fmt_current_folder = mp;
255 #endif
256
257 for (msgnum = revflag ? mp->hghsel : mp->lowsel;
258 (revflag ? msgnum >= mp->lowsel : msgnum <= mp->hghsel);
259 msgnum += (revflag ? -1 : 1)) {
260 if (is_selected(mp, msgnum)) {
261 if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
262 admonish (cp, "unable to open message");
263 continue;
264 }
265
266 if (hdrflag) {
267 printf ("FOLDER %s\t%s\n", folder, dtimenow(1));
268 }
269
270 /*
271 * Check if message is in any sequence given
272 * by Unseen-Sequence profile entry.
273 */
274 unseen = 0;
275 for (i = 0; i < num_unseen_seq; i++) {
276 if (in_sequence(mp, seqnum[i], msgnum)) {
277 unseen = 1;
278 break;
279 }
280 }
281
282 switch (state = scan (in, msgnum, 0, nfs, width,
283 msgnum == mp->curmsg, unseen,
284 folder, 0L, 1)) {
285 case SCNMSG:
286 case SCNENC:
287 case SCNERR:
288 break;
289
290 default:
291 adios (NULL, "scan() botch (%d)", state);
292
293 case SCNEOF:
294 advise (NULL, "message %d: empty", msgnum);
295 break;
296 }
297 hdrflag = 0;
298 fclose (in);
299 if (ontty)
300 fflush (stdout);
301 }
302 }
303
304 #ifdef LBL
305 seq_save (mp); /* because formatsbr might have made changes */
306 #endif
307
308 folder_free (mp); /* free folder/message structure */
309 if (clearflag)
310 clear_screen ();
311
312 done (0);
313 return 1;
314 }