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

  ViewVC Help
Powered by ViewVC 1.1.5