/[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 500 - (hide annotations) (download)
Sat May 3 05:31:07 2003 UTC (10 years ago) by weaselp
File MIME type: text/plain
File size: 21634 byte(s)
Mixmaster now uses broken-chain info from stats. I hope this doesn't break any
Nym functionality.
1 rabbi 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 weaselp 500 $Id: menu.c,v 1.15 2003/05/03 05:31:07 weaselp Exp $ */
10 rabbi 1
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 rabbi 262 #else /* end of POSIX */
21 rabbi 1 #include <io.h>
22 rabbi 262 #endif /* else if not POSIX */
23 rabbi 1 #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 rabbi 256 #ifdef USE_NCURSES
37 rabbi 1 char path[PATHMAX] = "stdin", path_with_tilde[PATHMAX], l[LINELEN];
38 rabbi 262 #else /* end of USE_NCURSES */
39 rabbi 256 char path[PATHMAX] = "stdin", l[LINELEN];
40 rabbi 262 #endif /* else if not USE_NCURSES */
41 rabbi 1 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 rabbi 256 #ifdef USE_NCURSES
52 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
61 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
88 rabbi 256 mix_status("Can't read %s.\n", path);
89 rabbi 1 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 ulfm 297 else if (strileft(l, "from:") || strileft(l, "path:")
98 ulfm 304 || strileft(l, "xref:") || strileft(l, "return-path"))
99 rabbi 1 mailfolder = 0;
100 ulfm 293 else
101 weaselp 332 break;
102 rabbi 1 }
103     if (eof || (mailfolder && strleft(l, "From ")) ||
104     (mailfolder == 0 && from != -1 &&
105     (strileft(l, "path:") ||
106 ulfm 304 strileft(l, "xref:") || strileft(l,"return-path")))) {
107 rabbi 1 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 rabbi 262 #endif /* USE_PGP */
130 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
168 rabbi 256 mix_status("%s is empty.\n", path);
169 rabbi 1 goto end;
170     }
171 ulfm 289 if (mailfolder == -1) {
172 rabbi 1 #ifdef USE_NCURSES
173     clear();
174     beep();
175 rabbi 262 #endif /* USE_NCURSES */
176 rabbi 256 mix_status("%s is not a mail folder.\n", path);
177 rabbi 1 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 rabbi 262 #endif /* not USE_NCURSES */
189 rabbi 1
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 rabbi 262 #endif /* USE_NCURSES */
202 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
416 rabbi 1
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 rabbi 262 #endif /* USE_NCURSES */
442 rabbi 1 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 ulfm 289 mvprintw(y++, x, "r)ead mail (or news article)");
493 rabbi 1 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 weaselp 500 int badchains[MAXREM][MAXREM];
824 rabbi 1 int rlist[2 * MAXREM];
825     char newchain[CHAINMAX];
826     char info[LINELEN];
827 weaselp 165 int num = 0, i, middlemanlast=0, ok = 1;
828 rabbi 1 int c, x, y;
829     int nymserv = 0;
830     int chain[20], chainlen = 0;
831     char reliability[9];
832    
833     if (chaintype == 2)
834     nymserv = 1, chaintype = 1;
835     assert(chaintype == 0 || chaintype == 1);
836    
837     clear();
838     standout();
839     if (nymserv)
840     printw("Select nym server:\n\n");
841     else
842     printw("Select remailer chain:\n\n");
843     standend();
844    
845     if (chaintype == 1)
846 weaselp 500 num = t1_rlist(remailer, badchains);
847 rabbi 1 else
848 weaselp 500 num = mix2_rlist(remailer, badchains);
849 rabbi 1
850     if (num < 1) {
851     mix_status("Can't read remailer list.");
852     beep();
853     return;
854     }
855     for (i = 0; i < num; i++) {
856     rlist[2 * i] = i + 1;
857     rlist[2 * i + 1] = remailer[i + 1].info[chaintype].reliability -
858     remailer[i + 1].info[chaintype].latency / 3600;
859     if (remailer[i + 1].info[chaintype].history[0] == '\0')
860     rlist[2 * i + 1] = -1;
861     if ((nymserv && !remailer[i + 1].flags.newnym) ||
862     ((chaintype == 0 && !remailer[i + 1].flags.mix) ||
863     (chaintype == 1 && !nymserv && (!remailer[i + 1].flags.ek
864     || !remailer[i + 1].flags.pgp))))
865     rlist[2 * i] = 0, rlist[2 * i + 1] = -2;
866     }
867     qsort(rlist, num - 1, 2 * sizeof(int), sortrel);
868    
869     for (i = 0; i < num; i++)
870     if (rlist[2 * i + 1] == -2) {
871     num = i;
872     break;
873     }
874     if (num < 1) {
875     mix_status("No remailers found!");
876     return;
877     }
878     if (num > 2 * (LINES - 6))
879     num = 2 * (LINES - 6);
880     if (num > 2 * 26)
881     num = 2 * 26;
882    
883     for (i = 0; i < num && rlist[2 * i + 1] > -2; i++) {
884     y = i, x = 0;
885     if (y >= LINES - 6)
886     y -= LINES - 6, x += 40;
887     mvprintw(y + 2, x, "%c", i < 26 ? i + 'a' : i - 26 + 'A');
888     mvprintw(y + 2, x + 2, "%s", remailer[rlist[2 * i]].name);
889     mvprintw(y + 2, x + 16, "%s",
890     remailer[rlist[2 * i]].info[chaintype].history);
891     sprintf(info, "%3.2f",
892     remailer[rlist[2 * i]].info[chaintype].reliability / 100.0);
893     mvprintw(y + 2, x + 29 + 6 - strlen(info), "%s%%", info);
894     }
895     y = num + 3;
896     if (y > LINES - 4)
897     y = LINES - 4;
898     mvprintw(y, 0, "* select at random");
899    
900     for (;;) {
901     newchain[0] = '\0';
902     for (i = 0; i < chainlen; i++) {
903     if (i)
904     strcatn(newchain, ",", CHAINMAX);
905     if (chain[i])
906     strcatn(newchain, remailer[chain[i]].name, CHAINMAX);
907     else
908     strcatn(newchain, "*", CHAINMAX);
909     }
910     if (chainlen > 0) {
911 weaselp 165 ok = 1;
912     middlemanlast = remailer[chain[chainlen - 1]].flags.middle;
913 weaselp 495 if (post && !remailer[chain[chainlen - 1]].flags.post && !(chain[chainlen - 1] == 0 /*randhop*/))
914 rabbi 1 ok = 0;
915     } else
916     ok = 1;
917    
918 weaselp 165 mvprintw(LINES - 4, 40,
919 weaselp 332 middlemanlast ?
920 weaselp 165 "MIDDLEMAN " :
921     (ok ?
922 weaselp 332 " " :
923 weaselp 165 "NO POSTING "));
924 rabbi 1 cl(LINES - 3, 0);
925     cl(LINES - 2, 0);
926     cl(LINES - 1, 0);
927     if(!nymserv){
928     chain_reliability(newchain, chaintype, reliability);
929     mvprintw(LINES - 4, 58, "(reliability: %s)", reliability);
930     }
931     mvprintw(LINES - 3, 0, nymserv ? "Nym server: %s" : "Chain: %s",
932     newchain);
933     refresh();
934     c = getch();
935     if (c == '\n' || c == '\r') {
936 weaselp 329 /* beep and sleep in case the user made a mistake */
937 weaselp 332 if (middlemanlast) {
938 weaselp 329 beep();
939     sleep(2);
940 rabbi 191 }
941 weaselp 165 if (ok || middlemanlast)
942 rabbi 1 break;
943     else
944     beep();
945     } else if (c == '*') {
946     if (chainlen > 19 || (nymserv && chainlen > 0))
947     beep();
948     else
949     chain[chainlen++] = 0;
950     } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
951     if (c >= 'a')
952     c -= 'a';
953     else
954     c = c - 'A' + 26;
955    
956     if (chainlen > 19 || (nymserv && chainlen > 0) || c >= num)
957     beep();
958     else
959     chain[chainlen++] = rlist[2 * c];
960     } else if (c == killchar())
961     chainlen = 0;
962     else if ((c == KEY_BACKSPACE || c == KEY_LEFT || c == erasechar())
963     && chainlen > 0)
964     --chainlen;
965     else
966     beep();
967     }
968     if (chainlen)
969     strncpy(chainstr, newchain, CHAINMAX);
970     }
971    
972 rabbi 262 #endif /* USE_NCURSES */

  ViewVC Help
Powered by ViewVC 1.1.5