Import a copy of Markus Schnalke's master's thesis: The Modern Mail Handler.
[mmh] / docs / historical / mh-6.8.5 / uip / scan.c
1 /* scan.c - display a one-line "scan" listing */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: scan.c,v 1.17 1994/04/21 18:20:50 jromine Exp $";
4 #endif  /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/formatsbr.h"
8 #include "../h/scansbr.h"
9 #include "../zotnet/tws.h"
10 #include <errno.h>
11 #include <stdio.h>
12 #ifdef LOCALE
13 #include        <locale.h>
14 #endif
15
16 /* \f */
17
18 static struct swit switches[] = {
19 #define CLRSW   0
20     "clear", 0,
21 #define NCLRSW  1
22     "noclear", 0,
23
24 #define FORMSW  2
25     "form formatfile", 0,
26 #define FMTSW   3
27     "format string", 5,
28
29 #define HEADSW  4
30     "header", 0,
31 #define NHEADSW 5
32     "noheader", 0,
33
34 #define WIDSW   6
35     "width columns", 0,
36
37 #define REVSW   7
38     "reverse", 0,
39 #define NREVSW  8
40     "noreverse", 0,
41
42 #define FILESW  9
43     "file file", 4,
44
45 #define HELPSW  10
46     "help", 4,
47
48     NULL, 0
49 };
50
51 /* \f */
52
53 extern int errno;
54 #ifdef  LBL     /* global for sbr/formatsbr.c - yech! */
55 extern struct msgs *fmt_current_folder; 
56 #endif
57
58
59 void    clear_screen ();
60
61 /* \f */
62
63 /* ARGSUSED */
64
65 main (argc, argv)
66 int     argc;
67 char   *argv[];
68 {
69      int    clearflag = 0,
70             hdrflag = 0,
71             revflag = 0,        /* used to be #ifdef BERK */
72             width = 0,
73             msgp = 0,
74             bits,               /* should match mp->msgstats[] type */
75             ontty,
76             state,
77             msgnum;
78     long    clock;
79     char   *cp,
80            *maildir,
81            *file = NULL,
82            *folder = NULL,
83            *form = NULL,
84            *format = NULL,
85             buf[100],
86           **ap,
87           **argp,
88            *nfs,
89            *arguments[MAXARGS],
90            *msgs[MAXARGS];
91     struct msgs *mp;
92     FILE * in;
93
94 #ifdef LOCALE
95         setlocale(LC_ALL, "");
96 #endif
97     invo_name = r1bindex (argv[0], '/');
98     mts_init (invo_name);
99     if ((cp = m_find (invo_name)) != NULL) {
100         ap = brkstring (cp = getcpy (cp), " ", "\n");
101         ap = copyip (ap, arguments);
102     }
103     else
104         ap = arguments;
105     (void) copyip (argv + 1, ap);
106     argp = arguments;
107
108 /* \f */
109
110     while (cp = *argp++) {
111         if (*cp == '-')
112             switch (smatch (++cp, switches)) {
113                 case AMBIGSW: 
114                     ambigsw (cp, switches);
115                     done (1);
116                 case UNKWNSW: 
117                     adios (NULLCP, "-%s unknown", cp);
118                 case HELPSW: 
119                     (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
120                             invo_name);
121                     help (buf, switches);
122                     done (1);
123
124                 case CLRSW: 
125                     clearflag++;
126                     continue;
127                 case NCLRSW: 
128                     clearflag = 0;
129                     continue;
130
131                 case FORMSW: 
132                     if (!(form = *argp++) || *form == '-')
133                         adios (NULLCP, "missing argument to %s", argp[-2]);
134                     format = NULL;
135                     continue;
136                 case FMTSW: 
137                     if (!(format = *argp++) || *format == '-')
138                         adios (NULLCP, "missing argument to %s", argp[-2]);
139                     form = NULL;
140                     continue;
141
142                 case HEADSW: 
143                     hdrflag++;
144                     continue;
145                 case NHEADSW: 
146                     hdrflag = 0;
147                     continue;
148
149                 case WIDSW: 
150                     if (!(cp = *argp++) || *cp == '-')
151                         adios (NULLCP, "missing argument to %s", argp[-2]);
152                     width = atoi (cp);
153                     continue;
154                 case REVSW:
155                     revflag++;
156                     continue;
157                 case NREVSW:
158                     revflag = 0;
159                     continue;
160
161                 case FILESW:
162                     if (!(cp = *argp++) || (cp[0] == '-' && cp[1]))
163                         adios (NULLCP, "missing argument to %s", argp[-2]);
164                     if (strcmp (file = cp, "-"))
165                         file = path (cp, TFILE);
166                     continue;
167             }
168         if (*cp == '+' || *cp == '@') {
169             if (folder)
170                 adios (NULLCP, "only one folder at a time!");
171             else
172                 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
173         }
174         else
175             msgs[msgp++] = cp;
176     }
177
178
179     if (!m_find ("path"))
180         free (path ("./", TFOLDER));
181     nfs = new_fs (form, format, FORMAT);        /* must be before chdir() */
182
183     if (file) {
184         if (msgp)
185             adios (NULLCP, "\"msgs\" not allowed with -file");
186         if (folder)
187             adios (NULLCP, "\"+folder\" not allowed with -file");
188         /* we've been asked to scan a maildrop file */
189         if (strcmp (file, "-")) {
190             in = fopen (file, "r");
191             if (in == NULL)
192                 adios (file, "unable to open");
193         }
194         else {
195             in = stdin;
196             file = "stdin";
197         }
198
199 #ifndef JLR
200         if (hdrflag) {
201             (void) time (&clock);
202             printf ("Folder %-32s%s\n\n", file,
203                     dasctime (dlocaltime (&clock), TW_NULL));
204         }
205 #endif  /* JLR */
206         m_unknown (in);
207         for (msgnum = 1; ; ++msgnum) {
208             state = scan (in, msgnum, -1, nfs, width, 0, 0,
209                     hdrflag, file, 0L, 1);
210             if (state != SCNMSG && state != SCNENC)
211                 break;
212         }
213         fclose (in);
214         done (0);
215     }
216
217     if (!msgp)
218         msgs[msgp++] = "all";
219     if (!folder)
220         folder = m_getfolder ();
221     maildir = m_maildir (folder);
222
223     if (chdir (maildir) == NOTOK)
224         adios (maildir, "unable to change directory to");
225     if (!(mp = m_gmsg (folder)))
226         adios (NULLCP, "unable to read folder %s", folder);
227     if (mp -> hghmsg == 0)
228         adios (NULLCP, "no messages in %s", folder);
229
230     for (msgnum = 0; msgnum < msgp; msgnum++)
231         if (!m_convert (mp, msgs[msgnum]))
232             done(1);
233     m_setseq (mp);
234
235     m_replace (pfolder, folder);
236     m_sync (mp);
237     m_update ();
238
239     if (cp = m_find(usequence)) { /* set bits for each unseen sequence */
240         char *dp = NULL;
241
242         bits = 0;
243         for (ap = brkstring(dp = getcpy(cp), " ", "\n"); ap && *ap; ap++)
244             bits |= m_seqflag(mp, *ap);
245
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 /* \f */
258
259     for (msgnum = revflag ? mp -> hghsel : mp -> lowsel;
260             (revflag ? msgnum >= mp -> lowsel : msgnum <= mp -> hghsel);
261             msgnum += revflag ? (-1) : 1)
262         if (mp -> msgstats[msgnum] & SELECTED) {
263             if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
264 #ifdef  notdef
265                 if (errno != EACCES)
266 #endif
267                     admonish (cp, "unable to open message");
268 #ifdef  notdef
269                 else
270                     printf ("%*d  unreadable\n", DMAXFOLDER, msgnum);
271 #endif
272                 continue;
273             }
274
275 #ifndef JLR
276             if (hdrflag) {
277                 (void) time (&clock);
278                 printf ("Folder %-32s%s\n\n", folder,
279                         dasctime (dlocaltime (&clock), TW_NULL));
280             }
281 #endif  /* JLR */
282             switch (state = scan (in, msgnum, 0, nfs, width,
283                         msgnum == mp -> curmsg,
284                         mp -> msgstats[msgnum] & bits,
285                         hdrflag, folder, 0L, 1)) {
286                 case SCNMSG: 
287                 case SCNENC: 
288                 case SCNERR: 
289                     break;
290
291                 default: 
292                     adios (NULLCP, "scan() botch (%d)", state);
293
294                 case SCNEOF: 
295 #ifdef  notdef
296                     printf ("%*d  empty\n", DMAXFOLDER, msgnum);
297 #else
298                     advise (NULLCP, "message %d: empty", msgnum);
299 #endif
300                     break;
301             }
302             hdrflag = 0;
303             (void) fclose (in);
304             if (ontty)
305                 (void) fflush (stdout);
306         }
307 #ifdef  LBL
308     m_sync (mp);        /* because formatsbr might have made changes */
309 #endif
310
311 /* \f */
312
313     if (clearflag)
314         clear_screen ();
315
316     done (0);
317 }