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

  ViewVC Help
Powered by ViewVC 1.1.5