/[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 790 - (show annotations) (download)
Sat May 1 16:32:18 2004 UTC (9 years ago) by weasel
File MIME type: text/plain
File size: 14334 byte(s)
set location for "c)hain:" after calculating its reliability, as chain_reliability might print warnings
1 /* Mixmaster version 3.0 -- (C) 1999 - 2004 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$ */
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 /* end of POSIX */
20 #include <io.h>
21 #endif /* else if not POSIX */
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
37 #ifdef USE_PGP
38 int sign = 0, encrypt = 0, key = 0;
39
40 #endif /* USE_PGP */
41 #ifdef USE_NCURSES
42 char reliability[9];
43 int c;
44 char line[LINELEN];
45
46 #endif /* USE_NCURSES */
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 /* end of not USE_NCURSES */
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 /* else if USE_NCURSES */
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 /* USE_NCURSES */
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 #ifdef NYMSUPPORT
180 printw("n)ym: %s", thisnym);
181 #endif /* NYMSUPPORT */
182 if (!strleft(thisnym, NONANON)) {
183 chain_reliability(chain, 0, reliability); /* chaintype 0=mix */
184 cl(4, 0);
185 printw("c)hain: %-35s (reliability: %s)", chain, reliability);
186 cl(5, 0);
187 printw("r)edundancy: %3d copies ", numcopies);
188 }
189 cl(7, 0);
190 printw("d)estination: %s", dest);
191 cl(8, 0);
192 printw("s)ubject: %s", subject);
193 #ifdef USE_PGP
194 if (type != 'p' && type != 'f') {
195 cl(10, 0);
196 printw("pgp encry)ption: ");
197 if (encrypt)
198 printw("yes");
199 else
200 printw("no");
201 }
202 if (!streq(thisnym, ANON)) {
203 cl(11, 0);
204 printw("p)gp signature: ");
205 if (sign)
206 printw("yes");
207 else
208 printw("no");
209 cl(12, 0);
210 if (key == 0)
211 printw("attach pgp k)ey: no");
212 }
213 #endif /* USE_PGP */
214
215 if (txt->length == 0)
216 mvprintw(LINES - 3, 18,
217 "e)dit message f)ile q)uit");
218 else
219 mvprintw(LINES - 3, 0,
220 "m)ail message e)dit message f)ile q)uit");
221 move(LINES - 1, COLS - 1);
222 refresh();
223 c = getch();
224 if (c != ERR) {
225 mix_status("");
226 if (c == '\r' || c == '\n') { /* default action is edit or mail */
227 if (txt->length == 0)
228 c = 'e';
229 else
230 c = 'm';
231 }
232 switch (c) {
233 #ifdef NYMSUPPORT
234 case 'n':
235 menu_nym(thisnym);
236 goto redraw;
237 #endif /* NYMSUPPORT */
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 WIN32
344 // ShellExecuteEx(NULL,"open",path,NULL,NULL,SW_SHOWDEFAULT);
345
346 do {
347 /* FIXME: give this its own function */
348 SHELLEXECUTEINFO sei;
349 ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
350 sei.cbSize = sizeof(SHELLEXECUTEINFO);
351 sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
352 sei.hwnd = NULL;
353 sei.lpVerb = "open";
354 sei.lpFile = path;
355 sei.lpParameters = NULL;
356 sei.nShow = SW_SHOWNORMAL;
357
358 if (ShellExecuteEx(&sei) == TRUE) {
359 WaitForSingleObject(sei.hProcess, INFINITE);
360 CloseHandle(sei.hProcess);
361 }
362 } while (0);
363
364 #else /* WIN32 */
365
366 #ifdef USE_NCURSES
367 clear();
368 refresh();
369 endwin();
370 #endif /* USE_NCURSES */
371 system(s);
372 #ifdef USE_NCURSES
373 refresh();
374 #endif /* USE_NCURSES */
375
376 #endif /* WIN32 */
377
378 f = fopen(path, "r");
379 if (f == NULL) {
380 #ifdef USE_NCURSES
381 clear();
382 beep();
383 continue;
384 #else /* end of USE_NCURSES */
385 goto quit;
386 #endif /* else if not USE_NCURSES */
387 }
388 buf_reset(txt);
389 hdr = 0;
390 if (showhdr) {
391 buf_reset(tmp);
392 buf_read(tmp, f);
393 while (buf_getheader(tmp, field, content) == 0) {
394 if (bufieq(field, "subject"))
395 strncpy(subject, content->data,
396 sizeof(subject));
397 else if ((type == 'p' || type == 'f') &&
398 bufieq(field, "newsgroups"))
399 strncpy(dest, content->data, sizeof(dest));
400 else if (bufieq(field, "to"))
401 strncpy(dest, content->data, sizeof(dest));
402 else {
403 buf_appendheader(txt, field, content);
404 hdr = 1;
405 }
406 }
407 if (hdr)
408 buf_nl(txt);
409 buf_rest(txt, tmp);
410 } else
411 buf_read(txt, f);
412 fclose(f);
413 unlink(path);
414 strcatn(path, "~", PATHMAX);
415 unlink(path);
416 #ifndef USE_NCURSES
417 {
418 char line[4];
419
420 fprintf(stderr, "Send message [y/n]? ");
421 scanf("%3s", line);
422 if (!strleft(line, "y"))
423 goto quit;
424 }
425 #else /* end of not USE_NCURSES */
426 goto redraw;
427 }
428 break;
429 case 'm':
430 if (txt->length == 0)
431 beep();
432 else if (dest[0] == '\0') {
433 mix_status("No destination given.");
434 goto redraw;
435 } else {
436 mix_status("Creating message...");
437 #endif /* else if USE_NCURSES */
438 buf_reset(msg);
439
440 if (type == 'p' || type == 'f')
441 buf_appends(msg, "Newsgroups: ");
442 else
443 buf_appends(msg, "To: ");
444 buf_appends(msg, dest);
445 buf_nl(msg);
446 buf_appends(msg, "Subject: ");
447 if (subject[0] == '\0')
448 buf_appends(msg, "(no subject)");
449 else
450 buf_appends(msg, subject);
451 buf_nl(msg);
452 if (!hdr)
453 buf_nl(msg);
454 buf_cat(msg, txt);
455 #ifdef USE_PGP
456 {
457 BUFFER *p;
458
459 p = buf_new();
460 if (streq(thisnym, ANON))
461 sign = 0;
462 if (sign || (key && !strileft(thisnym, NONANON)))
463 user_pass(p);
464
465 if (encrypt || sign) {
466 if (pgp_mailenc((encrypt ? PGP_ENCRYPT : 0)
467 | (sign ? PGP_SIGN : 0) | PGP_TEXT
468 | (strleft(thisnym, NONANON) ? 0 : PGP_REMAIL),
469 msg, strleft(thisnym, NONANON) ?
470 ADDRESS : thisnym, p, PGPPUBRING,
471 strleft(thisnym, NONANON) ?
472 PGPSECRING : NYMSECRING) == -1) {
473 mix_genericerror();
474 #ifdef USE_NCURSES
475 beep();
476 goto redraw;
477 #endif /* USE_NCURSES */
478 }
479 }
480 buf_free(p);
481 }
482 #endif /* USE_PGP */
483
484 if (strleft(thisnym, NONANON)) {
485 FILE *f = NULL;
486
487 if (type == 'p' || type == 'f') {
488 if (strchr(NEWS, '@')) {
489 /* NOT_IMPLEMENTED; */
490 } else
491 f = openpipe(NEWS);
492 } else {
493 if (NAME[0]) {
494 buf_sets(tmp, NAME);
495 buf_appends(tmp, " <");
496 buf_appends(tmp, ADDRESS);
497 buf_appends(tmp, ">");
498 } else
499 buf_sets(tmp, ADDRESS);
500 mail_encode(msg, 0);
501 if (sendmail(msg, tmp->data, NULL) != 0) {
502 #ifdef USE_NCURSES
503 clear();
504 #endif /* USE_NCURSES */
505 mix_status("Error sending message.");
506 #ifdef USE_NCURSES
507 goto redraw;
508 #else /* end of USE_NCURSES */
509 goto quit;
510 #endif /* else if not USE_NCURSES */
511 }
512 }
513 #ifdef USE_NCURSES
514 clear();
515 #endif /* USE_NCURSES */
516 mix_status("Message sent non-anonymously.");
517 goto quit;
518 } else {
519 #ifdef USE_PGP
520 #ifdef NYMSUPPORT
521 if (!streq(thisnym, ANON)) {
522 if (nym_encrypt(msg, thisnym, (type == 'p' || type == 'f') ?
523 MSG_POST : MSG_MAIL) == 0)
524 type = 'm';
525 }
526 #endif /* NYMSUPPORT */
527 #endif /* USE_PGP */
528 err = mix_encrypt((type == 'p' || type == 'f') ?
529 MSG_POST : MSG_MAIL,
530 msg, chain, numcopies, chainlist);
531 if (err == 0) {
532 #ifdef USE_NCURSES
533 clear();
534 #endif /* USE_NCURSES */
535 for (n = 0; buf_getline(chainlist, tmp) == 0; n++) ;
536 if (n > 1)
537 mix_status("Done. (%d packets)", n);
538 else
539 mix_status("Chain: %s", chainlist->data);
540 goto quit;
541 } else {
542 #ifdef USE_NCURSES
543 beep();
544 #endif /* USE_NCURSES */
545 if (chainlist->length)
546 mix_status("%s", chainlist->data);
547 else
548 mix_genericerror();
549 }
550 }
551 }
552 #ifdef USE_NCURSES
553 break;
554 case 'q':
555 case 'Q':
556 clear();
557 goto quit;
558 #ifdef USE_PGP
559 case 'p':
560 if (!streq(thisnym, ANON))
561 sign = !sign;
562 break;
563 case 'y':
564 encrypt = !encrypt;
565 break;
566 case 'k':
567 if (!streq(thisnym, ANON)) {
568 BUFFER *p, *keytxt, *uid;
569
570 key = 1;
571 p = buf_new();
572 keytxt = buf_new();
573 uid = buf_new();
574
575 buf_appendf(uid, "<%s>", strleft(thisnym, NONANON) ? ADDRESS :
576 thisnym);
577 user_pass(p);
578 pgp_pubkeycert(uid, strleft(thisnym, NONANON) ?
579 PGPSECRING : NYMSECRING, p, keytxt, PGP_ARMOR_NYMKEY);
580
581 buf_clear(msg);
582 if (!hdr)
583 buf_nl(msg);
584 buf_cat(msg, txt);
585 buf_sets(p, "application/pgp-keys");
586 mime_attach(msg, keytxt, p);
587 hdr = 1;
588 buf_move(txt, msg);
589
590 buf_free(p);
591 buf_free(keytxt);
592 buf_free(uid);
593 }
594 break;
595 #endif /* USE_PGP */
596 default:
597 beep();
598 }
599 }
600 }
601 #endif /* USE_NCURSES */
602 quit:
603 buf_free(cc);
604 buf_free(cite);
605 buf_free(msg);
606 buf_free(txt);
607 buf_free(field);
608 buf_free(content);
609 buf_free(chainlist);
610 buf_free(tmp);
611 }

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5