/[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 91 - (show annotations) (download)
Wed Jul 10 01:58:49 2002 UTC (10 years, 11 months ago) by rabbi
File MIME type: text/plain
File size: 18663 byte(s)
Added the ability to store the key passphrase in the mix.cfg file instead of
having it compiled into the binary. This offers a number of advantages over the
compiled-in method and still allows for encrypted remote storage of keys.

In order to take advantage of the new changes, the Install script will need to
be modified. As this is being replaced with a proper autoconf system, we're
defering that until later.

The changes we're committing replace PASSPHRASE with PASS_PHRASE, which is read
from the config. If the compiled-in passphrase, PASSPHRASE, is set, that is
used instead. (This is how Mixmaster will function if you use the Install
script.)
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.6 2002/07/10 01:58:49 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 int REPGP = 1;
80
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 #ifdef PASSPHRASE
112 char PASS_PHRASE[LINELEN] = PASSPHRASE;
113 #else
114 char PASS_PHRASE[LINELEN] = "";
115 #endif
116 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 if (MIXDIR[strlen(MIXDIR) - 1] == DIRSEP)
142 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 strcatn(MIXDIR, DIRSEPSTR, PATHMAX);
159 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 read_conf_i(REPGP) ||
313 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 read_conf(PASS_PHRASE) ||
327 #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 strcatn(line, pw->pw_dir, PATHMAX);
385 if (line[strlen(line) - 1] != DIRSEP)
386 strcatn(line, DIRSEPSTR, PATHMAX);
387 strcatn(line, "Mix", PATHMAX);
388 err = mixdir(line, 1);
389 }
390 #endif
391
392 if (err == -1) {
393 getcwd(MIXDIR, PATHMAX);
394 mixdir(MIXDIR, 0);
395 }
396
397 strncpy(POOLDIR, MIXDIR, PATHMAX - 32);
398 strcatn(POOLDIR, POOL, PATHMAX);
399 if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP)
400 POOLDIR[strlen(POOLDIR) - 1] = '\0';
401 if (stat(POOLDIR, &buf) != 0)
402 if
403 #ifndef POSIX
404 (mkdir(POOLDIR) != 0)
405 #else
406 (mkdir(POOLDIR, S_IRWXU) == -1)
407 #endif
408 strncpy(POOLDIR, MIXDIR, PATHMAX);
409
410 f = mix_openfile(MIXCONF, "r");
411 if (f != NULL) {
412 while (fgets(line, LINELEN, f) != NULL)
413 if (line[0] > ' ' && line[0] != '#')
414 mix_configline(line);
415 fclose(f);
416 }
417 if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY)
418 IDEXP = 5 * SECONDSPERDAY;
419 if (MAXRANDHOPS > 20)
420 MAXRANDHOPS = 20;
421
422 if (strchr(SHORTNAME, '.'))
423 *strchr(SHORTNAME, '.') = '\0';
424 if (strchr(SHORTNAME, ' '))
425 *strchr(SHORTNAME, ' ') = '\0';
426 #ifdef HAVE_UNAME
427 if (SHORTNAME[0] == '\0' && uname(&uts) != -1)
428 strncpy(SHORTNAME, uts.nodename, LINELEN);
429 #elif defined(HAVE_GETHOSTNAME)
430 if (SHORTNAME[0] == '\0')
431 gethostname(SHORTNAME, LINELEN);
432 #endif
433 if (SHORTNAME[0] == '\0')
434 strcpy(SHORTNAME, "unknown");
435
436 if (ADDRESS[0] == '\0')
437 whoami(ADDRESS, "user");
438
439 #ifdef HAVE_GECOS
440 if (NAME[0] == '\0' && pw != NULL)
441 strcatn(NAME, pw->pw_gecos, sizeof(NAME));
442 #endif
443
444 if (REMAILERADDR[0] == '\0')
445 strncpy(REMAILERADDR, ADDRESS, LINELEN);
446
447 if (COMPLAINTS[0] == '\0')
448 strncpy(COMPLAINTS, REMAILERADDR, LINELEN);
449
450 if (strchr(REMAILERNAME, '@') == NULL) {
451 strcatn(REMAILERNAME, " <", LINELEN);
452 strcatn(REMAILERNAME, REMAILERADDR, LINELEN);
453 strcatn(REMAILERNAME, ">", LINELEN);
454 }
455 if (strchr(ANONNAME, '@') == NULL && ANONADDR[0] != '\0') {
456 strcatn(ANONNAME, " <", LINELEN);
457 strcatn(ANONNAME, ANONADDR, LINELEN);
458 strcatn(ANONNAME, ">", LINELEN);
459 }
460 if (strchr(ANONNAME, '@') == NULL) {
461 strcatn(ANONNAME, " <", LINELEN);
462 strcatn(ANONNAME, REMAILERADDR, LINELEN);
463 strcatn(ANONNAME, ">", LINELEN);
464 }
465 #ifndef USE_PGP
466 if (TYPE1[0] == '\0')
467 PGP = 0;
468 #endif
469 #ifndef USE_RSA
470 MIX = 0;
471 #endif
472
473 #ifdef WIN32
474 if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, &regpgp) == 0)
475 rkey++;
476 if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, &reg) == 0)
477 rkey++;
478 if (PGPPUBRING[0] == '\0' && rkey == 2) {
479 len = PATHMAX;
480 RegQueryValueEx(reg, "PubRing", 0, &type, PGPPUBRING, &len);
481 }
482 if (PGPSECRING[0] == '\0' && rkey == 2) {
483 len = PATHMAX;
484 RegQueryValueEx(reg, "SecRing", 0, &type, PGPSECRING, &len);
485 }
486 if (rkey == 2)
487 RegCloseKey(reg);
488 if (rkey)
489 RegCloseKey(regpgp);
490 RegCloseKey(regsw);
491 #endif
492
493 if (PGPPUBRING[0] == '\0') {
494 char *d;
495
496 if ((d = getenv("HOME")) != NULL) {
497 strcpy(PGPPUBRING, d);
498 strcatn(PGPPUBRING, "/.pgp/", PATHMAX);
499 }
500 strcatn(PGPPUBRING, "pubring.pkr", PATHMAX);
501 if (stat(PGPPUBRING, &buf) == -1)
502 strcpy(strrchr(PGPPUBRING, '.'), ".pgp");
503 }
504 if (PGPSECRING[0] == '\0') {
505 char *d;
506
507 if ((d = getenv("HOME")) != NULL) {
508 strcpy(PGPSECRING, d);
509 strcatn(PGPSECRING, "/.pgp/", PATHMAX);
510 }
511 strcatn(PGPSECRING, "secring.skr", PATHMAX);
512 if (stat(PGPSECRING, &buf) == -1)
513 strcpy(strrchr(PGPSECRING, '.'), ".pgp");
514 }
515 if (streq(NEWS, "mail-to-news"))
516 strncpy(NEWS, MAILtoNEWS, sizeof(NEWS));
517
518 if (f == NULL) {
519 f = mix_openfile(MIXCONF, "w");
520 if (f == NULL)
521 errlog(WARNING, "Can't open %s%s!\n", MIXDIR, MIXCONF);
522 else {
523 fprintf(f, "# mix.cfg - mixmaster configuration file\n");
524 fprintf(f, "NAME %s\n", NAME);
525 fprintf(f, "ADDRESS %s\n", ADDRESS);
526 fprintf(f, "\n# edit to set up a remailer:\n");
527 fprintf(f, "REMAIL n\n");
528 fprintf(f, "SHORTNAME %s\n", SHORTNAME);
529 fprintf(f, "REMAILERADDR %s\n", REMAILERADDR);
530 fprintf(f, "COMPLAINTS %s\n", COMPLAINTS);
531 fclose(f);
532 }
533 REMAIL = 0;
534 }
535
536 return (0);
537 }
538
539 /** Library initialization: ******************************************/
540
541 static int initialized = 0;
542
543 int mix_init(char *mixdir)
544 {
545 if (!initialized) {
546 if (mixdir)
547 strncpy(MIXDIR, mixdir, LINELEN);
548 mix_config();
549 #if defined(USE_SOCK) && defined(WIN32)
550 sock_init();
551 #endif
552 /* atexit (mix_exit); */
553 initialized = 1;
554 }
555
556 if (rnd_init() == -1)
557 rnd_seed();
558 return(0);
559 }
560
561 void mix_exit(void)
562 {
563 if (!initialized)
564 return;
565 rnd_final();
566 #if defined(USE_SOCK) && defined(WIN32)
567 sock_exit();
568 #endif
569 initialized=0;
570 }
571
572 int mix_regular(int force)
573 {
574 FILE *f;
575 long now, tpool = 0, tpop3 = 0, tdaily = 0;
576 int ret = 0;
577
578 mix_init(NULL);
579 now = time(NULL);
580
581 f = mix_openfile(REGULAR, "r+");
582 if (f != NULL) {
583 lock(f);
584 fscanf(f, "%ld %ld %ld", &tpool, &tpop3, &tdaily);
585 if (now - tpool > SENDPOOLTIME)
586 force |= FORCE_POOL;
587 #ifdef USE_SOCK
588 if (now - tpop3 > POP3TIME)
589 force |= FORCE_POP3;
590 #endif
591 if (now - tdaily > SECONDSPERDAY)
592 force |= FORCE_DAILY;
593 if (force & FORCE_POOL)
594 tpool = now;
595 if (force & FORCE_POP3)
596 tpop3 = now;
597 if (force & FORCE_DAILY)
598 tdaily = now;
599 rewind(f);
600 fprintf(f, "%ld %ld %ld\n", tpool, tpop3, tdaily);
601 unlock(f);
602 fclose(f);
603 } else {
604 force = FORCE_POOL | FORCE_POP3 | FORCE_DAILY;
605 f = mix_openfile(REGULAR, "w+");
606 if (f != NULL) {
607 lock(f);
608 fprintf(f, "%ld %ld %ld\n", now, now, now);
609 unlock(f);
610 fclose(f);
611 } else
612 errlog(ERRORMSG, "Can't create %s!\n", REGULAR);
613 }
614
615 if (force & FORCE_DAILY)
616 mix_daily(), ret = 1;
617 #ifdef USE_SOCK
618 if (force & FORCE_POP3)
619 pop3get();
620 #endif
621 if (force & FORCE_POOL)
622 ret = pool_send();
623
624 return (ret);
625 }
626
627 int mix_daily(void)
628 {
629 idexp();
630 pool_packetexp();
631 stats(NULL);
632 keymgt(0);
633 return (0);
634 }
635
636
637 #ifdef WIN32
638 /* Try to detect if we are the service or not...
639 seems there is no easy reliable way */
640 int is_nt_service(void)
641 {
642 static int issvc = -1;
643 #ifdef WIN32SERVICE
644 STARTUPINFO StartupInfo;
645 OSVERSIONINFO VersionInfo;
646 DWORD dwsize;
647
648 if (issvc != -1) /* do it only once */
649 return issvc;
650
651 VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
652 if (GetVersionEx(&VersionInfo))
653 if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
654 return issvc = 0; /* not NT - not the service */
655
656 if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo)))
657 /* reuse VersionInfo to save memory */
658 return issvc = 1; /* have no console - we are the service probably */
659
660 GetStartupInfo(&StartupInfo);
661 if (StartupInfo.lpDesktop[0] == 0)
662 return issvc = 1; /* have no desktop - we are the service probably */
663
664 if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1)
665 return issvc = 1; /* have no stdin,stderr,stdout - probably service */
666 #endif // WIN32SERVICE
667
668 return issvc = 0; // assume not the service
669 } // is_nt_service
670
671 HANDLE hMustTerminate = NULL;
672 void set_nt_exit_event(HANDLE h_svc_exit_event)
673 {
674 hMustTerminate = h_svc_exit_event;
675 } // set_nt_exit_event
676
677 #endif // WIN32
678
679 int mix_daemon(void)
680 {
681 long t;
682 t = SENDPOOLTIME;
683 #ifdef USE_SOCK
684 if (POP3TIME < t)
685 t = POP3TIME;
686 #endif
687
688 for(;;) {
689 mix_regular(0);
690 #ifdef WIN32
691 #ifdef WIN32SERVICE
692 if (hMustTerminate) {
693 if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) {
694 CloseHandle(hMustTerminate);
695 return 0;
696 }
697 } else
698 #endif
699 Sleep(t * 1000);
700 #else
701 sleep(t);
702 #endif
703 }
704 }
705
706 /** error ***************************************************************/
707
708 void errlog(int type, char *fmt,...)
709 {
710 va_list args;
711 BUFFER *msg;
712 FILE *e = NULL;
713 time_t t;
714 struct tm *tc;
715 char line[LINELEN];
716 int p;
717 char err[6][8] =
718 {"", "Error", "Warning", "Notice", "Info", "Info"};
719
720 if ((VERBOSE == 0 && type != ERRORMSG) || (type == LOG && VERBOSE < 2)
721 || (type == DEBUGINFO && VERBOSE < 3))
722 return;
723
724 t = time(NULL);
725 tc = localtime(&t);
726 strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S] ", tc);
727
728 msg = buf_new();
729 buf_appends(msg, line);
730 p = msg->length;
731 buf_appendf(msg, "%s: ", err[type]);
732 va_start(args, fmt);
733 buf_vappendf(msg, fmt, args);
734 va_end(args);
735
736 if (streq(ERRLOG, "stdout"))
737 e = stdout;
738 else if (streq(ERRLOG, "stderr"))
739 e = stderr;
740
741 if (e == NULL && (ERRLOG[0] == '\0' ||
742 (e = mix_openfile(ERRLOG, "a")) == NULL))
743 mix_status("%s", msg->data + p);
744 else {
745 buf_write(msg, e);
746 if (e != stderr && e != stdout) {
747 fclose(e);
748 /* duplicate the error message on screen */
749 mix_status("%s", msg->data + p);
750 }
751 }
752 buf_free(msg);
753 }
754
755 static char statusline[BUFSIZE] = "";
756
757 void mix_status(char *fmt,...)
758 {
759 va_list args;
760
761 if (fmt != NULL) {
762 va_start(args, fmt);
763 #ifdef _MSC
764 _vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
765 #else
766 vsnprintf(statusline, sizeof(statusline) - 1, fmt, args);
767 #endif
768 va_end(args);
769 }
770 #ifdef USE_NCURSES
771 if (menu_initialized) {
772 cl(LINES - 2, 10);
773 printw("%s", statusline);
774 refresh();
775 } else
776 #endif
777 {
778 fprintf(stderr, "%s", statusline);
779 }
780 }
781
782 void mix_genericerror(void)
783 {
784 if (streq(statusline, "") || strfind(statusline, "...") ||
785 strifind(statusline, "generating"))
786 mix_status("Failed!");
787 else
788 mix_status(NULL);
789 }

  ViewVC Help
Powered by ViewVC 1.1.5