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

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5