/[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 - (show 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 /* 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 $Id: mix.c,v 1.4 2001/12/12 18:50:09 rabbi Exp $ */
10
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 #ifdef WIN32
44 char SENDMAIL[LINELEN] = "outfile";
45 #else
46 char SENDMAIL[LINELEN] = "/usr/lib/sendmail -t";
47 #endif
48 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 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
136 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 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
153 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 if (line[strlen(line) - 1] != DIRSEP)
378 strcatn(line, DIRSEPSTR, PATHMAX);
379 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 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
392 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
629 #ifdef WIN32
630 /* Try to detect if we are the service or not...
631 seems there is no easy reliable way */
632 int is_nt_service(void)
633 {
634 static int issvc = -1;
635 #ifdef WIN32SERVICE
636 STARTUPINFO StartupInfo;
637 OSVERSIONINFO VersionInfo;
638 DWORD dwsize;
639
640 if (issvc != -1) /* do it only once */
641 return issvc;
642
643 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
644 if (GetVersionEx(&VersionInfo))
645 if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
646 return issvc = 0; /* not NT - not the service */
647
648 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
649 /* reuse VersionInfo to save memory */
650 return issvc = 1; /* have no console - we are the service probably */
651
652 GetStartupInfo(&StartupInfo);
653 if (StartupInfo.lpDesktop[0] == 0)
654 return issvc = 1; /* have no desktop - we are the service probably */
655
656 if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
657 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
658 #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 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 #ifdef WIN32SERVICE
684 if (hMustTerminate) {
685 if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
686 CloseHandle(hMustTerminate);
687 return 0;
688 }
689 } else
690 #endif
691 Sleep(t * 1000);
692 #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