|
|
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) == 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, *disp;
98: int f, *msgvec, lc, cc, t;
99: FILE *obuf;
100: struct stat statb;
101:
102: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
103: if ((file = snarf(str, &f)) == NOSTR)
104: return(1);
105: if (!f) {
106: *msgvec = first(0, MMNORM);
107: if (*msgvec == NULL) {
108: printf("No messages to save.\n");
109: return(1);
110: }
111: msgvec[1] = NULL;
112: }
113: if (f && getmsglist(str, msgvec, 0) < 0)
114: return(1);
115: if ((file = expand(file)) == NOSTR)
116: return(1);
117: printf("\"%s\" ", file);
118: flush();
119: if (stat(file, &statb) >= 0)
120: disp = "[Appended]";
121: else
122: disp = "[New file]";
123: if ((obuf = fopen(file, "a")) == NULL) {
124: perror(NOSTR);
125: return(1);
126: }
127: cc = lc = 0;
128: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
129: mesg = *ip;
130: touch(mesg);
131: mp = &message[mesg-1];
132: if ((t = send(mp, obuf)) < 0) {
133: perror(file);
134: fclose(obuf);
135: return(1);
136: }
137: lc += t;
138: cc += msize(mp);
139: mp->m_flag |= MSAVED;
140: }
141: fflush(obuf);
142: if (ferror(obuf))
143: perror(file);
144: fclose(obuf);
145: printf("%s %d/%d\n", disp, lc, cc);
146: return(0);
147: }
148:
149: /*
150: * Write the indicated messages at the end of the passed
151: * file name, minus header and trailing blank line.
152: */
153:
154: swrite(str)
155: char str[];
156: {
157: register int *ip, mesg;
158: register struct message *mp;
159: register char *file, *disp;
160: char linebuf[BUFSIZ];
161: int f, *msgvec, lc, cc, t;
162: FILE *obuf, *mesf;
163: struct stat statb;
164:
165: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec);
166: if ((file = snarf(str, &f)) == NOSTR)
167: return(1);
168: if ((file = expand(file)) == NOSTR)
169: return(1);
170: if (!f) {
171: *msgvec = first(0, MMNORM);
172: if (*msgvec == NULL) {
173: printf("No messages to write.\n");
174: return(1);
175: }
176: msgvec[1] = NULL;
177: }
178: if (f && getmsglist(str, msgvec, 0) < 0)
179: return(1);
180: printf("\"%s\" ", file);
181: flush();
182: if (stat(file, &statb) >= 0)
183: disp = "[Appended]";
184: else
185: disp = "[New file]";
186: if ((obuf = fopen(file, "a")) == NULL) {
187: perror(NOSTR);
188: return(1);
189: }
190: cc = lc = 0;
191: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
192: mesg = *ip;
193: touch(mesg);
194: mp = &message[mesg-1];
195: mesf = setinput(mp);
196: t = mp->m_lines - 2;
197: readline(mesf, linebuf);
198: while (t-- > 0) {
199: fgets(linebuf, BUFSIZ, mesf);
200: fputs(linebuf, obuf);
201: cc += strlen(linebuf);
202: }
203: lc += mp->m_lines - 2;
204: mp->m_flag |= MSAVED;
205: }
206: fflush(obuf);
207: if (ferror(obuf))
208: perror(file);
209: fclose(obuf);
210: printf("%s %d/%d\n", disp, lc, cc);
211: return(0);
212: }
213:
214: /*
215: * Snarf the file from the end of the command line and
216: * return a pointer to it. If there is no file attached,
217: * just return NOSTR. Put a null in front of the file
218: * name so that the message list processing won't see it,
219: * unless the file name is the only thing on the line, in
220: * which case, return 0 in the reference flag variable.
221: */
222:
223: char *
224: snarf(linebuf, flag)
225: char linebuf[];
226: int *flag;
227: {
228: register char *cp;
229:
230: *flag = 1;
231: cp = strlen(linebuf) + linebuf - 1;
232:
233: /*
234: * Strip away trailing blanks.
235: */
236:
237: while (*cp == ' ' && cp > linebuf)
238: cp--;
239: *++cp = 0;
240:
241: /*
242: * Now search for the beginning of the file name.
243: */
244:
245: while (cp > linebuf && !any(*cp, "\t "))
246: cp--;
247: if (*cp == '\0') {
248: printf("No file specified.\n");
249: return(NOSTR);
250: }
251: if (any(*cp, " \t"))
252: *cp++ = 0;
253: else
254: *flag = 0;
255: return(cp);
256: }
257:
258: /*
259: * Delete messages.
260: */
261:
262: delete(msgvec)
263: int msgvec[];
264: {
265: return(delm(msgvec));
266: }
267:
268: /*
269: * Delete messages, then type the new dot.
270: */
271:
272: deltype(msgvec)
273: int msgvec[];
274: {
275: int list[2];
276:
277: if (delm(msgvec) >= 0) {
278: list[0] = dot - &message[0];
279: list[0]++;
280: touch(list[0]);
281: list[1] = NULL;
282: return(type(list));
283: }
284: else {
285: printf("No more messages\n");
286: return(0);
287: }
288: }
289:
290: /*
291: * Delete the indicated messages.
292: * Set dot to some nice place afterwards.
293: * Internal interface.
294: */
295:
296: delm(msgvec)
297: int *msgvec;
298: {
299: register struct message *mp;
300: register *ip, mesg;
301: int last;
302:
303: last = NULL;
304: for (ip = msgvec; *ip != NULL; ip++) {
305: mesg = *ip;
306: touch(mesg);
307: mp = &message[mesg-1];
308: mp->m_flag |= MDELETED;
309: mp->m_flag &= ~(MPRESERVE|MSAVED);
310: last = mesg;
311: }
312: if (last != NULL) {
313: dot = &message[last-1];
314: last = first(0, MDELETED);
315: if (last != NULL) {
316: dot = &message[last-1];
317: return(0);
318: }
319: else {
320: dot = &message[0];
321: return(-1);
322: }
323: }
324:
325: /*
326: * Following can't happen -- it keeps lint happy
327: */
328:
329: return(-1);
330: }
331:
332: /*
333: * Undelete the indicated messages.
334: */
335:
336: undelete(msgvec)
337: int *msgvec;
338: {
339: register struct message *mp;
340: register *ip, mesg;
341:
342: for (ip = msgvec; ip-msgvec < msgCount; ip++) {
343: mesg = *ip;
344: if (mesg == 0)
345: return;
346: touch(mesg);
347: mp = &message[mesg-1];
348: dot = mp;
349: mp->m_flag &= ~MDELETED;
350: }
351: }
352:
353: /*
354: * Interactively dump core on "core"
355: */
356:
357: core()
358: {
359: register int pid;
360: int status;
361:
362: if ((pid = vfork()) == -1) {
363: perror("fork");
364: return(1);
365: }
366: if (pid == 0) {
367: abort();
368: _exit(1);
369: }
370: printf("Okie dokie");
371: fflush(stdout);
372: while (wait(&status) != pid)
373: ;
374: if (status & 0200)
375: printf(" -- Core dumped\n");
376: else
377: printf("\n");
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.