| 6 |
details. |
details. |
| 7 |
|
|
| 8 |
Mixmaster initialization, configuration |
Mixmaster initialization, configuration |
| 9 |
$Id: mix.c,v 1.18 2002/08/26 19:38:51 weaselp Exp $ */ |
$Id: mix.c,v 1.38 2002/10/18 20:42:35 rabbi Exp $ */ |
| 10 |
|
|
| 11 |
|
|
| 12 |
#include "mix3.h" |
#include "mix3.h" |
| 23 |
#include <unistd.h> |
#include <unistd.h> |
| 24 |
#include <pwd.h> |
#include <pwd.h> |
| 25 |
#include <sys/utsname.h> |
#include <sys/utsname.h> |
| 26 |
#else |
#else /* end of POSIX */ |
| 27 |
#include <io.h> |
#include <io.h> |
| 28 |
#include <direct.h> |
#include <direct.h> |
| 29 |
#endif |
#endif /* else if not POSIX */ |
| 30 |
#ifdef WIN32 |
#ifdef WIN32 |
| 31 |
#include <windows.h> |
#include <windows.h> |
| 32 |
#endif |
#endif /* WIN32 */ |
| 33 |
#include <assert.h> |
#include <assert.h> |
| 34 |
#include "menu.h" |
#include "menu.h" |
| 35 |
|
|
| 36 |
int buf_vappendf(BUFFER *b, char *fmt, va_list args); |
int buf_vappendf(BUFFER *b, char *fmt, va_list args); |
| 37 |
|
|
| 38 |
/** filenames ************************************************************/ |
/** filenames ************************************************************/ |
| 39 |
char MIXCONF[PATHMAX]; |
char MIXCONF[PATHMAX] = DEFAULT_MIXCONF; |
| 40 |
char DISCLAIMFILE[PATHMAX]; |
char DISCLAIMFILE[PATHMAX]; |
| 41 |
char FROMDSCLFILE[PATHMAX]; |
char FROMDSCLFILE[PATHMAX]; |
| 42 |
char MSGFOOTERFILE[PATHMAX]; |
char MSGFOOTERFILE[PATHMAX]; |
| 66 |
char TYPE1LIST[PATHMAX]; |
char TYPE1LIST[PATHMAX]; |
| 67 |
char TYPE2REL[PATHMAX]; |
char TYPE2REL[PATHMAX]; |
| 68 |
char TYPE2LIST[PATHMAX]; |
char TYPE2LIST[PATHMAX]; |
| 69 |
|
char PIDFILE[PATHMAX]; |
| 70 |
|
|
| 71 |
char PGPREMPUBRING[PATHMAX]; |
char PGPREMPUBRING[PATHMAX]; |
| 72 |
char PGPREMPUBASC[PATHMAX]; |
char PGPREMPUBASC[PATHMAX]; |
| 95 |
char COMPLAINTS[LINELEN]; |
char COMPLAINTS[LINELEN]; |
| 96 |
int AUTOREPLY; |
int AUTOREPLY; |
| 97 |
char SMTPRELAY[LINELEN]; |
char SMTPRELAY[LINELEN]; |
| 98 |
|
char SMTPUSERNAME[LINELEN]; |
| 99 |
|
char SMTPPASSWORD[LINELEN]; |
| 100 |
|
|
| 101 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 102 |
char HELONAME[LINELEN]; |
char HELONAME[LINELEN]; |
| 105 |
int POP3SIZELIMIT; |
int POP3SIZELIMIT; |
| 106 |
long POP3TIME; |
long POP3TIME; |
| 107 |
|
|
| 108 |
#endif |
#endif /* USE_SOCK */ |
| 109 |
|
|
| 110 |
char SHORTNAME[LINELEN]; |
char SHORTNAME[LINELEN]; |
| 111 |
|
|
| 119 |
|
|
| 120 |
int POOLSIZE; |
int POOLSIZE; |
| 121 |
int RATE; |
int RATE; |
| 122 |
|
int INDUMMYP; |
| 123 |
|
int OUTDUMMYP; |
| 124 |
|
int INDUMMYMAXP; |
| 125 |
|
int OUTDUMMYMAXP; |
| 126 |
int MIDDLEMAN; |
int MIDDLEMAN; |
| 127 |
int AUTOBLOCK; |
int AUTOBLOCK; |
| 128 |
char FORWARDTO[LINELEN]; |
char FORWARDTO[LINELEN]; |
| 130 |
int INFLATEMAX; /* maximal size of Inflate: padding */ |
int INFLATEMAX; /* maximal size of Inflate: padding */ |
| 131 |
int MAXRANDHOPS; |
int MAXRANDHOPS; |
| 132 |
int BINFILTER; /* filter binary attachments? */ |
int BINFILTER; /* filter binary attachments? */ |
| 133 |
int LISTSUPPORTED; /* list supported remailers in remailer-conf reply? */ |
int LISTSUPPORTED; /* list supported remailers in remailer-conf reply? */ |
| 134 |
long PACKETEXP; /* Expiration time for old packets */ |
long PACKETEXP; /* Expiration time for old packets */ |
| 135 |
long IDEXP; /* 0 = no ID log !! */ |
long IDEXP; /* 0 = no ID log !! */ |
| 136 |
long SENDPOOLTIME; /* frequency for sending pool messages */ |
long SENDPOOLTIME; /* frequency for sending pool messages */ |
| 137 |
long MAILINTIME; /* frequency for processing MAILIN mail */ |
long MAILINTIME; /* frequency for processing MAILIN mail */ |
| 138 |
|
|
| 139 |
|
long KEYLIFETIME; |
| 140 |
|
long KEYOVERLAPPERIOD; |
| 141 |
|
long KEYGRACEPERIOD; |
| 142 |
|
|
| 143 |
char ERRLOG[LINELEN]; |
char ERRLOG[LINELEN]; |
| 144 |
char ADDRESS[LINELEN]; |
char ADDRESS[LINELEN]; |
| 145 |
char NAME[LINELEN]; |
char NAME[LINELEN]; |
| 174 |
|
|
| 175 |
#if defined(S_IFDIR) && !defined(S_ISDIR) |
#if defined(S_IFDIR) && !defined(S_ISDIR) |
| 176 |
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
| 177 |
#endif |
#endif /* defined(S_IFDIR) && !defined(S_ISDIR) */ |
| 178 |
|
|
| 179 |
static int mixdir(char *d, int create) |
static int mixdir(char *d, int create) |
| 180 |
{ |
{ |
| 190 |
if (create) { |
if (create) { |
| 191 |
#ifndef POSIX |
#ifndef POSIX |
| 192 |
err = mkdir(MIXDIR); |
err = mkdir(MIXDIR); |
| 193 |
#else |
#else /* end of not POSIX */ |
| 194 |
err = mkdir(MIXDIR, S_IRWXU); |
err = mkdir(MIXDIR, S_IRWXU); |
| 195 |
#endif |
#endif /* else if POSIX */ |
| 196 |
if (err == 0) |
if (err == 0) |
| 197 |
errlog(NOTICE, "Creating directory %s.\n", MIXDIR); |
errlog(NOTICE, "Creating directory %s.\n", MIXDIR); |
| 198 |
} else |
} else |
| 211 |
#if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME)) |
#if defined(HAVE_GETDOMAINNAME) || (defined(HAVE_GETHOSTNAME) && ! defined(HAVE_UNAME)) |
| 212 |
char line[LINELEN]; |
char line[LINELEN]; |
| 213 |
|
|
| 214 |
#endif |
#endif /* defined(HAVE_GETDOMAINNAME) || [...] */ |
| 215 |
#ifdef HAVE_UNAME |
#ifdef HAVE_UNAME |
| 216 |
struct utsname uts; |
struct utsname uts; |
| 217 |
|
|
| 218 |
#endif |
#endif /* HAVE_UNAME */ |
| 219 |
#ifdef POSIX |
#ifdef POSIX |
| 220 |
p = getlogin(); |
p = getlogin(); |
| 221 |
#endif |
#endif /* POSIX */ |
| 222 |
if (p == NULL) |
if (p == NULL) |
| 223 |
strcpy(addr, defaultname); |
strcpy(addr, defaultname); |
| 224 |
else |
else |
| 228 |
#ifdef HAVE_UNAME |
#ifdef HAVE_UNAME |
| 229 |
if (uname(&uts) != -1) |
if (uname(&uts) != -1) |
| 230 |
strcatn(addr, uts.nodename, LINELEN); |
strcatn(addr, uts.nodename, LINELEN); |
| 231 |
#elif defined(HAVE_GETHOSTNAME) |
#elif defined(HAVE_GETHOSTNAME) /* end of HAVE_UNAME */ |
| 232 |
if (gethostname(line, LINELEN) == 0) |
if (gethostname(line, LINELEN) == 0) |
| 233 |
strcatn(addr, line, LINELEN); |
strcatn(addr, line, LINELEN); |
| 234 |
#endif |
#endif /* defined(HAVE_GETHOSTNAME) */ |
| 235 |
if (addr[strlen(addr) - 1] == '@') |
if (addr[strlen(addr) - 1] == '@') |
| 236 |
strcatn(addr, SHORTNAME, LINELEN); |
strcatn(addr, SHORTNAME, LINELEN); |
| 237 |
|
|
| 241 |
strcatn(addr, ".", LINELEN); |
strcatn(addr, ".", LINELEN); |
| 242 |
strcatn(addr, line, LINELEN); |
strcatn(addr, line, LINELEN); |
| 243 |
} |
} |
| 244 |
#endif |
#endif /* HAVE_GETDOMAINNAME */ |
| 245 |
} |
} |
| 246 |
} |
} |
| 247 |
|
|
| 321 |
while (isspace(*line)) |
while (isspace(*line)) |
| 322 |
line++; |
line++; |
| 323 |
switch (tolower(*line)) { |
switch (tolower(*line)) { |
| 324 |
case 'd': |
case 'y': /* years */ |
| 325 |
|
l += 365 * 24 * 60 * 60 * n; |
| 326 |
|
break; |
| 327 |
|
case 'b': /* months */ |
| 328 |
|
l += 30 * 24 * 60 * 60 * n; |
| 329 |
|
break; |
| 330 |
|
case 'w': /* weeks */ |
| 331 |
|
l += 7 * 24 * 60 * 60 * n; |
| 332 |
|
break; |
| 333 |
|
case 'd': /* days */ |
| 334 |
l += 24 * 60 * 60 * n; |
l += 24 * 60 * 60 * n; |
| 335 |
break; |
break; |
| 336 |
case 'm': |
case 's': /* seconds */ |
| 337 |
|
l += n; |
| 338 |
|
break; |
| 339 |
|
case 'm': /* minutes */ |
| 340 |
l += 60 * n; |
l += 60 * n; |
| 341 |
break; |
break; |
| 342 |
case 'h': |
case 'h': /* hours - default */ |
| 343 |
default: |
default: |
| 344 |
l += 60 * 60 * n; |
l += 60 * 60 * n; |
| 345 |
break; |
break; |
| 352 |
return (0); |
return (0); |
| 353 |
} |
} |
| 354 |
|
|
| 355 |
void mix_setdefaults() |
static void mix_setdefaults() |
| 356 |
{ |
{ |
| 357 |
#define strnncpy(a,b) strncpy(a, b, sizeof(a)); a[sizeof(a)-1] = '\0' |
#define strnncpy(a,b) strncpy(a, b, sizeof(a)); a[sizeof(a)-1] = '\0' |
| 358 |
|
|
|
strnncpy(MIXCONF , DEFAULT_MIXCONF); |
|
| 359 |
strnncpy(DISCLAIMFILE , DEFAULT_DISCLAIMFILE); |
strnncpy(DISCLAIMFILE , DEFAULT_DISCLAIMFILE); |
| 360 |
strnncpy(FROMDSCLFILE , DEFAULT_FROMDSCLFILE); |
strnncpy(FROMDSCLFILE , DEFAULT_FROMDSCLFILE); |
| 361 |
strnncpy(MSGFOOTERFILE, DEFAULT_MSGFOOTERFILE); |
strnncpy(MSGFOOTERFILE, DEFAULT_MSGFOOTERFILE); |
| 385 |
strnncpy(TYPE1LIST , DEFAULT_TYPE1LIST); |
strnncpy(TYPE1LIST , DEFAULT_TYPE1LIST); |
| 386 |
strnncpy(TYPE2REL , DEFAULT_TYPE2REL); |
strnncpy(TYPE2REL , DEFAULT_TYPE2REL); |
| 387 |
strnncpy(TYPE2LIST , DEFAULT_TYPE2LIST); |
strnncpy(TYPE2LIST , DEFAULT_TYPE2LIST); |
| 388 |
|
strnncpy(PIDFILE , DEFAULT_PIDFILE); |
| 389 |
|
|
| 390 |
strnncpy(PGPREMPUBRING, DEFAULT_PGPREMPUBRING); |
strnncpy(PGPREMPUBRING, DEFAULT_PGPREMPUBRING); |
| 391 |
strnncpy(PGPREMPUBASC , DEFAULT_PGPREMPUBASC); |
strnncpy(PGPREMPUBASC , DEFAULT_PGPREMPUBASC); |
| 400 |
/* programs */ |
/* programs */ |
| 401 |
#ifdef WIN32 |
#ifdef WIN32 |
| 402 |
strnncpy(SENDMAIL , "outfile"); |
strnncpy(SENDMAIL , "outfile"); |
| 403 |
#else |
#else /* end of WIN32 */ |
| 404 |
strnncpy(SENDMAIL , "/usr/lib/sendmail -t"); |
strnncpy(SENDMAIL , "/usr/lib/sendmail -t"); |
| 405 |
#endif |
#endif /* else if not WIN32 */ |
| 406 |
strnncpy(SENDANONMAIL , ""); |
strnncpy(SENDANONMAIL , ""); |
| 407 |
strnncpy(NEWS , ""); |
strnncpy(NEWS , ""); |
| 408 |
strnncpy(TYPE1 , ""); |
strnncpy(TYPE1 , ""); |
| 424 |
POP3SIZELIMIT = 0; |
POP3SIZELIMIT = 0; |
| 425 |
POP3TIME = 60 * 60; |
POP3TIME = 60 * 60; |
| 426 |
|
|
| 427 |
#endif |
#endif /* USE_SOCK */ |
| 428 |
|
|
| 429 |
strnncpy(SHORTNAME , ""); |
strnncpy(SHORTNAME , ""); |
| 430 |
|
|
| 438 |
|
|
| 439 |
POOLSIZE = 0; |
POOLSIZE = 0; |
| 440 |
RATE = 100; |
RATE = 100; |
| 441 |
MIDDLEMAN = 0; |
INDUMMYP = 3; /* add dummy messages with probability p for each message added to the pool */ |
| 442 |
|
OUTDUMMYP = 10; /* add dummy messages with probability p each time we send from the pool */ |
| 443 |
|
INDUMMYMAXP = 84; /* for both of the above: while (rnd < p) { senddummy(); } */ |
| 444 |
|
OUTDUMMYMAXP = 96; /* set max INDUMMYP and OUTDUMMYP such that 24 and 5.25 dummy messages will */ |
| 445 |
|
MIDDLEMAN = 0; /* be generated on average. More than this is insane. */ |
| 446 |
AUTOBLOCK = 1; |
AUTOBLOCK = 1; |
| 447 |
strnncpy(FORWARDTO, "*"); |
strnncpy(FORWARDTO, "*"); |
| 448 |
SIZELIMIT = 0; /* maximal size of remailed messages */ |
SIZELIMIT = 0; /* maximal size of remailed messages */ |
| 452 |
LISTSUPPORTED = 1; /* list supported remailers in remailer-conf reply? */ |
LISTSUPPORTED = 1; /* list supported remailers in remailer-conf reply? */ |
| 453 |
PACKETEXP = 7 * SECONDSPERDAY; /* Expiration time for old packets */ |
PACKETEXP = 7 * SECONDSPERDAY; /* Expiration time for old packets */ |
| 454 |
IDEXP = 7 * SECONDSPERDAY; /* 0 = no ID log !! */ |
IDEXP = 7 * SECONDSPERDAY; /* 0 = no ID log !! */ |
| 455 |
SENDPOOLTIME = 60 * 60; /* frequency for sending pool messages */ |
SENDPOOLTIME = 0; /* frequency for sending pool messages */ |
| 456 |
MAILINTIME = 5 * 60; /* frequency for processing MAILIN mail */ |
MAILINTIME = 5 * 60; /* frequency for processing MAILIN mail */ |
| 457 |
|
|
| 458 |
|
KEYLIFETIME = 13 * 30 * 24 * 60 * 60; /* validity period for keys. */ |
| 459 |
|
KEYOVERLAPPERIOD = 1 * 30 * 24 * 60 * 60; /* when keys have this amount of time */ |
| 460 |
|
/* left before expiration, create */ |
| 461 |
|
/* new ones when ./mix -K is run.*/ |
| 462 |
|
KEYGRACEPERIOD = 7 * 24 * 60 * 60; /* accept mail to the old key for this */ |
| 463 |
|
/* amount of time after it has expired. */ |
| 464 |
|
|
| 465 |
|
|
| 466 |
strnncpy(ERRLOG , ""); |
strnncpy(ERRLOG , ""); |
| 467 |
strnncpy(ADDRESS , ""); |
strnncpy(ADDRESS , ""); |
| 468 |
strnncpy(NAME , ""); |
strnncpy(NAME , ""); |
| 482 |
strnncpy(PGPSECRING, ""); |
strnncpy(PGPSECRING, ""); |
| 483 |
#ifdef COMPILEDPASS |
#ifdef COMPILEDPASS |
| 484 |
strnncpy(PASSPHRASE, COMPILEDPASS); |
strnncpy(PASSPHRASE, COMPILEDPASS); |
| 485 |
#else |
#else /* end of COMPILEDPASS */ |
| 486 |
strnncpy(PASSPHRASE, ""); |
strnncpy(PASSPHRASE, ""); |
| 487 |
#endif |
#endif /* else if not COMPILEDPASS */ |
| 488 |
strnncpy(MAILIN , ""); |
strnncpy(MAILIN , ""); |
| 489 |
strnncpy(MAILBOX , "mbox"); |
strnncpy(MAILBOX , "mbox"); |
| 490 |
strnncpy(MAILABUSE , ""); |
strnncpy(MAILABUSE , ""); |
| 493 |
strnncpy(MAILUSAGE , "nul:"); |
strnncpy(MAILUSAGE , "nul:"); |
| 494 |
strnncpy(MAILANON , "nul:"); |
strnncpy(MAILANON , "nul:"); |
| 495 |
strnncpy(MAILERROR , "nul:"); |
strnncpy(MAILERROR , "nul:"); |
| 496 |
#else |
#else /* end of WIN32 */ |
| 497 |
strnncpy(MAILUSAGE , "/dev/null"); |
strnncpy(MAILUSAGE , "/dev/null"); |
| 498 |
strnncpy(MAILANON , "/dev/null"); |
strnncpy(MAILANON , "/dev/null"); |
| 499 |
strnncpy(MAILERROR , "/dev/null"); |
strnncpy(MAILERROR , "/dev/null"); |
| 500 |
#endif |
#endif /* else if not WIN32 */ |
| 501 |
strnncpy(MAILBOUNCE, ""); |
strnncpy(MAILBOUNCE, ""); |
| 502 |
} |
} |
| 503 |
|
|
| 508 |
read_conf(ANONADDR) || read_conf(REMAILERNAME) || |
read_conf(ANONADDR) || read_conf(REMAILERNAME) || |
| 509 |
read_conf(ANONNAME) || read_conf(COMPLAINTS) || |
read_conf(ANONNAME) || read_conf(COMPLAINTS) || |
| 510 |
read_conf_i(AUTOREPLY) || read_conf(SMTPRELAY) || |
read_conf_i(AUTOREPLY) || read_conf(SMTPRELAY) || |
| 511 |
|
read_conf(SMTPUSERNAME) || read_conf(SMTPPASSWORD) || |
| 512 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 513 |
read_conf(HELONAME) || read_conf(ENVFROM) || |
read_conf(HELONAME) || read_conf(ENVFROM) || |
| 514 |
#endif |
#endif /* USE_SOCK */ |
| 515 |
read_conf(SENDMAIL) || read_conf(SENDANONMAIL) || |
read_conf(SENDMAIL) || read_conf(SENDANONMAIL) || |
| 516 |
read_conf_i(REMAIL) || read_conf_i(MIX) || |
read_conf_i(REMAIL) || read_conf_i(MIX) || |
| 517 |
read_conf_i(PGP) || read_conf_i(UNENCRYPTED) || |
read_conf_i(PGP) || read_conf_i(UNENCRYPTED) || |
| 521 |
read_conf(ORGANIZATION) || read_conf(MID) || |
read_conf(ORGANIZATION) || read_conf(MID) || |
| 522 |
read_conf(TYPE1) || read_conf_i(POOLSIZE) || |
read_conf(TYPE1) || read_conf_i(POOLSIZE) || |
| 523 |
read_conf_i(RATE) || read_conf_i(MIDDLEMAN) || |
read_conf_i(RATE) || read_conf_i(MIDDLEMAN) || |
| 524 |
|
read_conf_i(INDUMMYP) || |
| 525 |
|
read_conf_i(OUTDUMMYP) || |
| 526 |
read_conf_i(AUTOBLOCK) || read_conf(FORWARDTO) || |
read_conf_i(AUTOBLOCK) || read_conf(FORWARDTO) || |
| 527 |
read_conf_i(SIZELIMIT) || read_conf_i(INFLATEMAX) || |
read_conf_i(SIZELIMIT) || read_conf_i(INFLATEMAX) || |
| 528 |
read_conf_i(MAXRANDHOPS) || read_conf_i(BINFILTER) || |
read_conf_i(MAXRANDHOPS) || read_conf_i(BINFILTER) || |
| 534 |
read_conf_i(DISTANCE) || read_conf_i(MINREL) || |
read_conf_i(DISTANCE) || read_conf_i(MINREL) || |
| 535 |
read_conf_i(RELFINAL) || read_conf_t(MAXLAT) || |
read_conf_i(RELFINAL) || read_conf_t(MAXLAT) || |
| 536 |
read_conf(PGPPUBRING) || read_conf(PGPSECRING) || |
read_conf(PGPPUBRING) || read_conf(PGPSECRING) || |
| 537 |
read_conf(PASSPHRASE) || |
read_conf(PASSPHRASE) || read_conf_t(KEYLIFETIME) || |
| 538 |
|
read_conf_t(KEYGRACEPERIOD) || read_conf_t(KEYOVERLAPPERIOD) || |
| 539 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 540 |
read_conf_i(POP3DEL) || read_conf_i(POP3SIZELIMIT) || |
read_conf_i(POP3DEL) || read_conf_i(POP3SIZELIMIT) || |
| 541 |
read_conf_t(POP3TIME) || |
read_conf_t(POP3TIME) || |
| 542 |
#endif |
#endif /* USE_SOCK */ |
| 543 |
read_conf(MAILBOX) || read_conf(MAILABUSE) || |
read_conf(MAILBOX) || read_conf(MAILABUSE) || |
| 544 |
read_conf(MAILBLOCK) || read_conf(MAILUSAGE) || |
read_conf(MAILBLOCK) || read_conf(MAILUSAGE) || |
| 545 |
read_conf(MAILANON) || read_conf(MAILERROR) || |
read_conf(MAILANON) || read_conf(MAILERROR) || |
| 562 |
read_conf(TYPE2REL) || read_conf(TYPE2LIST) || |
read_conf(TYPE2REL) || read_conf(TYPE2LIST) || |
| 563 |
read_conf(PGPREMPUBRING) || read_conf(PGPREMPUBASC) || |
read_conf(PGPREMPUBRING) || read_conf(PGPREMPUBASC) || |
| 564 |
read_conf(PGPREMSECRING) || read_conf(NYMSECRING) || |
read_conf(PGPREMSECRING) || read_conf(NYMSECRING) || |
| 565 |
read_conf(NYMDB) ); |
read_conf(NYMDB) || read_conf(PIDFILE) ); |
| 566 |
} |
} |
| 567 |
|
|
| 568 |
static int mix_config(void) |
int mix_config(void) |
| 569 |
{ |
{ |
| 570 |
char *d; |
char *d; |
| 571 |
FILE *f; |
FILE *f; |
| 573 |
int err = -1; |
int err = -1; |
| 574 |
#ifdef POSIX |
#ifdef POSIX |
| 575 |
struct passwd *pw; |
struct passwd *pw; |
| 576 |
#endif |
#endif /* POSIX */ |
| 577 |
struct stat buf; |
struct stat buf; |
| 578 |
#ifdef HAVE_UNAME |
#ifdef HAVE_UNAME |
| 579 |
struct utsname uts; |
struct utsname uts; |
| 580 |
#endif |
#endif /* HAVE_UNAME */ |
| 581 |
#ifdef WIN32 |
#ifdef WIN32 |
| 582 |
HKEY regsw, reg, regpgp; |
HKEY regsw, reg, regpgp; |
| 583 |
DWORD type, len; |
DWORD type, len; |
| 584 |
int rkey = 0; |
int rkey = 0; |
| 585 |
#endif |
#endif /* WIN32 */ |
| 586 |
|
|
| 587 |
mix_setdefaults(); |
mix_setdefaults(); |
| 588 |
|
|
| 589 |
#ifdef POSIX |
#ifdef POSIX |
| 590 |
pw = getpwuid(getuid()); |
pw = getpwuid(getuid()); |
| 591 |
#endif |
#endif /* POSIX */ |
| 592 |
|
|
| 593 |
#ifdef WIN32 |
#ifdef WIN32 |
| 594 |
RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, ®sw); |
RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, ®sw); |
| 599 |
err = mixdir(line, 1); |
err = mixdir(line, 1); |
| 600 |
RegCloseKey(reg); |
RegCloseKey(reg); |
| 601 |
} |
} |
| 602 |
#endif |
#endif /* WIN32 */ |
| 603 |
|
|
| 604 |
if (err == -1 && (d = getenv("MIXPATH")) != NULL) |
if (err == -1 && (d = getenv("MIXPATH")) != NULL) |
| 605 |
err = mixdir(d, 1); |
err = mixdir(d, 1); |
| 607 |
#ifdef SPOOL |
#ifdef SPOOL |
| 608 |
if (err == -1 && strlen(SPOOL) > 0) |
if (err == -1 && strlen(SPOOL) > 0) |
| 609 |
err = mixdir(SPOOL, 0); |
err = mixdir(SPOOL, 0); |
| 610 |
#endif |
#endif /* SPOOL */ |
| 611 |
|
|
| 612 |
#ifdef POSIX |
#ifdef POSIX |
| 613 |
if (err == -1 && pw != NULL) { |
if (err == -1 && pw != NULL) { |
| 618 |
strcatn(line, HOMEMIXDIR, PATHMAX); |
strcatn(line, HOMEMIXDIR, PATHMAX); |
| 619 |
err = mixdir(line, 1); |
err = mixdir(line, 1); |
| 620 |
} |
} |
| 621 |
#endif |
#endif /* POSIX */ |
| 622 |
|
|
| 623 |
if (err == -1) { |
if (err == -1) { |
| 624 |
getcwd(MIXDIR, PATHMAX); |
getcwd(MIXDIR, PATHMAX); |
| 625 |
mixdir(MIXDIR, 0); |
mixdir(MIXDIR, 0); |
| 626 |
} |
} |
| 627 |
|
|
|
mixfile(POOLDIR, POOL); |
|
|
if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP) |
|
|
POOLDIR[strlen(POOLDIR) - 1] = '\0'; |
|
|
if (stat(POOLDIR, &buf) != 0) |
|
|
if |
|
|
#ifndef POSIX |
|
|
(mkdir(POOLDIR) != 0) |
|
|
#else |
|
|
(mkdir(POOLDIR, S_IRWXU) == -1) |
|
|
#endif |
|
|
strncpy(POOLDIR, MIXDIR, PATHMAX); |
|
|
|
|
| 628 |
#ifdef GLOBALMIXCONF |
#ifdef GLOBALMIXCONF |
| 629 |
f = mix_openfile(GLOBALMIXCONF, "r"); |
f = mix_openfile(GLOBALMIXCONF, "r"); |
| 630 |
if (f != NULL) { |
if (f != NULL) { |
| 633 |
mix_configline(line); |
mix_configline(line); |
| 634 |
fclose(f); |
fclose(f); |
| 635 |
} |
} |
| 636 |
#endif |
#endif /* GLOBALMIXCONF */ |
| 637 |
f = mix_openfile(MIXCONF, "r"); |
f = mix_openfile(MIXCONF, "r"); |
| 638 |
if (f != NULL) { |
if (f != NULL) { |
| 639 |
while (fgets(line, LINELEN, f) != NULL) |
while (fgets(line, LINELEN, f) != NULL) |
| 641 |
mix_configline(line); |
mix_configline(line); |
| 642 |
fclose(f); |
fclose(f); |
| 643 |
} |
} |
| 644 |
|
|
| 645 |
|
mixfile(POOLDIR, POOL); /* set POOLDIR after reading POOL from cfg file */ |
| 646 |
|
if (POOLDIR[strlen(POOLDIR) - 1] == DIRSEP) |
| 647 |
|
POOLDIR[strlen(POOLDIR) - 1] = '\0'; |
| 648 |
|
if (stat(POOLDIR, &buf) != 0) |
| 649 |
|
if |
| 650 |
|
#ifndef POSIX |
| 651 |
|
(mkdir(POOLDIR) != 0) |
| 652 |
|
#else /* end of not POSIX */ |
| 653 |
|
(mkdir(POOLDIR, S_IRWXU) == -1) |
| 654 |
|
#endif /* else if POSIX */ |
| 655 |
|
strncpy(POOLDIR, MIXDIR, PATHMAX); |
| 656 |
|
|
| 657 |
if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY) |
if (IDEXP > 0 && IDEXP < 5 * SECONDSPERDAY) |
| 658 |
IDEXP = 5 * SECONDSPERDAY; |
IDEXP = 5 * SECONDSPERDAY; |
| 659 |
if (MAXRANDHOPS > 20) |
if (MAXRANDHOPS > 20) |
| 660 |
MAXRANDHOPS = 20; |
MAXRANDHOPS = 20; |
| 661 |
|
if (INDUMMYP > INDUMMYMAXP) |
| 662 |
|
INDUMMYP = INDUMMYMAXP; |
| 663 |
|
if (OUTDUMMYP > OUTDUMMYMAXP) |
| 664 |
|
OUTDUMMYP = OUTDUMMYMAXP; |
| 665 |
|
|
| 666 |
if (strchr(SHORTNAME, '.')) |
if (strchr(SHORTNAME, '.')) |
| 667 |
*strchr(SHORTNAME, '.') = '\0'; |
*strchr(SHORTNAME, '.') = '\0'; |
| 670 |
#ifdef HAVE_UNAME |
#ifdef HAVE_UNAME |
| 671 |
if (SHORTNAME[0] == '\0' && uname(&uts) != -1) |
if (SHORTNAME[0] == '\0' && uname(&uts) != -1) |
| 672 |
strncpy(SHORTNAME, uts.nodename, LINELEN); |
strncpy(SHORTNAME, uts.nodename, LINELEN); |
| 673 |
#elif defined(HAVE_GETHOSTNAME) |
#elif defined(HAVE_GETHOSTNAME) /* end of HAVE_UNAME */ |
| 674 |
if (SHORTNAME[0] == '\0') |
if (SHORTNAME[0] == '\0') |
| 675 |
gethostname(SHORTNAME, LINELEN); |
gethostname(SHORTNAME, LINELEN); |
| 676 |
#endif |
#endif /* defined(HAVE_GETHOSTNAME) */ |
| 677 |
if (SHORTNAME[0] == '\0') |
if (SHORTNAME[0] == '\0') |
| 678 |
strcpy(SHORTNAME, "unknown"); |
strcpy(SHORTNAME, "unknown"); |
| 679 |
|
|
| 683 |
#ifdef HAVE_GECOS |
#ifdef HAVE_GECOS |
| 684 |
if (NAME[0] == '\0' && pw != NULL) |
if (NAME[0] == '\0' && pw != NULL) |
| 685 |
strcatn(NAME, pw->pw_gecos, sizeof(NAME)); |
strcatn(NAME, pw->pw_gecos, sizeof(NAME)); |
| 686 |
#endif |
#endif /* HAVE_GECOS */ |
| 687 |
|
|
| 688 |
if (REMAILERADDR[0] == '\0') |
if (REMAILERADDR[0] == '\0') |
| 689 |
strncpy(REMAILERADDR, ADDRESS, LINELEN); |
strncpy(REMAILERADDR, ADDRESS, LINELEN); |
| 709 |
#ifndef USE_PGP |
#ifndef USE_PGP |
| 710 |
if (TYPE1[0] == '\0') |
if (TYPE1[0] == '\0') |
| 711 |
PGP = 0; |
PGP = 0; |
| 712 |
#endif |
#endif /* not USE_PGP */ |
| 713 |
#ifndef USE_RSA |
#ifndef USE_RSA |
| 714 |
MIX = 0; |
MIX = 0; |
| 715 |
#endif |
#endif /* not USE_RSA */ |
| 716 |
|
|
| 717 |
#ifdef WIN32 |
#ifdef WIN32 |
| 718 |
if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, ®pgp) == 0) |
if (RegOpenKeyEx(regsw, "PGP", 0, KEY_ALL_ACCESS, ®pgp) == 0) |
| 719 |
rkey++; |
rkey++; |
| 720 |
if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, ®) == 0) |
if (rkey && RegOpenKeyEx(regpgp, "PGPlib", 0, KEY_QUERY_VALUE, ®) == 0) |
| 721 |
rkey++; |
rkey++; |
| 732 |
if (rkey) |
if (rkey) |
| 733 |
RegCloseKey(regpgp); |
RegCloseKey(regpgp); |
| 734 |
RegCloseKey(regsw); |
RegCloseKey(regsw); |
| 735 |
#endif |
#endif /* WIN32 */ |
| 736 |
|
|
| 737 |
if (PGPPUBRING[0] == '\0') { |
if (PGPPUBRING[0] == '\0') { |
| 738 |
char *d; |
char *d; |
| 776 |
fprintf(f, "COMPLAINTS %s\n", COMPLAINTS); |
fprintf(f, "COMPLAINTS %s\n", COMPLAINTS); |
| 777 |
fclose(f); |
fclose(f); |
| 778 |
} |
} |
| 779 |
#endif |
#endif /* not GLOBALMIXCONF */ |
| 780 |
REMAIL = 0; |
REMAIL = 0; |
| 781 |
} |
} |
| 782 |
|
|
| 783 |
if (strncmp(ENTEREDPASSPHRASE, "", LINELEN) != 0) { |
if (ENTEREDPASSPHRASE[0] != '\0') { |
| 784 |
strncpy(PASSPHRASE, ENTEREDPASSPHRASE, LINELEN); |
strncpy(PASSPHRASE, ENTEREDPASSPHRASE, LINELEN); |
| 785 |
PASSPHRASE[LINELEN-1] = 0; |
PASSPHRASE[LINELEN-1] = 0; |
| 786 |
}; |
}; |
| 800 |
mix_config(); |
mix_config(); |
| 801 |
#if defined(USE_SOCK) && defined(WIN32) |
#if defined(USE_SOCK) && defined(WIN32) |
| 802 |
sock_init(); |
sock_init(); |
| 803 |
#endif |
#endif /* defined(USE_SOCK) && defined(WIN32) */ |
| 804 |
/* atexit (mix_exit); */ |
/* atexit (mix_exit); */ |
| 805 |
initialized = 1; |
initialized = 1; |
| 806 |
} |
} |
| 817 |
rnd_final(); |
rnd_final(); |
| 818 |
#if defined(USE_SOCK) && defined(WIN32) |
#if defined(USE_SOCK) && defined(WIN32) |
| 819 |
sock_exit(); |
sock_exit(); |
| 820 |
#endif |
#endif /* defined(USE_SOCK) && defined(WIN32) */ |
| 821 |
initialized=0; |
initialized=0; |
| 822 |
} |
} |
| 823 |
|
|
| 839 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 840 |
if (now - tpop3 >= POP3TIME) |
if (now - tpop3 >= POP3TIME) |
| 841 |
force |= FORCE_POP3 | FORCE_MAILIN; |
force |= FORCE_POP3 | FORCE_MAILIN; |
| 842 |
#endif |
#endif /* USE_SOCK */ |
| 843 |
if (now - tdaily >= SECONDSPERDAY) |
if (now - tdaily >= SECONDSPERDAY) |
| 844 |
force |= FORCE_DAILY; |
force |= FORCE_DAILY; |
| 845 |
if (now - tmailin >= MAILINTIME) |
if (now - tmailin >= MAILINTIME) |
| 873 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 874 |
if (force & FORCE_POP3) |
if (force & FORCE_POP3) |
| 875 |
pop3get(); |
pop3get(); |
| 876 |
#endif |
#endif /* USE_SOCK */ |
| 877 |
if (force & FORCE_MAILIN) |
if (force & FORCE_MAILIN) |
| 878 |
ret = process_mailin(); |
ret = process_mailin(); |
| 879 |
if (force & FORCE_POOL) |
if (force & FORCE_POOL) |
| 900 |
@author PP |
@author PP |
| 901 |
@return nothing |
@return nothing |
| 902 |
*/ |
*/ |
| 903 |
|
#ifdef POSIX |
| 904 |
void sighandler(int signal) { |
void sighandler(int signal) { |
| 905 |
if (signal == SIGHUP) |
if (signal == SIGHUP) |
| 906 |
rereadconfig = 1; |
rereadconfig = 1; |
| 907 |
else if (signal == SIGINT || signal == SIGTERM) |
else if (signal == SIGINT || signal == SIGTERM) |
| 908 |
terminatedaemon = 1; |
terminatedaemon = 1; |
| 909 |
}; |
}; |
| 910 |
|
#endif /* POSIX */ |
| 911 |
|
|
| 912 |
/** Set the signal handler for SIGHUP, SIGINT and SIGTERM |
/** Set the signal handler for SIGHUP, SIGINT and SIGTERM |
| 913 |
This function registers signal handlers so that |
This function registers signal handlers so that |
| 919 |
|
|
| 920 |
@param restart Whether or not system calls should be |
@param restart Whether or not system calls should be |
| 921 |
restarted. Usually we want this, the |
restarted. Usually we want this, the |
| 922 |
only excetion is the sleep() in the |
only excetion is the sleep() in the |
| 923 |
daemon mail loop. |
daemon mail loop. |
| 924 |
@author PP |
@author PP |
| 925 |
@return -1 if calling sigaction failed, 0 on |
@return -1 if calling sigaction failed, 0 on |
| 926 |
no error |
no error |
| 934 |
memset(&hdl, 0, sizeof(hdl)); |
memset(&hdl, 0, sizeof(hdl)); |
| 935 |
hdl.sa_handler = sighandler; |
hdl.sa_handler = sighandler; |
| 936 |
hdl.sa_flags = restart ? SA_RESTART : 0; |
hdl.sa_flags = restart ? SA_RESTART : 0; |
| 937 |
|
|
| 938 |
if (sigaction(SIGHUP, &hdl, NULL)) |
if (sigaction(SIGHUP, &hdl, NULL)) |
| 939 |
err = -1; |
err = -1; |
| 940 |
if (sigaction(SIGINT, &hdl, NULL)) |
if (sigaction(SIGINT, &hdl, NULL)) |
| 948 |
} |
} |
| 949 |
|
|
| 950 |
#ifdef WIN32 |
#ifdef WIN32 |
| 951 |
/* Try to detect if we are the service or not... |
/* Try to detect if we are the service or not... |
| 952 |
seems there is no easy reliable way */ |
seems there is no easy reliable way */ |
| 953 |
int is_nt_service(void) |
int is_nt_service(void) |
| 954 |
{ |
{ |
| 955 |
static int issvc = -1; |
static int issvc = -1; |
| 956 |
#ifdef WIN32SERVICE |
#ifdef WIN32SERVICE |
| 957 |
STARTUPINFO StartupInfo; |
STARTUPINFO StartupInfo; |
| 959 |
DWORD dwsize; |
DWORD dwsize; |
| 960 |
|
|
| 961 |
if (issvc != -1) /* do it only once */ |
if (issvc != -1) /* do it only once */ |
| 962 |
return issvc; |
return issvc; |
| 963 |
|
|
| 964 |
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo); |
VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo); |
| 965 |
if (GetVersionEx(&VersionInfo)) |
if (GetVersionEx(&VersionInfo)) |
| 966 |
if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) |
if (VersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) |
| 967 |
return issvc = 0; /* not NT - not the service */ |
return issvc = 0; /* not NT - not the service */ |
|
|
|
|
if (!GetConsoleTitle(&VersionInfo,sizeof(VersionInfo))) |
|
|
/* reuse VersionInfo to save memory */ |
|
|
return issvc = 1; /* have no console - we are the service probably */ |
|
| 968 |
|
|
| 969 |
GetStartupInfo(&StartupInfo); |
GetStartupInfo(&StartupInfo); |
| 970 |
if (StartupInfo.lpDesktop[0] == 0) |
if (StartupInfo.lpDesktop[0] == 0) |
| 971 |
return issvc = 1; /* have no desktop - we are the service probably */ |
return issvc = 1; /* have no desktop - we are the service probably */ |
| 972 |
|
#endif /* WIN32SERVICE */ |
|
if (_fileno(stdin) == -1 && _fileno(stdout) == -1 && _fileno(stderr) == -1) |
|
|
return issvc = 1; /* have no stdin,stderr,stdout - probably service */ |
|
|
#endif // WIN32SERVICE |
|
| 973 |
|
|
| 974 |
return issvc = 0; // assume not the service |
return issvc = 0; /* assume not the service */ |
| 975 |
} // is_nt_service |
} /* is_nt_service */ |
| 976 |
|
|
| 977 |
HANDLE hMustTerminate = NULL; |
HANDLE hMustTerminate = NULL; |
| 978 |
void set_nt_exit_event(HANDLE h_svc_exit_event) |
void set_nt_exit_event(HANDLE h_svc_exit_event) |
| 979 |
{ |
{ |
| 980 |
hMustTerminate = h_svc_exit_event; |
hMustTerminate = h_svc_exit_event; |
| 981 |
} // set_nt_exit_event |
} /* set_nt_exit_event */ |
| 982 |
|
|
| 983 |
#endif // WIN32 |
#endif /* WIN32 */ |
| 984 |
|
|
| 985 |
int mix_daemon(void) |
int mix_daemon(void) |
| 986 |
{ |
{ |
| 987 |
long t, slept; |
long t, slept; |
| 988 |
t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME; |
t = SENDPOOLTIME; |
| 989 |
|
if (MAILINTIME < t && (MAILIN != NULL && MAILIN[0] != '\0')) |
| 990 |
|
t = MAILINTIME; |
| 991 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 992 |
if (POP3TIME < t) |
if (POP3TIME < t) |
| 993 |
t = POP3TIME; |
t = POP3TIME; |
| 994 |
#endif |
#endif /* USE_SOCK */ |
| 995 |
|
if (t < 5) |
| 996 |
|
t = 5; /* Some kind of safety for broken systems */ |
| 997 |
slept = t; |
slept = t; |
| 998 |
|
|
| 999 |
setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */ |
setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */ |
| 1000 |
for(;;) { |
for(;;) { |
| 1001 |
if (terminatedaemon) |
if (terminatedaemon) |
| 1002 |
exit(0); |
break; |
| 1003 |
if (rereadconfig) { |
if (rereadconfig) { |
| 1004 |
rereadconfig = 0; |
rereadconfig = 0; |
| 1005 |
mix_config(); |
mix_config(); |
| 1006 |
t = (MAILINTIME < SENDPOOLTIME && (MAILIN != NULL && (strcmp(MAILIN, "") != 0))) ? MAILINTIME : SENDPOOLTIME; |
t = SENDPOOLTIME; |
| 1007 |
|
if (MAILINTIME < t && (MAILIN != NULL && MAILIN[0] != '\0')) |
| 1008 |
|
t = MAILINTIME; |
| 1009 |
#ifdef USE_SOCK |
#ifdef USE_SOCK |
| 1010 |
if (POP3TIME < t) |
if (POP3TIME < t) |
| 1011 |
t = POP3TIME; |
t = POP3TIME; |
| 1012 |
#endif |
if (t < 5) |
| 1013 |
|
t = 5; /* Some kind of safety for broken systems */ |
| 1014 |
|
#endif /* USE_SOCK */ |
| 1015 |
} |
} |
| 1016 |
if (slept >= t) { |
if (slept >= t) { |
| 1017 |
mix_regular(0); |
mix_regular(0); |
| 1018 |
slept = 0; |
slept = 0; |
| 1019 |
} |
} |
| 1020 |
|
|
| 1021 |
|
#ifdef WIN32SERVICE |
| 1022 |
|
if (hMustTerminate) { |
| 1023 |
|
if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) { |
| 1024 |
|
CloseHandle(hMustTerminate); |
| 1025 |
|
terminatedaemon = 1; |
| 1026 |
|
} |
| 1027 |
|
} |
| 1028 |
|
#endif /* WIN32SERVICE */ |
| 1029 |
|
|
| 1030 |
if (!terminatedaemon && !rereadconfig) { |
if (!terminatedaemon && !rereadconfig) { |
| 1031 |
setsignalhandler(0); /* set signal handlers; don't restart system calls */ |
setsignalhandler(0); /* set signal handlers; don't restart system calls */ |
| 1032 |
#ifdef WIN32 |
#ifdef WIN32 |
| 1033 |
#ifdef WIN32SERVICE |
Sleep(t * 1000); /* how to get the real number of seconds slept? */ |
| 1034 |
if (hMustTerminate) { |
slept = t; |
| 1035 |
if (WaitForSingleObject(hMustTerminate, t * 1000) == WAIT_OBJECT_0) { |
#else /* end of WIN32 */ |
|
CloseHandle(hMustTerminate); |
|
|
return 0; |
|
|
} |
|
|
} else |
|
|
#endif |
|
|
Sleep(t * 1000); |
|
|
#else |
|
| 1036 |
slept += (t - slept) - sleep(t - slept); |
slept += (t - slept) - sleep(t - slept); |
| 1037 |
#endif |
#endif /* else if not WIN32 */ |
| 1038 |
setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */ |
setsignalhandler(1); /* set signal handlers and restart any interrupted system calls */ |
| 1039 |
} |
} |
| 1040 |
} |
} |
| 1041 |
|
return (0); |
| 1042 |
} |
} |
| 1043 |
|
|
| 1044 |
/** error ***************************************************************/ |
/** error ***************************************************************/ |
| 1100 |
va_start(args, fmt); |
va_start(args, fmt); |
| 1101 |
#ifdef _MSC |
#ifdef _MSC |
| 1102 |
_vsnprintf(statusline, sizeof(statusline) - 1, fmt, args); |
_vsnprintf(statusline, sizeof(statusline) - 1, fmt, args); |
| 1103 |
#else |
#else /* end of _MSC */ |
| 1104 |
vsnprintf(statusline, sizeof(statusline) - 1, fmt, args); |
vsnprintf(statusline, sizeof(statusline) - 1, fmt, args); |
| 1105 |
#endif |
#endif /* else if not _MSC */ |
| 1106 |
va_end(args); |
va_end(args); |
| 1107 |
} |
} |
| 1108 |
#ifdef USE_NCURSES |
#ifdef USE_NCURSES |
| 1111 |
printw("%s", statusline); |
printw("%s", statusline); |
| 1112 |
refresh(); |
refresh(); |
| 1113 |
} else |
} else |
| 1114 |
#endif |
#endif /* USE_NCURSES */ |
| 1115 |
{ |
{ |
| 1116 |
fprintf(stderr, "%s", statusline); |
fprintf(stderr, "%s", statusline); |
| 1117 |
} |
} |