/[pkg-mixmaster]/trunk/Mix/Src/menusend.c
ViewVC logotype

Contents of /trunk/Mix/Src/menusend.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations) (download)
Tue Nov 6 23:41:58 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 13046 byte(s)
First round of changes adding support for Mixmaster as a service under
Windows NT.
1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
2
3 Mixmaster may be redistributed and modified under certain conditions.
4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5 ANY KIND, either express or implied. See the file COPYRIGHT for
6 details.
7
8 Menu-based user interface -- send message
9 $Id: menusend.c,v 1.2 2001/11/06 23:41:58 rabbi Exp $ */
10
11
12 #include "menu.h"
13 #include "mix3.h"
14 #include <string.h>
15 #include <ctype.h>
16 #include <stdlib.h>
17 #ifdef POSIX
18 #include <unistd.h>
19 #else
20 #include <io.h>
21 #endif
22
23 /* Command line option +nn to position the cursor? */
24 #define cursorpos (strfind(editor, "emacs") || streq(editor, "vi") || \
25 streq(editor, "joe"))
26
27 void send_message(int type, char *nym, BUFFER *in)
28 {
29 char dest[LINELEN] = "", subject[LINELEN] = "";
30 char chain[CHAINMAX], thisnym[LINELEN], path[PATHMAX];
31 BUFFER *chainlist, *msg, *txt, *tmp, *field, *content, *cc, *cite;
32 int numcopies;
33 int hdr = 0; /* txt buffer contains header lines */
34 FILE *f;
35 int n, err;
36 char reliability[9];
37
38 #ifdef USE_PGP
39 int sign = 0, encrypt = 0, key = 0;
40
41 #endif
42 #ifdef USE_NCURSES
43 int c;
44 char line[LINELEN];
45
46 #endif
47 msg = buf_new();
48 tmp = buf_new();
49 txt = buf_new();
50 field = buf_new();
51 content = buf_new();
52 chainlist = buf_new();
53 cc = buf_new();
54 cite = buf_new();
55 strncpy(chain, CHAIN, CHAINMAX);
56 numcopies = NUMCOPIES;
57
58 mix_status("");
59 strncpy(thisnym, nym, sizeof(thisnym));
60
61 if (in != NULL)
62 buf_set(txt, in);
63
64 if (bufileft(txt, "From "))
65 buf_getline(txt, field); /* ignore envelope From */
66
67 if (type == 'p' || type == 'm') {
68 #ifndef USE_NCURSES
69 mix_status("Invalid option to -f");
70 mix_exit();
71 exit(1);
72 #else
73 clear();
74 echo();
75 if (in != NULL)
76 mvprintw(1, 0, "%s forwarding message...", thisnym);
77 if (type == 'p')
78 mvprintw(3, 0, "Newsgroups: ");
79 else
80 mvprintw(3, 0, "Send message to: ");
81 refresh();
82 wgetnstr(stdscr, dest, LINELEN);
83 if (dest[0] == '\0') {
84 noecho();
85 cl(3, 0);
86 goto quit;
87 }
88 if (txt->length == 0) {
89 mvprintw(4, 0, "Subject: ");
90 refresh();
91 wgetnstr(stdscr, subject, LINELEN);
92 } else {
93 strcpy(subject, "Forwarded message");
94 while (buf_getheader(txt, field, content) == 0) {
95 if (bufieq(field, "subject")) {
96 strncpy(subject, content->data, sizeof(subject));
97 strcatn(subject, " (fwd)", sizeof(subject));
98 }
99 if (bufieq(field, "from") || bufieq(field, "subject") ||
100 bufieq(field, "date"))
101 buf_appendheader(tmp, field, content);
102 }
103 buf_nl(tmp);
104 buf_rest(tmp, txt);
105 buf_move(txt, tmp);
106 }
107 noecho();
108 #endif
109 } else {
110 strcpy(subject, "Re: your mail");
111 while (buf_getheader(txt, field, content) == 0) {
112 if (bufieq(field, "subject")) {
113 if (bufileft(content, "Re:"))
114 subject[0] = '\0';
115 else
116 strcpy(subject, "Re: ");
117 strcatn(subject, content->data, sizeof(subject));
118 }
119 if (bufieq(field, "from"))
120 buf_set(cite, content);
121 if (type == 'p' || type == 'f') {
122 if (dest[0] == '\0' && bufieq(field, "newsgroups"))
123 strncpy(dest, content->data, sizeof(dest));
124 if (bufieq(field, "followup-to") && !bufieq(content, "poster"))
125 strncpy(dest, content->data, sizeof(dest));
126 if (bufieq(field, "message-id"))
127 buf_appendf(tmp, "References: %b\n", content);
128 } else {
129 if (dest[0] == '\0' && bufieq(field, "from"))
130 strncpy(dest, content->data, sizeof(dest));
131 if (bufieq(field, "reply-to"))
132 strncpy(dest, content->data, sizeof(dest));
133 if (type == 'g' && (bufieq(field, "to") || bufieq(field, "cc"))) {
134 if (cc->length)
135 buf_appends(cc, ", ");
136 buf_cat(cc, content);
137 }
138 if (bufieq(field, "message-id"))
139 buf_appendf(tmp, "In-Reply-To: %b\n", content);
140 }
141 }
142 if (cc->length)
143 buf_appendf(tmp, "Cc: %b\n", cc);
144 if (tmp->length > 0)
145 hdr = 1;
146 if (hdr)
147 buf_nl(tmp);
148
149 if ((type == 'f' || type == 'g') && cite->length) {
150 buf_appendf(tmp, "%b wrote:\n\n", cite);
151 }
152 if (type == 'r')
153 buf_appends(tmp, "You wrote:\n\n");
154
155 while (buf_getline(txt, content) != -1)
156 buf_appendf(tmp, "> %b\n", content);
157 buf_set(txt, tmp);
158 if (dest[0] == '\0') {
159 #ifdef USE_NCURSES
160 beep();
161 mix_status("No recipient address found.");
162 #endif
163 goto quit;
164 }
165 goto edit;
166 }
167
168 #ifdef USE_NCURSES
169 redraw:
170 clear();
171
172 for (;;) {
173 standout();
174 mvprintw(0, 0, "Mixmaster %s - ", VERSION);
175 printw(type == 'p' || type == 'f' ? "posting to Usenet" : "sending mail");
176 standend();
177 mix_status(NULL);
178 cl(2, 0);
179 printw("n)ym: %s", thisnym);
180 if (!strleft(thisnym, NONANON)) {
181 cl(4, 0);
182 chain_reliability(chain, 0, reliability); /* chaintype 0=mix */
183 printw("c)hain: %-35s (reliability: %s)", chain, reliability);
184 cl(5, 0);
185 printw("r)edundancy: %3d copies ", numcopies);
186 }
187 cl(7, 0);
188 printw("d)estination: %s", dest);
189 cl(8, 0);
190 printw("s)ubject: %s", subject);
191 #ifdef USE_PGP
192 if (type != 'p' && type != 'f') {
193 cl(10, 0);
194 printw("pgp encry)ption: ");
195 if (encrypt)
196 printw("yes");
197 else
198 printw("no");
199 }
200 if (!streq(thisnym, ANON)) {
201 cl(11, 0);
202 printw("p)gp signature: ");
203 if (sign)
204 printw("yes");
205 else
206 printw("no");
207 cl(12, 0);
208 if (key == 0)
209 printw("attach pgp k)ey: no");
210 }
211 #endif
212
213 if (txt->length == 0)
214 mvprintw(LINES - 3, 18,
215 "e)dit message f)ile q)uit");
216 else
217 mvprintw(LINES - 3, 0,
218 "m)ail message e)dit message f)ile q)uit");
219 move(LINES - 1, COLS - 1);
220 refresh();
221 c = getch();
222 if (c != ERR) {
223 mix_status("");
224 if (c == '\r' || c == '\n') { /* default action is edit or mail */
225 if (txt->length == 0)
226 c = 'e';
227 else
228 c = 'm';
229 }
230 switch (c) {
231 case 'n':
232 menu_nym(thisnym);
233 goto redraw;
234 case '\014':
235 goto redraw;
236 case 'd':
237 echo();
238 cl(LINES - 3, 20);
239 cl(7, 14);
240 wgetnstr(stdscr, dest, LINELEN);
241 noecho();
242 break;
243 case 's':
244 echo();
245 cl(LINES - 3, 20);
246 cl(8, 10);
247 wgetnstr(stdscr, subject, LINELEN);
248 noecho();
249 break;
250 case 'c':
251 menu_chain(chain, 0, (type == 'p' || type == 'f')
252 && streq(thisnym, ANON));
253 goto redraw;
254 case 'r':
255 echo();
256 cl(LINES - 5, 20);
257 cl(5, 13);
258 wgetnstr(stdscr, line, LINELEN);
259 numcopies = strtol(line, NULL, 10);
260 if (numcopies < 1 || numcopies > 10)
261 numcopies = 1;
262 noecho();
263 break;
264 case 'f':
265 cl(LINES - 3, 0);
266 askfilename(path);
267 cl(LINES - 3, 0);
268 if (txt->length) {
269 buf_sets(tmp, path);
270 buf_clear(msg);
271 if (!hdr)
272 buf_nl(msg);
273 buf_cat(msg, txt);
274 if (attachfile(msg, tmp) == -1)
275 beep();
276 else {
277 buf_move(txt, msg);
278 hdr = 1;
279 }
280 } else {
281 if ((f = fopen(path, "r")) != NULL) {
282 buf_clear(txt);
283 buf_read(txt, f);
284 fclose(f);
285 } else
286 beep();
287 }
288 break;
289 case 'e':
290 #endif
291 {
292 char s[PATHMAX];
293 char *editor;
294 int showhdr; /* show header in the editor? */
295 int linecount;
296
297 edit:
298 editor = getenv("EDITOR");
299 if (editor == NULL)
300 editor = "vi";
301 showhdr = 1;
302 linecount = 1;
303 sprintf(path, "%s%cx%02x%02x%02x%02x.txt", POOLDIR, DIRSEP,
304 rnd_byte(), rnd_byte(), rnd_byte(), rnd_byte());
305 f = fopen(path, "w");
306 if (f == NULL) {
307 #ifdef USE_NCURSES
308 beep();
309 #endif
310 } else {
311
312 if (!cursorpos && txt->length == 0 && (type == 'm' || type == 'p'))
313 showhdr = 0;
314
315 if (showhdr)
316 {
317 if (type == 'f' || type == 'p')
318 fprintf(f, "Newsgroups: %s\n", dest);
319 if (type == 'r' || type == 'g' || type == 'm')
320 fprintf(f, "To: %s\n", dest);
321 fprintf(f, "Subject: %s\n", subject);
322 linecount += 2;
323 if (hdr)
324 while (buf_getline(txt, NULL) == 0) linecount++;
325 else
326 fprintf(f, "\n");
327 linecount++;
328 if (txt->length == 0)
329 fprintf(f, "\n");
330 }
331 buf_write(txt, f);
332 fclose(f);
333 }
334 if (linecount > 1 && cursorpos)
335 snprintf(s, PATHMAX, "%s +%d %s", editor, linecount, path);
336 else
337 snprintf(s, PATHMAX, "%s %s", editor, path);
338
339 #ifdef USE_NCURSES
340 clear();
341 refresh();
342 endwin();
343 #endif
344 system(s);
345 #ifdef USE_NCURSES
346 refresh();
347 #endif
348
349 f = fopen(path, "r");
350 if (f == NULL) {
351 #ifdef USE_NCURSES
352 clear();
353 beep();
354 continue;
355 #else
356 goto quit;
357 #endif
358 }
359 buf_reset(txt);
360 hdr = 0;
361 if (showhdr) {
362 buf_reset(tmp);
363 buf_read(tmp, f);
364 while (buf_getheader(tmp, field, content) == 0) {
365 if (bufieq(field, "subject"))
366 strncpy(subject, content->data,
367 sizeof(subject));
368 else if ((type == 'p' || type == 'f') &&
369 bufieq(field, "newsgroups"))
370 strncpy(dest, content->data, sizeof(dest));
371 else if (bufieq(field, "to"))
372 strncpy(dest, content->data, sizeof(dest));
373 else {
374 buf_appendheader(txt, field, content);
375 hdr = 1;
376 }
377 }
378 if (hdr)
379 buf_nl(txt);
380 buf_rest(txt, tmp);
381 } else
382 buf_read(txt, f);
383 fclose(f);
384 unlink(path);
385 strcatn(path, "~", PATHMAX);
386 unlink(path);
387 #ifndef USE_NCURSES
388 {
389 char line[4];
390
391 fprintf(stderr, "Send message [y/n]? ");
392 scanf("%3s", line);
393 if (!strleft(line, "y"))
394 goto quit;
395 }
396 #else
397 goto redraw;
398 }
399 break;
400 case 'm':
401 if (txt->length == 0)
402 beep();
403 else if (dest[0] == '\0') {
404 mix_status("No destination given.");
405 goto redraw;
406 } else {
407 mix_status("Creating message...");
408 #endif
409 buf_reset(msg);
410
411 if (type == 'p' || type == 'f')
412 buf_appends(msg, "Newsgroups: ");
413 else
414 buf_appends(msg, "To: ");
415 buf_appends(msg, dest);
416 buf_nl(msg);
417 buf_appends(msg, "Subject: ");
418 if (subject[0] == '\0')
419 buf_appends(msg, "(no subject)");
420 else
421 buf_appends(msg, subject);
422 buf_nl(msg);
423 if (!hdr)
424 buf_nl(msg);
425 buf_cat(msg, txt);
426 #ifdef USE_PGP
427 {
428 BUFFER *p;
429
430 p = buf_new();
431 if (streq(thisnym, ANON))
432 sign = 0;
433 if (sign || (key && !strileft(thisnym, NONANON)))
434 user_pass(p);
435
436 if (encrypt || sign) {
437 if (pgp_mailenc((encrypt ? PGP_ENCRYPT : 0)
438 | (sign ? PGP_SIGN : 0) | PGP_TEXT
439 | (strleft(thisnym, NONANON) ? 0 : PGP_REMAIL),
440 msg, strleft(thisnym, NONANON) ?
441 ADDRESS : thisnym, p, PGPPUBRING,
442 strleft(thisnym, NONANON) ?
443 PGPSECRING : NYMSECRING) == -1) {
444 mix_genericerror();
445 #ifdef USE_NCURSES
446 beep();
447 goto redraw;
448 #endif
449 }
450 }
451 buf_free(p);
452 }
453 #endif
454
455 if (strleft(thisnym, NONANON)) {
456 FILE *f = NULL;
457
458 if (type == 'p' || type == 'f') {
459 if (strchr(NEWS, '@')) {
460 /* NOT_IMPLEMENTED; */
461 } else
462 f = openpipe(NEWS);
463 } else {
464 if (NAME[0]) {
465 buf_sets(tmp, NAME);
466 buf_appends(tmp, " <");
467 buf_appends(tmp, ADDRESS);
468 buf_appends(tmp, ">");
469 } else
470 buf_sets(tmp, ADDRESS);
471 mail_encode(msg, 0);
472 if (sendmail(msg, tmp->data, NULL) != 0) {
473 #ifdef USE_NCURSES
474 clear();
475 #endif
476 mix_status("Error sending message.");
477 #ifdef USE_NCURSES
478 goto redraw;
479 #else
480 goto quit;
481 #endif
482 }
483 }
484 #ifdef USE_NCURSES
485 clear();
486 #endif
487 mix_status("Message sent non-anonymously.");
488 goto quit;
489 } else {
490 #ifdef USE_PGP
491 if (!streq(thisnym, ANON)) {
492 if (nym_encrypt(msg, thisnym, (type == 'p' || type == 'f') ?
493 MSG_POST : MSG_MAIL) == 0)
494 type = 'm';
495 }
496 #endif
497 err = mix_encrypt((type == 'p' || type == 'f') ?
498 MSG_POST : MSG_MAIL,
499 msg, chain, numcopies, chainlist);
500 if (err == 0) {
501 #ifdef USE_NCURSES
502 clear();
503 #endif
504 for (n = 0; buf_getline(chainlist, tmp) == 0; n++) ;
505 if (n > 1)
506 mix_status("Done. (%d packets)", n);
507 else
508 mix_status("Chain: %s", chainlist->data);
509 goto quit;
510 } else {
511 #ifdef USE_NCURSES
512 beep();
513 #endif
514 if (chainlist->length)
515 mix_status("%s", chainlist->data);
516 else
517 mix_genericerror();
518 }
519 }
520 }
521 #ifdef USE_NCURSES
522 break;
523 case 'q':
524 case 'Q':
525 clear();
526 goto quit;
527 #ifdef USE_PGP
528 case 'p':
529 if (!streq(thisnym, ANON))
530 sign = !sign;
531 break;
532 case 'y':
533 encrypt = !encrypt;
534 break;
535 case 'k':
536 if (!streq(thisnym, ANON)) {
537 BUFFER *p, *keytxt, *uid;
538
539 key = 1;
540 p = buf_new();
541 keytxt = buf_new();
542 uid = buf_new();
543
544 buf_appendf(uid, "<%s>", strleft(thisnym, NONANON) ? ADDRESS :
545 thisnym);
546 user_pass(p);
547 pgp_pubkeycert(uid, strleft(thisnym, NONANON) ?
548 PGPSECRING : NYMSECRING, p, keytxt, 3);
549
550 buf_clear(msg);
551 if (!hdr)
552 buf_nl(msg);
553 buf_cat(msg, txt);
554 buf_sets(p, "application/pgp-keys");
555 mime_attach(msg, keytxt, p);
556 hdr = 1;
557 buf_move(txt, msg);
558
559 buf_free(p);
560 buf_free(keytxt);
561 buf_free(uid);
562 }
563 break;
564 #endif
565 default:
566 beep();
567 }
568 }
569 }
570 #endif
571 quit:
572 buf_free(cc);
573 buf_free(cite);
574 buf_free(msg);
575 buf_free(txt);
576 buf_free(field);
577 buf_free(content);
578 buf_free(chainlist);
579 buf_free(tmp);
580 }

  ViewVC Help
Powered by ViewVC 1.1.5