/[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 - (hide annotations) (download)
Wed Oct 31 08:19:51 2001 UTC (11 years, 6 months ago) by rabbi
File MIME type: text/plain
File size: 20854 byte(s)
Initial revision
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     $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