/[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 102 - (hide annotations) (download)
Wed Jul 24 07:48:50 2002 UTC (10 years, 9 months ago) by rabbi
File MIME type: text/plain
File size: 18692 byte(s)
We have changed the compile-time option PASSPHRASE to be named
COMPILEDPASS. We have changed the configuration file option PASS_PHRASE to
be named PASSPHRASE. We have added documentation for the new configuration
file option and made changes in the man page to reflect the name change.

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

  ViewVC Help
Powered by ViewVC 1.1.5