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

Contents of /branches/mixmaster_2_9_STABLE/Mix/Src/menusend.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.5