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

  ViewVC Help
Powered by ViewVC 1.1.5