]> diplodocus.org Git - nmh/blob - docs/historical/mh-nov-1983/cmds/forw.c
Removed --depth 1 from git clone invocation.
[nmh] / docs / historical / mh-nov-1983 / cmds / forw.c
1 #ifndef lint
2 static char sccsid[] = "@(#)forw.c 4.1 2/23/83";
3 #endif
4
5 #include "mh.h"
6 #include <stdio.h>
7 #include <signal.h>
8 #include <strings.h>
9
10 #define NONE 0
11 #define NOUSE 0
12
13 /* #define TEST 1 */
14
15 int *vec[MAXARGS];
16 struct msgs *mp;
17 char drft[128];
18 int inplace; /* preserve links in anno */
19
20 char *anyl[] = {
21 "no", 0,
22 "yes", 0,
23 "list", 0,
24 0,
25 };
26
27 char *anyv[] = {
28 "no", 0,
29 "yes", 0,
30 "verbose", 0,
31 0,
32 };
33
34 struct swit switches[] = {
35 "all", -3, /* 0 */
36 "annotate", 0, /* 1 */
37 "noannotate", 0, /* 2 */
38 "editor editor", 0, /* 3 */
39 "form formfile", 0, /* 4 */
40 "inplace", 0, /* 5 */
41 "noinplace", 0, /* 6 */
42 "help", 4, /* 7 */
43 0, 0
44 };
45
46 char *aleqs[] = {
47 "list", 0, /* 0 */
48 "edit [<editor>]", 0, /* 1 */
49 "quit [delete]", 0, /* 2 */
50 "send [verbose]", 0, /* 3 */
51 0
52 };
53
54
55 main(argc, argv)
56 char *argv[];
57 {
58 char *folder, *maildir, *msgs[100], *ed, *form;
59 register int msgnum;
60 register char *cp, **ap;
61 int msgp, status, anot;
62 int in, out, intr;
63 int pid, wpid, msgcnt;
64 char *arguments[50], **argp;
65 char numbuf[5];
66
67 #ifdef NEWS
68 m_news();
69 #endif
70 form = 0; anot = 0; folder = 0; msgp = 0; ed = 0;
71 cp = r1bindex(argv[0], '/');
72 if((cp = m_find(cp)) != NULL) {
73 ap = brkstring(cp = getcpy(cp), " ", "\n");
74 ap = copyip(ap, arguments);
75 } else
76 ap = arguments;
77 copyip(argv+1, ap);
78 argp = arguments;
79 while(cp = *argp++) {
80 if(*cp == '-')
81 switch(smatch(++cp, switches)) {
82 case -2:ambigsw(cp, switches); /* ambiguous */
83 goto leave;
84 /* unknown */
85 case -1:fprintf(stderr, "forw: -%s unknown\n", cp);
86 goto leave;
87 /* -all */
88 case 0: fprintf(stderr, "\"-all\" changed to \"all\"\n");
89 goto leave;
90 case 1: anot = 1; continue; /* -annotate */
91 case 2: anot = 0; continue; /* -noannotate */
92 case 3: if(!(ed = *argp++)) { /* -editor */
93 missing: fprintf(stderr, "forw: Missing argument for %s switch\n", argp[-2]);
94 goto leave;
95 }
96 continue;
97 case 4: if(!(form = *argp++)) /* -form */
98 goto missing;
99 continue;
100 case 5: inplace = 1; continue; /* -inplace */
101 case 6: inplace = 0; continue; /* -noinplace */
102 /* -help */
103 case 7: help("forw [+folder] [msgs] [switches]",
104 switches);
105 goto leave;
106 }
107 if(*cp == '+') {
108 if(folder) {
109 fprintf(stderr, "Only one folder at a time.\n");
110 goto leave;
111 } else
112 folder = cp + 1;
113 } else
114 msgs[msgp++] = cp;
115 }
116 if(!msgp)
117 msgs[msgp++] = "cur";
118 if(!folder)
119 folder = m_getfolder();
120 maildir = m_maildir(folder);
121 if(chdir(maildir) < 0) {
122 fprintf(stderr, "Can't chdir to: ");
123 perror(maildir);
124 goto leave;
125 }
126 if(!(mp = m_gmsg(folder))) {
127 fprintf(stderr, "Can't read folder!?\n");
128 goto leave;
129 }
130 if(mp->hghmsg == 0) {
131 fprintf(stderr, "No messages in \"%s\".\n", folder);
132 goto leave;
133 }
134 for(msgnum = 0; msgnum < msgp; msgnum++)
135 if(!m_convert(msgs[msgnum]))
136 goto leave;
137 if(mp->numsel == 0) {
138 fprintf(stderr, "forw: italian salami.\n"); /* never get here */
139 goto leave;
140 }
141 if(form) {
142 if((in = open(m_maildir(form), 0)) < 0) {
143 fprintf(stderr, "forw: Can't open form file: %s\n", form);
144 goto leave;
145 }
146 } else if((in = open(m_maildir(components), 0)) < 0 &&
147 (in = open(stdcomps, 0)) < 0) {
148 fprintf(stderr, "forw: Can't open default components file!!\n");
149 goto leave;
150 }
151 copy(m_maildir(draft), drft);
152 if((out = open(drft, 0)) >= 0) {
153 if(!fdcompare(in, out)) {
154 cp = concat("\"", drft, "\" exists; Delete? ", 0);
155 while((msgnum = gans(cp, anyl)) == 2)
156 showfile(drft);
157 if(!msgnum)
158 return;
159 }
160 close(out);
161 }
162 if((out = creat(drft, m_gmprot())) < 0) {
163 fprintf(stderr, "Can't create \"%s\"\n", drft);
164 goto leave;
165 }
166 cpydata(in, out);
167 close(in);
168 for(msgcnt = 1, msgnum = mp->lowsel; msgnum <= mp->hghsel; msgnum++)
169 if(mp->msgstats[msgnum]&SELECTED) {
170 if((in = open(cp = m_name(msgnum), 0)) < 0) {
171 fprintf(stderr, "Can't open message \"%s\"\n", cp);
172 unlink(drft);
173 goto leave;
174 }
175 type(out, "\n\n-------");
176 if(msgnum == mp->lowsel) {
177 type(out, " Forwarded Message");
178 if(mp->numsel > 1)
179 type(out, "s");
180 } else {
181 type(out, " Message ");
182 sprintf(numbuf, "%d", msgcnt);
183 type(out, numbuf);
184 }
185 type(out, "\n\n");
186 cpydata(in, out);
187 close(in);
188 msgcnt++;
189 }
190 type(out, "\n\n------- End of Forwarded Message");
191 if(mp->numsel > 1)
192 type(out, "s");
193 type(out, "\n");
194 close(out);
195 m_replace(pfolder, folder);
196 if(mp->lowsel != mp->curmsg)
197 m_setcur(mp->lowsel);
198 if(m_edit(&ed, drft, NOUSE, NONE) < 0)
199 goto leave;
200
201 #ifdef TEST
202 fprintf(stderr, "!! Test Version of SEND Being Run !!\n");
203 fprintf(stderr, " Send verbose !\n\n");
204 #endif
205 for(;;) {
206 if(!(argp = getans("\nWhat now? ", aleqs)))
207 goto leave;
208 switch(smatch(*argp, aleqs)) {
209 case 0: showfile(drft); /* list */
210 break;
211 case 1: if(*++argp) /* edit */
212 ed = *argp;
213 if(m_edit(&ed, drft, NOUSE, NONE) == -1)
214 goto leave;
215 break;
216 case 2: if(*++argp && *argp[0] == 'd') /* quit */
217 if(unlink(drft) == -1) {
218 fprintf(stderr, "Can't unlink %s ", drft);
219 perror("");
220 }
221 goto leave;
222 case 3: if(*++argp) cp = *argp; else cp = ""; /* send */
223
224 if(!mp->msgflags&READONLY) { /* annotate first */
225 if(anot > 0) {
226 while((pid = fork()) == -1) sleep(5);
227 if(pid) {
228 while(wpid=wait((int *)NULL)!= -1 && wpid!= pid);
229 doano();
230 goto leave;
231 }
232 }
233 }
234 if(!m_send(cp, drft))
235 goto leave;
236 default:fprintf(stderr, "forw: illegal option\n"); /*##*/
237 break;
238 }
239 }
240
241 leave:
242 m_update();
243 done(0);
244 }
245
246
247 cpydata(in, out)
248 {
249 char buf[BUFSIZ];
250 register int i;
251
252 do
253 if((i = read(in, buf, sizeof buf)) > 0)
254 write(out, buf, i);
255 while(i == sizeof buf);
256 }
257
258
259 doano()
260 {
261 FILE *in;
262 char name[NAMESZ], field[256];
263 register int ind, state;
264 register char *text;
265
266 if(stat(drft, field) != -1) {
267 fprintf(stderr, "%s not sent-- no annotations made.\n", drft);
268 return;
269 }
270 text = copy(drft, field);
271 text[1] = 0;
272 do
273 *text = text[-1];
274 while(--text >= field && *text != '/');
275 *++text =
276 #ifdef UCB
277 '#';
278 #else
279 ','; /* New backup convention */
280 #endif
281 if((in = fopen(field, "r")) == NULL) {
282 fprintf(stderr, "Can't open "); perror(field);
283 return;
284 }
285 state = FLD;
286 text = 0;
287 for(;;) switch(state = m_getfld(state, name, field, sizeof field, in)) {
288
289 case FLD:
290 case FLDEOF:
291 case FLDPLUS:
292 if(uleq(name, "to") || uleq(name, "cc") == 0) {
293 if(state == FLD) {
294 text = add(name, text);
295 text = add(":", text);
296 }
297 text = add(field, text);
298 }
299 if(state == FLDEOF)
300 goto out;
301 continue;
302 case BODY:
303 case BODYEOF:
304 goto out;
305 default:
306 fprintf(stderr, "Getfld returned %d\n", state);
307 return;
308 }
309
310 out:
311 fclose(in);
312
313 for(ind = mp->lowsel; ind <= mp->hghsel; ind++)
314 if(mp->msgstats[ind] & SELECTED)
315 annotate(m_name(ind), "Forwarded", text, inplace);
316 }