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