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