/[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 105 - (hide annotations) (download)
Wed Jul 24 09:00:11 2002 UTC (10 years, 9 months ago) by weaselp
File MIME type: text/plain
File size: 21639 byte(s)
Make all filenames configurable in mix.cfg.
Add global mix.cfg support (compile time option).
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     Mixmaster initialization, configuration
9 weaselp 105 $Id: mix.c,v 1.9 2002/07/24 09:00:11 weaselp Exp $ */
10 rabbi 1
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 weaselp 105 /** 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 rabbi 1 /** config ***************************************************************/
78    
79     char MIXDIR[PATHMAX];
80     char POOLDIR[PATHMAX];
81    
82     /* programs */
83 rabbi 11 #ifdef WIN32
84     char SENDMAIL[LINELEN] = "outfile";
85     #else
86 rabbi 1 char SENDMAIL[LINELEN] = "/usr/lib/sendmail -t";
87 rabbi 11 #endif
88 rabbi 1 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 = 1;
115     int MIX = 1;
116     int PGP = 1;
117     int UNENCRYPTED = 0;
118     int REMIX = 1;
119 rabbi 62 int REPGP = 1;
120 rabbi 1
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 rabbi 102 #ifdef COMPILEDPASS
152     char PASSPHRASE[LINELEN] = COMPILEDPASS;
153 rabbi 91 #else
154 rabbi 102 char PASSPHRASE[LINELEN] = "";
155 rabbi 91 #endif
156 rabbi 1 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 rabbi 11 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
182 rabbi 1 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 rabbi 11 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
199 rabbi 1 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)
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 rabbi 62 read_conf_i(REPGP) ||
353 rabbi 1 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 rabbi 102 read_conf(PASSPHRASE) ||
367 rabbi 1 #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 weaselp 105 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 rabbi 1 }
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 weaselp 96 strncpy(line, pw->pw_dir, PATHMAX);
444     line[PATHMAX-1] = '\0';
445 rabbi 11 if (line[strlen(line) - 1] != DIRSEP)
446     strcatn(line, DIRSEPSTR, PATHMAX);
447 weaselp 105 strcatn(line, HOMEMIXDIR, PATHMAX);
448 rabbi 1 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 rabbi 11 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
460 rabbi 1 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 weaselp 105 #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 rabbi 1 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 weaselp 105 #ifndef GLOBALMIXCONF
589     /* Only write the config file in non systemwide installation */
590 rabbi 1 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 weaselp 105 #endif
605 rabbi 1 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 rabbi 30
709     #ifdef WIN32
710 rabbi 37 /* Try to detect if we are the service or not...
711     seems there is no easy reliable way */
712 rabbi 30 int is_nt_service(void)
713 rabbi 37 {
714 rabbi 30 static int issvc = -1;
715     #ifdef WIN32SERVICE
716     STARTUPINFO StartupInfo;
717     OSVERSIONINFO VersionInfo;
718     DWORD dwsize;
719    
720 rabbi 37 if (issvc != -1) /* do it only once */
721 rabbi 30 return issvc;
722    
723     VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
724     if (GetVersionEx(&VersionInfo))
725     if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
726 rabbi 37 return issvc = 0; /* not NT - not the service */
727 rabbi 30
728 rabbi 37 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
729     /* reuse VersionInfo to save memory */
730     return issvc = 1; /* have no console - we are the service probably */
731 rabbi 30
732     GetStartupInfo(&StartupInfo);
733     if (StartupInfo.lpDesktop[0] == 0)
734 rabbi 37 return issvc = 1; /* have no desktop - we are the service probably */
735 rabbi 30
736     if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
737 rabbi 37 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
738 rabbi 30 #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 rabbi 1 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 rabbi 11 #ifdef WIN32SERVICE
764 rabbi 30 if (hMustTerminate) {
765     if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
766     CloseHandle(hMustTerminate);
767     return 0;
768     }
769     } else
770 rabbi 11 #endif
771 rabbi 30 Sleep(t * 1000);
772 rabbi 1 #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