source: trunk/third/nmh/uip/scan.c @ 12455

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