/[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 577 - (hide annotations) (download)
Wed Aug 20 19:28:57 2003 UTC (9 years, 9 months ago) by weaselp
File MIME type: text/plain
File size: 21833 byte(s)
Fix bug introduced with the NYMSUPPORT patch.  mixmaster -ff works again.
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 577 $Id: menu.c,v 1.17 2003/08/20 19:28:57 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 weaselp 574 #ifdef NYMSUPPORT
112 rabbi 1 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 weaselp 574 #else
131 weaselp 577 {
132     buf_clear(mail);
133     from = -1, subject = -1;
134     continue;
135     }
136 weaselp 574 #endif /* NYMSUPPORT */
137 rabbi 262 #endif /* USE_PGP */
138 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
176 rabbi 256 mix_status("%s is empty.\n", path);
177 rabbi 1 goto end;
178     }
179 ulfm 289 if (mailfolder == -1) {
180 rabbi 1 #ifdef USE_NCURSES
181     clear();
182     beep();
183 rabbi 262 #endif /* USE_NCURSES */
184 rabbi 256 mix_status("%s is not a mail folder.\n", path);
185 rabbi 1 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 rabbi 262 #endif /* not USE_NCURSES */
197 rabbi 1
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 rabbi 262 #endif /* USE_NCURSES */
210 rabbi 1 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 rabbi 262 #endif /* USE_NCURSES */
424 rabbi 1
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 rabbi 262 #endif /* USE_NCURSES */
450 rabbi 1 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     BUFFER *chainlist, *line;
479     char nym[LINELEN] = ANON;
480    
481     chainlist = buf_new();
482     line = buf_new();
483    
484     mix_init(NULL);
485     menu_init();
486    
487     menu_redraw:
488     clear();
489     for (;;) {
490     standout();
491     mvprintw(0, 0, "Mixmaster %s", VERSION);
492     mvprintw(0, COLS - sizeof(COPYRIGHT), COPYRIGHT);
493     standend();
494     mix_status(NULL);
495    
496 weaselp 574 #ifdef NYMSUPPORT
497 rabbi 1 mvprintw(8, 4, "n)ym: %s", nym);
498 weaselp 574 #endif /* NYMSUPPORT */
499 rabbi 1 y = 12, x = 25;
500     mvprintw(y++, x, "m)ail");
501     mvprintw(y++, x, "p)ost to Usenet");
502 ulfm 289 mvprintw(y++, x, "r)ead mail (or news article)");
503 rabbi 1 mvprintw(y++, x, "d)ummy message");
504     mvprintw(y++, x, "s)end messages from pool");
505     mvprintw(y++, x, "q)uit");
506    
507     pool = pool_read(NULL);
508     if (pool == 1)
509     mvprintw(4, 2, "%3d outgoing message in the pool. \n", pool);
510     else
511     mvprintw(4, 2, "%3d outgoing messages in the pool.\n", pool);
512    
513     move(LINES - 1, COLS - 1);
514     refresh();
515     c = getch();
516     if (c != ERR) {
517     mix_status("");
518     switch (c) {
519     case '\014':
520     mix_status("");
521     goto menu_redraw;
522 weaselp 574 #ifdef NYMSUPPORT
523 rabbi 1 case 'n':
524     menu_nym(nym);
525     goto menu_redraw;
526 weaselp 574 #endif /* NYMSUPPORT */
527 rabbi 1 case 'm':
528     case 'p':
529     send_message(c, nym, NULL);
530     break;
531     case 'd':
532     mix_status("Creating message...");
533     if (mix_encrypt(MSG_NULL, NULL, NULL, 1, chainlist) != 0) {
534     if (chainlist->length > 0)
535     mix_status("%s", chainlist->data);
536     else
537     mix_genericerror();
538     beep();
539     } else {
540     for (n = 0; buf_getline(chainlist, line) == 0; n++) ;
541     if (n > 1)
542     mix_status("Done (%d packets).", n);
543     else
544     mix_status("Chain: %s", chainlist->data);
545     }
546     break;
547     case 's':
548     mix_status("Mailing messages...");
549     mix_send();
550     mix_status("Done.");
551     break;
552     case 'r':
553     {
554     char name[LINELEN];
555    
556     cl(LINES - 3, 0);
557     if (getenv("MAIL"))
558     printw("File name [%s]: ", getenv("MAIL"));
559     else
560     printw("File name: ");
561     echo();
562     wgetnstr(stdscr, name, LINELEN);
563     noecho();
564     cl(LINES - 3, 0);
565     if (name[0] == '\0') {
566     if (getenv("MAIL"))
567     read_folder(0, getenv("MAIL"), nym);
568     } else
569     read_folder(0, name, nym);
570     }
571     break;
572     case 'q':
573     case 'Q':
574     goto quit;
575     default:
576     beep();
577     }
578     }
579     }
580    
581     quit:
582     menu_exit();
583     buf_free(chainlist);
584     buf_free(line);
585     }
586    
587     void read_message(BUFFER *message, char *nym)
588     {
589     int l = 0;
590     int c;
591     int inhdr = 1, txtbegin;
592     BUFFER *field, *content, *line, *hdr;
593     char sub[LINELEN] = "mail";
594     char thisnym[LINELEN] = "";
595    
596     field = buf_new();
597     content = buf_new();
598     line = buf_new();
599     hdr = buf_new();
600    
601     if (thisnym[0] == '\0')
602     strncpy(thisnym, nym, LINELEN);
603    
604     if (bufleft(message, "From nymserver ")) {
605     /* select nym if Nym: pseudo header is in the first line */
606     buf_getline(message, line);
607     buf_getheader(message, field, content);
608     if (bufieq(field, "Nym"))
609     strncpy(thisnym, content->data, sizeof(thisnym));
610     buf_rewind(message);
611     }
612     while (buf_getheader(message, field, content) == 0) {
613     if (bufieq(field, "received") || bufleft(field, "From "))
614     continue;
615     if (bufieq(field, "subject"))
616     strncpy(sub, content->data, sizeof(sub));
617     buf_appendheader(hdr, field, content);
618     }
619     if (strlen(sub) > COLS - strlen(VERSION) - strlen(thisnym) - 23)
620     sub[COLS - strlen(VERSION) - strlen(thisnym) - 24] = '\0';
621     txtbegin = message->ptr;
622    
623     loop:
624     clear();
625     standout();
626     mvprintw(0, 0, "Mixmaster %s", VERSION);
627     printw(" %.20s reading %.50s\n", thisnym, sub);
628     standend();
629     mix_status(NULL);
630    
631     while (l < LINES - 2) {
632     if (inhdr) {
633     if (buf_getline(hdr, line) == -1)
634     buf_clear(line), inhdr = 0;
635     } else {
636     if (buf_getline(message, line) == -1) {
637     standout();
638     mvprintw(LINES - 1, 0, "Command");
639     standend();
640     refresh();
641     for (;;) {
642     c = getch();
643     switch (c) {
644     case 'm':
645     case 'p':
646     case 'r':
647     case 'g':
648     case 'f':
649     send_message(c, thisnym, message);
650     goto end;
651     case 'u':
652     inhdr = 0;
653     message->ptr = txtbegin;
654     l = 0;
655     goto loop;
656     case 'h':
657     inhdr = 1;
658     hdr->ptr = 0;
659     message->ptr = txtbegin;
660     l = 0;
661     goto loop;
662     case 's':
663     savemsg(message);
664     /* fallthru */
665     case 'q':
666     case 'i':
667     case '\n':
668     case '\r':
669     goto end;
670     case '\014':
671     refresh();
672     continue;
673     default:
674     beep();
675     refresh();
676     }
677     }
678     }
679     }
680     mvprintw(l + 1, 0, "%s\n", line->data);
681     l += (line->length - 1) / COLS + 1;
682     }
683     standout();
684     mvprintw(LINES - 1, 0, "MORE");
685     standend();
686     refresh();
687     for (;;) {
688     c = getch();
689     switch (c) {
690     case 'm':
691     case 'p':
692     case 'r':
693     case 'g':
694     case 'f':
695     send_message(c, thisnym, message);
696     goto end;
697     case 'u':
698     inhdr = 0;
699     message->ptr = txtbegin;
700     l = 0;
701     goto loop;
702     case 'h':
703     inhdr = 1; /* show full header */
704     hdr->ptr = 0;
705     message->ptr = txtbegin;
706     l = 0;
707     goto loop;
708     case 's':
709     savemsg(message);
710     /* fallthru */
711     case 'q':
712     case 'i':
713     goto end;
714     case ' ':
715     case '\n':
716     case '\r':
717     l = 0;
718     goto loop;
719     case '\014':
720     refresh();
721     continue;
722     default:
723     beep();
724     refresh();
725     }
726     }
727     end:
728     buf_free(field);
729     buf_free(content);
730     buf_free(line);
731     buf_free(hdr);
732     }
733    
734     int menu_replychain(int *d, int *l, char *mdest, char *pdest, char *psub,
735     char *r)
736     {
737     int c;
738     char line[LINELEN];
739     char reliability[9];
740    
741     redraw:
742     clear();
743     standout();
744     printw("Create a nym reply block:");
745     standend();
746     mix_status(NULL);
747    
748     mvprintw(3, 0, "Type of reply block:\n");
749     if (*d == MSG_MAIL)
750     standout();
751     printw(" m)ail ");
752     if (*d == MSG_MAIL)
753     standend();
754    
755     if (*d == MSG_POST)
756     standout();
757     printw(" Usenet message p)ool ");
758     if (*d == MSG_POST)
759     standend();
760    
761     if (*d == MSG_NULL)
762     standout();
763     printw(" cover t)raffic ");
764     if (*d == MSG_NULL)
765     standend();
766    
767     if (*d != MSG_NULL)
768     mvprintw(6, 0, "d)estination: %s", *d == MSG_MAIL ? mdest : pdest);
769     if (psub && *d == MSG_POST)
770     mvprintw(7, 0, "s)ubject: %s", psub);
771     chain_reliability(r, 1, reliability); /* chaintype 1=ek */
772     mvprintw(8, 0, "c)hain: %-39s (reliability: %s)", r, reliability);
773     mvprintw(10, 0, "l)atency: %d hours", *l);
774     move(LINES - 1, COLS - 1);
775    
776     for (;;) {
777     refresh();
778     c = getch();
779     switch (c) {
780     case 'm':
781     *d = MSG_MAIL;
782     goto redraw;
783     case 'p':
784     *d = MSG_POST;
785     goto redraw;
786     case 't':
787     *d = MSG_NULL;
788     goto redraw;
789     case 'q':
790     return (-1);
791     case 'd':
792     cl(6, 0);
793     printw("d)estination: ");
794     echo();
795     wgetnstr(stdscr, *d == MSG_MAIL ? mdest : pdest, LINELEN);
796     noecho();
797     goto redraw;
798     case 'l':
799     cl(10, 0);
800     printw("l)atency: ");
801     echo();
802     wgetnstr(stdscr, line, LINELEN);
803     *l = strtol(line, NULL, 10);
804     if (*l < 0)
805     *l = 0;
806     noecho();
807     goto redraw;
808     case 'c':
809     menu_chain(r, 1, *d == MSG_POST);
810     goto redraw;
811     case '\014':
812     goto redraw;
813     case '\n':
814     case '\r':
815     return (0);
816     case 's':
817     if (*d == MSG_POST) {
818     cl(7, 0);
819     printw("s)ubject: ");
820     echo();
821     wgetnstr(stdscr, psub, LINELEN);
822     noecho();
823     goto redraw;
824     }
825     default:
826     beep();
827     }
828     }
829     }
830    
831     void menu_chain(char *chainstr, int chaintype, int post)
832     /* chaintype 0=mix 1=ek 2=newnym */
833     {
834     REMAILER remailer[MAXREM];
835 weaselp 500 int badchains[MAXREM][MAXREM];
836 rabbi 1 int rlist[2 * MAXREM];
837     char newchain[CHAINMAX];
838     char info[LINELEN];
839 weaselp 165 int num = 0, i, middlemanlast=0, ok = 1;
840 rabbi 1 int c, x, y;
841     int nymserv = 0;
842     int chain[20], chainlen = 0;
843     char reliability[9];
844    
845     if (chaintype == 2)
846     nymserv = 1, chaintype = 1;
847     assert(chaintype == 0 || chaintype == 1);
848    
849     clear();
850     standout();
851     if (nymserv)
852     printw("Select nym server:\n\n");
853     else
854     printw("Select remailer chain:\n\n");
855     standend();
856    
857     if (chaintype == 1)
858 weaselp 500 num = t1_rlist(remailer, badchains);
859 rabbi 1 else
860 weaselp 500 num = mix2_rlist(remailer, badchains);
861 rabbi 1
862     if (num < 1) {
863     mix_status("Can't read remailer list.");
864     beep();
865     return;
866     }
867     for (i = 0; i < num; i++) {
868     rlist[2 * i] = i + 1;
869     rlist[2 * i + 1] = remailer[i + 1].info[chaintype].reliability -
870     remailer[i + 1].info[chaintype].latency / 3600;
871     if (remailer[i + 1].info[chaintype].history[0] == '\0')
872     rlist[2 * i + 1] = -1;
873     if ((nymserv && !remailer[i + 1].flags.newnym) ||
874     ((chaintype == 0 && !remailer[i + 1].flags.mix) ||
875     (chaintype == 1 && !nymserv && (!remailer[i + 1].flags.ek
876     || !remailer[i + 1].flags.pgp))))
877     rlist[2 * i] = 0, rlist[2 * i + 1] = -2;
878     }
879     qsort(rlist, num - 1, 2 * sizeof(int), sortrel);
880    
881     for (i = 0; i < num; i++)
882     if (rlist[2 * i + 1] == -2) {
883     num = i;
884     break;
885     }
886     if (num < 1) {
887     mix_status("No remailers found!");
888     return;
889     }
890     if (num > 2 * (LINES - 6))
891     num = 2 * (LINES - 6);
892     if (num > 2 * 26)
893     num = 2 * 26;
894    
895     for (i = 0; i < num && rlist[2 * i + 1] > -2; i++) {
896     y = i, x = 0;
897     if (y >= LINES - 6)
898     y -= LINES - 6, x += 40;
899     mvprintw(y + 2, x, "%c", i < 26 ? i + 'a' : i - 26 + 'A');
900     mvprintw(y + 2, x + 2, "%s", remailer[rlist[2 * i]].name);
901     mvprintw(y + 2, x + 16, "%s",
902     remailer[rlist[2 * i]].info[chaintype].history);
903     sprintf(info, "%3.2f",
904     remailer[rlist[2 * i]].info[chaintype].reliability / 100.0);
905     mvprintw(y + 2, x + 29 + 6 - strlen(info), "%s%%", info);
906     }
907     y = num + 3;
908     if (y > LINES - 4)
909     y = LINES - 4;
910     mvprintw(y, 0, "* select at random");
911    
912     for (;;) {
913     newchain[0] = '\0';
914     for (i = 0; i < chainlen; i++) {
915     if (i)
916     strcatn(newchain, ",", CHAINMAX);
917     if (chain[i])
918     strcatn(newchain, remailer[chain[i]].name, CHAINMAX);
919     else
920     strcatn(newchain, "*", CHAINMAX);
921     }
922     if (chainlen > 0) {
923 weaselp 165 ok = 1;
924     middlemanlast = remailer[chain[chainlen - 1]].flags.middle;
925 weaselp 495 if (post && !remailer[chain[chainlen - 1]].flags.post && !(chain[chainlen - 1] == 0 /*randhop*/))
926 rabbi 1 ok = 0;
927     } else
928     ok = 1;
929    
930 weaselp 165 mvprintw(LINES - 4, 40,
931 weaselp 332 middlemanlast ?
932 weaselp 165 "MIDDLEMAN " :
933     (ok ?
934 weaselp 332 " " :
935 weaselp 165 "NO POSTING "));
936 rabbi 1 cl(LINES - 3, 0);
937     cl(LINES - 2, 0);
938     cl(LINES - 1, 0);
939     if(!nymserv){
940     chain_reliability(newchain, chaintype, reliability);
941     mvprintw(LINES - 4, 58, "(reliability: %s)", reliability);
942     }
943     mvprintw(LINES - 3, 0, nymserv ? "Nym server: %s" : "Chain: %s",
944     newchain);
945     refresh();
946     c = getch();
947     if (c == '\n' || c == '\r') {
948 weaselp 329 /* beep and sleep in case the user made a mistake */
949 weaselp 332 if (middlemanlast) {
950 weaselp 329 beep();
951     sleep(2);
952 rabbi 191 }
953 weaselp 165 if (ok || middlemanlast)
954 rabbi 1 break;
955     else
956     beep();
957     } else if (c == '*') {
958     if (chainlen > 19 || (nymserv && chainlen > 0))
959     beep();
960     else
961     chain[chainlen++] = 0;
962     } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
963     if (c >= 'a')
964     c -= 'a';
965     else
966     c = c - 'A' + 26;
967    
968     if (chainlen > 19 || (nymserv && chainlen > 0) || c >= num)
969     beep();
970     else
971     chain[chainlen++] = rlist[2 * c];
972     } else if (c == killchar())
973     chainlen = 0;
974     else if ((c == KEY_BACKSPACE || c == KEY_LEFT || c == erasechar())
975     && chainlen > 0)
976     --chainlen;
977     else
978     beep();
979     }
980     if (chainlen)
981     strncpy(chainstr, newchain, CHAINMAX);
982     }
983    
984 rabbi 262 #endif /* USE_NCURSES */

  ViewVC Help
Powered by ViewVC 1.1.5