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

  ViewVC Help
Powered by ViewVC 1.1.5