BSD 4_4_Lite1 release
[unix-history] / usr / src / contrib / mh-6.8.3a / uip / show.c
CommitLineData
ad787160
C
1/* show.c - list messages */
2#ifndef lint
ed554bc5 3static char ident[] = "@(#)$Id: show.c,v 1.14 1993/10/26 20:09:21 jromine Exp $";
ad787160
C
4#endif /* lint */
5
6#include "../h/mh.h"
7#include <ctype.h>
8#include <stdio.h>
9#ifdef LOCALE
10#include <locale.h>
11#endif
12
13/* \f */
14
15static struct swit switches[] = {
16#define DRFTSW 0
17 "draft", 5,
18
19#define FORMSW 1
20 "form formfile", 4,
21#define PROGSW 2
22 "moreproc program", 4,
23#define NPROGSW 3
24 "nomoreproc", 3,
25#define LENSW 4
26 "length lines", 4,
27#define WIDSW 5
28 "width columns", 4,
29
30#define SHOWSW 6
31 "showproc program", 4,
32#define NSHOWSW 7
33 "noshowproc", 3,
34
35#define HEADSW 8
36 "header", 4,
37#define NHEADSW 9
38 "noheader", 3,
39
40#define FILESW 10
41 "file file", -4, /* interface from showfile */
42
43#define HELPSW 11
44 "help", 4,
45
46 NULL, 0
47};
48
49#ifdef MIME
50static int nontext();
51#endif
52
53#define SHOW 0
54#define NEXT 1
55#define PREV 2
56
57/* \f */
58
59/* ARGSUSED */
60
61main (argc, argv)
62int argc;
63char **argv;
64{
65 int draftsw = 0,
66 headersw = 1,
67 nshow = 0,
68 msgp = 0,
69 vecp = 1,
70 procp = 1,
71 isdf = 0,
72 mode = SHOW,
73 msgnum;
74 char *cp,
75 *maildir,
76 *file = NULL,
77 *folder = NULL,
78 *proc,
79 buf[100],
80 **ap,
81 **argp,
82 *arguments[MAXARGS],
83 *msgs[MAXARGS],
84 *vec[MAXARGS];
85 struct msgs *mp;
86
87#ifdef LOCALE
88 setlocale(LC_ALL, "");
89#endif
90 invo_name = r1bindex (argv[0], '/');
91 if (uleq (invo_name, "next"))
92 mode = NEXT;
93 else
94 if (uleq (invo_name, "prev"))
95 mode = PREV;
96 if ((cp = m_find (invo_name)) != NULL) {
97 ap = brkstring (cp = getcpy (cp), " ", "\n");
98 ap = copyip (ap, arguments);
99 }
100 else
101 ap = arguments;
102 (void) copyip (argv + 1, ap);
103 argp = arguments;
104
105/* \f */
106
107 while (cp = *argp++) {
108 if (*cp == '-')
109 switch (smatch (++cp, switches)) {
110 case AMBIGSW:
111 ambigsw (cp, switches);
112 done (1);
113 case UNKWNSW:
114 case NPROGSW:
115 vec[vecp++] = --cp;
116 continue;
117 case HELPSW:
118 (void) sprintf (buf,
119 "%s [+folder] %s[switches] [switches for showproc]",
120 invo_name, mode == SHOW ? "[msgs] ": "");
121 help (buf, switches);
122 done (1);
123
124 case DRFTSW:
125 if (file)
126 adios (NULLCP, "only one file at a time!");
127 draftsw++;
128 if (mode == SHOW)
129 continue;
130 usage: ;
131 adios (NULLCP,
132 "usage: %s [+folder] [switches] [switches for showproc]",
133 invo_name);
134 case FILESW:
135 if (mode != SHOW)
136 goto usage;
137 if (draftsw || file)
138 adios (NULLCP, "only one file at a time!");
139 if (!(cp = *argp++) || *cp == '-')
140 adios (NULLCP, "missing argument to %s", argp[-2]);
141 file = path (cp, TFILE);
142 continue;
143
144 case HEADSW:
145 headersw++;
146 continue;
147 case NHEADSW:
148 headersw = 0;
149 continue;
150
151 case FORMSW:
152 vec[vecp++] = --cp;
153 if (!(cp = *argp++) || *cp == '-')
154 adios (NULLCP, "missing argument to %s", argp[-2]);
155 vec[vecp++] = getcpy (libpath(cp));
156 continue;
157
158 case PROGSW:
159 case LENSW:
160 case WIDSW:
161 vec[vecp++] = --cp;
162 if (!(cp = *argp++) || *cp == '-')
163 adios (NULLCP, "missing argument to %s", argp[-2]);
164 vec[vecp++] = cp;
165 continue;
166
167 case SHOWSW:
168 if (!(showproc = *argp++) || *showproc == '-')
169 adios (NULLCP, "missing argument to %s", argp[-2]);
170 nshow = 0;
171 continue;
172 case NSHOWSW:
173 nshow++;
174 continue;
175 }
176 if (*cp == '+' || *cp == '@') {
177 if (folder)
178 adios (NULLCP, "only one folder at a time!");
179 else
180 folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
181 }
182 else
183 if (mode != SHOW)
184 goto usage;
185 else
186 msgs[msgp++] = cp;
187 }
188 procp = vecp;
189
190/* \f */
191
192 if (!m_find ("path"))
193 free (path ("./", TFOLDER));
194
195 if (draftsw || file) {
196 if (msgp)
197 adios (NULLCP, "only one file at a time!");
198 vec[vecp++] = draftsw
199 ? getcpy (m_draft (folder, msgp ? msgs[0] : NULL, 1, &isdf))
200 : file;
201 goto go_to_it;
202 }
203
204#ifdef WHATNOW
205 if (!msgp && !folder && mode == SHOW && (cp = getenv ("mhdraft")) && *cp) {
206 draftsw++;
207 vec[vecp++] = cp;
208 goto go_to_it;
209 }
210#endif /* WHATNOW */
211
212 if (!msgp)
213 msgs[msgp++] = mode == NEXT ? "next" : mode == PREV ? "prev" : "cur";
214 if (!folder)
215 folder = m_getfolder ();
216 maildir = m_maildir (folder);
217
218 if (chdir (maildir) == NOTOK)
219 adios (maildir, "unable to change directory to");
220 if (!(mp = m_gmsg (folder)))
221 adios (NULLCP, "unable to read folder %s", folder);
222 if (mp -> hghmsg == 0)
223 adios (NULLCP, "no messages in %s", folder);
224
225 for (msgnum = 0; msgnum < msgp; msgnum++)
226 if (!m_convert (mp, msgs[msgnum]))
227 done (1);
228 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
229 if (mp -> msgstats[msgnum] & SELECTED)
230 mp -> msgstats[msgnum] |= UNSEEN;
231 m_setseq (mp);
232 m_setvis (mp, 1);
233
234 if (mp -> numsel > MAXARGS - 2)
235 adios (NULLCP, "more than %d messages for show exec", MAXARGS - 2);
236 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
237 if (mp -> msgstats[msgnum] & SELECTED)
238 vec[vecp++] = getcpy (m_name (msgnum));
239
240 m_replace (pfolder, folder);
241 if (mp -> hghsel != mp -> curmsg)
242 m_setcur (mp, mp -> hghsel);
243 m_sync (mp);
244 m_update ();
245
246 if (vecp == 2 && headersw)
247 printf ("(Message %s:%s)\n", folder, vec[1]);
248
249/* \f */
250
251go_to_it: ;
252 (void) fflush (stdout);
253
254 vec[vecp] = NULL;
255
256#ifdef MIME
257 if (!nshow && !getenv ("NOMHNPROC")) {
258 if (!(cp = m_find ("mhnproc")))
259 cp = "mhn";
260
261 if (draftsw || file) {
262 if (nontext (vec[vecp - 1])) {
263 vec[vecp] = vec[vecp - 1];
264 vec[vecp - 1] = "-file";
265 vecp++;
266 goto use_mmp;
267 }
268 }
269 else
270 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
271 if ((mp -> msgstats[msgnum] & SELECTED)
272 && nontext (m_name (msgnum))) {
273use_mmp: ;
274 proc = cp;
275 vec[vecp++] = "-show";
276 vec[vecp] = NULL;
277 goto finish;
278 }
279 }
280#endif /* MIME */
281 if (nshow)
282 proc = "/bin/cat";
283 else {
284 if (folder && !draftsw && !file)
285 (void) m_putenv ("mhfolder", folder);
286 if (strcmp (r1bindex (showproc, '/'), "mhl") == 0) {
287 vec[0] = "mhl";
288 (void) mhl (vecp, vec);
289 done (0);
290 }
291 proc = showproc;
292 }
293
294 if (!draftsw
295 && !file
296 && chdir (maildir = concat (m_maildir (""), "/", NULLCP))
297 != NOTOK) {
298 mp -> foldpath = concat (mp -> foldpath, "/", NULLCP);
299 cp = ssequal (maildir, mp -> foldpath)
300 ? mp -> foldpath + strlen (maildir)
301 : mp -> foldpath;
302 for (msgnum = procp; msgnum < vecp; msgnum++)
303 vec[msgnum] = concat (cp, vec[msgnum], NULLCP);
304 }
305
306finish:;
307 vec[0] = r1bindex (proc, '/');
308 execvp (proc, vec);
309 adios (proc, "unable to exec");
310}
311
312/* \f */
313
314/* Cheat: we are loaded with adrparse, which wants a routine called
315 OfficialName(). We call adrparse:getm() with the correct arguments
316 to prevent OfficialName() from being called. Hence, the following
317 is to keep the loader happy.
318 */
319
320char *OfficialName (name)
321register char *name;
322{
323 return name;
324}
325
326/* \f */
327
328#ifdef MIME
329#include "../h/mhn.h"
330
331
332static int nontext (msgnam)
333char *msgnam;
334{
335 int result,
336 state;
337 register char *bp,
338 *dp;
ed554bc5
C
339 char *chset,
340 *cp,
ad787160
C
341 buf[BUFSIZ],
342 name[NAMESZ];
343 FILE *fp;
344
345 if ((fp = fopen (msgnam, "r")) == NULL)
346 return 0;
347
ed554bc5
C
348 if (!(chset = getenv ("MM_CHARSET")))
349 chset = "us-ascii";
350
ad787160
C
351 for (state = FLD;;)
352 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
353 case FLD:
354 case FLDPLUS:
355 case FLDEOF:
356 if (uleq (name, TYPE_FIELD)) {
357 int passno;
358 char c;
359
360 cp = add (buf, NULLCP);
361 while (state == FLDPLUS) {
362 state = m_getfld (state, name, buf, sizeof buf, fp);
363 cp = add (buf, cp);
364 }
365 bp = cp;
366 passno = 1;
367
368again: ;
369 for (; isspace (*bp); bp++)
370 continue;
371 if (*bp == '(') {
372 int i;
373
374 for (bp++, i = 0;;) {
375 switch (*bp++) {
376 case '\0':
377invalid: ;
378 result = 0;
379 goto out;
380 case '\\':
381 if (*bp++ == '\0')
382 goto invalid;
383 continue;
384 case '(':
385 i++;
386 /* and fall... */
387 default:
388 continue;
389 case ')':
390 if (--i < 0)
391 break;
392 continue;
393 }
394 break;
395 }
396 }
397 if (passno == 2) {
398 if (*bp != '/')
399 goto invalid;
400 bp++;
401 passno = 3;
402 goto again;
403 }
404 for (dp = bp; istoken (*dp); dp++)
405 continue;
406 c = *dp, *dp = NULL;
407 if (*bp == NULL)
408 goto invalid;
409 if (passno > 1) {
410 if (result = !uleq (bp, "plain"))
411 goto out;
412 *dp = c;
413 for (dp++; isspace (*dp); dp++)
414 continue;
415 if (result = !uprf (dp, "charset"))
416 goto out;
417 dp += sizeof "charset" - 1;
418 while (isspace (*dp))
419 dp++;
420 if (*dp++ != '=')
421 goto invalid;
422 while (isspace (*dp))
423 dp++;
424 if (*dp == '"') {
ed554bc5 425 if (bp = index (++dp, '"'))
ad787160
C
426 *bp = NULL;
427 }
428 else
ed554bc5
C
429 for (bp = dp; *bp; bp++)
430 if (isspace (*bp)) {
431 *bp = NULL;
432 break;
433 }
434 if ((result = !uleq (dp, chset))
435 && uleq (dp, "us-ascii")
436 && uleq (chset, "iso-8859-1"))
437 result = 0;
ad787160
C
438 }
439 else
440 if (!(result = !uleq (bp, "text"))) {
441 *dp = c;
442 bp = dp;
443 passno = 2;
444 goto again;
445 }
446
447out: ;
448 free (cp);
449 if (result) {
450 (void) fclose (fp);
451 return result;
452 }
453 break;
454 }
455 if (uleq (name, ENCODING_FIELD)) {
456 cp = add (buf, NULLCP);
457 while (state == FLDPLUS) {
458 state = m_getfld (state, name, buf, sizeof buf, fp);
459 cp = add (buf, cp);
460 }
461 for (bp = cp; isspace (*bp); bp++)
462 continue;
463 for (dp = bp; istoken (*dp); dp++)
464 continue;
465 *dp = NULL;
ed554bc5
C
466 result = !uleq (bp, "7bit")
467 && !uleq (bp, "8bit")
468 && !uleq (bp, "binary");
ad787160
C
469
470 free (cp);
471 if (result) {
472 (void) fclose (fp);
473 return result;
474 }
475 break;
476 }
477 while (state == FLDPLUS)
478 state = m_getfld (state, name, buf, sizeof buf, fp);
479 break;
480
481 default:
482 (void) fclose (fp);
483 return 0;
484 }
485}
486#endif /* MIME */