date and time created 80/10/08 09:51:11 by kas
[unix-history] / usr / src / usr.bin / mail / cmd1.c
CommitLineData
d702437a
KS
1#
2#include "rcv.h"
3#include <sys/stat.h>
4
5/*
6 * Mail -- a mail program
7 *
8 * User commands.
9 */
10
11static char *SccsId = "@(#)cmd1.c 1.1 %G%";
12
13/*
14 * Print the current active headings.
15 */
16
17static int screen;
18
19headers(msgvec)
20 int *msgvec;
21{
22 register int n, mesg, flag;
23 register struct message *mp;
24
25 n = msgvec[0];
26 if (n != 0)
27 screen = (n-1)/SCREEN;
28 if (screen < 0)
29 screen = 0;
30 mp = &message[screen * SCREEN];
31 if (mp >= &message[msgCount])
32 mp = &message[msgCount - SCREEN];
33 if (mp < &message[0])
34 mp = &message[0];
35 flag = 0;
36 mesg = mp - &message[0];
37 dot = mp;
38 for (; mp < &message[msgCount]; mp++) {
39 mesg++;
40 if (mp->m_flag & MDELETED)
41 continue;
42 if (flag++ >= SCREEN)
43 break;
44 printhead(mesg);
45 sreset();
46 }
47 if (flag == 0) {
48 printf("No more mail.\n");
49 return(1);
50 }
51 return(0);
52}
53
54/*
55 * Scroll to the next/previous screen
56 */
57
58scroll(arg)
59 char arg[];
60{
61 register int s;
62 int cur[1];
63
64 cur[0] = 0;
65 s = screen;
66 switch (*arg) {
67 case 0:
68 case '+':
69 s++;
70 if (s*SCREEN > msgCount) {
71 printf("On last screenful of messages\n");
72 return(0);
73 }
74 screen = s;
75 break;
76
77 case '-':
78 if (--s < 0) {
79 printf("On first screenful of messages\n");
80 return(0);
81 }
82 screen = s;
83 break;
84
85 default:
86 printf("Unrecognized scrolling command \"%s\"\n", arg);
87 return(1);
88 }
89 return(headers(cur));
90}
91
92
93/*
94 * Print out the headlines for each message
95 * in the passed message list.
96 */
97
98from(msgvec)
99 int *msgvec;
100{
101 register int *ip;
102
103 for (ip = msgvec; *ip != NULL; ip++) {
104 printhead(*ip);
105 sreset();
106 }
107 if (--ip >= msgvec)
108 dot = &message[*ip - 1];
109 return(0);
110}
111
112/*
113 * Print out the header of a specific message.
114 * This is a slight improvement to the standard one.
115 */
116
117printhead(mesg)
118{
119 struct message *mp;
120 FILE *ibuf;
121 char headline[LINESIZE], wcount[10], *subjline, dispc;
122 char pbuf[BUFSIZ];
123 int s;
124 struct headline hl;
125 register char *cp;
126
127 mp = &message[mesg-1];
128 ibuf = setinput(mp);
129 readline(ibuf, headline);
130 subjline = hfield("subject", mp);
131 if (subjline == NOSTR)
132 subjline = hfield("subj", mp);
133
134 /*
135 * Bletch!
136 */
137
138 if (subjline != NOSTR && strlen(subjline) > 28)
139 subjline[29] = '\0';
140 dispc = ' ';
141 if (mp->m_flag & MSAVED)
142 dispc = '*';
143 if (mp->m_flag & MPRESERVE)
144 dispc = 'P';
145 parse(headline, &hl, pbuf);
146 sprintf(wcount, " %d/%d", mp->m_lines, mp->m_size);
147 s = strlen(wcount);
148 cp = wcount + s;
149 while (s < 7)
150 s++, *cp++ = ' ';
151 *cp = '\0';
152 if (subjline != NOSTR)
153 printf("%c%3d %-8s %16.16s %s \"%s\"\n", dispc, mesg,
154 nameof(mp), hl.l_date, wcount, subjline);
155 else
156 printf("%c%3d %-8s %16.16s %s\n", dispc, mesg,
157 nameof(mp), hl.l_date, wcount);
158}
159
160/*
161 * Print out the value of dot.
162 */
163
164pdot()
165{
166 printf("%d\n", dot - &message[0] + 1);
167 return(0);
168}
169
170/*
171 * Print out all the possible commands.
172 */
173
174pcmdlist()
175{
176 register struct cmd *cp;
177 register int cc;
178 extern struct cmd cmdtab[];
179
180 printf("Commands are:\n");
181 for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
182 cc += strlen(cp->c_name) + 2;
183 if (cc > 72) {
184 printf("\n");
185 cc = strlen(cp->c_name) + 2;
186 }
187 if ((cp+1)->c_name != NOSTR)
188 printf("%s, ", cp->c_name);
189 else
190 printf("%s\n", cp->c_name);
191 }
192 return(0);
193}
194
195/*
196 * Type out the messages requested.
197 */
198
199type(msgvec)
200 int *msgvec;
201{
202 register *ip;
203 register struct message *mp;
204 register int mesg;
205 int c;
206 FILE *ibuf;
207
208 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
209 mesg = *ip;
210 touch(mesg);
211 mp = &message[mesg-1];
212 dot = mp;
213 print(mp);
214 }
215 return(0);
216}
217
218/*
219 * Print the indicated message on standard output.
220 */
221
222print(mp)
223 register struct message *mp;
224{
225
226 if (value("quiet") == NOSTR)
227 printf("Message %2d:\n", mp - &message[0] + 1);
228 touch(mp - &message[0] + 1);
229 send(mp, stdout);
230}
231
232/*
233 * Print the top so many lines of each desired message.
234 * The number of lines is taken from the variable "toplines"
235 * and defaults to 5.
236 */
237
238top(msgvec)
239 int *msgvec;
240{
241 register int *ip;
242 register struct message *mp;
243 register int mesg;
244 int c, topl, lines, lineb;
245 char *valtop, linebuf[LINESIZE];
246 FILE *ibuf;
247
248 topl = 5;
249 valtop = value("toplines");
250 if (valtop != NOSTR) {
251 topl = atoi(valtop);
252 if (topl < 0 || topl > 10000)
253 topl = 5;
254 }
255 lineb = 1;
256 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
257 mesg = *ip;
258 touch(mesg);
259 mp = &message[mesg-1];
260 dot = mp;
261 if (value("quiet") == NOSTR)
262 printf("Message %2d:\n", mesg);
263 ibuf = setinput(mp);
264 c = mp->m_lines;
265 if (!lineb)
266 printf("\n");
267 for (lines = 0; lines < c && lines <= topl; lines++) {
268 if (readline(ibuf, linebuf) <= 0)
269 break;
270 puts(linebuf);
271 lineb = blankline(linebuf);
272 }
273 }
274 return(0);
275}
276
277/*
278 * Touch all the given messages so that they will
279 * get mboxed.
280 */
281
282stouch(msgvec)
283 int msgvec[];
284{
285 register int *ip;
286
287 for (ip = msgvec; *ip != 0; ip++) {
288 touch(*ip);
289 dot = &message[*ip-1];
290 dot->m_flag &= ~MPRESERVE;
291 }
292 return(0);
293}