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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 137 - (show annotations) (download)
Mon Aug 19 19:55:58 2002 UTC (10 years, 9 months ago) by rabbi
File MIME type: text/plain
File size: 21665 byte(s)
Mixmaster now defaults to not offering network services if the line
"REMAIL = Y" is not present in mix.cfg.
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 Mixmaster initialization, configuration
9 $Id: mix.c,v 1.11 2002/08/19 19:55:58 rabbi Exp $ */
10
11
12 #include "mix3.h"
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdarg.h>
17 #include <ctype.h>
18 #include <time.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #ifdef POSIX
22 #include <unistd.h>
23 #include <pwd.h>
24 #include <sys/utsname.h>
25 #else
26 #include <io.h>
27 #include <direct.h>
28 #endif
29 #ifdef WIN32
30 #include <windows.h>
31 #endif
32 #include <assert.h>
33 #include "menu.h"
34
35 int buf_vappendf(BUFFER *b, char *fmt, va_list args);
36
37 /** filenames ************************************************************/
38 char MIXCONF[PATHMAX] = DEFAULT_MIXCONF; /* mixmaster configuration file */
39 char DISCLAIMFILE[PATHMAX] = DEFAULT_DISCLAIMFILE;
40 char FROMDSCLFILE[PATHMAX] = DEFAULT_FROMDSCLFILE;
41 char POP3CONF[PATHMAX] = DEFAULT_POP3CONF;
42 char HELPFILE[PATHMAX] = DEFAULT_HELPFILE;
43 char ABUSEFILE[PATHMAX] = DEFAULT_ABUSEFILE;
44 char REPLYFILE[PATHMAX] = DEFAULT_REPLYFILE;
45 char USAGEFILE[PATHMAX] = DEFAULT_USAGEFILE;
46 char USAGELOG[PATHMAX] = DEFAULT_USAGELOG;
47 char BLOCKFILE[PATHMAX] = DEFAULT_BLOCKFILE;
48 char ADMKEYFILE[PATHMAX] = DEFAULT_ADMKEYFILE;
49 char KEYFILE[PATHMAX] = DEFAULT_KEYFILE;
50 char PGPKEY[PATHMAX] = DEFAULT_PGPKEY;
51 char DSAPARAMS[PATHMAX] = DEFAULT_DSAPARAMS;
52 char DHPARAMS[PATHMAX] = DEFAULT_DHPARAMS;
53 char MIXRAND[PATHMAX] = DEFAULT_MIXRAND;
54 char SECRING[PATHMAX] = DEFAULT_SECRING;
55 char PUBRING[PATHMAX] = DEFAULT_PUBRING;
56 char IDLOG[PATHMAX] = DEFAULT_IDLOG;
57 char STATS[PATHMAX] = DEFAULT_STATS;
58 /* To enable multiple dest.blk files, edit the following line. */
59 /* Filenames must be seperated by one space. */
60 char DESTBLOCK[PATHMAX] = DEFAULT_DESTBLOCK;
61 char DESTALLOW[PATHMAX] = DEFAULT_DESTALLOW;
62 char SOURCEBLOCK[PATHMAX] = DEFAULT_SOURCEBLOCK;
63 char HDRFILTER[PATHMAX] = DEFAULT_HDRFILTER;
64 char REGULAR[PATHMAX] = DEFAULT_REGULAR;
65 char POOL[PATHMAX] = DEFAULT_POOL; /* remailer pool subdirectory */
66 char TYPE1LIST[PATHMAX] = DEFAULT_TYPE1LIST;
67 char TYPE2REL[PATHMAX] = DEFAULT_TYPE2REL;
68 char TYPE2LIST[PATHMAX] = DEFAULT_TYPE2LIST;
69
70 char PGPREMPUBRING[PATHMAX] = DEFAULT_PGPREMPUBRING;
71 char PGPREMPUBASC[PATHMAX] = DEFAULT_PGPREMPUBASC;
72 char PGPREMSECRING[PATHMAX] = DEFAULT_PGPREMSECRING;
73 char NYMSECRING[PATHMAX] = DEFAULT_NYMSECRING;
74 char NYMDB[PATHMAX] = DEFAULT_NYMDB;
75
76
77 /** config ***************************************************************/
78
79 char MIXDIR[PATHMAX];
80 char POOLDIR[PATHMAX];
81
82 /* programs */
83 #ifdef WIN32
84 char SENDMAIL[LINELEN] = "outfile";
85 #else
86 char SENDMAIL[LINELEN] = "/usr/lib/sendmail -t";
87 #endif
88 char SENDANONMAIL[LINELEN];
89 char NEWS[LINELEN];
90 char TYPE1[LINELEN];
91
92 /* addresses */
93 char MAILtoNEWS[LINELEN] = "mail2news@anon.lcs.mit.edu";
94 char REMAILERNAME[LINELEN] = "Anonymous Remailer";
95 char ANONNAME[LINELEN] = "Anonymous";
96 char REMAILERADDR[LINELEN];
97 char ANONADDR[LINELEN];
98 char COMPLAINTS[LINELEN];
99 int AUTOREPLY;
100 char SMTPRELAY[LINELEN];
101
102 #ifdef USE_SOCK
103 char HELONAME[LINELEN];
104 char ENVFROM[LINELEN];
105 int POP3DEL = 0;
106 int POP3SIZELIMIT = 0;
107 long POP3TIME = 60 * 60;
108
109 #endif
110
111 char SHORTNAME[LINELEN];
112
113 /* remailer configuration */
114 int REMAIL = 0;
115 int MIX = 1;
116 int PGP = 1;
117 int UNENCRYPTED = 0;
118 int REMIX = 1;
119 int REPGP = 1;
120
121 int POOLSIZE = 0;
122 int RATE = 100;
123 int MIDDLEMAN = 0;
124 int AUTOBLOCK = 1;
125 char FORWARDTO[LINELEN] = "*";
126 int SIZELIMIT = 0; /* maximal size of remailed messages */
127 int INFLATEMAX = 50; /* maximal size of Inflate: padding */
128 int MAXRANDHOPS = 20;
129 int BINFILTER = 0; /* filter binary attachments? */
130 long PACKETEXP = 7 * SECONDSPERDAY; /* Expiration time for old packets */
131 long IDEXP = 7 * SECONDSPERDAY; /* 0 = no ID log !! */
132 long SENDPOOLTIME = 60 * 60; /* frequency for sending pool messages */
133
134 char ERRLOG[LINELEN];
135 char ADDRESS[LINELEN];
136 char NAME[LINELEN];
137
138 char ORGANIZATION[LINELEN] = "Anonymous Posting Service";
139 char MID[LINELEN] = "y";
140
141 /* client config */
142 int NUMCOPIES = 1;
143 char CHAIN[LINELEN] = "*,*,*,*";
144 int VERBOSE = 2;
145 int DISTANCE = 2;
146 int MINREL = 98;
147 int RELFINAL = 99;
148 long MAXLAT = 36 * 60 * 60;
149 char PGPPUBRING[PATHMAX];
150 char PGPSECRING[PATHMAX];
151 #ifdef COMPILEDPASS
152 char PASSPHRASE[LINELEN] = COMPILEDPASS;
153 #else
154 char PASSPHRASE[LINELEN] = "";
155 #endif
156 char MAILBOX[PATHMAX] = "mbox";
157 char MAILABUSE[PATHMAX];
158 char MAILBLOCK[PATHMAX];
159 #ifdef WIN32
160 char MAILUSAGE[PATHMAX] = "nul:";
161 char MAILANON[PATHMAX] = "nul:";
162 char MAILERROR[PATHMAX] = "nul:";
163 #else
164 char MAILUSAGE[PATHMAX] = "/dev/null";
165 char MAILANON[PATHMAX] = "/dev/null";
166 char MAILERROR[PATHMAX] = "/dev/null";
167 #endif
168 char MAILBOUNCE[PATHMAX];
169
170 #if defined(S_IFDIR) && !defined(S_ISDIR)
171 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
172 #endif
173
174 static int mixdir(char *d, int create)
175 {
176 int err;
177 struct stat buf;
178
179 if (d != MIXDIR)
180 strncpy(MIXDIR, d, PATHMAX);
181 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
182 MIXDIR[strlen(MIXDIR) - 1] = '\0';
183 err = stat(MIXDIR, &buf);
184 if (err == -1) {
185 if (create) {
186 #ifndef POSIX
187 err = mkdir(MIXDIR);
188 #else
189 err = mkdir(MIXDIR, S_IRWXU);
190 #endif
191 if (err == 0)
192 errlog(NOTICE, "Creating directory %s.\n", MIXDIR);
193 } else
194 err = 1;
195 } else if (!S_ISDIR(buf.st_mode))
196 err = -1;
197 if (err == 0)
198 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
199 return (err);
200 }
201
202 void whoami(char *addr, char *defaultname)
203 {
204 char *p = NULL;
205
206 #if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME))
207 char line[LINELEN];
208
209 #endif
210 #ifdef HAVE_UNAME
211 struct utsname uts;
212
213 #endif
214 #ifdef POSIX
215 p = getlogin();
216 #endif
217 if (p == NULL)
218 strcpy(addr, defaultname);
219 else
220 strncpy(addr, p, LINELEN);
221
222 strcatn(addr, "@", LINELEN);
223 #ifdef HAVE_UNAME
224 if (uname(&uts) != -1)
225 strcatn(addr, uts.nodename, LINELEN);
226 #elif defined(HAVE_GETHOSTNAME)
227 if (gethostname(line, LINELEN) == 0)
228 strcatn(addr, line, LINELEN);
229 #endif
230 if (addr[strlen(addr) - 1] == '@')
231 strcatn(addr, SHORTNAME, LINELEN);
232
233 if (strchr(strchr(addr, '@'), '.') == NULL) {
234 #ifdef HAVE_GETDOMAINNAME
235 if (getdomainname(line, LINELEN) == 0 && !streq(line, "(none)")) {
236 strcatn(addr, ".", LINELEN);
237 strcatn(addr, line, LINELEN);
238 }
239 #endif
240 }
241 }
242
243 #define read_conf(t) readconfline(line, #t, sizeof(#t)-1, t)
244
245 static int readconfline(char *line, char *name, int namelen, char *var)
246 {
247 if (strncmp(line, name, namelen) == 0 &&
248 (isspace(line[namelen]) || line[namelen] == '=')) {
249 line += namelen;
250 if (*line == '=')
251 line++;
252 while (isspace(*line))
253 line++;
254 if (line[0] == '\n' || line[0] == '\0') /* leave default */
255 return (1);
256 strncpy(var, line, LINELEN);
257 if (var[strlen(var) - 1] == '\n')
258 var[strlen(var) - 1] = '\0';
259 return (1);
260 } else
261 return (0);
262 }
263
264 #define read_conf_i(t) readiconfline(line, #t, sizeof(#t)-1, &t)
265
266 static int readiconfline(char *line, char *name, int namelen, int *var)
267 {
268 if (strncmp(line, name, namelen) == 0 &&
269 (isspace(line[namelen]) || line[namelen] == '=')) {
270 line += namelen;
271 if (*line == '=')
272 line++;
273 while (isspace(*line))
274 line++;
275 if (line[0] == '\n' || line[0] == '\0') /* leave default */
276 return (1);
277 switch (tolower(line[0])) {
278 case 'n':
279 *var = 0;
280 break;
281 case 'y':
282 *var = 1;
283 break;
284 case 'x':
285 *var = 2;
286 break;
287 default:
288 sscanf(line, "%d", var);
289 }
290 return (1);
291 } else
292 return (0);
293 }
294
295 #define read_conf_t(t) readtconfline(line, #t, sizeof(#t)-1, &t)
296
297 static int readtconfline(char *line, char *name, int namelen, long *var)
298 {
299 char *linenext;
300 int mod = 0;
301 long l = 0;
302 long n;
303
304 if (strncmp(line, name, namelen) == 0 &&
305 (isspace(line[namelen]) || line[namelen] == '=')) {
306 line += namelen;
307 if (*line == '=')
308 line++;
309 for (;; line++) {
310 n = strtol(line, &linenext, 10);
311 if (linenext == line)
312 break;
313 line = linenext;
314 mod = 1;
315 assert(line != NULL);
316 while (isspace(*line))
317 line++;
318 switch (tolower(*line)) {
319 case 'd':
320 l += 24 * 60 * 60 * n;
321 break;
322 case 'm':
323 l += 60 * n;
324 break;
325 case 'h':
326 default:
327 l += 60 * 60 * n;
328 break;
329 }
330 }
331 if (mod)
332 *var = l;
333 return (1);
334 } else
335 return (0);
336 }
337
338 int mix_configline(char *line)
339 {
340 return (read_conf(ADDRESS) || read_conf(NAME) ||
341 read_conf(SHORTNAME) || read_conf(REMAILERADDR) ||
342 read_conf(ANONADDR) || read_conf(REMAILERNAME) ||
343 read_conf(ANONNAME) || read_conf(COMPLAINTS) ||
344 read_conf_i(AUTOREPLY) || read_conf(SMTPRELAY) ||
345 #ifdef USE_SOCK
346 read_conf(HELONAME) || read_conf(ENVFROM) ||
347 #endif
348 read_conf(SENDMAIL) || read_conf(SENDANONMAIL) ||
349 read_conf_i(REMAIL) || read_conf_i(MIX) ||
350 read_conf_i(PGP) || read_conf_i(UNENCRYPTED) ||
351 read_conf_i(REMIX) || read_conf(NEWS) ||
352 read_conf_i(REPGP) ||
353 read_conf(MAILtoNEWS) || read_conf(ERRLOG) ||
354 read_conf(ORGANIZATION) || read_conf(MID) ||
355 read_conf(TYPE1) || read_conf_i(POOLSIZE) ||
356 read_conf_i(RATE) || read_conf_i(MIDDLEMAN) ||
357 read_conf_i(AUTOBLOCK) || read_conf(FORWARDTO) ||
358 read_conf_i(SIZELIMIT) || read_conf_i(INFLATEMAX) ||
359 read_conf_i(MAXRANDHOPS) || read_conf_i(BINFILTER) ||
360 read_conf_t(PACKETEXP) || read_conf_t(IDEXP) ||
361 read_conf_t(SENDPOOLTIME) || read_conf_i(NUMCOPIES) ||
362 read_conf(CHAIN) || read_conf_i(VERBOSE) ||
363 read_conf_i(DISTANCE) || read_conf_i(MINREL) ||
364 read_conf_i(RELFINAL) || read_conf_t(MAXLAT) ||
365 read_conf(PGPPUBRING) || read_conf(PGPSECRING) ||
366 read_conf(PASSPHRASE) ||
367 #ifdef USE_SOCK
368 read_conf_i(POP3DEL) || read_conf_i(POP3SIZELIMIT) ||
369 read_conf_t(POP3TIME) ||
370 #endif
371 read_conf(MAILBOX) || read_conf(MAILABUSE) ||
372 read_conf(MAILBLOCK) || read_conf(MAILUSAGE) ||
373 read_conf(MAILANON) || read_conf(MAILERROR) ||
374 read_conf(MAILBOUNCE) ||
375
376 read_conf(DISCLAIMFILE) || read_conf(FROMDSCLFILE) ||
377 read_conf(POP3CONF) || read_conf(HELPFILE) ||
378 read_conf(ABUSEFILE) || read_conf(REPLYFILE) ||
379 read_conf(USAGEFILE) || read_conf(USAGELOG) ||
380 read_conf(BLOCKFILE) || read_conf(ADMKEYFILE) ||
381 read_conf(KEYFILE) || read_conf(PGPKEY) ||
382 read_conf(DSAPARAMS) || read_conf(DHPARAMS) ||
383 read_conf(MIXRAND) || read_conf(SECRING) ||
384 read_conf(PUBRING) || read_conf(IDLOG) ||
385 read_conf(STATS) || read_conf(DESTBLOCK) ||
386 read_conf(DESTALLOW) || read_conf(SOURCEBLOCK) ||
387 read_conf(HDRFILTER) || read_conf(REGULAR) ||
388 read_conf(POOL) || read_conf(TYPE1LIST) ||
389 read_conf(TYPE2REL) || read_conf(TYPE2LIST) ||
390 read_conf(PGPREMPUBRING) || read_conf(PGPREMPUBASC) ||
391 read_conf(PGPREMSECRING) || read_conf(NYMSECRING) ||
392 read_conf(NYMDB) );
393
394 }
395
396 static int mix_config(void)
397 {
398 char *d;
399 FILE *f;
400 char line[PATHMAX];
401 int err = -1;
402 #ifdef POSIX
403 struct passwd *pw;
404 #endif
405 struct stat buf;
406 #ifdef HAVE_UNAME
407 struct utsname uts;
408 #endif
409 #ifdef WIN32
410 HKEY regsw, reg, regpgp;
411 DWORD type, len;
412 int rkey = 0;
413 #endif
414
415 #ifdef POSIX
416 pw = getpwuid(getuid());
417 #endif
418
419 if (MIXDIR[0]) /* if set by main() */
420 err = mixdir(MIXDIR, 1);
421
422 #ifdef WIN32
423 RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &regsw);
424 len=sizeof(line);
425 if (err == -1 &&
426 RegOpenKeyEx(regsw, "Mixmaster", 0, KEY_QUERY_VALUE, &reg) == 0) {
427 if (RegQueryValueEx(reg, "MixDir", 0, &type, line, &len) == 0)
428 err = mixdir(line, 1);
429 RegCloseKey(reg);
430 }
431 #endif
432
433 if (err == -1 && (d = getenv("MIXPATH")) != NULL)
434 err = mixdir(d, 1);
435
436 #ifdef SPOOL
437 if (err == -1 && strlen(SPOOL) > 0)
438 err = mixdir(SPOOL, 0);
439 #endif
440
441 #ifdef POSIX
442 if (err == -1 && pw != NULL) {
443 strncpy(line, pw->pw_dir, PATHMAX);
444 line[PATHMAX-1] = '\0';
445 if (line[strlen(line) - 1] != DIRSEP)
446 strcatn(line, DIRSEPSTR, PATHMAX);
447 strcatn(line, HOMEMIXDIR, PATHMAX);
448 err = mixdir(line, 1);
449 }
450 #endif
451
452 if (err == -1) {
453 getcwd(MIXDIR, PATHMAX);
454 mixdir(MIXDIR, 0);
455 }
456
457 strncpy(POOLDIR, MIXDIR, PATHMAX - 32);
458 strcatn(POOLDIR, POOL, PATHMAX);
459 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
460 POOLDIR[strlen(POOLDIR) - 1] = '\0';
461 if (stat(POOLDIR, &buf) != 0)
462 if
463 #ifndef POSIX
464 (mkdir(POOLDIR) != 0)
465 #else
466 (mkdir(POOLDIR, S_IRWXU) == -1)
467 #endif
468 strncpy(POOLDIR, MIXDIR, PATHMAX);
469
470 #ifdef GLOBALMIXCONF
471 f = mix_openfile(GLOBALMIXCONF, "r");
472 if (f != NULL) {
473 while (fgets(line, LINELEN, f) != NULL)
474 if (line[0] > ' ' && line[0] != '#')
475 mix_configline(line);
476 fclose(f);
477 }
478 #endif
479 f = mix_openfile(MIXCONF, "r");
480 if (f != NULL) {
481 while (fgets(line, LINELEN, f) != NULL)
482 if (line[0] > ' ' && line[0] != '#')
483 mix_configline(line);
484 fclose(f);
485 }
486 if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY)
487 IDEXP = 5 * SECONDSPERDAY;
488 if (MAXRANDHOPS > 20)
489 MAXRANDHOPS = 20;
490
491 if (strchr(SHORTNAME, '.'))
492 *strchr(SHORTNAME, '.') = '\0';
493 if (strchr(SHORTNAME, ' '))
494 *strchr(SHORTNAME, ' ') = '\0';
495 #ifdef HAVE_UNAME
496 if (SHORTNAME[0] == '\0' && uname(&uts) != -1)
497 strncpy(SHORTNAME, uts.nodename, LINELEN);
498 #elif defined(HAVE_GETHOSTNAME)
499 if (SHORTNAME[0] == '\0')
500 gethostname(SHORTNAME, LINELEN);
501 #endif
502 if (SHORTNAME[0] == '\0')
503 strcpy(SHORTNAME, "unknown");
504
505 if (ADDRESS[0] == '\0')
506 whoami(ADDRESS, "user");
507
508 #ifdef HAVE_GECOS
509 if (NAME[0] == '\0' && pw != NULL)
510 strcatn(NAME, pw->pw_gecos, sizeof(NAME));
511 #endif
512
513 if (REMAILERADDR[0] == '\0')
514 strncpy(REMAILERADDR, ADDRESS, LINELEN);
515
516 if (COMPLAINTS[0] == '\0')
517 strncpy(COMPLAINTS, REMAILERADDR, LINELEN);
518
519 if (strchr(REMAILERNAME, '@') == NULL) {
520 strcatn(REMAILERNAME, " <", LINELEN);
521 strcatn(REMAILERNAME, REMAILERADDR, LINELEN);
522 strcatn(REMAILERNAME, ">", LINELEN);
523 }
524 if (strchr(ANONNAME, '@') == NULL && ANONADDR[0] != '\0') {
525 strcatn(ANONNAME, " <", LINELEN);
526 strcatn(ANONNAME, ANONADDR, LINELEN);
527 strcatn(ANONNAME, ">", LINELEN);
528 }
529 if (strchr(ANONNAME, '@') == NULL) {
530 strcatn(ANONNAME, " <", LINELEN);
531 strcatn(ANONNAME, REMAILERADDR, LINELEN);
532 strcatn(ANONNAME, ">", LINELEN);
533 }
534 #ifndef USE_PGP
535 if (TYPE1[0] == '\0')
536 PGP = 0;
537 #endif
538 #ifndef USE_RSA
539 MIX = 0;
540 #endif
541
542 #ifdef WIN32
543 if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, &regpgp) == 0)
544 rkey++;
545 if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, &reg) == 0)
546 rkey++;
547 if (PGPPUBRING[0] == '\0' && rkey == 2) {
548 len = PATHMAX;
549 RegQueryValueEx(reg, "PubRing", 0, &type, PGPPUBRING, &len);
550 }
551 if (PGPSECRING[0] == '\0' && rkey == 2) {
552 len = PATHMAX;
553 RegQueryValueEx(reg, "SecRing", 0, &type, PGPSECRING, &len);
554 }
555 if (rkey == 2)
556 RegCloseKey(reg);
557 if (rkey)
558 RegCloseKey(regpgp);
559 RegCloseKey(regsw);
560 #endif
561
562 if (PGPPUBRING[0] == '\0') {
563 char *d;
564
565 if ((d = getenv("HOME")) != NULL) {
566 strcpy(PGPPUBRING, d);
567 strcatn(PGPPUBRING, "/.pgp/", PATHMAX);
568 }
569 strcatn(PGPPUBRING, "pubring.pkr", PATHMAX);
570 if (stat(PGPPUBRING, &buf) == -1)
571 strcpy(strrchr(PGPPUBRING, '.'), ".pgp");
572 }
573 if (PGPSECRING[0] == '\0') {
574 char *d;
575
576 if ((d = getenv("HOME")) != NULL) {
577 strcpy(PGPSECRING, d);
578 strcatn(PGPSECRING, "/.pgp/", PATHMAX);
579 }
580 strcatn(PGPSECRING, "secring.skr", PATHMAX);
581 if (stat(PGPSECRING, &buf) == -1)
582 strcpy(strrchr(PGPSECRING, '.'), ".pgp");
583 }
584 if (streq(NEWS, "mail-to-news"))
585 strncpy(NEWS, MAILtoNEWS, sizeof(NEWS));
586
587 if (f == NULL) {
588 #ifndef GLOBALMIXCONF
589 /* Only write the config file in non systemwide installation */
590 f = mix_openfile(MIXCONF, "w");
591 if (f == NULL)
592 errlog(WARNING, "Can't open %s%s!\n", MIXDIR, MIXCONF);
593 else {
594 fprintf(f, "# mix.cfg - mixmaster configuration file\n");
595 fprintf(f, "NAME %s\n", NAME);
596 fprintf(f, "ADDRESS %s\n", ADDRESS);
597 fprintf(f, "\n# edit to set up a remailer:\n");
598 fprintf(f, "REMAIL n\n");
599 fprintf(f, "SHORTNAME %s\n", SHORTNAME);
600 fprintf(f, "REMAILERADDR %s\n", REMAILERADDR);
601 fprintf(f, "COMPLAINTS %s\n", COMPLAINTS);
602 fclose(f);
603 }
604 #endif
605 REMAIL = 0;
606 }
607
608 return (0);
609 }
610
611 /** Library initialization: ******************************************/
612
613 static int initialized = 0;
614
615 int mix_init(char *mixdir)
616 {
617 if (!initialized) {
618 if (mixdir)
619 strncpy(MIXDIR, mixdir, LINELEN);
620 mix_config();
621 #if defined(USE_SOCK) && defined(WIN32)
622 sock_init();
623 #endif
624 /* atexit (mix_exit); */
625 initialized = 1;
626 }
627
628 if (rnd_init() == -1)
629 rnd_seed();
630 return(0);
631 }
632
633 void mix_exit(void)
634 {
635 if (!initialized)
636 return;
637 rnd_final();
638 #if defined(USE_SOCK) && defined(WIN32)
639 sock_exit();
640 #endif
641 initialized=0;
642 }
643
644 int mix_regular(int force)
645 {
646 FILE *f;
647 long now, tpool = 0, tpop3 = 0, tdaily = 0;
648 int ret = 0;
649
650 mix_init(NULL);
651 now = time(NULL);
652
653 f = mix_openfile(REGULAR, "r+");
654 if (f != NULL) {
655 lock(f);
656 fscanf(f, "%ld %ld %ld", &tpool, &tpop3, &tdaily);
657 if (now - tpool > SENDPOOLTIME)
658 force |= FORCE_POOL;
659 #ifdef USE_SOCK
660 if (now - tpop3 > POP3TIME)
661 force |= FORCE_POP3;
662 #endif
663 if (now - tdaily > SECONDSPERDAY)
664 force |= FORCE_DAILY;
665 if (force & FORCE_POOL)
666 tpool = now;
667 if (force & FORCE_POP3)
668 tpop3 = now;
669 if (force & FORCE_DAILY)
670 tdaily = now;
671 rewind(f);
672 fprintf(f, "%ld %ld %ld\n", tpool, tpop3, tdaily);
673 unlock(f);
674 fclose(f);
675 } else {
676 force = FORCE_POOL | FORCE_POP3 | FORCE_DAILY;
677 f = mix_openfile(REGULAR, "w+");
678 if (f != NULL) {
679 lock(f);
680 fprintf(f, "%ld %ld %ld\n", now, now, now);
681 unlock(f);
682 fclose(f);
683 } else
684 errlog(ERRORMSG, "Can't create %s!\n", REGULAR);
685 }
686
687 if (force & FORCE_DAILY)
688 mix_daily(), ret = 1;
689 #ifdef USE_SOCK
690 if (force & FORCE_POP3)
691 pop3get();
692 #endif
693 if (force & FORCE_POOL)
694 ret = pool_send();
695
696 return (ret);
697 }
698
699 int mix_daily(void)
700 {
701 idexp();
702 pool_packetexp();
703 stats(NULL);
704 keymgt(0);
705 return (0);
706 }
707
708
709 #ifdef WIN32
710 /* Try to detect if we are the service or not...
711 seems there is no easy reliable way */
712 int is_nt_service(void)
713 {
714 static int issvc = -1;
715 #ifdef WIN32SERVICE
716 STARTUPINFO StartupInfo;
717 OSVERSIONINFO VersionInfo;
718 DWORD dwsize;
719
720 if (issvc != -1) /* do it only once */
721 return issvc;
722
723 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
724 if (GetVersionEx(&VersionInfo))
725 if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
726 return issvc = 0; /* not NT - not the service */
727
728 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
729 /* reuse VersionInfo to save memory */
730 return issvc = 1; /* have no console - we are the service probably */
731
732 GetStartupInfo(&StartupInfo);
733 if (StartupInfo.lpDesktop[0] == 0)
734 return issvc = 1; /* have no desktop - we are the service probably */
735
736 if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
737 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
738 #endif // WIN32SERVICE
739
740 return issvc = 0; // assume not the service
741 } // is_nt_service
742
743 HANDLE hMustTerminate = NULL;
744 void set_nt_exit_event(HANDLE h_svc_exit_event)
745 {
746 hMustTerminate = h_svc_exit_event;
747 } // set_nt_exit_event
748
749 #endif // WIN32
750
751 int mix_daemon(void)
752 {
753 long t;
754 t = SENDPOOLTIME;
755 #ifdef USE_SOCK
756 if (POP3TIME < t)
757 t = POP3TIME;
758 #endif
759
760 for(;;) {
761 mix_regular(0);
762 #ifdef WIN32
763 #ifdef WIN32SERVICE
764 if (hMustTerminate) {
765 if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
766 CloseHandle(hMustTerminate);
767 return 0;
768 }
769 } else
770 #endif
771 Sleep(t * 1000);
772 #else
773 sleep(t);
774 #endif
775 }
776 }
777
778 /** error ***************************************************************/
779
780 void errlog(int type, char *fmt,...)
781 {
782 va_list args;
783 BUFFER *msg;
784 FILE *e = NULL;
785 time_t t;
786 struct tm *tc;
787 char line[LINELEN];
788 int p;
789 char err[6][8] =
790 {"", "Error", "Warning", "Notice", "Info", "Info"};
791
792 if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
793 || (type == DEBUGINFO && VERBOSE < 3))
794 return;
795
796 t = time(NULL);
797 tc = localtime(&t);
798 strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);
799
800 msg = buf_new();
801 buf_appends(msg, line);
802 p = msg->length;
803 buf_appendf(msg, "%s: ", err[type]);
804 va_start(args, fmt);
805 buf_vappendf(msg, fmt, args);
806 va_end(args);
807
808 if (streq(ERRLOG, "stdout"))
809 e = stdout;
810 else if (streq(ERRLOG, "stderr"))
811 e = stderr;
812
813 if (e == NULL && (ERRLOG[0] == '\0' ||
814 (e = mix_openfile(ERRLOG, "a")) == NULL))
815 mix_status("%s", msg->data + p);
816 else {
817 buf_write(msg, e);
818 if (e != stderr && e != stdout) {
819 fclose(e);
820 /* duplicate the error message on screen */
821 mix_status("%s", msg->data + p);
822 }
823 }
824 buf_free(msg);
825 }
826
827 static char statusline[BUFSIZE] = "";
828
829 void mix_status(char *fmt,...)
830 {
831 va_list args;
832
833 if (fmt != NULL) {
834 va_start(args, fmt);
835 #ifdef _MSC
836 _vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
837 #else
838 vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
839 #endif
840 va_end(args);
841 }
842 #ifdef USE_NCURSES
843 if (menu_initialized) {
844 cl(LINES - 2, 10);
845 printw("%s", statusline);
846 refresh();
847 } else
848 #endif
849 {
850 fprintf(stderr, "%s", statusline);
851 }
852 }
853
854 void mix_genericerror(void)
855 {
856 if (streq(statusline, "") || strfind(statusline, "...") ||
857 strifind(statusline, "generating"))
858 mix_status("Failed!");
859 else
860 mix_status(NULL);
861 }

  ViewVC Help
Powered by ViewVC 1.1.5