|
|
1.1 root 1: #
2:
3: #include "rcv.h"
4: #include <sys/stat.h>
5:
6: /*
7: * Mail -- a mail program
8: *
9: * More user commands.
10: */
11:
12: /*
13: * If any arguments were given, go to the next applicable argument
14: * following dot, otherwise, go to the next applicable message.
15: * If given as first command with no arguments, print first message.
16: */
17:
18: next(msgvec)
19: int *msgvec;
20: {
21: register struct message *mp;
22: register int *ip, *ip2;
23: int list[2], mdot;
24:
25: if (*msgvec != NULL) {
26:
27: /*
28: * If some messages were supplied, find the
29: * first applicable one following dot using
30: * wrap around.
31: */
32:
33: mdot = dot - &message[0] + 1;
34: for (ip = msgvec; *ip != NULL; ip++)
35: if (*ip > mdot)
36: break;
37: if (*ip == NULL)
38: ip = msgvec;
39: ip2 = ip;
40: do {
41: if (*ip2 != NULL)
42: ip2++;
43: if (*ip2 == NULL)
44: ip2 = msgvec;
45: mp = &message[*ip2 - 1];
46: if ((mp->m_flag & (MDELETED|MSAVED)) == 0) {
47: dot = mp;
48: goto hitit;
49: }
50: } while (ip2 != ip);
51: printf("No messages applicable\n");
52: return(1);
53: }
54:
55: /*
56: * If this is the first command, select message 1.
57: * Note that this must exist for us to get here at all.
58: */
59:
60: if (!sawcom) {
61: dot = &message[0];
62: goto hitit;
63: }
64:
65: /*
66: * Just find the next good message after dot, no
67: * wraparound.
68: */
69:
70: for (mp = dot+1; mp < &message[msgCount]; mp++)
71: if ((mp->m_flag & (MDELETED|MSAVED)) == 0)
72: break;
73: if (mp >= &message[msgCount]) {
74: printf("At EOF\n");
75: return(0);
76: }
77: dot = mp;
78: hitit:
79: /*
80: * Print dot.
81: */
82:
83: list[0] = dot - &message[0] + 1;
84: list[1] = NULL;
85: return(type(list));
86: }
87:
88: /*
89: * Save the indicated messages at the end of the passed file name.
90: */
91:
92: save(str)
93: char str[];
94: {
95: register int *ip, mesg;
96: register struct message *mp;
97: char *file;
98: int f, *msgvec, lc, cc, t;
99: FILE *obuf;
100:
101: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
102: if ((file = snarf(str, &f)) == NOSTR)
103: return(1);
104: if (!f) {
105: *msgvec = first(0, MMNORM);
106: if (*msgvec == NULL) {
107: printf("No messages to save.\n");
108: return(1);
109: }
110: msgvec[1] = NULL;
111: }
112: if (f && getmsglist(str, msgvec, 0) < 0)
113: return(1);
114: if ((file = expand(file)) == NOSTR)
115: return(1);
116: printf("\"%s\" ", file);
117: flush();
118: if ((obuf = fopen(file, "a")) == NULL) {
119: perror(NOSTR);
120: return(1);
121: }
122: cc = lc = 0;
123: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
124: mesg = *ip;
125: touch(mesg);
126: mp = &message[mesg-1];
127: if ((t = send(mp, obuf)) < 0) {
128: perror(file);
129: fclose(obuf);
130: return(1);
131: }
132: lc += t;
133: cc += msize(mp);
134: mp->m_flag |= MSAVED;
135: }
136: fflush(obuf);
137: if (ferror(obuf))
138: perror(file);
139: fclose(obuf);
140: printf("%d/%d\n", lc, cc);
141: return(0);
142: }
143:
144: /*
145: * Write the indicated messages at the end of the passed
146: * file name, minus header and trailing blank line.
147: */
148:
149: swrite(str)
150: char str[];
151: {
152: register int *ip, mesg;
153: register struct message *mp;
154: register char *file;
155: char linebuf[BUFSIZ];
156: int f, *msgvec, lc, cc, t;
157: FILE *obuf, *mesf;
158:
159: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
160: if ((file = snarf(str, &f)) == NOSTR)
161: return(1);
162: if ((file = expand(file)) == NOSTR)
163: return(1);
164: if (!f) {
165: *msgvec = first(0, MMNORM);
166: if (*msgvec == NULL) {
167: printf("No messages to write.\n");
168: return(1);
169: }
170: msgvec[1] = NULL;
171: }
172: if (f && getmsglist(str, msgvec, 0) < 0)
173: return(1);
174: printf("\"%s\" ", file);
175: flush();
176: if ((obuf = fopen(file, "a")) == NULL) {
177: perror(NOSTR);
178: return(1);
179: }
180: cc = lc = 0;
181: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
182: mesg = *ip;
183: touch(mesg);
184: mp = &message[mesg-1];
185: mesf = setinput(mp);
186: t = mp->m_lines - 2;
187: readline(mesf, linebuf);
188: while (t-- > 0) {
189: fgets(linebuf, BUFSIZ, mesf);
190: fputs(linebuf, obuf);
191: cc += strlen(linebuf);
192: }
193: lc += mp->m_lines - 2;
194: mp->m_flag |= MSAVED;
195: }
196: fflush(obuf);
197: if (ferror(obuf))
198: perror(file);
199: fclose(obuf);
200: printf("%d/%d\n", lc, cc);
201: return(0);
202: }
203:
204: /*
205: * Snarf the file from the end of the command line and
206: * return a pointer to it. If there is no file attached,
207: * just return NOSTR. Put a null in front of the file
208: * name so that the message list processing won't see it,
209: * unless the file name is the only thing on the line, in
210: * which case, return 0 in the reference flag variable.
211: */
212:
213: char *
214: snarf(linebuf, flag)
215: char linebuf[];
216: int *flag;
217: {
218: register char *cp;
219:
220: *flag = 1;
221: cp = strlen(linebuf) + linebuf - 1;
222:
223: /*
224: * Strip away trailing blanks.
225: */
226:
227: while (*cp == ' ' && cp > linebuf)
228: cp--;
229: *++cp = 0;
230:
231: /*
232: * Now search for the beginning of the file name.
233: */
234:
235: while (cp > linebuf && !any(*cp, "\t "))
236: cp--;
237: if (*cp == '\0') {
238: printf("No file specified.\n");
239: return(NOSTR);
240: }
241: if (any(*cp, " \t"))
242: *cp++ = 0;
243: else
244: *flag = 0;
245: return(cp);
246: }
247:
248: /*
249: * Delete messages.
250: */
251:
252: delete(msgvec)
253: int msgvec[];
254: {
255: return(delm(msgvec));
256: }
257:
258: /*
259: * Delete messages, then type the new dot.
260: */
261:
262: deltype(msgvec)
263: int msgvec[];
264: {
265: int list[2];
266:
267: if (delm(msgvec) >= 0) {
268: list[0] = dot - &message[0];
269: list[0]++;
270: touch(list[0]);
271: list[1] = NULL;
272: return(type(list));
273: }
274: else {
275: printf("No more messages\n");
276: return(0);
277: }
278: }
279:
280: /*
281: * Delete the indicated messages.
282: * Set dot to some nice place afterwards.
283: * Internal interface.
284: */
285:
286: delm(msgvec)
287: int *msgvec;
288: {
289: register struct message *mp;
290: register *ip, mesg;
291: int last;
292:
293: last = NULL;
294: for (ip = msgvec; *ip != NULL; ip++) {
295: mesg = *ip;
296: touch(mesg);
297: mp = &message[mesg-1];
298: mp->m_flag |= MDELETED;
299: mp->m_flag &= ~(MPRESERVE|MSAVED);
300: last = mesg;
301: }
302: if (last != NULL) {
303: dot = &message[last-1];
304: last = first(0, MDELETED);
305: if (last != NULL) {
306: dot = &message[last-1];
307: return(0);
308: }
309: else {
310: dot = &message[0];
311: return(-1);
312: }
313: }
314:
315: /*
316: * Following can't happen -- it keeps lint happy
317: */
318:
319: return(-1);
320: }
321:
322: /*
323: * Undelete the indicated messages.
324: */
325:
326: undelete(msgvec)
327: int *msgvec;
328: {
329: register struct message *mp;
330: register *ip, mesg;
331:
332: for (ip = msgvec; ip-msgvec < msgCount; ip++) {
333: mesg = *ip;
334: if (mesg == 0)
335: return;
336: touch(mesg);
337: mp = &message[mesg-1];
338: dot = mp;
339: mp->m_flag &= ~MDELETED;
340: }
341: }
342:
343: /*
344: * Interactively dump core on "core"
345: */
346:
347: core()
348: {
349: register int pid;
350: int status;
351:
352: if ((pid = vfork()) == -1) {
353: perror("fork");
354: return(1);
355: }
356: if (pid == 0) {
357: abort();
358: _exit(1);
359: }
360: printf("Okie dokie");
361: fflush(stdout);
362: while (wait(&status) != pid)
363: ;
364: if (status & 0200)
365: printf(" -- Core dumped\n");
366: else
367: printf("\n");
368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.