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