1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 - 2013 Steffen "Daode" Nurpmeso <sdaoden@users.sf.net>.
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
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. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 * Print the current active headings.
50 * Don't change dot if invoker didn't give an argument.
55 /* Prepare and print "[Message: xy]:" intro */
56 static void _show_msg_overview(struct message
*mp
, int msg_no
, FILE *obuf
);
58 static void onpipe(int signo
);
59 static int dispc(struct message
*mp
, const char *a
);
60 static int scroll1(char *arg
, int onlynew
);
62 static void _parse_head(struct message
*mp
, char date
[FROM_DATEBUF
]);
63 static void hprf(const char *fmt
, int mesg
, FILE *f
, int threaded
,
64 const char *attrlist
);
65 static int putindent(FILE *fp
, struct message
*mp
, int maxwidth
);
66 static int type1(int *msgvec
, int doign
, int page
, int pipe
, int decode
,
67 char *cmd
, off_t
*tstats
);
68 static int pipe1(char *str
, int doign
);
71 _show_msg_overview(struct message
*mp
, int msg_no
, FILE *obuf
)
73 fprintf(obuf
, tr(17, "[-- Message %2d -- %lu lines, %lu bytes --]:\n"),
74 msg_no
, (ul_it
)mp
->m_lines
, (ul_it
)mp
->m_size
);
81 fprintf(stderr
, tr(10, "The requested feature is not compiled in\n"));
91 if (cp
== NULL
|| *cp
== '\0')
100 int g
, k
, n
, mesg
, flag
= 0, lastg
= 1;
101 struct message
*mp
, *mq
, *lastmq
= NULL
;
103 enum mflag fl
= MNEW
|MFLAGGED
;
105 time_current_update(&time_current
, FAL0
);
108 n
= msgvec
[0]; /* n == {-2, -1, 0}: called from scroll() */
116 if (mb
.mb_threaded
== 0) {
119 for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
127 if ((n
> 0 && mp
== &message
[n
-1]) ||
128 (n
== 0 && g
== k
) ||
129 (n
== -2 && g
== k
+ size
&&
132 (mp
->m_flag
& fl
) != 0))
136 if (lastmq
&& (n
==-2 || (n
==-1 && mp
== &message
[msgCount
]))) {
142 mesg
= mp
- &message
[0];
143 if (dot
!= &message
[n
-1]) {
144 for (mq
= mp
; mq
< &message
[msgCount
]; mq
++)
151 if (mb
.mb_type
== MB_IMAP
)
152 imap_getheaders(mesg
+1, mesg
+ size
);
154 for (; mp
< &message
[msgCount
]; mp
++) {
160 printhead(mesg
, stdout
, 0);
162 } else { /* threaded */
165 for (mp
= threadroot
; mp
; mp
= next_in_thread(mp
))
166 if (visible(mp
) && (mp
->m_collapsed
<= 0 ||
167 mp
== &message
[n
-1])) {
174 if ((n
> 0 && mp
== &message
[n
-1]) ||
175 (n
== 0 && g
== k
) ||
176 (n
== -2 && g
== k
+ size
&&
179 (mp
->m_flag
& fl
) != 0))
183 if (lastmq
&& (n
==-2 || (n
==-1 && mp
==&message
[msgCount
]))) {
189 if (dot
!= &message
[n
-1]) {
190 for (mq
= mp
; mq
; mq
= next_in_thread(mq
))
191 if (visible(mq
) && mq
->m_collapsed
<= 0) {
197 if (visible(mp
) && (mp
->m_collapsed
<= 0 ||
198 mp
== &message
[n
-1])) {
201 printhead(mp
- &message
[0] + 1, stdout
,
204 mp
= next_in_thread(mp
);
208 printf(tr(6, "No more mail.\n"));
215 * Scroll to the next/previous screen
220 return scroll1(v
, 0);
226 return scroll1(v
, 1);
230 scroll1(char *arg
, int onlynew
)
235 cur
[0] = onlynew
? -1 : 0;
238 case '1': case '2': case '3': case '4': case '5':
239 case '6': case '7': case '8': case '9': case '0':
246 screen
= msgCount
/ size
;
252 screen
+= atoi(arg
+ 1);
254 if (screen
* size
> msgCount
) {
255 screen
= msgCount
/ size
;
256 printf(catgets(catd
, CATSET
, 7,
257 "On last screenful of messages\n"));
265 screen
-= atoi(arg
+ 1);
268 printf(catgets(catd
, CATSET
, 8,
269 "On first screenful of messages\n"));
276 printf(catgets(catd
, CATSET
, 9,
277 "Unrecognized scrolling command \"%s\"\n"), arg
);
280 return(headers(cur
));
284 * Compute screen size.
292 if ((cp
= value("screen")) != NULL
&& (s
= atoi(cp
)) > 0)
294 return scrnheight
- 4;
297 static sigjmp_buf pipejmp
;
304 siglongjmp(pipejmp
, 1);
308 * Print out the headlines for each message
309 * in the passed message list.
314 int *msgvec
= v
, *ip
, n
;
316 FILE *volatile obuf
= stdout
;
318 time_current_update(&time_current
, FAL0
);
320 /* TODO unfixable memory leaks still */
321 if (IS_TTY_SESSION() && (cp
= value("crt")) != NULL
) {
322 for (n
= 0, ip
= msgvec
; *ip
; ip
++)
324 if (n
> (*cp
== '\0' ? screensize() : atoi((char*)cp
)) + 3) {
326 if (sigsetjmp(pipejmp
, 1))
329 if ((obuf
= Popen(p
, "w", NULL
, 1)) == NULL
) {
334 safe_signal(SIGPIPE
, onpipe
);
337 for (ip
= msgvec
; *ip
!= 0; ip
++)
338 printhead(*ip
, obuf
, mb
.mb_threaded
);
340 setdot(&message
[*ip
- 1]);
342 if (obuf
!= stdout
) {
343 safe_signal(SIGPIPE
, SIG_IGN
);
345 safe_signal(SIGPIPE
, dflpipe
);
351 dispc(struct message
*mp
, const char *a
)
358 if ((mp
->m_flag
& (MREAD
|MNEW
)) == MREAD
)
360 if ((mp
->m_flag
& (MREAD
|MNEW
)) == (MREAD
|MNEW
))
362 if (mp
->m_flag
& MANSWERED
)
364 if (mp
->m_flag
& MDRAFTED
)
366 if ((mp
->m_flag
& (MREAD
|MNEW
)) == MNEW
)
368 if ((mp
->m_flag
& (MREAD
|MNEW
)) == 0)
370 if (mp
->m_flag
& MSPAM
)
372 if (mp
->m_flag
& MSAVED
)
374 if (mp
->m_flag
& MPRESERVE
)
376 if (mp
->m_flag
& (MBOX
|MBOXED
))
378 if (mp
->m_flag
& MFLAGGED
)
380 if (mb
.mb_threaded
== 1 && mp
->m_collapsed
> 0)
382 if (mb
.mb_threaded
== 1 && mp
->m_collapsed
< 0)
388 _parse_head(struct message
*mp
, char date
[FROM_DATEBUF
])
395 if ((ibuf
= setinput(&mb
, mp
, NEED_HEADER
)) != NULL
&&
396 (hlen
= readline_restart(ibuf
, &hline
, &hsize
, 0)) > 0)
397 (void)extract_date_from_from_(hline
, hlen
, date
);
403 hprf(const char *fmt
, int mesg
, FILE *f
, int threaded
, const char *attrlist
)
405 char datebuf
[FROM_DATEBUF
], *subjline
, *cp
;
407 char const *datefmt
, *date
, *name
, *fp
;
408 int B
, c
, i
, n
, s
, fromlen
, subjlen
= scrnwidth
, isto
= 0, isaddr
= 0;
409 struct message
*mp
= &message
[mesg
- 1];
410 time_t datet
= mp
->m_time
;
413 if ((datefmt
= value("datefield")) != NULL
) {
414 fp
= hfield1("date", mp
);/* TODO use m_date field! */
420 date
= fakedate(datet
);
421 fp
= value("datefield-markout-older");
422 i
= (*datefmt
!= '\0');
424 i
|= (*fp
!= '\0') ? 2 | 4 : 2;
425 /* May we strftime(3)? */
427 memcpy(&time_current
.tc_local
, localtime(&datet
),
428 sizeof time_current
.tc_local
);
429 if ((i
& 2) && (datet
> time_current
.tc_time
||
430 #define _6M ((DATE_DAYSYEAR / 2) * DATE_SECSDAY)
431 (datet
+ _6M
< time_current
.tc_time
))) {
433 if ((datefmt
= (i
& 4) ? fp
: NULL
) == NULL
) {
434 memset(datebuf
, ' ', FROM_DATEBUF
); /* xxx ur */
435 memcpy(datebuf
+ 4, date
+ 4, 7);
436 datebuf
[4 + 7] = ' ';
437 memcpy(datebuf
+ 4 + 7 + 1, date
+ 20, 4);
438 datebuf
[4 + 7 + 1 + 4] = '\0';
441 } else if ((i
& 1) == 0)
443 } else if (datet
== (time_t)0 && (mp
->m_flag
& MNOFROM
) == 0) {
444 /* TODO eliminate this path, query the FROM_ date in setptr(),
445 * TODO all other codepaths do so by themselves ALREADY ?????
446 * TODO assert(mp->m_time != 0);, then
447 * TODO ALSO changes behaviour of markout-non-current */
448 _parse_head(mp
, datebuf
);
452 date
= fakedate(datet
);
457 if ((subjline
= hfield1("subject", mp
)) != NULL
) {
459 in
.l
= strlen(subjline
);
460 mime_fromhdr(&in
, &out
, TD_ICONV
| TD_ISPR
);
466 if (name
!= NULL
&& value("showto") && is_myname(skin(name
))) {
467 if ((cp
= hfield1("to", mp
)) != NULL
) {
477 if (value("showname"))
478 name
= realname(name
);
480 name
= prstr(skin(name
));
484 for (fp
= fmt
; *fp
; fp
++) {
488 } else if (*fp
== '+')
490 while (digitchar(*fp
))
495 #if defined (HAVE_MBTOWC) && defined (HAVE_WCWIDTH)
496 if (mb_cur_max
> 1) {
498 if ((s
= mbtowc(&wc
, fp
, mb_cur_max
)) < 0)
501 if ((n
= wcwidth(wc
)) < 0)
505 #endif /* HAVE_MBTOWC && HAVE_WCWIDTH */
515 for (fp
= fmt
; *fp
; fp
++) {
516 if ((c
= *fp
& 0xFF) == '%') {
523 } else if (*fp
== '+')
525 if (digitchar(*fp
)) {
527 n
= 10*n
+ *fp
- '0';
528 while (fp
++, digitchar(*fp
));
533 switch ((c
= *fp
& 0xFF)) {
542 c
= dispc(mp
, attrlist
);
544 n
= fprintf(f
, "%*c", n
, c
);
552 for (i
=msgCount
; i
>999; i
/=10)
555 subjlen
-= fprintf(f
, "%*d", n
, mesg
);
564 if (isto
) /* XXX tr()! */
566 subjlen
-= fprintf(f
, "%s%s", isto
? "To " : "",
567 colalign(name
, fromlen
, n
));
570 if (datefmt
!= NULL
) {
571 i
= strftime(datebuf
, sizeof datebuf
,
573 &time_current
.tc_local
);
577 fprintf(stderr
, tr(174,
578 "Ignored date format, "
582 (ul_it
)sizeof datebuf
);
587 subjlen
-= fprintf(f
, "%*.*s", n
, n
, date
);
593 subjlen
-= fprintf(f
, "%*ld", n
,
605 subjlen
-= fprintf(f
, "%*lu", n
,
610 subjlen
-= putindent(f
, mp
,
622 n
-= (n
< 0) ? -2 : 2;
623 if (subjline
!= NULL
&& n
!= 0) {
624 /* pretty pathetic */
625 fprintf(f
, B
? "\"%s\"" : "%s",
626 colalign(subjline
, ABS(n
), n
));
633 subjlen
-= fprintf(f
, "%*lu", n
, mp
->m_uid
);
642 subjlen
-= fprintf(f
, "%*u", n
, threaded
== 1 ?
649 for (i
=msgCount
; i
>999; i
/=10)
652 subjlen
-= fprintf(f
, "%*ld", n
, threaded
?
653 mp
->m_threadpos
: mesg
);
660 snprintf(buf
, sizeof buf
, "%u.%u",
661 (mp
->m_spamscore
>> 8),
662 (mp
->m_spamscore
& 0xFF));
663 subjlen
-= fprintf(f
, "%*s",
681 * Print out the indenting in threaded display.
684 putindent(FILE *fp
, struct message
*mp
, int maxwidth
)
690 int important
= MNEW
|MFLAGGED
;
692 if (mp
->m_level
== 0)
694 cs
= ac_alloc(mp
->m_level
);
695 us
= ac_alloc(mp
->m_level
* sizeof *us
);
697 if (mp
->m_younger
&& (unsigned)i
+ 1 == mp
->m_younger
->m_level
) {
698 if (mp
->m_parent
&& mp
->m_parent
->m_flag
& important
)
699 us
[i
] = mp
->m_flag
& important
? 0x2523 : 0x2520;
701 us
[i
] = mp
->m_flag
& important
? 0x251D : 0x251C;
704 if (mp
->m_parent
&& mp
->m_parent
->m_flag
& important
)
705 us
[i
] = mp
->m_flag
& important
? 0x2517 : 0x2516;
707 us
[i
] = mp
->m_flag
& important
? 0x2515 : 0x2514;
711 for (i
= mp
->m_level
- 2; i
>= 0; i
--) {
713 if ((unsigned)i
> mq
->m_level
- 1) {
719 mq
->m_parent
->m_flag
&important
)
730 for (indent
= 0; (unsigned)indent
< mp
->m_level
&& indent
< maxwidth
;
732 if (indent
< maxwidth
- 1)
733 putuc(us
[indent
], cs
[indent
] & 0377, fp
);
735 putuc(0x21B8, '^', fp
);
743 printhead(int mesg
, FILE *f
, int threaded
)
745 int bsdflags
, bsdheadline
, sz
;
746 char attrlist
[30], *cp
;
749 bsdflags
= value("bsdcompat") != NULL
|| value("bsdflags") != NULL
||
750 getenv("SYSV3") != NULL
;
751 strcpy(attrlist
, bsdflags
? "NU *HMFAT+-$" : "NUROSPMFAT+-$");
752 if ((cp
= value("attrlist")) != NULL
) {
754 if (sz
> (int)sizeof attrlist
- 1)
755 sz
= (int)sizeof attrlist
- 1;
756 memcpy(attrlist
, cp
, sz
);
758 bsdheadline
= value("bsdcompat") != NULL
||
759 value("bsdheadline") != NULL
;
760 if ((fmt
= value("headline")) == NULL
)
762 "%>%a%m %-20f %16d %3l/%-5o %i%-S" :
763 "%>%a%m %-18f %16d %4l/%-5o %i%-s";
764 hprf(fmt
, mesg
, f
, threaded
, attrlist
);
768 * Print out the value of dot.
775 printf(catgets(catd
, CATSET
, 13, "%d\n"),
776 (int)(dot
- &message
[0] + 1));
781 * Print out all the possible commands.
785 _pcmd_cmp(void const *s1
, void const *s2
)
787 struct cmd
const *const*c1
= s1
, *const*c2
= s2
;
788 return (strcmp((*c1
)->c_name
, (*c2
)->c_name
));
795 extern struct cmd
const cmdtab
[];
796 struct cmd
const **cpa
, *cp
, **cursor
;
800 for (i
= 0; cmdtab
[i
].c_name
!= NULL
; ++i
)
803 cpa
= ac_alloc(sizeof(cp
) * i
);
805 for (i
= 0; (cp
= cmdtab
+ i
)->c_name
!= NULL
; ++i
)
809 qsort(cpa
, i
, sizeof(cp
), &_pcmd_cmp
);
811 printf(tr(14, "Commands are:\n"));
812 for (i
= 0, cursor
= cpa
; (cp
= *cursor
++) != NULL
;) {
814 if (cp
->c_func
== &ccmdnotsupp
)
816 j
= strlen(cp
->c_name
) + 2;
821 printf((*cursor
!= NULL
? "%s, " : "%s\n"), cp
->c_name
);
829 * Type out the messages requested.
831 static sigjmp_buf pipestop
;
838 siglongjmp(pipestop
, 1);
842 type1(int *msgvec
, int doign
, int page
, int pipe
, int decode
,
843 char *cmd
, off_t
*tstats
)
853 if (sigsetjmp(pipestop
, 1))
859 obuf
= Popen(cmd
, "w", cp
, 1);
864 safe_signal(SIGPIPE
, brokpipe
);
866 } else if ((options
& OPT_TTYOUT
) &&
867 (page
|| (cp
= value("crt")) != NULL
)) {
870 for (ip
= msgvec
; *ip
&& ip
-msgvec
< msgCount
; ip
++) {
871 if ((message
[*ip
-1].m_have
& HAVE_BODY
) == 0) {
872 if ((get_body(&message
[*ip
- 1])) !=
876 nlines
+= message
[*ip
- 1].m_lines
;
879 if (page
|| nlines
> (*cp
? atoi(cp
) : realscreenheight
)) {
880 char const *p
= get_pager();
881 obuf
= Popen(p
, "w", NULL
, 1);
886 safe_signal(SIGPIPE
, brokpipe
);
889 for (ip
= msgvec
; *ip
&& ip
- msgvec
< msgCount
; ip
++) {
890 mp
= &message
[*ip
- 1];
894 if (! pipe
&& ip
!= msgvec
)
896 _show_msg_overview(mp
, *ip
, obuf
);
897 send(mp
, obuf
, doign
? ignore
: 0, NULL
,
898 pipe
&& value("piperaw") ? SEND_MBOX
:
900 doign
? SEND_TODISP
: SEND_TODISP_ALL
,
902 if (pipe
&& value("page")) {
906 tstats
[0] += mstats
[0];
907 tstats
[1] += mstats
[1];
911 if (obuf
!= stdout
) {
913 * Ignore SIGPIPE so it can't cause a duplicate close.
915 safe_signal(SIGPIPE
, SIG_IGN
);
917 safe_signal(SIGPIPE
, dflpipe
);
923 * Get the last, possibly quoted part of linebuf.
926 laststring(char *linebuf
, int *flag
, int strip
)
932 cp
= strlen(linebuf
) + linebuf
- 1;
935 * Strip away trailing blanks.
937 while (cp
> linebuf
&& whitechar(*cp
& 0377))
946 * Now search for the beginning of the command name.
949 if (quoted
== '\'' || quoted
== '\"') {
954 while (cp
> linebuf
) {
957 } else if (*(cp
- 1) != '\\') {
975 while (cp
> linebuf
&& !whitechar(*cp
& 0377))
977 if (whitechar(*cp
& 0377))
989 * Pipe the messages requested.
992 pipe1(char *str
, int doign
)
999 msgvec
= (int *)salloc((msgCount
+ 2) * sizeof *msgvec
);
1000 if ((cmd
= laststring(str
, &f
, 1)) == NULL
) {
1002 if (cmd
== NULL
|| *cmd
== '\0') {
1003 fputs(catgets(catd
, CATSET
, 16,
1004 "variable cmd not set\n"), stderr
);
1009 *msgvec
= first(0, MMNORM
);
1013 puts(catgets(catd
, CATSET
, 18, "No messages to pipe."));
1017 } else if (getmsglist(str
, msgvec
, 0) < 0)
1022 printf("No applicable messages.\n");
1025 printf(catgets(catd
, CATSET
, 268, "Pipe to: \"%s\"\n"), cmd
);
1026 stats
[0] = stats
[1] = 0;
1027 if ((ret
= type1(msgvec
, doign
, 0, 1, 0, cmd
, stats
)) == 0) {
1028 printf("\"%s\" ", cmd
);
1030 printf("%lu", (long)stats
[0]);
1032 printf(catgets(catd
, CATSET
, 27, "binary"));
1033 printf("/%lu\n", (long)stats
[1]);
1039 * Paginate messages, honor ignored fields.
1045 return (type1(msgvec
, 1, 1, 0, 0, NULL
, NULL
));
1049 * Paginate messages, even printing ignored fields.
1056 return (type1(msgvec
, 0, 1, 0, 0, NULL
, NULL
));
1060 * Type out messages, honor ignored fields.
1067 return(type1(msgvec
, 1, 0, 0, 0, NULL
, NULL
));
1071 * Type out messages, even printing ignored fields.
1078 return(type1(msgvec
, 0, 0, 0, 0, NULL
, NULL
));
1082 * Show MIME-encoded message text, including all fields.
1089 return(type1(msgvec
, 0, 0, 0, 1, NULL
, NULL
));
1093 * Pipe messages, honor ignored fields.
1099 return(pipe1(str
, 1));
1102 * Pipe messages, not respecting ignored fields.
1108 return(pipe1(str
, 0));
1112 * Print the top so many lines of each desired message.
1113 * The number of lines is taken from the variable "toplines"
1114 * and defaults to 5.
1119 int *msgvec
= v
, *ip
, c
, topl
, lines
, empty_last
;
1121 char *cp
, *linebuf
= NULL
;
1126 cp
= value("toplines");
1129 if (topl
< 0 || topl
> 10000)
1133 for (ip
= msgvec
; *ip
&& ip
-msgvec
< msgCount
; ip
++) {
1134 mp
= &message
[*ip
- 1];
1137 did_print_dot
= TRU1
;
1140 _show_msg_overview(mp
, *ip
, stdout
);
1141 if (mp
->m_flag
& MNOFROM
)
1142 printf("From %s %s\n", fakefrom(mp
),
1143 fakedate(mp
->m_time
));
1144 if ((ibuf
= setinput(&mb
, mp
, NEED_BODY
)) == NULL
) { /* XXX could use TOP */
1149 for (lines
= 0; lines
< c
&& lines
<= topl
; lines
++) {
1150 if (readline_restart(ibuf
, &linebuf
, &linesize
, 0) < 0)
1154 for (cp
= linebuf
; *cp
&& blankchar(*cp
); ++cp
)
1156 empty_last
= (*cp
== '\0');
1160 if (linebuf
!= NULL
)
1166 * Touch all the given messages so that they will
1175 for (ip
= msgvec
; *ip
!= 0; ip
++) {
1176 setdot(&message
[*ip
-1]);
1177 dot
->m_flag
|= MTOUCH
;
1178 dot
->m_flag
&= ~MPRESERVE
;
1180 * POSIX interpretation necessary.
1182 did_print_dot
= TRU1
;
1188 * Make sure all passed messages get mboxed.
1196 for (ip
= msgvec
; *ip
!= 0; ip
++) {
1197 setdot(&message
[*ip
-1]);
1198 dot
->m_flag
|= MTOUCH
|MBOX
;
1199 dot
->m_flag
&= ~MPRESERVE
;
1201 * POSIX interpretation necessary.
1203 did_print_dot
= TRU1
;
1209 * List the folders the user currently has.
1214 char dirname
[MAXPATHLEN
], *name
, **argv
= v
;
1218 name
= expand(*argv
);
1221 } else if (! getfold(dirname
, sizeof dirname
)) {
1222 fprintf(stderr
, tr(20, "No value set for \"folder\"\n"));
1227 if (which_protocol(name
) == PROTO_IMAP
) {
1229 imap_folders(name
, *argv
== NULL
);
1231 return ccmdnotsupp(NULL
);
1234 if ((cmd
= value("LISTER")) == NULL
)
1236 run_command(cmd
, 0, -1, -1, name
, NULL
, NULL
);