Localize pjw() in maildir.c (TODO -> torek); obsolete hash()
[s-mailx.git] / cmd1.c
blob86f7eceb8e852f85052a7b3c319aab6598761ffa
1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
2 *@ User commands.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 - 2015 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
6 */
7 /*
8 * Copyright (c) 1980, 1993
9 * The Regents of the University of California. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 #undef n_FILE
36 #define n_FILE cmd1
38 #ifndef HAVE_AMALGAMATION
39 # include "nail.h"
40 #endif
42 static int _screen;
44 /* Prepare and print "[Message: xy]:" intro */
45 static void _show_msg_overview(FILE *obuf, struct message *mp, int msg_no);
47 /* ... And place the extracted date in `date' */
48 static void _parse_from_(struct message *mp, char date[FROM_DATEBUF]);
50 /* Print out the header of a specific message
51 * __hprf: handle *headline*
52 * __subject: return -1 if Subject: yet seen, otherwise smalloc()d Subject:
53 * __putindent: print out the indenting in threaded display */
54 static void _print_head(size_t yetprinted, size_t msgno, FILE *f,
55 bool_t threaded);
56 static void __hprf(size_t yetprinted, char const *fmt, size_t msgno,
57 FILE *f, bool_t threaded, char const *attrlist);
58 static char * __subject(struct message *mp, bool_t threaded,
59 size_t yetprinted);
60 static int __putindent(FILE *fp, struct message *mp, int maxwidth);
62 static int _dispc(struct message *mp, char const *a);
64 /* Shared `z' implementation */
65 static int a_cmd_scroll(char const *arg, bool_t onlynew);
67 /* Shared `headers' implementation */
68 static int _headers(int msgspec);
70 /* Show the requested messages */
71 static int _type1(int *msgvec, bool_t doign, bool_t dopage, bool_t dopipe,
72 bool_t dodecode, char *cmd, ui64_t *tstats);
74 /* Pipe the requested messages */
75 static int _pipe1(char *str, int doign);
77 /* `top' / `Top' */
78 static int a_cmd_top(void *vp, struct ignoretab *itp);
80 static void
81 _show_msg_overview(FILE *obuf, struct message *mp, int msg_no)
83 char const *cpre = "", *csuf = "";
84 NYD_ENTER;
86 #ifdef HAVE_COLOUR
87 if (pstate & PS_COLOUR_ACTIVE) {
88 struct n_colour_pen *cpen;
90 if ((cpen = n_colour_pen_create(n_COLOUR_ID_VIEW_MSGINFO, NULL)) != NULL){
91 struct str const *sp;
93 if ((sp = n_colour_pen_to_str(cpen)) != NULL)
94 cpre = sp->s;
95 if ((sp = n_colour_reset_to_str()) != NULL)
96 csuf = sp->s;
99 #endif
100 fprintf(obuf, _("%s[-- Message %2d -- %lu lines, %lu bytes --]:%s\n"),
101 cpre, msg_no, (ul_i)mp->m_lines, (ul_i)mp->m_size, csuf);
102 NYD_LEAVE;
105 static void
106 _parse_from_(struct message *mp, char date[FROM_DATEBUF]) /* TODO line pool */
108 FILE *ibuf;
109 int hlen;
110 char *hline = NULL;
111 size_t hsize = 0;
112 NYD_ENTER;
114 if ((ibuf = setinput(&mb, mp, NEED_HEADER)) != NULL &&
115 (hlen = readline_restart(ibuf, &hline, &hsize, 0)) > 0)
116 extract_date_from_from_(hline, hlen, date);
117 if (hline != NULL)
118 free(hline);
119 NYD_LEAVE;
122 static void
123 _print_head(size_t yetprinted, size_t msgno, FILE *f, bool_t threaded)
125 enum {attrlen = 14};
126 char attrlist[attrlen +1], *cp;
127 char const *fmt;
128 NYD_ENTER;
130 if ((cp = ok_vlook(attrlist)) != NULL) {
131 if (strlen(cp) == attrlen) {
132 memcpy(attrlist, cp, attrlen +1);
133 goto jattrok;
135 n_err(_("*attrlist* is not of the correct length, using builtin\n"));
138 if (ok_blook(bsdcompat) || ok_blook(bsdflags)) {
139 char const bsdattr[attrlen +1] = "NU *HMFAT+-$~";
140 memcpy(attrlist, bsdattr, sizeof bsdattr);
141 } else if (ok_blook(SYSV3)) {
142 char const bsdattr[attrlen +1] = "NU *HMFAT+-$~";
143 memcpy(attrlist, bsdattr, sizeof bsdattr);
144 OBSOLETE(_("*SYSV3*: please use *bsdcompat* or *bsdflags*, "
145 "or set *attrlist*"));
146 } else {
147 char const pattr[attrlen +1] = "NUROSPMFAT+-$~";
148 memcpy(attrlist, pattr, sizeof pattr);
151 jattrok:
152 if ((fmt = ok_vlook(headline)) == NULL) {
153 fmt = ((ok_blook(bsdcompat) || ok_blook(bsdheadline))
154 ? "%>%a%m %-20f %16d %3l/%-5o %i%-S"
155 : "%>%a%m %-18f %16d %4l/%-5o %i%-s");
158 __hprf(yetprinted, fmt, msgno, f, threaded, attrlist);
159 NYD_LEAVE;
162 static void
163 __hprf(size_t yetprinted, char const *fmt, size_t msgno, FILE *f,
164 bool_t threaded, char const *attrlist)
166 char buf[16], datebuf[FROM_DATEBUF], cbuf[8], *cp, *subjline;
167 char const *datefmt, *date, *name, *fp n_COLOUR( COMMA *colo_tag );
168 int i, n, s, wleft, subjlen;
169 struct message *mp;
170 time_t datet;
171 n_COLOUR( struct n_colour_pen *cpen_new COMMA *cpen_cur COMMA *cpen_bas; )
172 enum {
173 _NONE = 0,
174 _ISDOT = 1<<0,
175 _ISADDR = 1<<1,
176 _ISTO = 1<<2,
177 _IFMT = 1<<3,
178 _LOOP_MASK = (1<<4) - 1,
179 _SFMT = 1<<4
180 } flags = _NONE;
181 NYD_ENTER;
182 UNUSED(buf);
184 if ((mp = message + msgno - 1) == dot)
185 flags = _ISDOT;
186 datet = mp->m_time;
187 date = NULL;
188 n_COLOUR( colo_tag = NULL; )
190 datefmt = ok_vlook(datefield);
191 jredo:
192 if (datefmt != NULL) {
193 fp = hfield1("date", mp);/* TODO use m_date field! */
194 if (fp == NULL) {
195 datefmt = NULL;
196 goto jredo;
198 datet = rfctime(fp);
199 date = fakedate(datet);
200 fp = ok_vlook(datefield_markout_older);
201 i = (*datefmt != '\0');
202 if (fp != NULL)
203 i |= (*fp != '\0') ? 2 | 4 : 2; /* XXX no magics */
205 /* May we strftime(3)? */
206 if (i & (1 | 4))
207 memcpy(&time_current.tc_local, localtime(&datet),
208 sizeof time_current.tc_local);
210 if ((i & 2) && (datet > time_current.tc_time + DATE_SECSDAY ||
211 #define _6M ((DATE_DAYSYEAR / 2) * DATE_SECSDAY)
212 (datet + _6M < time_current.tc_time))) {
213 #undef _6M
214 if ((datefmt = (i & 4) ? fp : NULL) == NULL) {
215 memset(datebuf, ' ', FROM_DATEBUF); /* xxx ur */
216 memcpy(datebuf + 4, date + 4, 7);
217 datebuf[4 + 7] = ' ';
218 memcpy(datebuf + 4 + 7 + 1, date + 20, 4);
219 datebuf[4 + 7 + 1 + 4] = '\0';
220 date = datebuf;
222 n_COLOUR( colo_tag = n_COLOUR_TAG_SUM_OLDER; )
223 } else if ((i & 1) == 0)
224 datefmt = NULL;
225 } else if (datet == (time_t)0 && !(mp->m_flag & MNOFROM)) {
226 /* TODO eliminate this path, query the FROM_ date in setptr(),
227 * TODO all other codepaths do so by themselves ALREADY ?????
228 * TODO assert(mp->m_time != 0);, then
229 * TODO ALSO changes behaviour of datefield_markout_older */
230 _parse_from_(mp, datebuf);
231 date = datebuf;
232 } else
233 date = fakedate(datet);
235 flags |= _ISADDR;
236 name = name1(mp, 0);
237 if (name != NULL && ok_blook(showto) && is_myname(skin(name))) {
238 if ((cp = hfield1("to", mp)) != NULL) {
239 name = cp;
240 flags |= _ISTO;
243 if (name == NULL) {
244 name = "";
245 flags &= ~_ISADDR;
247 if (flags & _ISADDR)
248 name = ok_blook(showname) ? realname(name) : prstr(skin(name));
250 subjline = NULL;
252 /* Detect the width of the non-format characters in *headline*;
253 * like that we can simply use putc() in the next loop, since we have
254 * already calculated their column widths (TODO it's sick) */
255 wleft = subjlen = scrnwidth;
257 for (fp = fmt; *fp != '\0'; ++fp) {
258 if (*fp == '%') {
259 if (*++fp == '-')
260 ++fp;
261 else if (*fp == '+')
262 ++fp;
263 if (digitchar(*fp)) {
264 n = 0;
266 n = 10*n + *fp - '0';
267 while (++fp, digitchar(*fp));
268 subjlen -= n;
270 if (*fp == 'i')
271 flags |= _IFMT;
273 if (*fp == '\0')
274 break;
275 } else {
276 #ifdef HAVE_WCWIDTH
277 if (mb_cur_max > 1) {
278 wchar_t wc;
279 if ((s = mbtowc(&wc, fp, mb_cur_max)) == -1)
280 n = s = 1;
281 else if ((n = wcwidth(wc)) == -1)
282 n = 1;
283 } else
284 #endif
285 n = s = 1;
286 subjlen -= n;
287 wleft -= n;
288 while (--s > 0)
289 ++fp;
293 /* Walk *headline*, producing output TODO not (really) MB safe */
294 #ifdef HAVE_COLOUR
295 if (flags & _ISDOT)
296 colo_tag = n_COLOUR_TAG_SUM_DOT;
297 cpen_bas = n_colour_pen_create(n_COLOUR_ID_SUM_HEADER, colo_tag);
298 n_colour_pen_put(cpen_new = cpen_cur = cpen_bas, f);
299 #endif
301 for (fp = fmt; *fp != '\0'; ++fp) {
302 char c;
304 if ((c = *fp & 0xFF) != '%') {
305 #ifdef HAVE_COLOUR
306 if ((cpen_new = cpen_bas) != cpen_cur)
307 n_colour_pen_put(cpen_cur = cpen_new, f);
308 #endif
309 putc(c, f);
310 continue;
313 flags &= _LOOP_MASK;
314 n = 0;
315 s = 1;
316 if ((c = *++fp) == '-') {
317 s = -1;
318 ++fp;
319 } else if (c == '+')
320 ++fp;
321 if (digitchar(*fp)) {
323 n = 10*n + *fp - '0';
324 while (++fp, digitchar(*fp));
327 if ((c = *fp & 0xFF) == '\0')
328 break;
329 n *= s;
331 cbuf[1] = '\0';
332 switch (c) {
333 case '%':
334 goto jputcb;
335 case '>':
336 case '<':
337 if (flags & _ISDOT) {
338 n_COLOUR( cpen_new = n_colour_pen_create(n_COLOUR_ID_SUM_DOTMARK,
339 colo_tag); );
340 if (options & OPT_UNICODE) {
341 if (c == '>')
342 /* 25B8;BLACK RIGHT-POINTING SMALL TRIANGLE: â–¸ */
343 cbuf[1] = (char)0x96, cbuf[2] = (char)0xB8;
344 else
345 /* 25C2;BLACK LEFT-POINTING SMALL TRIANGLE: â—‚ */
346 cbuf[1] = (char)0x97, cbuf[2] = (char)0x82;
347 c = (char)0xE2;
348 cbuf[3] = '\0';
350 } else
351 c = ' ';
352 goto jputcb;
353 case '$':
354 #ifdef HAVE_SPAM
355 if (n == 0)
356 n = 5;
357 if (UICMP(32, ABS(n), >, wleft))
358 n = (n < 0) ? -wleft : wleft;
359 snprintf(buf, sizeof buf, "%u.%02u",
360 (mp->m_spamscore >> 8), (mp->m_spamscore & 0xFF));
361 n = fprintf(f, "%*s", n, buf);
362 wleft = (n >= 0) ? wleft - n : 0;
363 break;
364 #else
365 c = '?';
366 goto jputcb;
367 #endif
368 case 'a':
369 c = _dispc(mp, attrlist);
370 jputcb:
371 #ifdef HAVE_COLOUR
372 if (cpen_new == cpen_cur)
373 cpen_new = cpen_bas;
374 if (cpen_new != cpen_cur)
375 n_colour_pen_put(cpen_cur = cpen_new, f);
376 #endif
377 if (UICMP(32, ABS(n), >, wleft))
378 n = (n < 0) ? -wleft : wleft;
379 cbuf[0] = c;
380 n = fprintf(f, "%*s", n, cbuf);
381 wleft = (n >= 0) ? wleft - n : 0;
382 #ifdef HAVE_COLOUR
383 if ((cpen_new = cpen_bas) != cpen_cur)
384 n_colour_pen_put(cpen_cur = cpen_new, f);
385 #endif
386 break;
387 case 'd':
388 if (datefmt != NULL) {
389 i = strftime(datebuf, sizeof datebuf, datefmt,
390 &time_current.tc_local);
391 if (i != 0)
392 date = datebuf;
393 else
394 n_err(_("Ignored date format, it excesses the target "
395 "buffer (%lu bytes)\n"), (ul_i)sizeof(datebuf));
396 datefmt = NULL;
398 if (n == 0)
399 n = 16;
400 if (UICMP(32, ABS(n), >, wleft))
401 n = (n < 0) ? -wleft : wleft;
402 n = fprintf(f, "%*.*s", n, n, date);
403 wleft = (n >= 0) ? wleft - n : 0;
404 break;
405 case 'e':
406 if (n == 0)
407 n = 2;
408 if (UICMP(32, ABS(n), >, wleft))
409 n = (n < 0) ? -wleft : wleft;
410 n = fprintf(f, "%*u", n, (threaded == 1 ? mp->m_level : 0));
411 wleft = (n >= 0) ? wleft - n : 0;
412 break;
413 case 'f':
414 if (n == 0) {
415 n = 18;
416 if (s < 0)
417 n = -n;
419 i = ABS(n);
420 if (i > wleft) {
421 i = wleft;
422 n = (n < 0) ? -wleft : wleft;
424 if (flags & _ISTO) /* XXX tr()! */
425 i -= 3;
426 n = fprintf(f, "%s%s", ((flags & _ISTO) ? "To " : ""),
427 colalign(name, i, n, &wleft));
428 if (n < 0)
429 wleft = 0;
430 else if (flags & _ISTO)
431 wleft -= 3;
432 break;
433 case 'i':
434 if (threaded) {
435 #ifdef HAVE_COLOUR
436 cpen_new = n_colour_pen_create(n_COLOUR_ID_SUM_THREAD, colo_tag);
437 if (cpen_new != cpen_cur)
438 n_colour_pen_put(cpen_cur = cpen_new, f);
439 #endif
440 n = __putindent(f, mp, MIN(wleft, scrnwidth - 60));
441 wleft = (n >= 0) ? wleft - n : 0;
442 #ifdef HAVE_COLOUR
443 if ((cpen_new = cpen_bas) != cpen_cur)
444 n_colour_pen_put(cpen_cur = cpen_new, f);
445 #endif
447 break;
448 case 'l':
449 if (n == 0)
450 n = 4;
451 if (UICMP(32, ABS(n), >, wleft))
452 n = (n < 0) ? -wleft : wleft;
453 if (mp->m_xlines) {
454 n = fprintf(f, "%*ld", n, mp->m_xlines);
455 wleft = (n >= 0) ? wleft - n : 0;
456 } else {
457 n = ABS(n);
458 wleft -= n;
459 while (n-- != 0)
460 putc(' ', f);
462 break;
463 case 'm':
464 if (n == 0) {
465 n = 3;
466 if (threaded)
467 for (i = msgCount; i > 999; i /= 10)
468 ++n;
470 if (UICMP(32, ABS(n), >, wleft))
471 n = (n < 0) ? -wleft : wleft;
472 n = fprintf(f, "%*lu", n, (ul_i)msgno);
473 wleft = (n >= 0) ? wleft - n : 0;
474 break;
475 case 'o':
476 if (n == 0)
477 n = -5;
478 if (UICMP(32, ABS(n), >, wleft))
479 n = (n < 0) ? -wleft : wleft;
480 n = fprintf(f, "%*lu", n, (ul_i)mp->m_xsize);
481 wleft = (n >= 0) ? wleft - n : 0;
482 break;
483 case 'S':
484 flags |= _SFMT;
485 /*FALLTHRU*/
486 case 's':
487 if (n == 0)
488 n = subjlen - 2;
489 if (n > 0 && s < 0)
490 n = -n;
491 if (subjlen > wleft)
492 subjlen = wleft;
493 if (UICMP(32, ABS(n), >, subjlen))
494 n = (n < 0) ? -subjlen : subjlen;
495 if (flags & _SFMT)
496 n -= (n < 0) ? -2 : 2;
497 if (n == 0)
498 break;
499 if (subjline == NULL)
500 subjline = __subject(mp, (threaded && (flags & _IFMT)), yetprinted);
501 if (subjline == (char*)-1) {
502 n = fprintf(f, "%*s", n, "");
503 wleft = (n >= 0) ? wleft - n : 0;
504 } else {
505 n = fprintf(f, ((flags & _SFMT) ? "\"%s\"" : "%s"),
506 colalign(subjline, ABS(n), n, &wleft));
507 if (n < 0)
508 wleft = 0;
510 break;
511 case 'T': { /* Message recipient flags */
512 /* We never can reuse "name" since it's the full name */
513 struct name const *np = lextract(hfield1("to", mp), GTO | GSKIN);
514 c = ' ';
515 i = 0;
516 j_A_redo:
517 for (; np != NULL; np = np->n_flink) {
518 switch (is_mlist(np->n_name, FAL0)) {
519 case MLIST_SUBSCRIBED: c = 'S'; goto jputcb;
520 case MLIST_KNOWN: c = 'L'; goto jputcb;
521 case MLIST_OTHER:
522 default: break;
525 if (i != 0)
526 goto jputcb;
527 ++i;
528 np = lextract(hfield1("cc", mp), GCC | GSKIN);
529 goto j_A_redo;
531 case 't':
532 if (n == 0) {
533 n = 3;
534 if (threaded)
535 for (i = msgCount; i > 999; i /= 10)
536 ++n;
538 if (UICMP(32, ABS(n), >, wleft))
539 n = (n < 0) ? -wleft : wleft;
540 n = fprintf(f, "%*lu",
541 n, (threaded ? (ul_i)mp->m_threadpos : (ul_i)msgno));
542 wleft = (n >= 0) ? wleft - n : 0;
543 break;
544 default:
545 if (options & OPT_D_V)
546 n_err(_("Unkown *headline* format: \"%%%c\"\n"), c);
547 c = '?';
548 goto jputcb;
551 if (wleft <= 0)
552 break;
555 #ifdef HAVE_COLOUR
556 n_colour_reset(f);
557 #endif
558 putc('\n', f);
560 if (subjline != NULL && subjline != (char*)-1)
561 free(subjline);
562 NYD_LEAVE;
565 static char *
566 __subject(struct message *mp, bool_t threaded, size_t yetprinted)
568 struct str in, out;
569 char *rv = (char*)-1, *ms;
570 NYD_ENTER;
572 if ((ms = hfield1("subject", mp)) == NULL)
573 goto jleave;
575 in.l = strlen(in.s = ms);
576 mime_fromhdr(&in, &out, TD_ICONV | TD_ISPR);
577 rv = ms = out.s;
579 if (!threaded || mp->m_level == 0)
580 goto jleave;
582 /* In a display thread - check wether this message uses the same
583 * Subject: as it's parent or elder neighbour, suppress printing it if
584 * this is the case. To extend this a bit, ignore any leading Re: or
585 * Fwd: plus follow-up WS. Ignore invisible messages along the way */
586 ms = subject_re_trim(ms);
588 for (; (mp = prev_in_thread(mp)) != NULL && yetprinted-- > 0;) {
589 char *os;
591 if (visible(mp) && (os = hfield1("subject", mp)) != NULL) {
592 struct str oout;
593 int x;
595 in.l = strlen(in.s = os);
596 mime_fromhdr(&in, &oout, TD_ICONV | TD_ISPR);
597 x = asccasecmp(ms, subject_re_trim(oout.s));
598 free(oout.s);
600 if (!x) {
601 free(out.s);
602 rv = (char*)-1;
604 break;
607 jleave:
608 NYD_LEAVE;
609 return rv;
612 static int
613 __putindent(FILE *fp, struct message *mp, int maxwidth)/* XXX no magic consts */
615 struct message *mq;
616 int *us, indlvl, indw, i, important = MNEW | MFLAGGED;
617 char *cs;
618 NYD_ENTER;
620 if (mp->m_level == 0 || maxwidth == 0) {
621 indw = 0;
622 goto jleave;
625 cs = ac_alloc(mp->m_level);
626 us = ac_alloc(mp->m_level * sizeof *us);
628 i = mp->m_level - 1;
629 if (mp->m_younger && UICMP(32, i + 1, ==, mp->m_younger->m_level)) {
630 if (mp->m_parent && mp->m_parent->m_flag & important)
631 us[i] = mp->m_flag & important ? 0x2523 : 0x2520;
632 else
633 us[i] = mp->m_flag & important ? 0x251D : 0x251C;
634 cs[i] = '+';
635 } else {
636 if (mp->m_parent && mp->m_parent->m_flag & important)
637 us[i] = mp->m_flag & important ? 0x2517 : 0x2516;
638 else
639 us[i] = mp->m_flag & important ? 0x2515 : 0x2514;
640 cs[i] = '\\';
643 mq = mp->m_parent;
644 for (i = mp->m_level - 2; i >= 0; --i) {
645 if (mq) {
646 if (UICMP(32, i, >, mq->m_level - 1)) {
647 us[i] = cs[i] = ' ';
648 continue;
650 if (mq->m_younger) {
651 if (mq->m_parent && (mq->m_parent->m_flag & important))
652 us[i] = 0x2503;
653 else
654 us[i] = 0x2502;
655 cs[i] = '|';
656 } else
657 us[i] = cs[i] = ' ';
658 mq = mq->m_parent;
659 } else
660 us[i] = cs[i] = ' ';
663 --maxwidth;
664 for (indlvl = indw = 0; (ui8_t)indlvl < mp->m_level && indw < maxwidth;
665 ++indlvl) {
666 if (indw < maxwidth - 1)
667 indw += (int)putuc(us[indlvl], cs[indlvl] & 0xFF, fp);
668 else
669 indw += (int)putuc(0x21B8, '^', fp);
671 indw += putuc(0x25B8, '>', fp);
673 ac_free(us);
674 ac_free(cs);
675 jleave:
676 NYD_LEAVE;
677 return indw;
680 static int
681 _dispc(struct message *mp, char const *a)
683 int i = ' ';
684 NYD_ENTER;
686 if ((mp->m_flag & (MREAD | MNEW)) == MREAD)
687 i = a[3];
688 if ((mp->m_flag & (MREAD | MNEW)) == (MREAD | MNEW))
689 i = a[2];
690 if (mp->m_flag & MANSWERED)
691 i = a[8];
692 if (mp->m_flag & MDRAFTED)
693 i = a[9];
694 if ((mp->m_flag & (MREAD | MNEW)) == MNEW)
695 i = a[0];
696 if (!(mp->m_flag & (MREAD | MNEW)))
697 i = a[1];
698 if (mp->m_flag & MSPAM)
699 i = a[12];
700 if (mp->m_flag & MSPAMUNSURE)
701 i = a[13];
702 if (mp->m_flag & MSAVED)
703 i = a[4];
704 if (mp->m_flag & MPRESERVE)
705 i = a[5];
706 if (mp->m_flag & (MBOX | MBOXED))
707 i = a[6];
708 if (mp->m_flag & MFLAGGED)
709 i = a[7];
710 if (mb.mb_threaded == 1 && mp->m_collapsed > 0)
711 i = a[11];
712 if (mb.mb_threaded == 1 && mp->m_collapsed < 0)
713 i = a[10];
714 NYD_LEAVE;
715 return i;
718 static int
719 a_cmd_scroll(char const *arg, bool_t onlynew){
720 long l;
721 char *eptr;
722 bool_t isabs;
723 int msgspec, size, maxs;
724 NYD2_ENTER;
726 msgspec = onlynew ? -1 : 0;
727 size = screensize();
728 maxs = msgCount / size;
730 switch(*arg){
731 case '\0':
732 ++_screen;
733 goto jfwd;
734 case '$':
735 if(arg[1] != '\0')
736 goto jerr;
737 if(_screen == maxs)
738 goto jerrfwd;
739 _screen = maxs;
740 break;
741 case '+':
742 if(arg[1] == '\0')
743 ++_screen;
744 else{
745 isabs = FAL0;
747 ++arg;
748 if(0){
749 case '1': case '2': case '3': case '4': case '5':
750 case '6': case '7': case '8': case '9': case '0':
751 isabs = TRU1;
753 l = strtol(arg, &eptr, 10);
754 if(*eptr != '\0')
755 goto jerr;
756 if(l > maxs - (isabs ? 0 : _screen))
757 goto jerrfwd;
758 _screen = isabs ? (int)l : _screen + l;
760 jfwd:
761 if(_screen > maxs){
762 jerrfwd:
763 _screen = maxs;
764 printf(_("On last screenful of messages\n"));
766 break;
768 case '-':
769 if(arg[1] == '\0')
770 --_screen;
771 else{
772 ++arg;
773 l = strtol(arg, &eptr, 10);
774 if(*eptr != '\0')
775 goto jerr;
776 if(l > _screen)
777 goto jerrbwd;
778 _screen -= l;
780 if(_screen < 0){
781 jerrbwd:
782 _screen = 0;
783 printf(_("On first screenful of messages\n"));
785 if(msgspec == -1)
786 msgspec = -2;
787 break;
788 default:
789 jerr:
790 n_err(_("Unrecognized scrolling command \"%s\"\n"), arg);
791 size = 1;
792 goto jleave;
795 size = _headers(msgspec);
796 jleave:
797 NYD2_LEAVE;
798 return size;
801 static int
802 _headers(int msgspec) /* TODO rework v15 */
804 struct n_sigman sm;
805 bool_t volatile isrelax;
806 ui32_t volatile flag;
807 int g, k, mesg, size, lastg = 1;
808 struct message *mp, *mq, *lastmq = NULL;
809 enum mflag fl = MNEW | MFLAGGED;
810 NYD_ENTER;
812 time_current_update(&time_current, FAL0);
814 flag = 0;
815 isrelax = FAL0;
816 n_SIGMAN_ENTER_SWITCH(&sm, n_SIGMAN_ALL) {
817 case 0:
818 break;
819 default:
820 goto jleave;
823 #ifdef HAVE_COLOUR
824 if (options & OPT_INTERACTIVE)
825 n_colour_env_create(n_COLOUR_CTX_SUM, FAL0);
826 #endif
828 size = screensize();
829 if (_screen < 0)
830 _screen = 0;
831 #if 0 /* FIXME original code path */
832 k = _screen * size;
833 #else
834 if (msgspec <= 0)
835 k = _screen * size;
836 else
837 k = msgspec;
838 #endif
839 if (k >= msgCount)
840 k = msgCount - size;
841 if (k < 0)
842 k = 0;
844 if (mb.mb_threaded == 0) {
845 g = 0;
846 mq = message;
847 for (mp = message; PTRCMP(mp, <, message + msgCount); ++mp)
848 if (visible(mp)) {
849 if (g % size == 0)
850 mq = mp;
851 if (mp->m_flag & fl) {
852 lastg = g;
853 lastmq = mq;
855 if ((msgspec > 0 && PTRCMP(mp, ==, message + msgspec - 1)) ||
856 (msgspec == 0 && g == k) ||
857 (msgspec == -2 && g == k + size && lastmq) ||
858 (msgspec < 0 && g >= k && (mp->m_flag & fl) != 0))
859 break;
860 g++;
862 if (lastmq && (msgspec == -2 ||
863 (msgspec == -1 && PTRCMP(mp, ==, message + msgCount)))) {
864 g = lastg;
865 mq = lastmq;
867 _screen = g / size;
869 mp = mq;
870 mesg = (int)PTR2SIZE(mp - message);
871 if (PTRCMP(dot, !=, message + msgspec - 1)) { /* TODO really?? */
872 for (mq = mp; PTRCMP(mq, <, message + msgCount); ++mq)
873 if (visible(mq)) {
874 setdot(mq);
875 break;
879 srelax_hold();
880 isrelax = TRU1;
881 for (; PTRCMP(mp, <, message + msgCount); ++mp) {
882 ++mesg;
883 if (!visible(mp))
884 continue;
885 if (UICMP(32, flag++, >=, size))
886 break;
887 _print_head(0, mesg, stdout, 0);
888 srelax();
890 srelax_rele();
891 isrelax = FAL0;
892 } else { /* threaded */
893 g = 0;
894 mq = threadroot;
895 for (mp = threadroot; mp; mp = next_in_thread(mp))
896 if (visible(mp) &&
897 (mp->m_collapsed <= 0 ||
898 PTRCMP(mp, ==, message + msgspec - 1))) {
899 if (g % size == 0)
900 mq = mp;
901 if (mp->m_flag & fl) {
902 lastg = g;
903 lastmq = mq;
905 if ((msgspec > 0 && PTRCMP(mp, ==, message + msgspec - 1)) ||
906 (msgspec == 0 && g == k) ||
907 (msgspec == -2 && g == k + size && lastmq) ||
908 (msgspec < 0 && g >= k && (mp->m_flag & fl) != 0))
909 break;
910 g++;
912 if (lastmq && (msgspec == -2 ||
913 (msgspec == -1 && PTRCMP(mp, ==, message + msgCount)))) {
914 g = lastg;
915 mq = lastmq;
917 _screen = g / size;
918 mp = mq;
919 if (PTRCMP(dot, !=, message + msgspec - 1)) { /* TODO really?? */
920 for (mq = mp; mq; mq = next_in_thread(mq))
921 if (visible(mq) && mq->m_collapsed <= 0) {
922 setdot(mq);
923 break;
927 srelax_hold();
928 isrelax = TRU1;
929 while (mp) {
930 if (visible(mp) &&
931 (mp->m_collapsed <= 0 ||
932 PTRCMP(mp, ==, message + msgspec - 1))) {
933 if (UICMP(32, flag++, >=, size))
934 break;
935 _print_head(flag - 1, PTR2SIZE(mp - message + 1), stdout,
936 mb.mb_threaded);
937 srelax();
939 mp = next_in_thread(mp);
941 srelax_rele();
942 isrelax = FAL0;
945 if (!flag) {
946 printf(_("No more mail.\n"));
947 if (pstate & (PS_HOOK_MASK | PS_ROBOT))
948 flag = !flag;
951 n_sigman_cleanup_ping(&sm);
952 jleave:
953 if (isrelax)
954 srelax_rele();
955 n_COLOUR( n_colour_env_gut((sm.sm_signo != SIGPIPE) ? stdout : NULL); )
956 NYD_LEAVE;
957 n_sigman_leave(&sm, n_SIGMAN_VIPSIGS_NTTYOUT);
958 return !flag;
961 static int
962 _type1(int *msgvec, bool_t doign, bool_t dopage, bool_t dopipe,
963 bool_t dodecode, char *cmd, ui64_t *tstats)
965 struct n_sigman sm;
966 ui64_t mstats[1];
967 int rv = 1, *ip;
968 struct message *mp;
969 char const *cp;
970 FILE * volatile obuf;
971 bool_t volatile isrelax = FAL0;
972 NYD_ENTER;
973 {/* C89.. */
974 enum sendaction const action = ((dopipe && ok_blook(piperaw))
975 ? SEND_MBOX : dodecode
976 ? SEND_SHOW : doign
977 ? SEND_TODISP : SEND_TODISP_ALL);
978 bool_t const volatile formfeed = (dopipe && ok_blook(page));
979 obuf = stdout;
981 n_SIGMAN_ENTER_SWITCH(&sm, n_SIGMAN_ALL) {
982 case 0:
983 break;
984 default:
985 goto jleave;
988 if (dopipe) {
989 if ((obuf = Popen(cmd, "w", ok_vlook(SHELL), NULL, 1)) == NULL) {
990 n_perr(cmd, 0);
991 obuf = stdout;
993 } else if ((options & OPT_TTYOUT) && (dopage ||
994 ((options & OPT_INTERACTIVE) && (cp = ok_vlook(crt)) != NULL))) {
995 size_t nlines = 0;
997 if (!dopage) {
998 for (ip = msgvec; *ip && PTRCMP(ip - msgvec, <, msgCount); ++ip) {
999 mp = message + *ip - 1;
1000 if (!(mp->m_have & HAVE_BODY))
1001 if (get_body(mp) != OKAY)
1002 goto jcleanup_leave;
1003 nlines += mp->m_lines + 1; /* Message info XXX and PARTS... */
1007 /* >= not <: we return to the prompt */
1008 if (dopage || UICMP(z, nlines, >=,
1009 (*cp != '\0' ? strtoul(cp, NULL, 0) : (size_t)realscreenheight))) {
1010 if ((obuf = n_pager_open()) == NULL)
1011 obuf = stdout;
1013 #ifdef HAVE_COLOUR
1014 if ((options & OPT_INTERACTIVE) &&
1015 (action == SEND_TODISP || action == SEND_TODISP_ALL ||
1016 action == SEND_SHOW))
1017 n_colour_env_create(n_COLOUR_CTX_VIEW, obuf != stdout);
1018 #endif
1020 #ifdef HAVE_COLOUR
1021 else if ((options & OPT_INTERACTIVE) &&
1022 (action == SEND_TODISP || action == SEND_TODISP_ALL))
1023 n_colour_env_create(n_COLOUR_CTX_VIEW, FAL0);
1024 #endif
1026 /*TODO unless we have our signal manager special care must be taken */
1027 srelax_hold();
1028 isrelax = TRU1;
1029 for (ip = msgvec; *ip && PTRCMP(ip - msgvec, <, msgCount); ++ip) {
1030 mp = message + *ip - 1;
1031 touch(mp);
1032 setdot(mp);
1033 pstate |= PS_DID_PRINT_DOT;
1034 uncollapse1(mp, 1);
1035 if (!dopipe && ip != msgvec)
1036 fprintf(obuf, "\n");
1037 if (action != SEND_MBOX)
1038 _show_msg_overview(obuf, mp, *ip);
1039 sendmp(mp, obuf, (doign ? ignore : NULL), NULL, action, mstats);
1040 srelax();
1041 if (formfeed) /* TODO a nicer way to separate piped messages! */
1042 putc('\f', obuf);
1043 if (tstats != NULL)
1044 tstats[0] += mstats[0];
1046 srelax_rele();
1047 isrelax = FAL0;
1049 rv = 0;
1050 jcleanup_leave:
1051 n_sigman_cleanup_ping(&sm);
1052 jleave:
1053 if (isrelax)
1054 srelax_rele();
1055 n_COLOUR( n_colour_env_gut((sm.sm_signo != SIGPIPE) ? obuf : NULL); )
1056 if (obuf != stdout)
1057 n_pager_close(obuf);
1059 NYD_LEAVE;
1060 n_sigman_leave(&sm, n_SIGMAN_VIPSIGS_NTTYOUT);
1061 return rv;
1064 static int
1065 _pipe1(char *str, int doign)
1067 ui64_t stats[1];
1068 char *cmd;
1069 int *msgvec, rv = 1;
1070 bool_t needs_list;
1071 NYD_ENTER;
1073 if ((cmd = laststring(str, &needs_list, TRU1)) == NULL) {
1074 cmd = ok_vlook(cmd);
1075 if (cmd == NULL || *cmd == '\0') {
1076 n_err(_("Variable *cmd* not set\n"));
1077 goto jleave;
1081 msgvec = salloc((msgCount + 2) * sizeof *msgvec);
1083 if (!needs_list) {
1084 *msgvec = first(0, MMNORM);
1085 if (*msgvec == 0) {
1086 if (pstate & (PS_HOOK_MASK | PS_ROBOT)) {
1087 rv = 0;
1088 goto jleave;
1090 puts(_("No messages to pipe."));
1091 goto jleave;
1093 msgvec[1] = 0;
1094 } else if (getmsglist(str, msgvec, 0) < 0)
1095 goto jleave;
1096 if (*msgvec == 0) {
1097 if (pstate & (PS_HOOK_MASK | PS_ROBOT)) {
1098 rv = 0;
1099 goto jleave;
1101 printf("No applicable messages.\n");
1102 goto jleave;
1105 printf(_("Pipe to: \"%s\"\n"), cmd);
1106 stats[0] = 0;
1107 if ((rv = _type1(msgvec, doign, FAL0, TRU1, FAL0, cmd, stats)) == 0)
1108 printf("\"%s\" %" PRIu64 " bytes\n", cmd, stats[0]);
1109 jleave:
1110 NYD_LEAVE;
1111 return rv;
1114 static int
1115 a_cmd_top(void *vp, struct ignoretab *itp){
1116 struct n_string s;
1117 int *msgvec, *ip;
1118 enum{a_NONE, a_SQUEEZE = 1<<0,
1119 a_EMPTY = 1<<8, a_STOP = 1<<9, a_WORKMASK = 0xFF00} f;
1120 size_t tmax, plines;
1121 FILE *iobuf, *pbuf;
1122 NYD2_ENTER;
1124 if((iobuf = Ftmp(NULL, "topio", OF_RDWR | OF_UNLINK | OF_REGISTER)) == NULL){
1125 n_perr(_("`top': I/O temporary file"), 0);
1126 vp = NULL;
1127 goto jleave;
1129 if((pbuf = Ftmp(NULL, "toppag", OF_RDWR | OF_UNLINK | OF_REGISTER)) == NULL){
1130 n_perr(_("`top': temporary pager file"), 0);
1131 vp = NULL;
1132 goto jleave1;
1135 /* TODO In v15 we should query the m_message object, and directly send only
1136 * TODO those parts, optionally over empty-line-squeeze and quote-strip
1137 * TODO filters, in which we are interested in: only text content!
1138 * TODO And: with *topsqueeze*, header/content separating empty line.. */
1139 pstate &= ~PS_MSGLIST_DIRECT; /* TODO NO ATTACHMENTS */
1140 plines = 0;
1142 #ifdef HAVE_COLOUR
1143 if (options & OPT_INTERACTIVE)
1144 n_colour_env_create(n_COLOUR_CTX_VIEW, TRU1);
1145 #endif
1146 n_string_creat_auto(&s);
1147 /* C99 */{
1148 long l;
1150 if((l = strtol(ok_vlook(toplines), NULL, 0)) <= 0){
1151 tmax = screensize();
1152 if(l < 0){
1153 l = ABS(l);
1154 tmax >>= l;
1156 }else
1157 tmax = l;
1159 f = ok_blook(topsqueeze) ? a_SQUEEZE : a_NONE;
1161 for(ip = msgvec = vp;
1162 *ip != 0 && UICMP(z, PTR2SIZE(ip - msgvec), <, msgCount); ++ip){
1163 struct message *mp;
1165 mp = &message[*ip - 1];
1166 touch(mp);
1167 setdot(mp);
1168 pstate |= PS_DID_PRINT_DOT;
1169 uncollapse1(mp, 1);
1171 rewind(iobuf);
1172 if(ftruncate(fileno(iobuf), 0)){
1173 n_perr(_("`top': ftruncate(2)"), 0);
1174 vp = NULL;
1175 break;
1177 if(sendmp(mp, iobuf, itp, NULL, SEND_TODISP_ALL, NULL) < 0){
1178 n_err(_("`top': failed to prepare message %d\n"), *ip);
1179 vp = NULL;
1180 break;
1182 fflush_rewind(iobuf);
1184 _show_msg_overview(pbuf, mp, *ip);
1185 ++plines;
1186 /* C99 */{
1187 size_t l;
1189 n_string_trunc(&s, 0);
1190 for(l = 0, f &= ~a_WORKMASK; !(f & a_STOP);){
1191 int c;
1193 if((c = getc(iobuf)) == EOF){
1194 f |= a_STOP;
1195 c = '\n';
1198 if(c != '\n')
1199 n_string_push_c(&s, c);
1200 else if((f & a_SQUEEZE) && s.s_len == 0){
1201 if(!(f & a_STOP) && ((f & a_EMPTY) || tmax - 1 <= l))
1202 continue;
1203 if(putc('\n', pbuf) == EOF){
1204 vp = NULL;
1205 break;
1207 f |= a_EMPTY;
1208 ++l;
1209 }else{
1210 char const *cp, *xcp;
1212 cp = n_string_cp_const(&s);
1213 /* TODO Brute simple skip part overviews; see above.. */
1214 if(!(f & a_SQUEEZE))
1215 c = '\1';
1216 else if(s.s_len > 8 &&
1217 (xcp = strstr(cp, "[-- ")) != NULL &&
1218 PTRCMP(xcp, <, strstr(cp, " --]")))
1219 c = '\0';
1220 else for(; (c = *cp) != '\0'; ++cp){
1221 if(!asciichar(c))
1222 break;
1223 if(!blankspacechar(c)){
1224 if(!ISQUOTE(c))
1225 break;
1226 c = '\0';
1227 break;
1231 if(c != '\0'){
1232 if(fputs(n_string_cp_const(&s), pbuf) == EOF ||
1233 putc('\n', pbuf) == EOF){
1234 vp = NULL;
1235 break;
1237 if(++l >= tmax)
1238 break;
1239 f &= ~a_EMPTY;
1240 }else
1241 f |= a_EMPTY;
1242 n_string_trunc(&s, 0);
1245 if(vp == NULL)
1246 break;
1247 if(l > 0)
1248 plines += l;
1249 else{
1250 if(!(f & a_EMPTY) && putc('\n', pbuf) == EOF){
1251 vp = NULL;
1252 break;
1254 ++plines;
1259 n_string_gut(&s);
1260 n_COLOUR( n_colour_env_gut(pbuf); )
1262 fflush(pbuf);
1263 page_or_print(pbuf, plines);
1265 Fclose(pbuf);
1266 jleave1:
1267 Fclose(iobuf);
1268 jleave:
1269 NYD2_LEAVE;
1270 return (vp != NULL);
1273 FL int
1274 c_cmdnotsupp(void *v) /* TODO -> lex.c */
1276 NYD_ENTER;
1277 UNUSED(v);
1278 n_err(_("The requested feature is not compiled in\n"));
1279 NYD_LEAVE;
1280 return 1;
1283 FL int
1284 c_headers(void *v)
1286 int rv;
1287 NYD_ENTER;
1289 rv = print_header_group((int*)v);
1290 NYD_LEAVE;
1291 return rv;
1294 FL int
1295 print_header_group(int *vector)
1297 int rv;
1298 NYD_ENTER;
1300 assert(vector != NULL && vector != (void*)-1);
1301 rv = _headers(vector[0]);
1302 NYD_LEAVE;
1303 return rv;
1306 FL int
1307 c_scroll(void *v)
1309 int rv;
1310 NYD_ENTER;
1312 rv = a_cmd_scroll(v, FAL0);
1313 NYD_LEAVE;
1314 return rv;
1317 FL int
1318 c_Scroll(void *v)
1320 int rv;
1321 NYD_ENTER;
1323 rv = a_cmd_scroll(v, TRU1);
1324 NYD_LEAVE;
1325 return rv;
1328 FL int
1329 c_from(void *v)
1331 struct n_sigman sm;
1332 int *msgvec = v, *ip, n;
1333 char *cp;
1334 FILE * volatile obuf;
1335 bool_t volatile isrelax;
1336 NYD_ENTER;
1338 time_current_update(&time_current, FAL0);
1340 obuf = stdout;
1341 isrelax = FAL0;
1342 n_SIGMAN_ENTER_SWITCH(&sm, n_SIGMAN_ALL) {
1343 case 0:
1344 break;
1345 default:
1346 goto jleave;
1349 if (options & OPT_INTERACTIVE) {
1350 if ((cp = ok_vlook(crt)) != NULL) {
1351 for (n = 0, ip = msgvec; *ip != 0; ++ip)
1352 ++n;
1353 if (UICMP(z, n, >, (*cp == '\0'
1354 ? (size_t)screensize() : strtoul(cp, NULL, 0)) + 3) &&
1355 (obuf = n_pager_open()) == NULL)
1356 obuf = stdout;
1358 n_COLOUR( n_colour_env_create(n_COLOUR_CTX_SUM, obuf != stdout); )
1361 /* Update dot before display so that the dotmark etc. are correct */
1362 for (ip = msgvec; *ip != 0; ++ip)
1364 if (--ip >= msgvec)
1365 setdot(message + *ip - 1);
1367 srelax_hold();
1368 isrelax = TRU1;
1369 for (n = 0, ip = msgvec; *ip != 0; ++ip) { /* TODO join into _print_head() */
1370 _print_head((size_t)n++, (size_t)*ip, obuf, mb.mb_threaded);
1371 srelax();
1373 srelax_rele();
1374 isrelax = FAL0;
1376 n_sigman_cleanup_ping(&sm);
1377 jleave:
1378 if (isrelax)
1379 srelax_rele();
1380 n_COLOUR( n_colour_env_gut((sm.sm_signo != SIGPIPE) ? obuf : NULL); )
1381 if (obuf != stdout)
1382 n_pager_close(obuf);
1383 NYD_LEAVE;
1384 n_sigman_leave(&sm, n_SIGMAN_VIPSIGS_NTTYOUT);
1385 return 0;
1388 FL void
1389 print_headers(size_t bottom, size_t topx, bool_t only_marked)
1391 struct n_sigman sm;
1392 bool_t volatile isrelax;
1393 size_t printed;
1394 NYD_ENTER;
1396 time_current_update(&time_current, FAL0);
1398 isrelax = FAL0;
1399 n_SIGMAN_ENTER_SWITCH(&sm, n_SIGMAN_ALL) {
1400 case 0:
1401 break;
1402 default:
1403 goto jleave;
1406 #ifdef HAVE_COLOUR
1407 if (options & OPT_INTERACTIVE)
1408 n_colour_env_create(n_COLOUR_CTX_SUM, FAL0);
1409 #endif
1411 srelax_hold();
1412 isrelax = TRU1;
1413 for (printed = 0; bottom <= topx; ++bottom) {
1414 struct message *mp = message + bottom - 1;
1415 if (only_marked) {
1416 if (!(mp->m_flag & MMARK))
1417 continue;
1418 } else if (!visible(mp))
1419 continue;
1420 _print_head(printed++, bottom, stdout, FAL0);
1421 srelax();
1423 srelax_rele();
1424 isrelax = FAL0;
1426 n_sigman_cleanup_ping(&sm);
1427 jleave:
1428 if (isrelax)
1429 srelax_rele();
1430 n_COLOUR( n_colour_env_gut((sm.sm_signo != SIGPIPE) ? stdout : NULL); )
1431 NYD_LEAVE;
1432 n_sigman_leave(&sm, n_SIGMAN_VIPSIGS_NTTYOUT);
1435 FL int
1436 c_pdot(void *v)
1438 NYD_ENTER;
1439 UNUSED(v);
1440 printf("%d\n", (int)PTR2SIZE(dot - message + 1));
1441 NYD_LEAVE;
1442 return 0;
1445 FL int
1446 c_more(void *v)
1448 int *msgvec = v, rv;
1449 NYD_ENTER;
1451 rv = _type1(msgvec, TRU1, TRU1, FAL0, FAL0, NULL, NULL);
1452 NYD_LEAVE;
1453 return rv;
1456 FL int
1457 c_More(void *v)
1459 int *msgvec = v, rv;
1460 NYD_ENTER;
1462 rv = _type1(msgvec, FAL0, TRU1, FAL0, FAL0, NULL, NULL);
1463 NYD_LEAVE;
1464 return rv;
1467 FL int
1468 c_type(void *v)
1470 int *msgvec = v, rv;
1471 NYD_ENTER;
1473 rv = _type1(msgvec, TRU1, FAL0, FAL0, FAL0, NULL, NULL);
1474 NYD_LEAVE;
1475 return rv;
1478 FL int
1479 c_Type(void *v)
1481 int *msgvec = v, rv;
1482 NYD_ENTER;
1484 rv = _type1(msgvec, FAL0, FAL0, FAL0, FAL0, NULL, NULL);
1485 NYD_LEAVE;
1486 return rv;
1489 FL int
1490 c_show(void *v)
1492 int *msgvec = v, rv;
1493 NYD_ENTER;
1495 rv = _type1(msgvec, FAL0, FAL0, FAL0, TRU1, NULL, NULL);
1496 NYD_LEAVE;
1497 return rv;
1500 FL int
1501 c_pipe(void *v)
1503 char *str = v;
1504 int rv;
1505 NYD_ENTER;
1507 rv = _pipe1(str, 1);
1508 NYD_LEAVE;
1509 return rv;
1512 FL int
1513 c_Pipe(void *v)
1515 char *str = v;
1516 int rv;
1517 NYD_ENTER;
1519 rv = _pipe1(str, 0);
1520 NYD_LEAVE;
1521 return rv;
1524 FL int
1525 c_top(void *v){
1526 struct ignoretab it[2];
1527 int rv;
1528 NYD_ENTER;
1530 n_ignoretab_creat(&it[0], TRU1);
1531 n_ignoretab_creat(&it[1], TRU1);
1532 n_ignoretab_insert(&it[1], "from", sizeof("from") -1);
1533 n_ignoretab_insert(&it[1], "to", sizeof("to") -1);
1534 n_ignoretab_insert(&it[1], "cc", sizeof("cc") -1);
1535 n_ignoretab_insert(&it[1], "subject", sizeof("subject") -1);
1537 rv = !a_cmd_top(v, it);
1538 NYD_LEAVE;
1539 return rv;
1542 FL int
1543 c_Top(void *v){
1544 int rv;
1545 NYD_ENTER;
1547 rv = !a_cmd_top(v, ignore);
1548 NYD_LEAVE;
1549 return rv;
1552 FL int
1553 c_folders(void *v)
1555 char const *cp;
1556 char **argv;
1557 int rv;
1558 NYD_ENTER;
1560 rv = 1;
1562 if(*(argv = v) != NULL){
1563 if((cp = fexpand(*argv, FEXP_NSHELL | FEXP_LOCAL)) == NULL)
1564 goto jleave;
1565 }else
1566 cp = folder_query();
1568 run_command(ok_vlook(LISTER), 0, COMMAND_FD_PASS, COMMAND_FD_PASS, cp,
1569 NULL, NULL, NULL);
1570 jleave:
1571 NYD_LEAVE;
1572 return rv;
1575 /* s-it-mode */