/[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 30 - (show annotations) (download)
Tue Dec 11 20:59:26 2001 UTC (11 years, 5 months ago) by rabbi
File MIME type: text/plain
File size: 18702 byte(s)
Changes for WIN32 Service support. service.c is totally re-written,
service.h is removed. main.c is now cleaner.

TODO: better solution to the Win32/Unix directory seperation issue. Sring
operations on every path is a lot of extra work. Why not fopen() ?
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.3 2001/12/11 20:59:26 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
631 int is_nt_service(void)
632 { // Try to detect if we are the service or not... seems there is no easy reliable way :-(
633 static int issvc = -1;
634 #ifdef WIN32SERVICE
635 STARTUPINFO StartupInfo;
636 OSVERSIONINFO VersionInfo;
637 DWORD dwsize;
638
639 if (issvc != -1) //do it only once
640 return issvc;
641
642 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
643 if (GetVersionEx(&VersionInfo))
644 if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
645 return issvc = 0; // not NT - not the service
646
647 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo))) // reuse VersionInfo to save memory
648 return issvc = 1; // have no console - we are the service probably...
649
650 dwsize = sizeof(VersionInfo);
651 if (GetUserName(&VersionInfo,&dwsize)) // reuse VersionInfo again
652 if (!strcmp(&VersionInfo, "SYSTEM"))
653 return issvc = 1; // SYSTEM user - we are the service probably...
654
655 GetStartupInfo(&StartupInfo);
656 if (StartupInfo.lpDesktop[0] == 0)
657 return issvc = 1; // have no desktop - we are the service probably...
658
659 if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
660 return issvc = 1; // have no stdin,stderr,stdout - we are the service probably...
661 #endif // WIN32SERVICE
662
663 return issvc = 0; // assume not the service
664 } // is_nt_service
665
666 HANDLE hMustTerminate = NULL;
667 void set_nt_exit_event(HANDLE h_svc_exit_event)
668 {
669 hMustTerminate = h_svc_exit_event;
670 } // set_nt_exit_event
671
672 #endif // WIN32
673
674 int mix_daemon(void)
675 {
676 long t;
677 t = SENDPOOLTIME;
678 #ifdef USE_SOCK
679 if (POP3TIME < t)
680 t = POP3TIME;
681 #endif
682
683 for(;;) {
684 mix_regular(0);
685 #ifdef WIN32
686 #ifdef WIN32SERVICE
687 if (hMustTerminate) {
688 if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
689 CloseHandle(hMustTerminate);
690 return 0;
691 }
692 } else
693 #endif
694 Sleep(t * 1000);
695 #else
696 sleep(t);
697 #endif
698 }
699 }
700
701 /** error ***************************************************************/
702
703 void errlog(int type, char *fmt,...)
704 {
705 va_list args;
706 BUFFER *msg;
707 FILE *e = NULL;
708 time_t t;
709 struct tm *tc;
710 char line[LINELEN];
711 int p;
712 char err[6][8] =
713 {"", "Error", "Warning", "Notice", "Info", "Info"};
714
715 if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
716 || (type == DEBUGINFO && VERBOSE < 3))
717 return;
718
719 t = time(NULL);
720 tc = localtime(&t);
721 strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);
722
723 msg = buf_new();
724 buf_appends(msg, line);
725 p = msg->length;
726 buf_appendf(msg, "%s: ", err[type]);
727 va_start(args, fmt);
728 buf_vappendf(msg, fmt, args);
729 va_end(args);
730
731 if (streq(ERRLOG, "stdout"))
732 e = stdout;
733 else if (streq(ERRLOG, "stderr"))
734 e = stderr;
735
736 if (e == NULL && (ERRLOG[0] == '\0' ||
737 (e = mix_openfile(ERRLOG, "a")) == NULL))
738 mix_status("%s", msg->data + p);
739 else {
740 buf_write(msg, e);
741 if (e != stderr && e != stdout) {
742 fclose(e);
743 /* duplicate the error message on screen */
744 mix_status("%s", msg->data + p);
745 }
746 }
747 buf_free(msg);
748 }
749
750 static char statusline[BUFSIZE] = "";
751
752 void mix_status(char *fmt,...)
753 {
754 va_list args;
755
756 if (fmt != NULL) {
757 va_start(args, fmt);
758 #ifdef _MSC
759 _vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
760 #else
761 vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
762 #endif
763 va_end(args);
764 }
765 #ifdef USE_NCURSES
766 if (menu_initialized) {
767 cl(LINES - 2, 10);
768 printw("%s", statusline);
769 refresh();
770 } else
771 #endif
772 {
773 fprintf(stderr, "%s", statusline);
774 }
775 }
776
777 void mix_genericerror(void)
778 {
779 if (streq(statusline, "") || strfind(statusline, "...") ||
780 strifind(statusline, "generating"))
781 mix_status("Failed!");
782 else
783 mix_status(NULL);
784 }

  ViewVC Help
Powered by ViewVC 1.1.5