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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 304 - (show annotations) (download)
Wed Oct 2 19:49:17 2002 UTC (10 years, 7 months ago) by ulfm
File MIME type: text/plain
File size: 21582 byte(s)
an email file could also start with Return-Path
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
9 $Id: menu.c,v 1.11 2002/10/02 19:49:17 ulfm Exp $ */
10
11
12 #include "menu.h"
13 #include "mix3.h"
14 #include <string.h>
15 #include <ctype.h>
16 #include <stdlib.h>
17 #include <fcntl.h>
18 #ifdef POSIX
19 #include <unistd.h>
20 #else /* end of POSIX */
21 #include <io.h>
22 #endif /* else if not POSIX */
23 #include <assert.h>
24
25 void menu_folder(char command, char *foldername)
26 {
27 mix_init(NULL);
28 if (foldername)
29 menu_init();
30 read_folder(command, foldername, ANON);
31 menu_exit();
32 }
33
34 void read_folder(char command, char *foldername, char *nym)
35 {
36 #ifdef USE_NCURSES
37 char path[PATHMAX] = "stdin", path_with_tilde[PATHMAX], l[LINELEN];
38 #else /* end of USE_NCURSES */
39 char path[PATHMAX] = "stdin", l[LINELEN];
40 #endif /* else if not USE_NCURSES */
41 char *h;
42 FILE *f;
43 BUFFER *folder;
44 BUFFER *line, *field, *content, *name;
45 BUFFER *index;
46 BUFFER *mail, *log;
47 int mailfolder = -1; /* -1 = unknown, 0 = no mailfolder, 1 = mailfolder */
48 int num = 0;
49 long from = -1, subject = -1;
50 int folder_has_changed;
51 #ifdef USE_NCURSES
52 BUFFER *deleted_message;
53 BUFFER *new_folder;
54 BUFFER *new_index;
55 long length;
56 char sub[LINELEN], str[LINELEN], search[LINELEN] = "";
57 long p;
58 int display, range, selected, i, redraw, c, q;
59
60 #endif /* USE_NCURSES */
61 int ispgp = 0, eof = 0;
62 folder_has_changed = 0;
63
64 line = buf_new();
65 field = buf_new();
66 content = buf_new();
67 index = buf_new();
68 mail = buf_new();
69 name = buf_new();
70 folder = buf_new();
71 log = buf_new();
72
73 if (foldername == NULL)
74 f = stdin;
75 else {
76 if (foldername[0] == '~' && (h = getenv("HOME")) != NULL) {
77 strncpy(path, h, PATHMAX);
78 strcatn(path, foldername + 1, PATHMAX);
79 } else
80 strncpy(path, foldername, PATHMAX);
81 f = fopen(path, "r");
82 }
83 if (f == NULL) {
84 #ifdef USE_NCURSES
85 if (foldername)
86 beep();
87 #endif /* USE_NCURSES */
88 mix_status("Can't read %s.\n", path);
89 goto end;
90 }
91 for (;;) {
92 if (fgets(l, sizeof(l), f) == NULL)
93 eof = 1;
94 else if (mailfolder == -1) {
95 if (strleft(l, "From "))
96 mailfolder = 1;
97 else if (strileft(l, "from:") || strileft(l, "path:")
98 || strileft(l, "xref:") || strileft(l, "return-path"))
99 mailfolder = 0;
100 else
101 break;
102 }
103 if (eof || (mailfolder && strleft(l, "From ")) ||
104 (mailfolder == 0 && from != -1 &&
105 (strileft(l, "path:") ||
106 strileft(l, "xref:") || strileft(l,"return-path")))) {
107 if (num > 1)
108 mix_status("Reading message %d", num);
109 #ifdef USE_PGP
110 if (ispgp)
111 switch (nym_decrypt(mail, NULL, log)) {
112 case 2:
113 from = -1, subject = -1;
114 while (buf_getline(mail, line) == 0) {
115 if (bufileft(line, "from:"))
116 from = folder->length + mail->ptr - line->length - 1;
117 if (bufileft(line, "subject:"))
118 subject = folder->length + mail->ptr - line->length - 1;
119 }
120 folder_has_changed = 1;
121 break;
122 case -1:
123 buf_clear(mail);
124 from = -1, subject = -1;
125 continue;
126 default:
127 ;
128 }
129 #endif /* USE_PGP */
130 buf_cat(folder, mail);
131 buf_clear(mail);
132 ispgp = 0;
133 if (num > 0) {
134 buf_appendl(index, from);
135 buf_appendl(index, subject);
136 }
137 if (eof)
138 break;
139
140 buf_appendl(index, folder->length);
141 from = subject = -1;
142 num++;
143 }
144 if (from == -1 && strileft(l, "from:"))
145 from = folder->length + mail->length;
146
147 if (subject == -1 && strileft(l, "subject:"))
148 subject = folder->length + mail->length;
149
150 buf_appends(mail, l);
151 if (strleft(l, begin_pgp))
152 ispgp = 1;
153 }
154
155 if (foldername)
156 fclose(f);
157 else {
158 dup2(open("/dev/tty", O_RDWR), fileno(stdin));
159 menu_init();
160 }
161
162 mix_status("");
163 if (folder->length == 0) {
164 #ifdef USE_NCURSES
165 clear();
166 beep();
167 #endif /* USE_NCURSES */
168 mix_status("%s is empty.\n", path);
169 goto end;
170 }
171 if (mailfolder == -1) {
172 #ifdef USE_NCURSES
173 clear();
174 beep();
175 #endif /* USE_NCURSES */
176 mix_status("%s is not a mail folder.\n", path);
177 goto end;
178 }
179 #ifndef USE_NCURSES
180 if (command == 0) {
181 buf_write(folder, stdout);
182 goto end;
183 }
184 if (num > 1) {
185 mix_status("Folder contains several messages.");
186 goto end;
187 }
188 #endif /* not USE_NCURSES */
189
190 if (num < 2) {
191 folder->ptr = 0;
192 mimedecode(folder);
193
194 if (command != 0)
195 send_message(command, nym, folder);
196 #ifdef USE_NCURSES
197 else
198 read_message(folder, nym);
199
200 clear();
201 #endif /* USE_NCURSES */
202 goto end;
203 }
204 #ifdef USE_NCURSES
205 display = selected = 0;
206 range = LINES - 3;
207 redraw = 2;
208
209 for (;;) {
210 if (selected < 0)
211 selected = 0;
212 if (selected >= num)
213 selected = num - 1;
214
215 if (selected < display) {
216 display = selected - range / 2;
217 redraw = 2;
218 }
219 if (selected >= display + range) {
220 display = selected - range / 2;
221 redraw = 2;
222 }
223 if (display >= num - 5)
224 display = num - 5;
225 if (display < 0)
226 display = 0;
227
228 if (redraw) {
229 if (redraw == 2) {
230 clear();
231 standout();
232 mvprintw(0, 0, "Mixmaster %s", VERSION);
233 printw(" %.20s reading %.50s", nym, path);
234 standend();
235 }
236 for (i = display; i < display + range; i++) {
237 if (i < num) {
238 index->ptr = 12 * i;
239 p = buf_getl(index);
240 buf_clear(name);
241 folder->ptr = buf_getl(index);
242 if (folder->ptr < 0)
243 folder->ptr = 0;
244 else {
245 buf_getheader(folder, field, line);
246 if (line->length) {
247 decode_header(line);
248 rfc822_name(line, name);
249 }
250 }
251 if (i == selected)
252 standout();
253
254 mvaddnstr(i - display + 2, 0, name->data, 18);
255
256 sub[0] = '\0';
257 folder->ptr = buf_getl(index);
258 if (folder->ptr < 0)
259 folder->ptr = 0;
260 else {
261 buf_getheader(folder, field, content);
262 if (content->length) {
263 decode_header(content);
264 strncpy(sub, content->data, sizeof(sub));
265 }
266 }
267 if (sub[0] == '\0')
268 strcpy(sub, "(no subject)");
269 mvaddnstr(i - display + 2, 20, sub, COLS - 21);
270
271 if (i == selected)
272 standend();
273 }
274 }
275 }
276 move(LINES - 1, COLS - 1);
277 refresh();
278 redraw = 0;
279
280 c = getch();
281 switch (c) {
282 case '\014':
283 display = selected - range / 2;
284 redraw = 2;
285 break;
286 case 'q':
287 clear();
288 goto end;
289 case '/':
290 echo();
291 cl(LINES - 1, 0);
292 printw("Search: ");
293 refresh();
294 wgetnstr(stdscr, str, LINELEN);
295 if (str[0] != '\0')
296 strncpy(search, str, LINELEN);
297 noecho();
298 for (i = (selected < num ? selected + 1 : 0); i < num; i++) {
299 index->ptr = 12 * i + 4;
300 folder->ptr = buf_getl(index);
301 if (folder->ptr < 0)
302 folder->ptr = 0;
303 else {
304 buf_getheader(folder, field, line);
305 if (line->length) {
306 decode_header(line);
307 if (bufifind(line, search))
308 break;
309 }
310 }
311 folder->ptr = buf_getl(index);
312 if (folder->ptr < 0)
313 folder->ptr = 0;
314 else {
315 buf_getheader(folder, field, line);
316 if (line->length) {
317 decode_header(line);
318 if (bufifind(line, search))
319 break;
320 }
321 }
322 }
323 if (i < num)
324 selected = i;
325 else
326 beep();
327 redraw = 1;
328 break;
329 case '\r': /* read message */
330 case '\n':
331 case 'r': /* reply to message */
332 case 'g':
333 case 'f':
334 case 'm':
335 case 'p':
336 case 's':
337 index->ptr = 12 * selected;
338 p = buf_getl(index);
339 if (selected < num - 1) {
340 index->ptr = 12 * (selected + 1);
341 q = buf_getl(index) - p;
342 } else
343 q = folder->length - p;
344 buf_clear(mail);
345 buf_append(mail, folder->data + p, q);
346 mimedecode(mail);
347 if(c == 's')
348 savemsg(mail);
349 else{
350 if (c == '\r' || c == '\n')
351 read_message(mail, nym);
352 else
353 send_message(c, nym, mail);
354 }
355 redraw = 2;
356 break;
357 case 'd': /* delete message */
358 /* Remove message from folder */
359 if(num > 0){
360 index->ptr = 12 * selected;
361 p = buf_getl(index);
362 if (selected < num - 1) {
363 index->ptr = 12 * (selected + 1);
364 q = buf_getl(index) - p;
365 } else
366 q = folder->length - p;
367 deleted_message = buf_new();
368 new_folder = buf_new();
369 buf_cut_out(folder, deleted_message, new_folder, p, q);
370 buf_free(deleted_message);
371 buf_free(folder);
372 folder = new_folder;
373 /* Update index file */
374 new_index = buf_new();
375 index->ptr = 0;
376 if(selected > 0)
377 buf_get(index, new_index, 12 * selected);
378 index->ptr = 12 * (selected + 1);
379 while((from = buf_getl(index)) != -1){
380 subject = buf_getl(index);
381 length = buf_getl(index);
382 buf_appendl(new_index, from - q);
383 buf_appendl(new_index, subject - q);
384 buf_appendl(new_index, length - q);
385 }
386 buf_free(index);
387 index = new_index;
388 /* Done */
389 num--;
390 folder_has_changed = 1;
391 }
392 redraw = 2;
393 break;
394 case KEY_UP:
395 selected--;
396 redraw = 1;
397 break;
398 case KEY_DOWN:
399 case 'n': /* nym ???? */
400 selected++;
401 redraw = 1;
402 break;
403 case KEY_PPAGE:
404 selected -= range;
405 redraw = 1;
406 break;
407 case KEY_NPAGE:
408 selected += range;
409 redraw = 1;
410 break;
411 default:
412 beep();
413 }
414 }
415 #endif /* USE_NCURSES */
416
417 end:
418 #ifdef USE_NCURSES
419 /* If folder has changed, ask user about saving new folder. */
420 if (folder_has_changed && !streq(path, "stdin")) {
421 mvprintw(LINES - 2, 0, "Buffer has changed. Save [y/n]? ");
422 c = getch();
423 cl(LINES - 2, 0);
424 if ((c == 'y') || (c == 'Y')){
425 strncpy(path_with_tilde, path, PATHMAX-1);
426 strcat(path_with_tilde, "~");
427 rename(path, path_with_tilde); /* Rename folder to folder~ */
428 f = fopen(path, "w"); /* Write new folder */
429 if (f == NULL)
430 mix_status("Can't write to %s.", path);
431 else{
432 buf_write(folder, f);
433 mix_status("Wrote %s.", path);
434 fclose(f);
435 }
436 }
437 else{
438 mix_status("%s was not saved.", path);
439 }
440 }
441 #endif /* USE_NCURSES */
442 buf_free(folder);
443 buf_free(line);
444 buf_free(field);
445 buf_free(content);
446 buf_free(index);
447 buf_free(mail);
448 buf_free(name);
449 buf_free(log);
450 }
451
452 #ifdef USE_NCURSES
453 static int sortrel(const void *a, const void *b)
454 {
455 int na, ra, nb, rb;
456
457 na = *(int *) a;
458 nb = *(int *) b;
459
460 ra = *((int *) a + 1);
461 rb = *((int *) b + 1);
462 return rb - ra;
463 }
464
465 void menu_main(void)
466 {
467 int y, x;
468 int pool, n;
469 int c;
470 BUFFER *chainlist, *line;
471 char nym[LINELEN] = ANON;
472
473 chainlist = buf_new();
474 line = buf_new();
475
476 mix_init(NULL);
477 menu_init();
478
479 menu_redraw:
480 clear();
481 for (;;) {
482 standout();
483 mvprintw(0, 0, "Mixmaster %s", VERSION);
484 mvprintw(0, COLS - sizeof(COPYRIGHT), COPYRIGHT);
485 standend();
486 mix_status(NULL);
487
488 mvprintw(8, 4, "n)ym: %s", nym);
489 y = 12, x = 25;
490 mvprintw(y++, x, "m)ail");
491 mvprintw(y++, x, "p)ost to Usenet");
492 mvprintw(y++, x, "r)ead mail (or news article)");
493 mvprintw(y++, x, "d)ummy message");
494 mvprintw(y++, x, "s)end messages from pool");
495 mvprintw(y++, x, "q)uit");
496
497 pool = pool_read(NULL);
498 if (pool == 1)
499 mvprintw(4, 2, "%3d outgoing message in the pool. \n", pool);
500 else
501 mvprintw(4, 2, "%3d outgoing messages in the pool.\n", pool);
502
503 move(LINES - 1, COLS - 1);
504 refresh();
505 c = getch();
506 if (c != ERR) {
507 mix_status("");
508 switch (c) {
509 case '\014':
510 mix_status("");
511 goto menu_redraw;
512 case 'n':
513 menu_nym(nym);
514 goto menu_redraw;
515 case 'm':
516 case 'p':
517 send_message(c, nym, NULL);
518 break;
519 case 'd':
520 mix_status("Creating message...");
521 if (mix_encrypt(MSG_NULL, NULL, NULL, 1, chainlist) != 0) {
522 if (chainlist->length > 0)
523 mix_status("%s", chainlist->data);
524 else
525 mix_genericerror();
526 beep();
527 } else {
528 for (n = 0; buf_getline(chainlist, line) == 0; n++) ;
529 if (n > 1)
530 mix_status("Done (%d packets).", n);
531 else
532 mix_status("Chain: %s", chainlist->data);
533 }
534 break;
535 case 's':
536 mix_status("Mailing messages...");
537 mix_send();
538 mix_status("Done.");
539 break;
540 case 'r':
541 {
542 char name[LINELEN];
543
544 cl(LINES - 3, 0);
545 if (getenv("MAIL"))
546 printw("File name [%s]: ", getenv("MAIL"));
547 else
548 printw("File name: ");
549 echo();
550 wgetnstr(stdscr, name, LINELEN);
551 noecho();
552 cl(LINES - 3, 0);
553 if (name[0] == '\0') {
554 if (getenv("MAIL"))
555 read_folder(0, getenv("MAIL"), nym);
556 } else
557 read_folder(0, name, nym);
558 }
559 break;
560 case 'q':
561 case 'Q':
562 goto quit;
563 default:
564 beep();
565 }
566 }
567 }
568
569 quit:
570 menu_exit();
571 buf_free(chainlist);
572 buf_free(line);
573 }
574
575 void read_message(BUFFER *message, char *nym)
576 {
577 int l = 0;
578 int c;
579 int inhdr = 1, txtbegin;
580 BUFFER *field, *content, *line, *hdr;
581 char sub[LINELEN] = "mail";
582 char thisnym[LINELEN] = "";
583
584 field = buf_new();
585 content = buf_new();
586 line = buf_new();
587 hdr = buf_new();
588
589 if (thisnym[0] == '\0')
590 strncpy(thisnym, nym, LINELEN);
591
592 if (bufleft(message, "From nymserver ")) {
593 /* select nym if Nym: pseudo header is in the first line */
594 buf_getline(message, line);
595 buf_getheader(message, field, content);
596 if (bufieq(field, "Nym"))
597 strncpy(thisnym, content->data, sizeof(thisnym));
598 buf_rewind(message);
599 }
600 while (buf_getheader(message, field, content) == 0) {
601 if (bufieq(field, "received") || bufleft(field, "From "))
602 continue;
603 if (bufieq(field, "subject"))
604 strncpy(sub, content->data, sizeof(sub));
605 buf_appendheader(hdr, field, content);
606 }
607 if (strlen(sub) > COLS - strlen(VERSION) - strlen(thisnym) - 23)
608 sub[COLS - strlen(VERSION) - strlen(thisnym) - 24] = '\0';
609 txtbegin = message->ptr;
610
611 loop:
612 clear();
613 standout();
614 mvprintw(0, 0, "Mixmaster %s", VERSION);
615 printw(" %.20s reading %.50s\n", thisnym, sub);
616 standend();
617 mix_status(NULL);
618
619 while (l < LINES - 2) {
620 if (inhdr) {
621 if (buf_getline(hdr, line) == -1)
622 buf_clear(line), inhdr = 0;
623 } else {
624 if (buf_getline(message, line) == -1) {
625 standout();
626 mvprintw(LINES - 1, 0, "Command");
627 standend();
628 refresh();
629 for (;;) {
630 c = getch();
631 switch (c) {
632 case 'm':
633 case 'p':
634 case 'r':
635 case 'g':
636 case 'f':
637 send_message(c, thisnym, message);
638 goto end;
639 case 'u':
640 inhdr = 0;
641 message->ptr = txtbegin;
642 l = 0;
643 goto loop;
644 case 'h':
645 inhdr = 1;
646 hdr->ptr = 0;
647 message->ptr = txtbegin;
648 l = 0;
649 goto loop;
650 case 's':
651 savemsg(message);
652 /* fallthru */
653 case 'q':
654 case 'i':
655 case '\n':
656 case '\r':
657 goto end;
658 case '\014':
659 refresh();
660 continue;
661 default:
662 beep();
663 refresh();
664 }
665 }
666 }
667 }
668 mvprintw(l + 1, 0, "%s\n", line->data);
669 l += (line->length - 1) / COLS + 1;
670 }
671 standout();
672 mvprintw(LINES - 1, 0, "MORE");
673 standend();
674 refresh();
675 for (;;) {
676 c = getch();
677 switch (c) {
678 case 'm':
679 case 'p':
680 case 'r':
681 case 'g':
682 case 'f':
683 send_message(c, thisnym, message);
684 goto end;
685 case 'u':
686 inhdr = 0;
687 message->ptr = txtbegin;
688 l = 0;
689 goto loop;
690 case 'h':
691 inhdr = 1; /* show full header */
692 hdr->ptr = 0;
693 message->ptr = txtbegin;
694 l = 0;
695 goto loop;
696 case 's':
697 savemsg(message);
698 /* fallthru */
699 case 'q':
700 case 'i':
701 goto end;
702 case ' ':
703 case '\n':
704 case '\r':
705 l = 0;
706 goto loop;
707 case '\014':
708 refresh();
709 continue;
710 default:
711 beep();
712 refresh();
713 }
714 }
715 end:
716 buf_free(field);
717 buf_free(content);
718 buf_free(line);
719 buf_free(hdr);
720 }
721
722 int menu_replychain(int *d, int *l, char *mdest, char *pdest, char *psub,
723 char *r)
724 {
725 int c;
726 char line[LINELEN];
727 char reliability[9];
728
729 redraw:
730 clear();
731 standout();
732 printw("Create a nym reply block:");
733 standend();
734 mix_status(NULL);
735
736 mvprintw(3, 0, "Type of reply block:\n");
737 if (*d == MSG_MAIL)
738 standout();
739 printw(" m)ail ");
740 if (*d == MSG_MAIL)
741 standend();
742
743 if (*d == MSG_POST)
744 standout();
745 printw(" Usenet message p)ool ");
746 if (*d == MSG_POST)
747 standend();
748
749 if (*d == MSG_NULL)
750 standout();
751 printw(" cover t)raffic ");
752 if (*d == MSG_NULL)
753 standend();
754
755 if (*d != MSG_NULL)
756 mvprintw(6, 0, "d)estination: %s", *d == MSG_MAIL ? mdest : pdest);
757 if (psub && *d == MSG_POST)
758 mvprintw(7, 0, "s)ubject: %s", psub);
759 chain_reliability(r, 1, reliability); /* chaintype 1=ek */
760 mvprintw(8, 0, "c)hain: %-39s (reliability: %s)", r, reliability);
761 mvprintw(10, 0, "l)atency: %d hours", *l);
762 move(LINES - 1, COLS - 1);
763
764 for (;;) {
765 refresh();
766 c = getch();
767 switch (c) {
768 case 'm':
769 *d = MSG_MAIL;
770 goto redraw;
771 case 'p':
772 *d = MSG_POST;
773 goto redraw;
774 case 't':
775 *d = MSG_NULL;
776 goto redraw;
777 case 'q':
778 return (-1);
779 case 'd':
780 cl(6, 0);
781 printw("d)estination: ");
782 echo();
783 wgetnstr(stdscr, *d == MSG_MAIL ? mdest : pdest, LINELEN);
784 noecho();
785 goto redraw;
786 case 'l':
787 cl(10, 0);
788 printw("l)atency: ");
789 echo();
790 wgetnstr(stdscr, line, LINELEN);
791 *l = strtol(line, NULL, 10);
792 if (*l < 0)
793 *l = 0;
794 noecho();
795 goto redraw;
796 case 'c':
797 menu_chain(r, 1, *d == MSG_POST);
798 goto redraw;
799 case '\014':
800 goto redraw;
801 case '\n':
802 case '\r':
803 return (0);
804 case 's':
805 if (*d == MSG_POST) {
806 cl(7, 0);
807 printw("s)ubject: ");
808 echo();
809 wgetnstr(stdscr, psub, LINELEN);
810 noecho();
811 goto redraw;
812 }
813 default:
814 beep();
815 }
816 }
817 }
818
819 void menu_chain(char *chainstr, int chaintype, int post)
820 /* chaintype 0=mix 1=ek 2=newnym */
821 {
822 REMAILER remailer[MAXREM];
823 int rlist[2 * MAXREM];
824 char newchain[CHAINMAX];
825 char info[LINELEN];
826 int num = 0, i, middlemanlast=0, ok = 1;
827 int c, x, y;
828 int nymserv = 0;
829 int chain[20], chainlen = 0;
830 char reliability[9];
831
832 if (chaintype == 2)
833 nymserv = 1, chaintype = 1;
834 assert(chaintype == 0 || chaintype == 1);
835
836 clear();
837 standout();
838 if (nymserv)
839 printw("Select nym server:\n\n");
840 else
841 printw("Select remailer chain:\n\n");
842 standend();
843
844 if (chaintype == 1)
845 num = t1_rlist(remailer);
846 else
847 num = mix2_rlist(remailer);
848
849 if (num < 1) {
850 mix_status("Can't read remailer list.");
851 beep();
852 return;
853 }
854 for (i = 0; i < num; i++) {
855 rlist[2 * i] = i + 1;
856 rlist[2 * i + 1] = remailer[i + 1].info[chaintype].reliability -
857 remailer[i + 1].info[chaintype].latency / 3600;
858 if (remailer[i + 1].info[chaintype].history[0] == '\0')
859 rlist[2 * i + 1] = -1;
860 if ((nymserv && !remailer[i + 1].flags.newnym) ||
861 ((chaintype == 0 && !remailer[i + 1].flags.mix) ||
862 (chaintype == 1 && !nymserv && (!remailer[i + 1].flags.ek
863 || !remailer[i + 1].flags.pgp))))
864 rlist[2 * i] = 0, rlist[2 * i + 1] = -2;
865 }
866 qsort(rlist, num - 1, 2 * sizeof(int), sortrel);
867
868 for (i = 0; i < num; i++)
869 if (rlist[2 * i + 1] == -2) {
870 num = i;
871 break;
872 }
873 if (num < 1) {
874 mix_status("No remailers found!");
875 return;
876 }
877 if (num > 2 * (LINES - 6))
878 num = 2 * (LINES - 6);
879 if (num > 2 * 26)
880 num = 2 * 26;
881
882 for (i = 0; i < num && rlist[2 * i + 1] > -2; i++) {
883 y = i, x = 0;
884 if (y >= LINES - 6)
885 y -= LINES - 6, x += 40;
886 mvprintw(y + 2, x, "%c", i < 26 ? i + 'a' : i - 26 + 'A');
887 mvprintw(y + 2, x + 2, "%s", remailer[rlist[2 * i]].name);
888 mvprintw(y + 2, x + 16, "%s",
889 remailer[rlist[2 * i]].info[chaintype].history);
890 sprintf(info, "%3.2f",
891 remailer[rlist[2 * i]].info[chaintype].reliability / 100.0);
892 mvprintw(y + 2, x + 29 + 6 - strlen(info), "%s%%", info);
893 }
894 y = num + 3;
895 if (y > LINES - 4)
896 y = LINES - 4;
897 mvprintw(y, 0, "* select at random");
898
899 for (;;) {
900 newchain[0] = '\0';
901 for (i = 0; i < chainlen; i++) {
902 if (i)
903 strcatn(newchain, ",", CHAINMAX);
904 if (chain[i])
905 strcatn(newchain, remailer[chain[i]].name, CHAINMAX);
906 else
907 strcatn(newchain, "*", CHAINMAX);
908 }
909 if (chainlen > 0) {
910 ok = 1;
911 middlemanlast = remailer[chain[chainlen - 1]].flags.middle;
912 if (post && !remailer[chain[chainlen - 1]].flags.post)
913 ok = 0;
914 } else
915 ok = 1;
916
917 mvprintw(LINES - 4, 40,
918 middlemanlast ?
919 "MIDDLEMAN " :
920 (ok ?
921 " " :
922 "NO POSTING "));
923 cl(LINES - 3, 0);
924 cl(LINES - 2, 0);
925 cl(LINES - 1, 0);
926 if(!nymserv){
927 chain_reliability(newchain, chaintype, reliability);
928 mvprintw(LINES - 4, 58, "(reliability: %s)", reliability);
929 }
930 mvprintw(LINES - 3, 0, nymserv ? "Nym server: %s" : "Chain: %s",
931 newchain);
932 refresh();
933 c = getch();
934 if (c == '\n' || c == '\r') {
935 /* beep and sleep in case the user made a mistake */
936 if (middlemanlast) {
937 beep();
938 sleep(2);
939 }
940 if (ok || middlemanlast)
941 break;
942 else
943 beep();
944 } else if (c == '*') {
945 if (chainlen > 19 || (nymserv && chainlen > 0))
946 beep();
947 else
948 chain[chainlen++] = 0;
949 } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
950 if (c >= 'a')
951 c -= 'a';
952 else
953 c = c - 'A' + 26;
954
955 if (chainlen > 19 || (nymserv && chainlen > 0) || c >= num)
956 beep();
957 else
958 chain[chainlen++] = rlist[2 * c];
959 } else if (c == killchar())
960 chainlen = 0;
961 else if ((c == KEY_BACKSPACE || c == KEY_LEFT || c == erasechar())
962 && chainlen > 0)
963 --chainlen;
964 else
965 beep();
966 }
967 if (chainlen)
968 strncpy(chainstr, newchain, CHAINMAX);
969 }
970
971 #endif /* USE_NCURSES */

  ViewVC Help
Powered by ViewVC 1.1.5