|
|
1.1 root 1: /*-
2: * Copyright (c) 1980 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)cmd1.c 5.21 (Berkeley) 6/25/90";
22: #endif /* not lint */
23:
24: #include "rcv.h"
25:
26: /*
27: * Mail -- a mail program
28: *
29: * User commands.
30: */
31:
32: /*
33: * Print the current active headings.
34: * Don't change dot if invoker didn't give an argument.
35: */
36:
37: static int screen;
38:
39: headers(msgvec)
40: int *msgvec;
41: {
42: register int n, mesg, flag;
43: register struct message *mp;
44: int size;
45:
46: size = screensize();
47: n = msgvec[0];
48: if (n != 0)
49: screen = (n-1)/size;
50: if (screen < 0)
51: screen = 0;
52: mp = &message[screen * size];
53: if (mp >= &message[msgCount])
54: mp = &message[msgCount - size];
55: if (mp < &message[0])
56: mp = &message[0];
57: flag = 0;
58: mesg = mp - &message[0];
59: if (dot != &message[n-1])
60: dot = mp;
61: for (; mp < &message[msgCount]; mp++) {
62: mesg++;
63: if (mp->m_flag & MDELETED)
64: continue;
65: if (flag++ >= size)
66: break;
67: printhead(mesg);
68: }
69: if (flag == 0) {
70: printf("No more mail.\n");
71: return(1);
72: }
73: return(0);
74: }
75:
76: /*
77: * Scroll to the next/previous screen
78: */
79: scroll(arg)
80: char arg[];
81: {
82: register int s, size;
83: int cur[1];
84:
85: cur[0] = 0;
86: size = screensize();
87: s = screen;
88: switch (*arg) {
89: case 0:
90: case '+':
91: s++;
92: if (s * size > msgCount) {
93: printf("On last screenful of messages\n");
94: return(0);
95: }
96: screen = s;
97: break;
98:
99: case '-':
100: if (--s < 0) {
101: printf("On first screenful of messages\n");
102: return(0);
103: }
104: screen = s;
105: break;
106:
107: default:
108: printf("Unrecognized scrolling command \"%s\"\n", arg);
109: return(1);
110: }
111: return(headers(cur));
112: }
113:
114: /*
115: * Compute screen size.
116: */
117: screensize()
118: {
119: int s;
120: char *cp;
121:
122: if ((cp = value("screen")) != NOSTR && (s = atoi(cp)) > 0)
123: return s;
124: return screenheight - 4;
125: }
126:
127: /*
128: * Print out the headlines for each message
129: * in the passed message list.
130: */
131:
132: from(msgvec)
133: int *msgvec;
134: {
135: register int *ip;
136:
137: for (ip = msgvec; *ip != NULL; ip++)
138: printhead(*ip);
139: if (--ip >= msgvec)
140: dot = &message[*ip - 1];
141: return(0);
142: }
143:
144: /*
145: * Print out the header of a specific message.
146: * This is a slight improvement to the standard one.
147: */
148:
149: printhead(mesg)
150: {
151: struct message *mp;
152: char headline[LINESIZE], wcount[LINESIZE], *subjline, dispc, curind;
153: char pbuf[BUFSIZ];
154: struct headline hl;
155: int subjlen;
156: char *name;
157:
158: mp = &message[mesg-1];
159: (void) readline(setinput(mp), headline, LINESIZE);
160: if ((subjline = hfield("subject", mp)) == NOSTR)
161: subjline = hfield("subj", mp);
162: /*
163: * Bletch!
164: */
165: curind = dot == mp ? '>' : ' ';
166: dispc = ' ';
167: if (mp->m_flag & MSAVED)
168: dispc = '*';
169: if (mp->m_flag & MPRESERVE)
170: dispc = 'P';
171: if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
172: dispc = 'N';
173: if ((mp->m_flag & (MREAD|MNEW)) == 0)
174: dispc = 'U';
175: if (mp->m_flag & MBOX)
176: dispc = 'M';
177: parse(headline, &hl, pbuf);
178: sprintf(wcount, "%3d/%-5ld", mp->m_lines, mp->m_size);
179: subjlen = screenwidth - 50 - strlen(wcount);
180: name = value("show-rcpt") != NOSTR ?
181: skin(hfield("to", mp)) : nameof(mp, 0);
182: if (subjline == NOSTR || subjlen < 0) /* pretty pathetic */
183: printf("%c%c%3d %-20.20s %16.16s %s\n",
184: curind, dispc, mesg, name, hl.l_date, wcount);
185: else
186: printf("%c%c%3d %-20.20s %16.16s %s \"%.*s\"\n",
187: curind, dispc, mesg, name, hl.l_date, wcount,
188: subjlen, subjline);
189: }
190:
191: /*
192: * Print out the value of dot.
193: */
194:
195: pdot()
196: {
197: printf("%d\n", dot - &message[0] + 1);
198: return(0);
199: }
200:
201: /*
202: * Print out all the possible commands.
203: */
204:
205: pcmdlist()
206: {
207: register struct cmd *cp;
208: register int cc;
209: extern struct cmd cmdtab[];
210:
211: printf("Commands are:\n");
212: for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
213: cc += strlen(cp->c_name) + 2;
214: if (cc > 72) {
215: printf("\n");
216: cc = strlen(cp->c_name) + 2;
217: }
218: if ((cp+1)->c_name != NOSTR)
219: printf("%s, ", cp->c_name);
220: else
221: printf("%s\n", cp->c_name);
222: }
223: return(0);
224: }
225:
226: /*
227: * Paginate messages, honor ignored fields.
228: */
229: more(msgvec)
230: int *msgvec;
231: {
232: return (type1(msgvec, 1, 1));
233: }
234:
235: /*
236: * Paginate messages, even printing ignored fields.
237: */
238: More(msgvec)
239: int *msgvec;
240: {
241:
242: return (type1(msgvec, 0, 1));
243: }
244:
245: /*
246: * Type out messages, honor ignored fields.
247: */
248: type(msgvec)
249: int *msgvec;
250: {
251:
252: return(type1(msgvec, 1, 0));
253: }
254:
255: /*
256: * Type out messages, even printing ignored fields.
257: */
258: Type(msgvec)
259: int *msgvec;
260: {
261:
262: return(type1(msgvec, 0, 0));
263: }
264:
265: /*
266: * Type out the messages requested.
267: */
268: jmp_buf pipestop;
269:
270: type1(msgvec, doign, page)
271: int *msgvec;
272: {
273: register *ip;
274: register struct message *mp;
275: register char *cp;
276: int nlines;
277: int brokpipe();
278: FILE *obuf;
279:
280: obuf = stdout;
281: if (setjmp(pipestop))
282: goto close_pipe;
283: if (value("interactive") != NOSTR &&
284: (page || (cp = value("crt")) != NOSTR)) {
285: nlines = 0;
286: if (!page) {
287: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++)
288: nlines += message[*ip - 1].m_lines;
289: }
290: if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) {
291: cp = value("PAGER");
292: if (cp == NULL || *cp == '\0')
293: cp = _PATH_MORE;
294: obuf = Popen(cp, "w");
295: if (obuf == NULL) {
296: perror(cp);
297: obuf = stdout;
298: } else
299: signal(SIGPIPE, brokpipe);
300: }
301: }
302: for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) {
303: mp = &message[*ip - 1];
304: touch(mp);
305: dot = mp;
306: if (value("quiet") == NOSTR)
307: fprintf(obuf, "Message %d:\n", *ip);
308: (void) send(mp, obuf, doign ? ignore : 0, NOSTR);
309: }
310: close_pipe:
311: if (obuf != stdout) {
312: /*
313: * Ignore SIGPIPE so it can't cause a duplicate close.
314: */
315: signal(SIGPIPE, SIG_IGN);
316: Pclose(obuf);
317: signal(SIGPIPE, SIG_DFL);
318: }
319: return(0);
320: }
321:
322: /*
323: * Respond to a broken pipe signal --
324: * probably caused by quitting more.
325: */
326:
327: brokpipe()
328: {
329: longjmp(pipestop, 1);
330: }
331:
332: /*
333: * Print the top so many lines of each desired message.
334: * The number of lines is taken from the variable "toplines"
335: * and defaults to 5.
336: */
337:
338: top(msgvec)
339: int *msgvec;
340: {
341: register int *ip;
342: register struct message *mp;
343: int c, topl, lines, lineb;
344: char *valtop, linebuf[LINESIZE];
345: FILE *ibuf;
346:
347: topl = 5;
348: valtop = value("toplines");
349: if (valtop != NOSTR) {
350: topl = atoi(valtop);
351: if (topl < 0 || topl > 10000)
352: topl = 5;
353: }
354: lineb = 1;
355: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
356: mp = &message[*ip - 1];
357: touch(mp);
358: dot = mp;
359: if (value("quiet") == NOSTR)
360: printf("Message %d:\n", *ip);
361: ibuf = setinput(mp);
362: c = mp->m_lines;
363: if (!lineb)
364: printf("\n");
365: for (lines = 0; lines < c && lines <= topl; lines++) {
366: if (readline(ibuf, linebuf, LINESIZE) < 0)
367: break;
368: puts(linebuf);
369: lineb = blankline(linebuf);
370: }
371: }
372: return(0);
373: }
374:
375: /*
376: * Touch all the given messages so that they will
377: * get mboxed.
378: */
379: stouch(msgvec)
380: int msgvec[];
381: {
382: register int *ip;
383:
384: for (ip = msgvec; *ip != 0; ip++) {
385: dot = &message[*ip-1];
386: dot->m_flag |= MTOUCH;
387: dot->m_flag &= ~MPRESERVE;
388: }
389: return(0);
390: }
391:
392: /*
393: * Make sure all passed messages get mboxed.
394: */
395:
396: mboxit(msgvec)
397: int msgvec[];
398: {
399: register int *ip;
400:
401: for (ip = msgvec; *ip != 0; ip++) {
402: dot = &message[*ip-1];
403: dot->m_flag |= MTOUCH|MBOX;
404: dot->m_flag &= ~MPRESERVE;
405: }
406: return(0);
407: }
408:
409: /*
410: * List the folders the user currently has.
411: */
412: folders()
413: {
414: char dirname[BUFSIZ];
415: char *cmd;
416:
417: if (getfold(dirname) < 0) {
418: printf("No value set for \"folder\"\n");
419: return 1;
420: }
421: if ((cmd = value("LISTER")) == NOSTR)
422: cmd = "ls";
423: (void) run_command(cmd, 0, -1, -1, dirname, NOSTR);
424: return 0;
425: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.