/[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 710 - (show annotations) (download)
Wed Jan 21 00:47:21 2004 UTC (9 years, 4 months ago) by rabbi
File MIME type: text/plain
File size: 13691 byte(s)
Updated copyright dates, doc issues, misc fixes.
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 cl(4, 0);
184 chain_reliability(chain, 0, reliability); /* chaintype 0=mix */
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 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 #ifdef NYMSUPPORT
496 if (!streq(thisnym, ANON)) {
497 if (nym_encrypt(msg, thisnym, (type == 'p' || type == 'f') ?
498 MSG_POST : MSG_MAIL) == 0)
499 type = 'm';
500 }
501 #endif /* NYMSUPPORT */
502 #endif /* USE_PGP */
503 err = mix_encrypt((type == 'p' || type == 'f') ?
504 MSG_POST : MSG_MAIL,
505 msg, chain, numcopies, chainlist);
506 if (err == 0) {
507 #ifdef USE_NCURSES
508 clear();
509 #endif /* USE_NCURSES */
510 for (n = 0; buf_getline(chainlist, tmp) == 0; n++) ;
511 if (n > 1)
512 mix_status("Done. (%d packets)", n);
513 else
514 mix_status("Chain: %s", chainlist->data);
515 goto quit;
516 } else {
517 #ifdef USE_NCURSES
518 beep();
519 #endif /* USE_NCURSES */
520 if (chainlist->length)
521 mix_status("%s", chainlist->data);
522 else
523 mix_genericerror();
524 }
525 }
526 }
527 #ifdef USE_NCURSES
528 break;
529 case 'q':
530 case 'Q':
531 clear();
532 goto quit;
533 #ifdef USE_PGP
534 case 'p':
535 if (!streq(thisnym, ANON))
536 sign = !sign;
537 break;
538 case 'y':
539 encrypt = !encrypt;
540 break;
541 case 'k':
542 if (!streq(thisnym, ANON)) {
543 BUFFER *p, *keytxt, *uid;
544
545 key = 1;
546 p = buf_new();
547 keytxt = buf_new();
548 uid = buf_new();
549
550 buf_appendf(uid, "<%s>", strleft(thisnym, NONANON) ? ADDRESS :
551 thisnym);
552 user_pass(p);
553 pgp_pubkeycert(uid, strleft(thisnym, NONANON) ?
554 PGPSECRING : NYMSECRING, p, keytxt, PGP_ARMOR_NYMKEY);
555
556 buf_clear(msg);
557 if (!hdr)
558 buf_nl(msg);
559 buf_cat(msg, txt);
560 buf_sets(p, "application/pgp-keys");
561 mime_attach(msg, keytxt, p);
562 hdr = 1;
563 buf_move(txt, msg);
564
565 buf_free(p);
566 buf_free(keytxt);
567 buf_free(uid);
568 }
569 break;
570 #endif /* USE_PGP */
571 default:
572 beep();
573 }
574 }
575 }
576 #endif /* USE_NCURSES */
577 quit:
578 buf_free(cc);
579 buf_free(cite);
580 buf_free(msg);
581 buf_free(txt);
582 buf_free(field);
583 buf_free(content);
584 buf_free(chainlist);
585 buf_free(tmp);
586 }

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5