/[pkg-mixmaster]/trunk/Mix/Src/main.c
ViewVC logotype

Contents of /trunk/Mix/Src/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations) (download)
Wed Oct 31 08:19:51 2001 UTC (11 years, 7 months ago) by rabbi
File MIME type: text/plain
File size: 15169 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     Command-line based frontend
9     $Id: main.c,v 1.1 2001/10/31 08:19:53 rabbi Exp $ */
10    
11    
12     #include "mix3.h"
13     #include <stdio.h>
14     #include <string.h>
15     #include <ctype.h>
16     #ifdef POSIX
17     #include <unistd.h>
18     #else
19     #include <io.h>
20     #endif
21    
22     static char *largopt(char *p, char *opt, char *name, int *error);
23     static void noarg(char *name, char p);
24    
25     /** main *****************************************************************/
26    
27     /* Returns:
28     0 successful operation
29     1 command line error
30     2 client error condition */
31    
32     int main(int argc, char *argv[])
33     {
34     int error = 0, deflt = 1, help = 0, readmail = 0, send = -1, sendpool = 0,
35     header = 1, maint = 0, keygen = 0, verbose = 2, sign = 0, encrypt = 0;
36     int daemon = 0, type_list = 0;
37    
38     #ifdef USE_SOCK
39     int pop3 = 0;
40    
41     #endif
42     char *filename = NULL;
43     int i;
44     int ret = 0;
45     char *p, *q;
46     char chain[1024] = "";
47     char nym[LINELEN] = "";
48     BUFFER *nymopt, *pseudonym, *attachments;
49     int numcopies = 0; /* default value set in mix.cfg */
50     BUFFER *msg, *chainlist, *field, *content;
51     FILE *f;
52    
53     mix_init(NULL);
54    
55     msg = buf_new();
56     chainlist = buf_new();
57     nymopt = buf_new();
58     pseudonym = buf_new();
59     attachments = buf_new();
60     field = buf_new();
61     content = buf_new();
62    
63     #ifdef USE_NCURSES
64     if (argc == 1) {
65     if (isatty(fileno(stdin)))
66     menu_main();
67     else
68     menu_folder(0, NULL);
69     goto end;
70     }
71     #endif
72     if (argc > 1 && strleft(argv[1], "-f")) {
73     menu_folder(strlen(argv[1]) > 2 ? argv[1][2] : 0,
74     argc < 3 ? NULL : argv[2]);
75     goto end;
76     }
77     for (i = 1; i < argc; i++) {
78     p = argv[i];
79     if (p[0] == '-' && p[1] != '\0') {
80     if (p[1] == '-') {
81     p += 2;
82     if (strieq(p, "help"))
83     help = 1, deflt = 0;
84     else if (streq(p, "verbose"))
85     verbose = 1;
86     else if (streq(p, "type-list"))
87     type_list = 1;
88     else if (streq(p, "dummy"))
89     send = MSG_NULL, deflt = 0;
90     else if (streq(p, "remailer"))
91     maint = 1, deflt = 0;
92     else if (streq(p, "generate-key"))
93     keygen = 2, deflt = 0;
94     else if (streq(p, "update-keys"))
95     keygen = 1, deflt = 0;
96     else if (streq(p, "send"))
97     sendpool = 1, deflt = 0;
98     else if (streq(p, "read-mail"))
99     readmail = 1, deflt = 0;
100     #ifdef USE_SOCK
101     else if (streq(p, "pop-mail"))
102     pop3 = 1, deflt = 0;
103     #endif
104     else if (streq(p, "daemon"))
105     daemon = 1, deflt = 0;
106     else if (streq(p, "post"))
107     send = MSG_POST;
108     else if (streq(p, "mail"))
109     send = MSG_MAIL;
110     else if (streq(p, "sign"))
111     sign = 1;
112     else if (streq(p, "encrypt"))
113     encrypt = 1;
114     else if ((q = largopt(p, "to", argv[0], &error)) != NULL) {
115     header = 0;
116     buf_appendf(msg, "To: %s\n", q);
117     } else if ((q = largopt(p, "post-to", argv[0], &error)) != NULL) {
118     send = MSG_POST, header = 0;
119     buf_appendf(msg, "Newsgroups: %s\n", q);
120     } else if ((q = largopt(p, "subject", argv[0], &error)) != NULL) {
121     buf_appendf(msg, "Subject: %s\n", q);
122     } else if ((q = largopt(p, "header", argv[0], &error)) != NULL) {
123     buf_appendf(msg, "%s\n", q);
124     } else if ((q = largopt(p, "chain", argv[0], &error)) != NULL) {
125     buf_appendf(msg, "Chain: %s\n", q);
126     }
127     #ifdef USE_PGP
128     else if ((q = largopt(p, "reply-chain", argv[0], &error)) != NULL) {
129     buf_appendf(msg, "Reply-Chain: %s\n", q);
130     } else if ((q = largopt(p, "latency", argv[0], &error)) != NULL) {
131     buf_appendf(msg, "Latency: %s\n", q);
132     } else if ((q = largopt(p, "attachment", argv[0], &error)) != NULL) {
133     buf_appendf(attachments, "%s\n", q);
134     } else if ((q = largopt(p, "nym-config", argv[0], &error)) != NULL) {
135     deflt = 0;
136     strncpy(nym, q, sizeof(nym));
137     if (i > argc && strileft(argv[i + 1], "name="))
138     buf_sets(pseudonym, argv[++i] + 5);
139     else if (i > argc && strileft(argv[i + 1], "opt="))
140     buf_appends(nymopt, argv[++i] + 5);
141     } else if ((q = largopt(p, "nym", argv[0], &error)) != NULL) {
142     buf_appendf(msg, "Nym: %s\n", q);
143     }
144     #endif
145     else if ((q = largopt(p, "copies", argv[0], &error)) != NULL) {
146     sscanf(q, "%d", &numcopies);
147     } else if (error == 0 && mix_configline(p) == 0) {
148     fprintf(stderr, "%s: Invalid option %s\n", argv[0], argv[i]);
149     error = 1;
150     }
151     } else {
152     while (*++p) {
153     switch (*p) {
154     case 'd':
155     send = MSG_NULL, deflt = 0;
156     break;
157     case 'R':
158     readmail = 1, deflt = 0;
159     break;
160     case 'S':
161     sendpool = 1, deflt = 0;
162     break;
163     case 'M':
164     maint = 1, deflt = 0;
165     break;
166     #ifdef USE_SOCK
167     case 'P':
168     pop3 = 1, deflt = 0;
169     break;
170     #endif
171     case 'D':
172     daemon = 1, deflt = 0;
173     break;
174     case 'G':
175     keygen = 2, deflt = 0;
176     break;
177     case 'K':
178     keygen = 1, deflt = 0;
179     break;
180     case 'L': /* backwards compatibility */
181     break;
182     case 'v':
183     verbose = 1;
184     break;
185     case 'h':
186     help = 1, deflt = 0;
187     break;
188     case 'T':
189     type_list = 1;
190     break;
191     case 't':
192     if (*(p + 1) == 'o')
193     p++;
194     header = 0;
195     if (i < argc - 1)
196     buf_appendf(msg, "To: %s\n", argv[++i]);
197     else {
198     fprintf(stderr, "%s: Missing argument for option -to\n",
199     argv[0]);
200     error = 1;
201     }
202     break;
203     case 's':
204     if (i < argc - 1)
205     buf_appendf(msg, "Subject: %s\n", argv[++i]);
206     else {
207     noarg(argv[0], *p);
208     error = 1;
209     }
210     break;
211     case 'l':
212     if (i < argc - 1)
213     buf_appendf(msg, "Chain: %s\n", argv[++i]);
214     else {
215     noarg(argv[0], *p);
216     error = 1;
217     }
218     break;
219     case 'r':
220     if (i < argc - 1)
221     buf_appendf(msg, "Reply-Chain: %s\n, argv[++i]");
222     else {
223     noarg(argv[0], *p);
224     error = 1;
225     }
226     break;
227     #ifdef USE_PGP
228     case 'n':
229     if (i < argc - 1)
230     buf_appendf(msg, "Nym: %s\n", argv[++i]);
231     else {
232     noarg(argv[0], *p);
233     error = 1;
234     }
235     break;
236     #endif
237     case 'c':
238     if (i < argc - 1)
239     sscanf(argv[++i], "%d", &numcopies);
240     else {
241     noarg(argv[0], *p);
242     error = 1;
243     }
244     break;
245     case 'p':
246     send = MSG_POST;
247     break;
248     case 'g':
249     if (i < argc - 1) {
250     send = MSG_POST, header = 0;
251     buf_appendf(msg, "Newsgroups: %s\n", argv[++i]);
252     } else {
253     noarg(argv[0], *p);
254     error = 1;
255     }
256     case 'a':
257     if (i < argc - 1)
258     buf_appendf(attachments, "%s\n", argv[++i]);
259     else {
260     noarg(argv[0], *p);
261     error = 1;
262     }
263     case 'm':
264     send = MSG_MAIL;
265     break;
266     default:
267     fprintf(stderr, "%s: Invalid option -%c\n", argv[0], *p);
268     error = 1;
269     break;
270     }
271     }
272     }
273     } else {
274     if (strchr(argv[i], '@')) {
275     header = 0;
276     buf_appendf(msg, "To: %s\n", argv[i]);
277     } else {
278     if (filename == NULL)
279     filename = argv[i];
280     else {
281     fprintf(stderr, "%s: Error in command line: %s\n", argv[0], argv[i]);
282     error = 1;
283     }
284     }
285     }
286     }
287    
288     if (error) {
289     ret = 1;
290     goto end;
291     }
292     if (type_list) {
293     if (file_to_out(TYPE2LIST) < 0) {
294     fprintf(stderr, "File %s not found.\n", TYPE2LIST);
295     }
296     goto end;
297     }
298     if (help || (isatty(fileno(stdin)) && isatty(fileno(stdout))))
299     fprintf(stderr, "Mixmaster %s - %s\n", VERSION, COPYRIGHT);
300    
301     if (help) {
302     printf("Usage: %s [options] [user@host] [filename]\n\n", argv[0]);
303     printf("Options:\n\
304     \n\
305     -h, --help summary of command line options\n\
306     -T, --type-list list available remailers\n\
307     -t, --to=user@host the recipient's address(es)\n\
308     -g, --post-to=newsgroup newsgroup(s) to post to\n\
309     -p, --post input is a Usenet article\n\
310     -m, --mail input is a mail message\n\
311     -s, --subject=subject message subject\n\
312     --header='header line' arbitrary message headers\n\
313     -a, --attachment=file attach a file\n"
314     #ifdef USE_PGP
315     "-n, --nym=yournym use pseudonym to send the message\n\
316     --encrypt encrypt the message using the PGP format\n\
317     --sign sign the message using the PGP format\n"
318     #endif
319     "-l, --chain=mix1,mix2,mix3,... specify a remailer chain\n\
320     -c, --copies=num send num copies to increase reliability\n\
321     -d, --dummy generate a dummy message\n\
322     -S, --send send the message(s) in the pool\n"
323     #ifdef USE_PGP
324     " --nym-config=yournym generate a new pseudonym\n\
325     --latency=hours reply chain latency\n\
326     --reply-chain=rem1,rem2,... reply chain for the pseudonym\n"
327     #endif
328     "-v, --verbose output informational messages\n\
329     -f [file] read a mail folder\n"
330     #ifndef USE_NCURSES
331     "\n-fr, -ff, -fg [file] send reply/followup/group reply to a message\n"
332     #endif
333     "\nThe input file is expected to contain mail headers if no address is\n\
334     specified in the command line.\n\
335     \n\
336     Remailer:\n\
337     \n\
338     -R, --read-mail read remailer message from stdin\n\
339     -M, --remailer process the remailer pool\n\
340     -D, --daemon remailer as background process\n"
341     #ifdef USE_SOCK
342     "-S, --send force sending messages from the pool\n"
343     #endif
344     "-P, --pop-mail force getting messages from POP3 servers\n\
345     -G, --generate-key generate a new remailer key\n\
346     -K, --update-keys generate remailer keys if necessary\n");
347    
348     ret = 0;
349     goto end;
350     }
351     if (deflt && send == -1)
352     send = MSG_MAIL;
353     if (nym[0] != 0)
354     send = -1;
355     if ((send == MSG_MAIL || send == MSG_POST) && filename == NULL &&
356     header == 1 && isatty(fileno(stdin))) {
357     /* we don't get here if USE_NCURSES is set */
358     printf("Run `%s -h' to view a summary of the command line options.\n\nEnter the message, complete with headers.\n",
359     argv[0]);
360     #ifdef UNIX
361     printf("When done, press ^D.\n\n");
362     #else
363     printf("When done, press ^Z.\n\n");
364     #endif
365     }
366     if (header == 0)
367     buf_nl(msg);
368    
369     if (readmail || send == MSG_MAIL || send == MSG_POST) {
370     if (filename == NULL || streq(filename, "-"))
371     f = stdin;
372     else {
373     f = fopen(filename, "r");
374     if (f == NULL)
375     fprintf(stderr, "Can't open %s.\n", filename);
376     }
377    
378     if (f && buf_read(msg, f) != -1) {
379     if (readmail)
380     mix_decrypt(msg);
381     if (send == MSG_MAIL || send == MSG_POST) {
382     BUFFER *sendmsg;
383     int numdest = 0;
384    
385     sendmsg = buf_new();
386    
387     while (buf_getheader(msg, field, content) == 0) {
388     if (bufieq(field, "nym")) {
389     strncpy(nym, content->data, sizeof(nym));
390     } else if (bufieq(field, "chain"))
391     if (strchr(content->data, ';')) {
392     i = strchr(content->data, ';') - (char *)content->data;
393     strncpy(chain, content->data, i);
394     if (strstr(content->data + i, "copies=") != NULL) {
395     sscanf(strstr(content->data + i, "copies=") +
396     sizeof("copies=") - 1, "%d", &numcopies);
397     }
398     } else
399     strncpy(chain, content->data, sizeof(chain));
400     else { /* line goes into message */
401     if ((send == MSG_MAIL && bufieq(field, "to"))
402     || (send == MSG_POST && bufieq(field, "newsgroups")))
403     numdest++;
404     if (bufieq(field, "from"))
405     fprintf(stderr, "Warning: The message has a From: line.\n");
406     buf_appendheader(sendmsg, field, content);
407     }
408     }
409     buf_nl(sendmsg);
410     buf_rest(sendmsg, msg);
411    
412     while (buf_getline(attachments, field) != -1)
413     if (attachfile(sendmsg, field) == -1) {
414     errlog(ERRORMSG, "Can't attach %b!\n", field);
415     ret = 2;
416     goto end;
417     }
418    
419     #ifdef USE_PGP
420     if (nym[0] != 0 && strchr(nym, '@') == NULL)
421     strcatn(nym, "@", sizeof(nym));
422     if (sign || encrypt) {
423     BUFFER *pass;
424    
425     pass = buf_new();
426     user_pass(pass);
427     if (pgp_mailenc((encrypt ? PGP_ENCRYPT : 0) |
428     (nym[0] != 0 && sign ? PGP_SIGN : 0) |
429     PGP_TEXT | PGP_REMAIL, sendmsg, nym,
430     pass, NULL, NYMSECRING) != 0) {
431     fprintf(stderr, "Encryption failed: missing key!");
432     ret = 2;
433     goto end;
434     }
435     buf_free(pass);
436     }
437     if (nym[0] != 0) {
438     if (nym_encrypt(sendmsg, nym, send) == 0)
439     send = MSG_MAIL;
440     else
441     fprintf(stderr, "Nym error, sending message anonymously.\n");
442     }
443     #endif
444     if (numdest == 0) {
445     fprintf(stderr, "No destination address given!\n");
446     ret = 2;
447     } else if (numcopies < 0 || numcopies > 10) {
448     fprintf(stderr, "Invalid number of copies!\n");
449     ret = 2;
450     } else {
451     if (mix_encrypt(send, sendmsg, chain, numcopies,
452     chainlist) == -1) {
453     ret = 2;
454     if (chainlist->length)
455     fprintf(stderr, "%s\n", chainlist->data);
456     else
457     fprintf(stderr, "Failed!\n");
458     } else if (verbose) {
459     fprintf(stderr, "Chain: ");
460     buf_write(chainlist, stderr);
461     }
462     }
463    
464     buf_free(sendmsg);
465     }
466     if (filename != NULL)
467     fclose(f);
468     } else
469     ret = 2;
470     }
471     if (send == MSG_NULL) {
472     if (msg->length) {
473     while (buf_getheader(msg, field, content) == 0) {
474     if (bufieq(field, "chain"))
475     strncpy(chain, content->data, sizeof(chain));
476     }
477     }
478     if (mix_encrypt(MSG_NULL, NULL, chain, numcopies, chainlist) == -1) {
479     ret = 2;
480     if (chainlist->length)
481     fprintf(stderr, "%s\n", chainlist->data);
482     else
483     fprintf(stderr, "Failed!\n");
484     } else if (verbose) {
485     fprintf(stderr, "Chain: ");
486     buf_write(chainlist, stderr);
487     }
488     }
489     #ifdef USE_PGP
490     if (nym[0] != 0) {
491     char nymserver[LINELEN] = "*";
492     BUFFER *chains;
493    
494     chains = buf_new();
495     if (numcopies < 1 || numcopies > 10)
496     numcopies = 1;
497     while (buf_getheader(msg, field, content) != -1) {
498     if (bufieq(field, "chain"))
499     strncpy(chain, content->data, sizeof(chain));
500     else if (bufieq(field, "reply-chain"))
501     buf_appendf(chains, "Chain: %b\n", content);
502     else if (field->length)
503     buf_appendheader(chains, field, content);
504     else
505     buf_nl(chains);
506     }
507     if (strchr(nym, '@')) {
508     strncpy(nymserver, strchr(nym, '@'), sizeof(nymserver));
509     *strchr(nym, '@') = '\0';
510     }
511     if (nym_config(NYM_CREATE, nym, nymserver, pseudonym,
512     chain, numcopies, chains, nymopt) < 0) {
513     ret = 2;
514     fprintf(stderr, "Failed!\n");
515     }
516     user_delpass();
517     buf_free(chains);
518     }
519     #endif
520    
521     if (keygen)
522     keymgt(keygen);
523     if (sendpool)
524     mix_send();
525     #ifdef USE_SOCK
526     if (pop3)
527     pop3get();
528     #endif
529     if (maint)
530     mix_regular(0);
531    
532     end:
533     buf_free(field);
534     buf_free(content);
535     buf_free(chainlist);
536     buf_free(msg);
537     buf_free(nymopt);
538     buf_free(pseudonym);
539     buf_free(attachments);
540    
541     if (daemon) {
542     #ifdef UNIX
543     int pid;
544    
545     fprintf(stderr, "Detaching.\n");
546     pid = fork();
547     if (pid > 0)
548     exit(0);
549     #endif
550     mix_daemon();
551     }
552     mix_exit();
553     return (ret);
554     }
555    
556     static char *largopt(char *p, char *opt, char *name, int *error)
557     {
558     if (streq(p, opt)) {
559     fprintf(stderr, "%s: Missing argument for option --%s\n", name, p);
560     *error = 1;
561     } else if (strleft(p, opt) && p[strlen(opt)] == '=') {
562     return (p + strlen(opt) + 1);
563     }
564     return (NULL);
565     }
566    
567     static void noarg(char *name, char p)
568     {
569     fprintf(stderr, "%s: Missing argument for option -%c\n", name, p);
570     }

  ViewVC Help
Powered by ViewVC 1.1.5