|
|
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: signal(SIGPIPE, brokpipe);
347: longjmp(pipestop, 1);
348: }
349:
350: /*
351: * Print the indicated message on standard output.
352: */
353:
354: print(mp, obuf, doign)
355: register struct message *mp;
356: FILE *obuf;
357: {
358:
359: if (value("quiet") == NOSTR)
360: fprintf(obuf, "Message %2d:\n", mp - &message[0] + 1);
361: touch(mp - &message[0] + 1);
362: send(mp, obuf, doign);
363: }
364:
365: /*
366: * Print the top so many lines of each desired message.
367: * The number of lines is taken from the variable "toplines"
368: * and defaults to 5.
369: */
370:
371: top(msgvec)
372: int *msgvec;
373: {
374: register int *ip;
375: register struct message *mp;
376: register int mesg;
377: int c, topl, lines, lineb;
378: char *valtop, linebuf[LINESIZE];
379: FILE *ibuf;
380:
381: topl = 5;
382: valtop = value("toplines");
383: if (valtop != NOSTR) {
384: topl = atoi(valtop);
385: if (topl < 0 || topl > 10000)
386: topl = 5;
387: }
388: lineb = 1;
389: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
390: mesg = *ip;
391: touch(mesg);
392: mp = &message[mesg-1];
393: dot = mp;
394: if (value("quiet") == NOSTR)
395: printf("Message %2d:\n", mesg);
396: ibuf = setinput(mp);
397: c = mp->m_lines;
398: if (!lineb)
399: printf("\n");
400: for (lines = 0; lines < c && lines <= topl; lines++) {
401: if (readline(ibuf, linebuf) <= 0)
402: break;
403: puts(linebuf);
404: lineb = blankline(linebuf);
405: }
406: }
407: return(0);
408: }
409:
410: /*
411: * Touch all the given messages so that they will
412: * get mboxed.
413: */
414:
415: stouch(msgvec)
416: int msgvec[];
417: {
418: register int *ip;
419:
420: for (ip = msgvec; *ip != 0; ip++) {
421: dot = &message[*ip-1];
422: dot->m_flag |= MTOUCH;
423: dot->m_flag &= ~MPRESERVE;
424: }
425: return(0);
426: }
427:
428: /*
429: * Make sure all passed messages get mboxed.
430: */
431:
432: mboxit(msgvec)
433: int msgvec[];
434: {
435: register int *ip;
436:
437: for (ip = msgvec; *ip != 0; ip++) {
438: dot = &message[*ip-1];
439: dot->m_flag |= MTOUCH|MBOX;
440: dot->m_flag &= ~MPRESERVE;
441: }
442: return(0);
443: }
444:
445: /*
446: * List the folders the user currently has.
447: */
448: folders()
449: {
450: char dirname[BUFSIZ], cmd[BUFSIZ];
451: int pid, s, e;
452:
453: if (getfold(dirname) < 0) {
454: printf("No value set for \"folder\"\n");
455: return(-1);
456: }
457: switch ((pid = fork())) {
458: case 0:
459: sigchild();
460: execlp("ls", "ls", dirname, 0);
461: clrbuf(stdout);
462: exit(1);
463:
464: case -1:
465: perror("fork");
466: return(-1);
467:
468: default:
469: while ((e = wait(&s)) != -1 && e != pid)
470: ;
471: }
472: return(0);
473: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.