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

  ViewVC Help
Powered by ViewVC 1.1.5