|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)cmd1.c 2.12 (Berkeley) 8/11/83";
3: #endif
4:
5: #include "rcv.h"
6: #include <sys/stat.h>
7:
8: /*
9: * Mail -- a mail program
10: *
11: * User commands.
12: */
13:
14: /*
15: * Print the current active headings.
16: * Don't change dot if invoker didn't give an argument.
17: */
18:
19: static int screen;
20:
21: headers(msgvec)
22: int *msgvec;
23: {
24: register int n, mesg, flag;
25: register struct message *mp;
26: int size;
27:
28: size = screensize();
29: n = msgvec[0];
30: if (n != 0)
31: screen = (n-1)/size;
32: if (screen < 0)
33: screen = 0;
34: mp = &message[screen * size];
35: if (mp >= &message[msgCount])
36: mp = &message[msgCount - size];
37: if (mp < &message[0])
38: mp = &message[0];
39: flag = 0;
40: mesg = mp - &message[0];
41: if (dot != &message[n-1])
42: dot = mp;
43: for (; mp < &message[msgCount]; mp++) {
44: mesg++;
45: if (mp->m_flag & MDELETED)
46: continue;
47: if (flag++ >= size)
48: break;
49: printhead(mesg);
50: sreset();
51: }
52: if (flag == 0) {
53: printf("No more mail.\n");
54: return(1);
55: }
56: return(0);
57: }
58:
59: /*
60: * Set the list of alternate names for out host.
61: */
62: local(namelist)
63: char **namelist;
64: {
65: register int c;
66: register char **ap, **ap2, *cp;
67:
68: c = argcount(namelist) + 1;
69: if (c == 1) {
70: if (localnames == 0)
71: return(0);
72: for (ap = localnames; *ap; ap++)
73: printf("%s ", *ap);
74: printf("\n");
75: return(0);
76: }
77: if (localnames != 0)
78: cfree((char *) localnames);
79: localnames = (char **) calloc(c, sizeof (char *));
80: for (ap = namelist, ap2 = localnames; *ap; ap++, ap2++) {
81: cp = (char *) calloc(strlen(*ap) + 1, sizeof (char));
82: strcpy(cp, *ap);
83: *ap2 = cp;
84: }
85: *ap2 = 0;
86: return(0);
87: }
88:
89: /*
90: * Scroll to the next/previous screen
91: */
92:
93: scroll(arg)
94: char arg[];
95: {
96: register int s, size;
97: int cur[1];
98:
99: cur[0] = 0;
100: size = screensize();
101: s = screen;
102: switch (*arg) {
103: case 0:
104: case '+':
105: s++;
106: if (s * size > msgCount) {
107: printf("On last screenful of messages\n");
108: return(0);
109: }
110: screen = s;
111: break;
112:
113: case '-':
114: if (--s < 0) {
115: printf("On first screenful of messages\n");
116: return(0);
117: }
118: screen = s;
119: break;
120:
121: default:
122: printf("Unrecognized scrolling command \"%s\"\n", arg);
123: return(1);
124: }
125: return(headers(cur));
126: }
127:
128: /*
129: * Compute what the screen size should be.
130: * We use the following algorithm:
131: * If user specifies with screen option, use that.
132: * If baud rate < 1200, use 5
133: * If baud rate = 1200, use 10
134: * If baud rate > 1200, use 20
135: */
136: screensize()
137: {
138: register char *cp;
139: register int s;
140:
141: if ((cp = value("screen")) != NOSTR) {
142: s = atoi(cp);
143: if (s > 0)
144: return(s);
145: }
146: if (baud < B1200)
147: s = 5;
148: else if (baud == B1200)
149: s = 10;
150: else
151: s = 20;
152: return(s);
153: }
154:
155: /*
156: * Print out the headlines for each message
157: * in the passed message list.
158: */
159:
160: from(msgvec)
161: int *msgvec;
162: {
163: register int *ip;
164:
165: for (ip = msgvec; *ip != NULL; ip++) {
166: printhead(*ip);
167: sreset();
168: }
169: if (--ip >= msgvec)
170: dot = &message[*ip - 1];
171: return(0);
172: }
173:
174: /*
175: * Print out the header of a specific message.
176: * This is a slight improvement to the standard one.
177: */
178:
179: printhead(mesg)
180: {
181: struct message *mp;
182: FILE *ibuf;
183: char headline[LINESIZE], wcount[10], *subjline, dispc, curind;
184: char pbuf[BUFSIZ];
185: int s;
186: struct headline hl;
187: register char *cp;
188:
189: mp = &message[mesg-1];
190: ibuf = setinput(mp);
191: readline(ibuf, headline);
192: subjline = hfield("subject", mp);
193: if (subjline == NOSTR)
194: subjline = hfield("subj", mp);
195:
196: /*
197: * Bletch!
198: */
199:
200: if (subjline != NOSTR && strlen(subjline) > 28)
201: subjline[29] = '\0';
202: curind = dot == mp ? '>' : ' ';
203: dispc = ' ';
204: if (mp->m_flag & MSAVED)
205: dispc = '*';
206: if (mp->m_flag & MPRESERVE)
207: dispc = 'P';
208: if ((mp->m_flag & (MREAD|MNEW)) == MNEW)
209: dispc = 'N';
210: if ((mp->m_flag & (MREAD|MNEW)) == 0)
211: dispc = 'U';
212: if (mp->m_flag & MBOX)
213: dispc = 'M';
214: parse(headline, &hl, pbuf);
215: sprintf(wcount, " %d/%ld", mp->m_lines, mp->m_size);
216: s = strlen(wcount);
217: cp = wcount + s;
218: while (s < 7)
219: s++, *cp++ = ' ';
220: *cp = '\0';
221: if (subjline != NOSTR)
222: printf("%c%c%3d %-8s %16.16s %s \"%s\"\n", curind, dispc, mesg,
223: nameof(mp, 0), hl.l_date, wcount, subjline);
224: else
225: printf("%c%c%3d %-8s %16.16s %s\n", curind, dispc, mesg,
226: nameof(mp, 0), hl.l_date, wcount);
227: }
228:
229: /*
230: * Print out the value of dot.
231: */
232:
233: pdot()
234: {
235: printf("%d\n", dot - &message[0] + 1);
236: return(0);
237: }
238:
239: /*
240: * Print out all the possible commands.
241: */
242:
243: pcmdlist()
244: {
245: register struct cmd *cp;
246: register int cc;
247: extern struct cmd cmdtab[];
248:
249: printf("Commands are:\n");
250: for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) {
251: cc += strlen(cp->c_name) + 2;
252: if (cc > 72) {
253: printf("\n");
254: cc = strlen(cp->c_name) + 2;
255: }
256: if ((cp+1)->c_name != NOSTR)
257: printf("%s, ", cp->c_name);
258: else
259: printf("%s\n", cp->c_name);
260: }
261: return(0);
262: }
263:
264: /*
265: * Type out messages, honor ignored fields.
266: */
267: type(msgvec)
268: int *msgvec;
269: {
270:
271: return(type1(msgvec, 1));
272: }
273:
274: /*
275: * Type out messages, even printing ignored fields.
276: */
277: Type(msgvec)
278: int *msgvec;
279: {
280:
281: return(type1(msgvec, 0));
282: }
283:
284: /*
285: * Type out the messages requested.
286: */
287: jmp_buf pipestop;
288:
289: type1(msgvec, doign)
290: int *msgvec;
291: {
292: register *ip;
293: register struct message *mp;
294: register int mesg;
295: register char *cp;
296: int c, nlines;
297: int brokpipe();
298: FILE *ibuf, *obuf;
299:
300: obuf = stdout;
301: if (setjmp(pipestop)) {
302: if (obuf != stdout) {
303: pipef = NULL;
304: pclose(obuf);
305: }
306: sigset(SIGPIPE, SIG_DFL);
307: return(0);
308: }
309: if (intty && outtty && (cp = value("crt")) != NOSTR) {
310: for (ip = msgvec, nlines = 0; *ip && ip-msgvec < msgCount; ip++)
311: nlines += message[*ip - 1].m_lines;
312: if (nlines > atoi(cp)) {
313: obuf = popen(MORE, "w");
314: if (obuf == NULL) {
315: perror(MORE);
316: obuf = stdout;
317: }
318: else {
319: pipef = obuf;
320: sigset(SIGPIPE, brokpipe);
321: }
322: }
323: }
324: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
325: mesg = *ip;
326: touch(mesg);
327: mp = &message[mesg-1];
328: dot = mp;
329: print(mp, obuf, doign);
330: }
331: if (obuf != stdout) {
332: pipef = NULL;
333: pclose(obuf);
334: }
335: sigset(SIGPIPE, SIG_DFL);
336: return(0);
337: }
338:
339: /*
340: * Respond to a broken pipe signal --
341: * probably caused by using quitting more.
342: */
343:
344: brokpipe()
345: {
346: # ifndef VMUNIX
347: signal(SIGPIPE, brokpipe);
348: # endif
349: longjmp(pipestop, 1);
350: }
351:
352: /*
353: * Print the indicated message on standard output.
354: */
355:
356: print(mp, obuf, doign)
357: register struct message *mp;
358: FILE *obuf;
359: {
360:
361: if (value("quiet") == NOSTR)
362: fprintf(obuf, "Message %2d:\n", mp - &message[0] + 1);
363: touch(mp - &message[0] + 1);
364: send(mp, obuf, doign);
365: }
366:
367: /*
368: * Print the top so many lines of each desired message.
369: * The number of lines is taken from the variable "toplines"
370: * and defaults to 5.
371: */
372:
373: top(msgvec)
374: int *msgvec;
375: {
376: register int *ip;
377: register struct message *mp;
378: register int mesg;
379: int c, topl, lines, lineb;
380: char *valtop, linebuf[LINESIZE];
381: FILE *ibuf;
382:
383: topl = 5;
384: valtop = value("toplines");
385: if (valtop != NOSTR) {
386: topl = atoi(valtop);
387: if (topl < 0 || topl > 10000)
388: topl = 5;
389: }
390: lineb = 1;
391: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
392: mesg = *ip;
393: touch(mesg);
394: mp = &message[mesg-1];
395: dot = mp;
396: if (value("quiet") == NOSTR)
397: printf("Message %2d:\n", mesg);
398: ibuf = setinput(mp);
399: c = mp->m_lines;
400: if (!lineb)
401: printf("\n");
402: for (lines = 0; lines < c && lines <= topl; lines++) {
403: if (readline(ibuf, linebuf) <= 0)
404: break;
405: puts(linebuf);
406: lineb = blankline(linebuf);
407: }
408: }
409: return(0);
410: }
411:
412: /*
413: * Touch all the given messages so that they will
414: * get mboxed.
415: */
416:
417: stouch(msgvec)
418: int msgvec[];
419: {
420: register int *ip;
421:
422: for (ip = msgvec; *ip != 0; ip++) {
423: dot = &message[*ip-1];
424: dot->m_flag |= MTOUCH;
425: dot->m_flag &= ~MPRESERVE;
426: }
427: return(0);
428: }
429:
430: /*
431: * Make sure all passed messages get mboxed.
432: */
433:
434: mboxit(msgvec)
435: int msgvec[];
436: {
437: register int *ip;
438:
439: for (ip = msgvec; *ip != 0; ip++) {
440: dot = &message[*ip-1];
441: dot->m_flag |= MTOUCH|MBOX;
442: dot->m_flag &= ~MPRESERVE;
443: }
444: return(0);
445: }
446:
447: /*
448: * List the folders the user currently has.
449: */
450: folders()
451: {
452: char dirname[BUFSIZ], cmd[BUFSIZ];
453: int pid, s, e;
454:
455: if (getfold(dirname) < 0) {
456: printf("No value set for \"folder\"\n");
457: return(-1);
458: }
459: switch ((pid = fork())) {
460: case 0:
461: sigchild();
462: execlp("ls", "ls", dirname, 0);
463: clrbuf(stdout);
464: exit(1);
465:
466: case -1:
467: perror("fork");
468: return(-1);
469:
470: default:
471: while ((e = wait(&s)) != -1 && e != pid)
472: ;
473: }
474: return(0);
475: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.