/[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 197 - (show annotations) (download)
Wed Aug 28 09:35:25 2002 UTC (10 years, 8 months ago) by weaselp
File MIME type: text/plain
File size: 27402 byte(s)
Write a pid file
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.19 2002/08/28 09:35:25 weaselp 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 <signal.h>
23 #include <unistd.h>
24 #include <pwd.h>
25 #include <sys/utsname.h>
26 #else
27 #include <io.h>
28 #include <direct.h>
29 #endif
30 #ifdef WIN32
31 #include <windows.h>
32 #endif
33 #include <assert.h>
34 #include "menu.h"
35
36 int buf_vappendf(BUFFER *b, char *fmt, va_list args);
37
38 /** filenames ************************************************************/
39 char MIXCONF[PATHMAX];
40 char DISCLAIMFILE[PATHMAX];
41 char FROMDSCLFILE[PATHMAX];
42 char MSGFOOTERFILE[PATHMAX];
43 char POP3CONF[PATHMAX];
44 char HELPFILE[PATHMAX];
45 char ABUSEFILE[PATHMAX];
46 char REPLYFILE[PATHMAX];
47 char USAGEFILE[PATHMAX];
48 char USAGELOG[PATHMAX];
49 char BLOCKFILE[PATHMAX];
50 char ADMKEYFILE[PATHMAX];
51 char KEYFILE[PATHMAX];
52 char PGPKEY[PATHMAX];
53 char DSAPARAMS[PATHMAX];
54 char DHPARAMS[PATHMAX];
55 char MIXRAND[PATHMAX];
56 char SECRING[PATHMAX];
57 char PUBRING[PATHMAX];
58 char IDLOG[PATHMAX];
59 char STATS[PATHMAX];
60 char DESTBLOCK[PATHMAX];
61 char DESTALLOW[PATHMAX];
62 char SOURCEBLOCK[PATHMAX];
63 char HDRFILTER[PATHMAX];
64 char REGULAR[PATHMAX];
65 char POOL[PATHMAX];
66 char TYPE1LIST[PATHMAX];
67 char TYPE2REL[PATHMAX];
68 char TYPE2LIST[PATHMAX];
69 char PIDFILE[PATHMAX];
70
71 char PGPREMPUBRING[PATHMAX];
72 char PGPREMPUBASC[PATHMAX];
73 char PGPREMSECRING[PATHMAX];
74 char NYMSECRING[PATHMAX];
75 char NYMDB[PATHMAX];
76
77
78 /** config ***************************************************************/
79
80 char MIXDIR[PATHMAX];
81 char POOLDIR[PATHMAX];
82
83 /* programs */
84 char SENDMAIL[LINELEN];
85 char SENDANONMAIL[LINELEN];
86 char NEWS[LINELEN];
87 char TYPE1[LINELEN];
88
89 /* addresses */
90 char MAILtoNEWS[LINELEN];
91 char REMAILERNAME[LINELEN];
92 char ANONNAME[LINELEN];
93 char REMAILERADDR[LINELEN];
94 char ANONADDR[LINELEN];
95 char COMPLAINTS[LINELEN];
96 int AUTOREPLY;
97 char SMTPRELAY[LINELEN];
98
99 #ifdef USE_SOCK
100 char HELONAME[LINELEN];
101 char ENVFROM[LINELEN];
102 int POP3DEL;
103 int POP3SIZELIMIT;
104 long POP3TIME;
105
106 #endif
107
108 char SHORTNAME[LINELEN];
109
110 /* remailer configuration */
111 int REMAIL;
112 int MIX;
113 int PGP;
114 int UNENCRYPTED;
115 int REMIX;
116 int REPGP;
117
118 int POOLSIZE;
119 int RATE;
120 int MIDDLEMAN;
121 int AUTOBLOCK;
122 char FORWARDTO[LINELEN];
123 int SIZELIMIT; /* maximal size of remailed messages */
124 int INFLATEMAX; /* maximal size of Inflate: padding */
125 int MAXRANDHOPS;
126 int BINFILTER; /* filter binary attachments? */
127 int LISTSUPPORTED; /* list supported remailers in remailer-conf reply? */
128 long PACKETEXP; /* Expiration time for old packets */
129 long IDEXP; /* 0 = no ID log !! */
130 long SENDPOOLTIME; /* frequency for sending pool messages */
131 long MAILINTIME; /* frequency for processing MAILIN mail */
132
133 char ERRLOG[LINELEN];
134 char ADDRESS[LINELEN];
135 char NAME[LINELEN];
136
137 char ORGANIZATION[LINELEN];
138 char MID[LINELEN];
139
140 /* client config */
141 int NUMCOPIES;
142 char CHAIN[LINELEN];
143 int VERBOSE;
144 int DISTANCE;
145 int MINREL;
146 int RELFINAL;
147 long MAXLAT;
148 char PGPPUBRING[PATHMAX];
149 char PGPSECRING[PATHMAX];
150 char PASSPHRASE[LINELEN];
151 char MAILIN[PATHMAX];
152 char MAILBOX[PATHMAX];
153 char MAILABUSE[PATHMAX];
154 char MAILBLOCK[PATHMAX];
155 char MAILUSAGE[PATHMAX];
156 char MAILANON[PATHMAX];
157 char MAILERROR[PATHMAX];
158 char MAILBOUNCE[PATHMAX];
159
160 char ENTEREDPASSPHRASE[LINELEN] = "";
161
162 static int rereadconfig = 0;
163 static int terminatedaemon = 0;
164
165 #if defined(S_IFDIR) && !defined(S_ISDIR)
166 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
167 #endif
168
169 static int mixdir(char *d, int create)
170 {
171 int err;
172 struct stat buf;
173
174 if (d != MIXDIR)
175 strncpy(MIXDIR, d, PATHMAX);
176 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
177 MIXDIR[strlen(MIXDIR) - 1] = '\0';
178 err = stat(MIXDIR, &buf);
179 if (err == -1) {
180 if (create) {
181 #ifndef POSIX
182 err = mkdir(MIXDIR);
183 #else
184 err = mkdir(MIXDIR, S_IRWXU);
185 #endif
186 if (err == 0)
187 errlog(NOTICE, "Creating directory %s.\n", MIXDIR);
188 } else
189 err = 1;
190 } else if (!S_ISDIR(buf.st_mode))
191 err = -1;
192 if (err == 0)
193 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
194 return (err);
195 }
196
197 void whoami(char *addr, char *defaultname)
198 {
199 char *p = NULL;
200
201 #if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME))
202 char line[LINELEN];
203
204 #endif
205 #ifdef HAVE_UNAME
206 struct utsname uts;
207
208 #endif
209 #ifdef POSIX
210 p = getlogin();
211 #endif
212 if (p == NULL)
213 strcpy(addr, defaultname);
214 else
215 strncpy(addr, p, LINELEN);
216
217 strcatn(addr, "@", LINELEN);
218 #ifdef HAVE_UNAME
219 if (uname(&uts) != -1)
220 strcatn(addr, uts.nodename, LINELEN);
221 #elif defined(HAVE_GETHOSTNAME)
222 if (gethostname(line, LINELEN) == 0)
223 strcatn(addr, line, LINELEN);
224 #endif
225 if (addr[strlen(addr) - 1] == '@')
226 strcatn(addr, SHORTNAME, LINELEN);
227
228 if (strchr(strchr(addr, '@'), '.') == NULL) {
229 #ifdef HAVE_GETDOMAINNAME
230 if (getdomainname(line, LINELEN) == 0 && !streq(line, "(none)")) {
231 strcatn(addr, ".", LINELEN);
232 strcatn(addr, line, LINELEN);
233 }
234 #endif
235 }
236 }
237
238 #define read_conf(t) readconfline(line, #t, sizeof(#t)-1, t)
239
240 static int readconfline(char *line, char *name, int namelen, char *var)
241 {
242 if (strncmp(line, name, namelen) == 0 &&
243 (isspace(line[namelen]) || line[namelen] == '=')) {
244 line += namelen;
245 if (*line == '=')
246 line++;
247 while (isspace(*line))
248 line++;
249 if (line[0] == '\n' || line[0] == '\0') /* leave default */
250 return (1);
251 strncpy(var, line, LINELEN);
252 if (var[strlen(var) - 1] == '\n')
253 var[strlen(var) - 1] = '\0';
254 return (1);
255 } else
256 return (0);
257 }
258
259 #define read_conf_i(t) readiconfline(line, #t, sizeof(#t)-1, &t)
260
261 static int readiconfline(char *line, char *name, int namelen, int *var)
262 {
263 if (strncmp(line, name, namelen) == 0 &&
264 (isspace(line[namelen]) || line[namelen] == '=')) {
265 line += namelen;
266 if (*line == '=')
267 line++;
268 while (isspace(*line))
269 line++;
270 if (line[0] == '\n' || line[0] == '\0') /* leave default */
271 return (1);
272 switch (tolower(line[0])) {
273 case 'n':
274 *var = 0;
275 break;
276 case 'y':
277 *var = 1;
278 break;
279 case 'x':
280 *var = 2;
281 break;
282 default:
283 sscanf(line, "%d", var);
284 }
285 return (1);
286 } else
287 return (0);
288 }
289
290 #define read_conf_t(t) readtconfline(line, #t, sizeof(#t)-1, &t)
291
292 static int readtconfline(char *line, char *name, int namelen, long *var)
293 {
294 char *linenext;
295 int mod = 0;
296 long l = 0;
297 long n;
298
299 if (strncmp(line, name, namelen) == 0 &&
300 (isspace(line[namelen]) || line[namelen] == '=')) {
301 line += namelen;
302 if (*line == '=')
303 line++;
304 for (;; line++) {
305 n = strtol(line, &linenext, 10);
306 if (linenext == line)
307 break;
308 line = linenext;
309 mod = 1;
310 assert(line != NULL);
311 while (isspace(*line))
312 line++;
313 switch (tolower(*line)) {
314 case 'd':
315 l += 24 * 60 * 60 * n;
316 break;
317 case 'm':
318 l += 60 * n;
319 break;
320 case 'h':
321 default:
322 l += 60 * 60 * n;
323 break;
324 }
325 }
326 if (mod)
327 *var = l;
328 return (1);
329 } else
330 return (0);
331 }
332
333 void mix_setdefaults()
334 {
335 #define strnncpy(a,b) strncpy(a, b, sizeof(a)); a[sizeof(a)-1] = '\0'
336
337 strnncpy(MIXCONF , DEFAULT_MIXCONF);
338 strnncpy(DISCLAIMFILE , DEFAULT_DISCLAIMFILE);
339 strnncpy(FROMDSCLFILE , DEFAULT_FROMDSCLFILE);
340 strnncpy(MSGFOOTERFILE, DEFAULT_MSGFOOTERFILE);
341 strnncpy(POP3CONF , DEFAULT_POP3CONF);
342 strnncpy(HELPFILE , DEFAULT_HELPFILE);
343 strnncpy(ABUSEFILE , DEFAULT_ABUSEFILE);
344 strnncpy(REPLYFILE , DEFAULT_REPLYFILE);
345 strnncpy(USAGEFILE , DEFAULT_USAGEFILE);
346 strnncpy(USAGELOG , DEFAULT_USAGELOG);
347 strnncpy(BLOCKFILE , DEFAULT_BLOCKFILE);
348 strnncpy(ADMKEYFILE , DEFAULT_ADMKEYFILE);
349 strnncpy(KEYFILE , DEFAULT_KEYFILE);
350 strnncpy(PGPKEY , DEFAULT_PGPKEY);
351 strnncpy(DSAPARAMS , DEFAULT_DSAPARAMS);
352 strnncpy(DHPARAMS , DEFAULT_DHPARAMS);
353 strnncpy(MIXRAND , DEFAULT_MIXRAND);
354 strnncpy(SECRING , DEFAULT_SECRING);
355 strnncpy(PUBRING , DEFAULT_PUBRING);
356 strnncpy(IDLOG , DEFAULT_IDLOG);
357 strnncpy(STATS , DEFAULT_STATS);
358 strnncpy(DESTBLOCK , DEFAULT_DESTBLOCK);
359 strnncpy(DESTALLOW , DEFAULT_DESTALLOW);
360 strnncpy(SOURCEBLOCK , DEFAULT_SOURCEBLOCK);
361 strnncpy(HDRFILTER , DEFAULT_HDRFILTER);
362 strnncpy(REGULAR , DEFAULT_REGULAR);
363 strnncpy(POOL , DEFAULT_POOL);
364 strnncpy(TYPE1LIST , DEFAULT_TYPE1LIST);
365 strnncpy(TYPE2REL , DEFAULT_TYPE2REL);
366 strnncpy(TYPE2LIST , DEFAULT_TYPE2LIST);
367 strnncpy(PIDFILE , DEFAULT_PIDFILE);
368
369 strnncpy(PGPREMPUBRING, DEFAULT_PGPREMPUBRING);
370 strnncpy(PGPREMPUBASC , DEFAULT_PGPREMPUBASC);
371 strnncpy(PGPREMSECRING, DEFAULT_PGPREMSECRING);
372 strnncpy(NYMSECRING , DEFAULT_NYMSECRING);
373 strnncpy(NYMDB , DEFAULT_NYMDB);
374
375
376 strnncpy(MIXDIR , "");
377 strnncpy(POOLDIR , "");
378
379 /* programs */
380 #ifdef WIN32
381 strnncpy(SENDMAIL , "outfile");
382 #else
383 strnncpy(SENDMAIL , "/usr/lib/sendmail -t");
384 #endif
385 strnncpy(SENDANONMAIL , "");
386 strnncpy(NEWS , "");
387 strnncpy(TYPE1 , "");
388
389 /* addresses */
390 strnncpy(MAILtoNEWS , "mail2news@anon.lcs.mit.edu");
391 strnncpy(REMAILERNAME , "Anonymous Remailer");
392 strnncpy(ANONNAME , "Anonymous");
393 strnncpy(REMAILERADDR , "");
394 strnncpy(ANONADDR , "");
395 strnncpy(COMPLAINTS , "");
396 strnncpy(SMTPRELAY , "");
397 AUTOREPLY = 0;
398
399 #ifdef USE_SOCK
400 strnncpy(HELONAME , "");
401 strnncpy(ENVFROM , "");
402 POP3DEL = 0;
403 POP3SIZELIMIT = 0;
404 POP3TIME = 60 * 60;
405
406 #endif
407
408 strnncpy(SHORTNAME , "");
409
410 /* configuration */
411 REMAIL = 0;
412 MIX = 1;
413 PGP = 1;
414 UNENCRYPTED = 0;
415 REMIX = 1;
416 REPGP = 1;
417
418 POOLSIZE = 0;
419 RATE = 100;
420 MIDDLEMAN = 0;
421 AUTOBLOCK = 1;
422 strnncpy(FORWARDTO, "*");
423 SIZELIMIT = 0; /* maximal size of remailed messages */
424 INFLATEMAX = 50; /* maximal size of Inflate: padding */
425 MAXRANDHOPS = 20;
426 BINFILTER = 0; /* filter binary attachments? */
427 LISTSUPPORTED = 1; /* list supported remailers in remailer-conf reply? */
428 PACKETEXP = 7 * SECONDSPERDAY; /* Expiration time for old packets */
429 IDEXP = 7 * SECONDSPERDAY; /* 0 = no ID log !! */
430 SENDPOOLTIME = 60 * 60; /* frequency for sending pool messages */
431 MAILINTIME = 5 * 60; /* frequency for processing MAILIN mail */
432
433 strnncpy(ERRLOG , "");
434 strnncpy(ADDRESS , "");
435 strnncpy(NAME , "");
436
437 strnncpy(ORGANIZATION, "Anonymous Posting Service");
438 strnncpy(MID , "y");
439
440 /* client config */
441 NUMCOPIES = 1;
442 strnncpy(CHAIN, "*,*,*,*");
443 VERBOSE = 2;
444 DISTANCE = 2;
445 MINREL = 98;
446 RELFINAL = 99;
447 MAXLAT = 36 * 60 * 60;
448 strnncpy(PGPPUBRING, "");
449 strnncpy(PGPSECRING, "");
450 #ifdef COMPILEDPASS
451 strnncpy(PASSPHRASE, COMPILEDPASS);
452 #else
453 strnncpy(PASSPHRASE, "");
454 #endif
455 strnncpy(MAILIN , "");
456 strnncpy(MAILBOX , "mbox");
457 strnncpy(MAILABUSE , "");
458 strnncpy(MAILBLOCK , "");
459 #ifdef WIN32
460 strnncpy(MAILUSAGE , "nul:");
461 strnncpy(MAILANON , "nul:");
462 strnncpy(MAILERROR , "nul:");
463 #else
464 strnncpy(MAILUSAGE , "/dev/null");
465 strnncpy(MAILANON , "/dev/null");
466 strnncpy(MAILERROR , "/dev/null");
467 #endif
468 strnncpy(MAILBOUNCE, "");
469 }
470
471 int mix_configline(char *line)
472 {
473 return (read_conf(ADDRESS) || read_conf(NAME) ||
474 read_conf(SHORTNAME) || read_conf(REMAILERADDR) ||
475 read_conf(ANONADDR) || read_conf(REMAILERNAME) ||
476 read_conf(ANONNAME) || read_conf(COMPLAINTS) ||
477 read_conf_i(AUTOREPLY) || read_conf(SMTPRELAY) ||
478 #ifdef USE_SOCK
479 read_conf(HELONAME) || read_conf(ENVFROM) ||
480 #endif
481 read_conf(SENDMAIL) || read_conf(SENDANONMAIL) ||
482 read_conf_i(REMAIL) || read_conf_i(MIX) ||
483 read_conf_i(PGP) || read_conf_i(UNENCRYPTED) ||
484 read_conf_i(REMIX) || read_conf(NEWS) ||
485 read_conf_i(REPGP) ||
486 read_conf(MAILtoNEWS) || read_conf(ERRLOG) ||
487 read_conf(ORGANIZATION) || read_conf(MID) ||
488 read_conf(TYPE1) || read_conf_i(POOLSIZE) ||
489 read_conf_i(RATE) || read_conf_i(MIDDLEMAN) ||
490 read_conf_i(AUTOBLOCK) || read_conf(FORWARDTO) ||
491 read_conf_i(SIZELIMIT) || read_conf_i(INFLATEMAX) ||
492 read_conf_i(MAXRANDHOPS) || read_conf_i(BINFILTER) ||
493 read_conf_i(LISTSUPPORTED) ||
494 read_conf_t(PACKETEXP) || read_conf_t(IDEXP) ||
495 read_conf_t(SENDPOOLTIME) || read_conf_i(NUMCOPIES) ||
496 read_conf_t(MAILINTIME) ||
497 read_conf(CHAIN) || read_conf_i(VERBOSE) ||
498 read_conf_i(DISTANCE) || read_conf_i(MINREL) ||
499 read_conf_i(RELFINAL) || read_conf_t(MAXLAT) ||
500 read_conf(PGPPUBRING) || read_conf(PGPSECRING) ||
501 read_conf(PASSPHRASE) ||
502 #ifdef USE_SOCK
503 read_conf_i(POP3DEL) || read_conf_i(POP3SIZELIMIT) ||
504 read_conf_t(POP3TIME) ||
505 #endif
506 read_conf(MAILBOX) || read_conf(MAILABUSE) ||
507 read_conf(MAILBLOCK) || read_conf(MAILUSAGE) ||
508 read_conf(MAILANON) || read_conf(MAILERROR) ||
509 read_conf(MAILBOUNCE) || read_conf(MAILIN) ||
510
511 read_conf(DISCLAIMFILE) || read_conf(FROMDSCLFILE) ||
512 read_conf(MSGFOOTERFILE) ||
513 read_conf(POP3CONF) || read_conf(HELPFILE) ||
514 read_conf(ABUSEFILE) || read_conf(REPLYFILE) ||
515 read_conf(USAGEFILE) || read_conf(USAGELOG) ||
516 read_conf(BLOCKFILE) || read_conf(ADMKEYFILE) ||
517 read_conf(KEYFILE) || read_conf(PGPKEY) ||
518 read_conf(DSAPARAMS) || read_conf(DHPARAMS) ||
519 read_conf(MIXRAND) || read_conf(SECRING) ||
520 read_conf(PUBRING) || read_conf(IDLOG) ||
521 read_conf(STATS) || read_conf(DESTBLOCK) ||
522 read_conf(DESTALLOW) || read_conf(SOURCEBLOCK) ||
523 read_conf(HDRFILTER) || read_conf(REGULAR) ||
524 read_conf(POOL) || read_conf(TYPE1LIST) ||
525 read_conf(TYPE2REL) || read_conf(TYPE2LIST) ||
526 read_conf(PGPREMPUBRING) || read_conf(PGPREMPUBASC) ||
527 read_conf(PGPREMSECRING) || read_conf(NYMSECRING) ||
528 read_conf(NYMDB) || read_conf(PIDFILE) );
529 }
530
531 static int mix_config(void)
532 {
533 char *d;
534 FILE *f;
535 char line[PATHMAX];
536 int err = -1;
537 #ifdef POSIX
538 struct passwd *pw;
539 #endif
540 struct stat buf;
541 #ifdef HAVE_UNAME
542 struct utsname uts;
543 #endif
544 #ifdef WIN32
545 HKEY regsw, reg, regpgp;
546 DWORD type, len;
547 int rkey = 0;
548 #endif
549
550 mix_setdefaults();
551
552 #ifdef POSIX
553 pw = getpwuid(getuid());
554 #endif
555
556 #ifdef WIN32
557 RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &regsw);
558 len=sizeof(line);
559 if (err == -1 &&
560 RegOpenKeyEx(regsw, "Mixmaster", 0, KEY_QUERY_VALUE, &reg) == 0) {
561 if (RegQueryValueEx(reg, "MixDir", 0, &type, line, &len) == 0)
562 err = mixdir(line, 1);
563 RegCloseKey(reg);
564 }
565 #endif
566
567 if (err == -1 && (d = getenv("MIXPATH")) != NULL)
568 err = mixdir(d, 1);
569
570 #ifdef SPOOL
571 if (err == -1 && strlen(SPOOL) > 0)
572 err = mixdir(SPOOL, 0);
573 #endif
574
575 #ifdef POSIX
576 if (err == -1 && pw != NULL) {
577 strncpy(line, pw->pw_dir, PATHMAX);
578 line[PATHMAX-1] = '\0';
579 if (line[strlen(line) - 1] != DIRSEP)
580 strcatn(line, DIRSEPSTR, PATHMAX);
581 strcatn(line, HOMEMIXDIR, PATHMAX);
582 err = mixdir(line, 1);
583 }
584 #endif
585
586 if (err == -1) {
587 getcwd(MIXDIR, PATHMAX);
588 mixdir(MIXDIR, 0);
589 }
590
591 mixfile(POOLDIR, POOL);
592 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
593 POOLDIR[strlen(POOLDIR) - 1] = '\0';
594 if (stat(POOLDIR, &buf) != 0)
595 if
596 #ifndef POSIX
597 (mkdir(POOLDIR) != 0)
598 #else
599 (mkdir(POOLDIR, S_IRWXU) == -1)
600 #endif
601 strncpy(POOLDIR, MIXDIR, PATHMAX);
602
603 #ifdef GLOBALMIXCONF
604 f = mix_openfile(GLOBALMIXCONF, "r");
605 if (f != NULL) {
606 while (fgets(line, LINELEN, f) != NULL)
607 if (line[0] > ' ' && line[0] != '#')
608 mix_configline(line);
609 fclose(f);
610 }
611 #endif
612 f = mix_openfile(MIXCONF, "r");
613 if (f != NULL) {
614 while (fgets(line, LINELEN, f) != NULL)
615 if (line[0] > ' ' && line[0] != '#')
616 mix_configline(line);
617 fclose(f);
618 }
619 if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY)
620 IDEXP = 5 * SECONDSPERDAY;
621 if (MAXRANDHOPS > 20)
622 MAXRANDHOPS = 20;
623
624 if (strchr(SHORTNAME, '.'))
625 *strchr(SHORTNAME, '.') = '\0';
626 if (strchr(SHORTNAME, ' '))
627 *strchr(SHORTNAME, ' ') = '\0';
628 #ifdef HAVE_UNAME
629 if (SHORTNAME[0] == '\0' && uname(&uts) != -1)
630 strncpy(SHORTNAME, uts.nodename, LINELEN);
631 #elif defined(HAVE_GETHOSTNAME)
632 if (SHORTNAME[0] == '\0')
633 gethostname(SHORTNAME, LINELEN);
634 #endif
635 if (SHORTNAME[0] == '\0')
636 strcpy(SHORTNAME, "unknown");
637
638 if (ADDRESS[0] == '\0')
639 whoami(ADDRESS, "user");
640
641 #ifdef HAVE_GECOS
642 if (NAME[0] == '\0' && pw != NULL)
643 strcatn(NAME, pw->pw_gecos, sizeof(NAME));
644 #endif
645
646 if (REMAILERADDR[0] == '\0')
647 strncpy(REMAILERADDR, ADDRESS, LINELEN);
648
649 if (COMPLAINTS[0] == '\0')
650 strncpy(COMPLAINTS, REMAILERADDR, LINELEN);
651
652 if (strchr(REMAILERNAME, '@') == NULL) {
653 strcatn(REMAILERNAME, " <", LINELEN);
654 strcatn(REMAILERNAME, REMAILERADDR, LINELEN);
655 strcatn(REMAILERNAME, ">", LINELEN);
656 }
657 if (strchr(ANONNAME, '@') == NULL && ANONADDR[0] != '\0') {
658 strcatn(ANONNAME, " <", LINELEN);
659 strcatn(ANONNAME, ANONADDR, LINELEN);
660 strcatn(ANONNAME, ">", LINELEN);
661 }
662 if (strchr(ANONNAME, '@') == NULL) {
663 strcatn(ANONNAME, " <", LINELEN);
664 strcatn(ANONNAME, REMAILERADDR, LINELEN);
665 strcatn(ANONNAME, ">", LINELEN);
666 }
667 #ifndef USE_PGP
668 if (TYPE1[0] == '\0')
669 PGP = 0;
670 #endif
671 #ifndef USE_RSA
672 MIX = 0;
673 #endif
674
675 #ifdef WIN32
676 if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, &regpgp) == 0)
677 rkey++;
678 if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, &reg) == 0)
679 rkey++;
680 if (PGPPUBRING[0] == '\0' && rkey == 2) {
681 len = PATHMAX;
682 RegQueryValueEx(reg, "PubRing", 0, &type, PGPPUBRING, &len);
683 }
684 if (PGPSECRING[0] == '\0' && rkey == 2) {
685 len = PATHMAX;
686 RegQueryValueEx(reg, "SecRing", 0, &type, PGPSECRING, &len);
687 }
688 if (rkey == 2)
689 RegCloseKey(reg);
690 if (rkey)
691 RegCloseKey(regpgp);
692 RegCloseKey(regsw);
693 #endif
694
695 if (PGPPUBRING[0] == '\0') {
696 char *d;
697
698 if ((d = getenv("HOME")) != NULL) {
699 strcpy(PGPPUBRING, d);
700 strcatn(PGPPUBRING, "/.pgp/", PATHMAX);
701 }
702 strcatn(PGPPUBRING, "pubring.pkr", PATHMAX);
703 if (stat(PGPPUBRING, &buf) == -1)
704 strcpy(strrchr(PGPPUBRING, '.'), ".pgp");
705 }
706 if (PGPSECRING[0] == '\0') {
707 char *d;
708
709 if ((d = getenv("HOME")) != NULL) {
710 strcpy(PGPSECRING, d);
711 strcatn(PGPSECRING, "/.pgp/", PATHMAX);
712 }
713 strcatn(PGPSECRING, "secring.skr", PATHMAX);
714 if (stat(PGPSECRING, &buf) == -1)
715 strcpy(strrchr(PGPSECRING, '.'), ".pgp");
716 }
717 if (streq(NEWS, "mail-to-news"))
718 strncpy(NEWS, MAILtoNEWS, sizeof(NEWS));
719
720 if (f == NULL) {
721 #ifndef GLOBALMIXCONF
722 /* Only write the config file in non systemwide installation */
723 f = mix_openfile(MIXCONF, "w");
724 if (f == NULL)
725 errlog(WARNING, "Can't open %s%s!\n", MIXDIR, MIXCONF);
726 else {
727 fprintf(f, "# mix.cfg - mixmaster configuration file\n");
728 fprintf(f, "NAME %s\n", NAME);
729 fprintf(f, "ADDRESS %s\n", ADDRESS);
730 fprintf(f, "\n# edit to set up a remailer:\n");
731 fprintf(f, "REMAIL n\n");
732 fprintf(f, "SHORTNAME %s\n", SHORTNAME);
733 fprintf(f, "REMAILERADDR %s\n", REMAILERADDR);
734 fprintf(f, "COMPLAINTS %s\n", COMPLAINTS);
735 fclose(f);
736 }
737 #endif
738 REMAIL = 0;
739 }
740
741 if (strncmp(ENTEREDPASSPHRASE, "", LINELEN) != 0) {
742 strncpy(PASSPHRASE, ENTEREDPASSPHRASE, LINELEN);
743 PASSPHRASE[LINELEN-1] = 0;
744 };
745
746 return (0);
747 }
748
749 /** Library initialization: ******************************************/
750
751 static int initialized = 0;
752
753 int mix_init(char *mixdir)
754 {
755 if (!initialized) {
756 if (mixdir)
757 strncpy(MIXDIR, mixdir, LINELEN);
758 mix_config();
759 #if defined(USE_SOCK) && defined(WIN32)
760 sock_init();
761 #endif
762 /* atexit (mix_exit); */
763 initialized = 1;
764 }
765
766 if (rnd_init() == -1)
767 rnd_seed();
768 return(0);
769 }
770
771 void mix_exit(void)
772 {
773 if (!initialized)
774 return;
775 rnd_final();
776 #if defined(USE_SOCK) && defined(WIN32)
777 sock_exit();
778 #endif
779 initialized=0;
780 }
781
782 int mix_regular(int force)
783 {
784 FILE *f;
785 long now, tpool = 0, tpop3 = 0, tdaily = 0, tmailin = 0;
786 int ret = 0;
787
788 mix_init(NULL);
789 now = time(NULL);
790
791 f = mix_openfile(REGULAR, "r+");
792 if (f != NULL) {
793 lock(f);
794 fscanf(f, "%ld %ld %ld %ld", &tpool, &tpop3, &tdaily, &tmailin);
795 if (now - tpool >= SENDPOOLTIME)
796 force |= FORCE_POOL | FORCE_MAILIN;
797 #ifdef USE_SOCK
798 if (now - tpop3 >= POP3TIME)
799 force |= FORCE_POP3 | FORCE_MAILIN;
800 #endif
801 if (now - tdaily >= SECONDSPERDAY)
802 force |= FORCE_DAILY;
803 if (now - tmailin >= MAILINTIME)
804 force |= FORCE_MAILIN;
805 if (force & FORCE_POOL)
806 tpool = now;
807 if (force & FORCE_POP3)
808 tpop3 = now;
809 if (force & FORCE_DAILY)
810 tdaily = now;
811 if (force & FORCE_MAILIN)
812 tmailin = now;
813 rewind(f);
814 fprintf(f, "%ld %ld %ld %ld\n", tpool, tpop3, tdaily, tmailin);
815 unlock(f);
816 fclose(f);
817 } else {
818 force = FORCE_POOL | FORCE_POP3 | FORCE_DAILY | FORCE_MAILIN;
819 f = mix_openfile(REGULAR, "w+");
820 if (f != NULL) {
821 lock(f);
822 fprintf(f, "%ld %ld %ld %ld\n", now, now, now, now);
823 unlock(f);
824 fclose(f);
825 } else
826 errlog(ERRORMSG, "Can't create %s!\n", REGULAR);
827 }
828
829 if (force & FORCE_DAILY)
830 mix_daily(), ret = 1;
831 #ifdef USE_SOCK
832 if (force & FORCE_POP3)
833 pop3get();
834 #endif
835 if (force & FORCE_MAILIN)
836 ret = process_mailin();
837 if (force & FORCE_POOL)
838 ret = pool_send();
839
840 return (ret);
841 }
842
843 int mix_daily(void)
844 {
845 idexp();
846 pool_packetexp();
847 stats(NULL);
848 keymgt(0);
849 return (0);
850 }
851
852 /** Handle signals SIGHUP, SIGINT, and SIGTERM
853 This signal handler gets called if the daemon
854 process receives one of SIGHUP, SIGINT, or SIGTERM.
855 It then sets either rereadconfig of terminatedaemon
856 to true depending on the signal received.
857
858 @author PP
859 @return nothing
860 */
861 void sighandler(int signal) {
862 if (signal == SIGHUP)
863 rereadconfig = 1;
864 else if (signal == SIGINT || signal == SIGTERM)
865 terminatedaemon = 1;
866 };
867
868 /** Set the signal handler for SIGHUP, SIGINT and SIGTERM
869 This function registers signal handlers so that
870 we can react on signals send by the user in daemon
871 mode. SIGHUP will instruct mixmaster to reload its
872 configuration while SIGINT and SIGTERM will instruct
873 it to shut down. Mixmaster will finish the current
874 pool run before it terminates.
875
876 @param restart Whether or not system calls should be
877 restarted. Usually we want this, the
878 only excetion is the sleep() in the
879 daemon mail loop.
880 @author PP
881 @return -1 if calling sigaction failed, 0 on
882 no error
883 */
884 int setsignalhandler(int restart)
885 {
886 #ifdef POSIX
887 struct sigaction hdl;
888 int err = 0;
889
890 memset(&hdl, 0, sizeof(hdl));
891 hdl.sa_handler = sighandler;
892 hdl.sa_flags = restart ? SA_RESTART : 0;
893
894 if (sigaction(SIGHUP, &hdl, NULL))
895 err = -1;
896 if (sigaction(SIGINT, &hdl, NULL))
897 err = -1;
898 if (sigaction(SIGTERM, &hdl, NULL))
899 err = -1;
900 return (err);
901 #else /* POSIX */
902 return(0);
903 #endif /* POSIX */
904 }
905
906 #ifdef WIN32
907 /* Try to detect if we are the service or not...
908 seems there is no easy reliable way */
909 int is_nt_service(void)
910 {
911 static int issvc = -1;
912 #ifdef WIN32SERVICE
913 STARTUPINFO StartupInfo;
914 OSVERSIONINFO VersionInfo;
915 DWORD dwsize;
916
917 if (issvc != -1) /* do it only once */
918 return issvc;
919
920 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
921 if (GetVersionEx(&VersionInfo))
922 if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
923 return issvc = 0; /* not NT - not the service */
924
925 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
926 /* reuse VersionInfo to save memory */
927 return issvc = 1; /* have no console - we are the service probably */
928
929 GetStartupInfo(&StartupInfo);
930 if (StartupInfo.lpDesktop[0] == 0)
931 return issvc = 1; /* have no desktop - we are the service probably */
932
933 if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
934 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
935 #endif // WIN32SERVICE
936
937 return issvc = 0; // assume not the service
938 } // is_nt_service
939
940 HANDLE hMustTerminate = NULL;
941 void set_nt_exit_event(HANDLE h_svc_exit_event)
942 {
943 hMustTerminate = h_svc_exit_event;
944 } // set_nt_exit_event
945
946 #endif // WIN32
947
948 int mix_daemon(void)
949 {
950 long t, slept;
951 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
952 #ifdef USE_SOCK
953 if (POP3TIME < t)
954 t = POP3TIME;
955 #endif
956 slept = t;
957
958 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
959 for(;;) {
960 if (terminatedaemon)
961 break;
962 if (rereadconfig) {
963 rereadconfig = 0;
964 mix_config();
965 t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME;
966 #ifdef USE_SOCK
967 if (POP3TIME < t)
968 t = POP3TIME;
969 #endif
970 }
971 if (slept >= t) {
972 mix_regular(0);
973 slept = 0;
974 }
975
976 if (!terminatedaemon && !rereadconfig) {
977 setsignalhandler(0); /* set signal handlers; don't restart system calls */
978 #ifdef WIN32
979 #ifdef WIN32SERVICE
980 if (hMustTerminate) {
981 if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
982 CloseHandle(hMustTerminate);
983 return 0;
984 }
985 } else
986 #endif
987 Sleep(t * 1000);
988 #else
989 slept += (t - slept) - sleep(t - slept);
990 #endif
991 setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */
992 }
993 }
994 return (0);
995 }
996
997 /** error ***************************************************************/
998
999 void errlog(int type, char *fmt,...)
1000 {
1001 va_list args;
1002 BUFFER *msg;
1003 FILE *e = NULL;
1004 time_t t;
1005 struct tm *tc;
1006 char line[LINELEN];
1007 int p;
1008 char err[6][8] =
1009 {"", "Error", "Warning", "Notice", "Info", "Info"};
1010
1011 if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
1012 || (type == DEBUGINFO && VERBOSE < 3))
1013 return;
1014
1015 t = time(NULL);
1016 tc = localtime(&t);
1017 strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);
1018
1019 msg = buf_new();
1020 buf_appends(msg, line);
1021 p = msg->length;
1022 buf_appendf(msg, "%s: ", err[type]);
1023 va_start(args, fmt);
1024 buf_vappendf(msg, fmt, args);
1025 va_end(args);
1026
1027 if (streq(ERRLOG, "stdout"))
1028 e = stdout;
1029 else if (streq(ERRLOG, "stderr"))
1030 e = stderr;
1031
1032 if (e == NULL && (ERRLOG[0] == '\0' ||
1033 (e = mix_openfile(ERRLOG, "a")) == NULL))
1034 mix_status("%s", msg->data + p);
1035 else {
1036 buf_write(msg, e);
1037 if (e != stderr && e != stdout) {
1038 fclose(e);
1039 /* duplicate the error message on screen */
1040 mix_status("%s", msg->data + p);
1041 }
1042 }
1043 buf_free(msg);
1044 }
1045
1046 static char statusline[BUFSIZE] = "";
1047
1048 void mix_status(char *fmt,...)
1049 {
1050 va_list args;
1051
1052 if (fmt != NULL) {
1053 va_start(args, fmt);
1054 #ifdef _MSC
1055 _vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
1056 #else
1057 vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
1058 #endif
1059 va_end(args);
1060 }
1061 #ifdef USE_NCURSES
1062 if (menu_initialized) {
1063 cl(LINES - 2, 10);
1064 printw("%s", statusline);
1065 refresh();
1066 } else
1067 #endif
1068 {
1069 fprintf(stderr, "%s", statusline);
1070 }
1071 }
1072
1073 void mix_genericerror(void)
1074 {
1075 if (streq(statusline, "") || strfind(statusline, "...") ||
1076 strifind(statusline, "generating"))
1077 mix_status("Failed!");
1078 else
1079 mix_status(NULL);
1080 }

  ViewVC Help
Powered by ViewVC 1.1.5