You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bforce/source/bforce/logger.c

536 lines
10 KiB
C

/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
* Copyright (c) 2004 Evgeniy Kozhuhovskiy, 2:450/256
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "version.h"
#include "logger.h"
#include "util.h"
/*
* Local variables for logger
*/
static FILE *log_fp = NULL;
static char log_name[BF_MAXPATH+1] = BFORCE_LOGFILE;
static char log_extension[32] = "";
static char log_ident[32] = "";
static char log_ttyname[32] = "";
#ifdef DEBUG
/*
* Local variables needed to make debug work
*/
static FILE *debug_fp = NULL;
static long debug_current_debuglevel = 0L;
static char debug_name[BF_MAXPATH+1] = BFORCE_DEBFILE;
static bool debug_invalid_name = FALSE;
/*
* Debug level names
*/
struct debuglevel {
const char *keystr;
unsigned long value;
} debuglevels[] = {
{ "Config", D_CONFIG },
{ "Override", D_OVERRIDE },
{ "Event", D_EVENT },
{ "Nodelist", D_NODELIST },
{ "Outbound", D_OUTBOUND },
{ "Info", D_INFO },
{ "HShake", D_HSHAKE },
{ "TtyIO", D_TTYIO },
{ "Modem", D_MODEM },
{ "Prot", D_PROT },
{ "Freq", D_FREQ },
{ "Statem", D_STATEM },
{ "Daemon", D_DAEMON },
{ "Full", D_FULL },
{ NULL, 0 }
};
#endif /* DEBUG */
#ifndef USE_SYSLOG
const char *log_getfilename(int whatfor)
{
const char *p = NULL;
switch(whatfor) {
case LOG_FILE_DAEMON:
if( (p = conf_string(cf_log_file_daemon)) == NULL )
p = DAEMON_LOGFILE;
break;
case LOG_FILE_SESSION:
if( (p = conf_string(cf_log_file)) == NULL )
p = BFORCE_LOGFILE;
break;
#ifdef DEBUG
case LOG_FILE_DEBUG:
if( (p = conf_string(cf_debug_file)) == NULL )
p = BFORCE_DEBFILE;
break;
#endif
case LOG_FILE_HISTORY:
break;
}
return p;
}
/*
* Logging part
*/
bool log_isopened(void)
{
return log_fp ? TRUE : FALSE;
}
int log_open(const char *logname, const char *ext, const char *tty)
{
if( log_fp )
log("warning: opening new log file, but previous was not closed");
if( logname )
{
/* Reset previous settings */
*log_name = '\0';
*log_extension = '\0';
*log_ttyname = '\0';
strnxcpy(log_name, logname, sizeof(log_name));
if( tty && *tty )
strnxcpy(log_ttyname, tty, sizeof(log_ttyname));
if( ext && *ext )
{
strnxcpy(log_extension, ext, sizeof(log_extension));
strnxcat(log_name, ".", sizeof(log_name));
strnxcat(log_name, ext, sizeof(log_name));
}
if( (log_fp = fopen(log_name, "a")) == NULL )
{
logerr("can't open log file \"%s\"", log_name);
return -1;
}
}
else if( log_name )
{
/* Open previously set log file */
if( (log_fp = fopen(log_name, "a")) == NULL )
{
logerr("can't open log file \"%s\"", log_name);
return -1;
}
} else
return -1;
return 0;
}
int log_close(void)
{
int rc = 0;
ASSERT(log_fp);
if( log_fp )
{
rc = fclose(log_fp); log_fp = NULL;
}
return rc;
}
int log_reopen(const char *logname, const char *ext, const char *tty)
{
ASSERT(logname != NULL);
if( log_isopened() )
{
if( !strcmp(logname, log_name)
&& !strcmp(log_extension ? log_extension : "", ext ? ext : "") )
{
return 0;
}
log_close();
}
return log_open(logname, ext, tty);
}
int log(const char *s, ...)
{
char timestr[40];
va_list args;
time_string_log(timestr, sizeof(timestr), 0);
va_start(args, s);
/*
* If log file is not opened print messages to the stderr
*/
if( log_fp == NULL )
{
fprintf(stderr, "%s ", timestr);
vfprintf(stderr, s, args);
putc('\n', stderr);
fflush(stderr);
}
else
{
int mypid = getpid();
if( log_ident[0] && log_ttyname[0] )
fprintf(log_fp, "%s %s.%s[%d] ", timestr, log_ident, log_ttyname, mypid);
else if( log_ident[0] )
fprintf(log_fp, "%s %s[%d] ", timestr, log_ident, mypid);
else if( log_ttyname[0] )
fprintf(log_fp, "%s %s[%d] ", timestr, log_ttyname, mypid);
else
fprintf(log_fp, "%s [%d] ", timestr, mypid);
vfprintf(log_fp, s, args);
putc('\n', log_fp);
fflush(log_fp);
}
va_end(args);
return 0;
}
int logerr(const char *s, ...)
{
char timestr[40];
va_list args;
time_string_log(timestr, sizeof(timestr), 0);
va_start(args, s);
/*
* If log file is not opened print messages to the stderr
*/
if( log_fp == NULL )
{
fprintf(stderr, "%s ", timestr);
vfprintf(stderr, s, args);
putc('\n', stderr);
if( errno == EACCES )
{
fprintf(stderr, "\tmessage: \"%s\" : errno = %d (euid = %d, egid = %d)\n",
strerror(errno), errno, geteuid(), getegid());
}
else
{
fprintf(stderr, "\tmessage: \"%s\" : errno = %d\n",
strerror(errno), errno);
}
fflush(stderr);
}
else
{
int mypid = getpid();
if( *log_ident && *log_ttyname )
fprintf(log_fp, "%s %s.%s[%d] ", timestr, log_ident, log_ttyname, mypid);
else if( *log_ident )
fprintf(log_fp, "%s %s[%d] ", timestr, log_ident, mypid);
else if( *log_ttyname )
fprintf(log_fp, "%s %s[%d] ", timestr, log_ttyname, mypid);
else
fprintf(log_fp, "%s [%d] ", timestr, mypid);
vfprintf(log_fp, s, args);
putc('\n', log_fp);
/*
* Print error message according to the errno value
*/
if( errno == EACCES )
{
fprintf(log_fp, "\tmessage: \"%s\" : errno = %d (euid = %d, egid = %d)\n",
strerror(errno), errno, geteuid(), getegid());
}
else if( errno )
{
fprintf(log_fp, "\tmessage: \"%s\" : errno = %d\n",
strerror(errno), errno);
}
fflush(log_fp);
}
va_end(args);
return 0;
}
#endif /* USE_SYSLOG */
#ifdef USE_SYSLOG
const char *log_getfilename(int whatfor)
{
const char *p = "/dev/null";
return p;
}
bool log_isopened(void)
{
return TRUE;
}
int log_open(const char *logname, const char *ext, const char *tty)
{
char *p = "bforce";
int fac = conf_number(cf_syslog_facility);
if( tty && *tty )
strncpy(p, tty, sizeof(p));
openlog(p, LOG_PID, fac);
return 0;
}
int log_reopen(const char *logname, const char *ext, const char *tty)
{
return 0;
}
int log_close(void)
{
closelog();
return 0;
}
int log(const char *s, ...)
{
char timestr[40];
va_list args;
int fac = conf_number(cf_syslog_facility);
const int LP_TTY = fac || LOG_INFO;
const int LP_A = fac || LOG_NOTICE;
const int LP_O = fac || LOG_DEBUG;
const int log_priority = fac || LOG_ERR;
time_string_log(timestr, sizeof(timestr), 0);
va_start(args, s);
int mypid = getpid();
if( log_ident[0] && log_ttyname[0] )
syslog(LP_TTY, "%s %s.%s[%d] ", timestr, log_ident, log_ttyname, mypid);
else if( log_ident[0] )
syslog(LP_A, "%s %s[%d] ", timestr, log_ident, mypid);
else if( log_ttyname[0] )
syslog(LP_O, "%s %s[%d] ", timestr, log_ttyname, mypid);
va_end(args);
return 0;
}
int logerr(const char *s, ...)
{
char timestr[40];
va_list args;
int fac = conf_number(cf_syslog_facility);
const int log_priority = fac || LOG_ERR;
time_string_log(timestr, sizeof(timestr), 0);
va_start(args, s);
int mypid = getpid();
vsyslog(log_priority, s, args);
va_end(args);
return 0;
}
#endif /* USE_SYSLOG */
/*
* Debugging part
*/
#ifdef DEBUG
void debug_setlevel(long newlevel, bool logit)
{
if( logit && newlevel != debug_current_debuglevel )
{
log("changing debug level from 0x%07x to 0x%07x",
debug_current_debuglevel, newlevel);
debug_current_debuglevel = newlevel;
}
}
bool debug_isopened(void)
{
return debug_fp ? TRUE : FALSE;
}
int debug_parsestring(char *str, unsigned long *deblevel)
{
int i, rc = 0;
char *n;
char *p_str = NULL;
ASSERT(str != NULL);
*deblevel = 0L;
for( p_str = string_token(str, &n, NULL, 0); p_str;
p_str = string_token(NULL, &n, NULL, 0) )
{
for( i = 0; debuglevels[i].keystr; i++ )
{
if( strcasecmp(p_str, debuglevels[i].keystr) == 0 )
{
*deblevel |= debuglevels[i].value;
break;
}
}
if( debuglevels[i].keystr == NULL )
{
log("unknown debug level \"%s\"", p_str);
rc = 1;
}
}
return rc;
}
void debug_setfilename(const char *debugname)
{
ASSERT(debugname != NULL);
if( !strcmp(debug_name, debugname) ) return;
if( debug_isopened() ) debug_close();
/* Reset ignore flag */
if( debug_invalid_name )
debug_invalid_name = FALSE;
strnxcpy(debug_name, debugname, sizeof(debug_name));
}
int debug_open(const char *debugname)
{
char buf[40];
ASSERT(debug_fp == NULL);
if( debugname )
{
if( (debug_fp = fopen(debugname, "a")) == NULL )
{
logerr("can't open debug file \"%s\"", debugname);
return -1;
}
strnxcpy(debug_name, debugname, sizeof(debug_name));
}
else if( debug_name )
{
if( (debug_fp = fopen(debug_name, "a")) == NULL )
{
/* Don't try to open it next time */
debug_invalid_name = TRUE;
logerr("can't open debug file \"%s\"", debug_name);
return -1;
}
} else
return -1;
/* Put banner */
fprintf(debug_fp, "****************************************************\n");
fprintf(debug_fp, " Starting binkleyforce version %s\n", BF_VERSION);
fprintf(debug_fp, " Time: %s, PID: %d, UID: %d, GID: %d, EUID: %d, EGID %d\n",
time_string_long(buf, sizeof(buf), 0), getpid(),
getuid(), getgid(), geteuid(), getegid());
fprintf(debug_fp, "****************************************************\n");
fflush(debug_fp);
return 0;
}
int debug_close(void)
{
char buf[40];
int rc = 0;
ASSERT(debug_fp != NULL);
if( debug_fp )
{
fprintf(debug_fp, "****************************************************\n");
fprintf(debug_fp, " Closing binkleyforce debug file at %s\n",
time_string_long(buf, sizeof(buf), 0));
fprintf(debug_fp, "****************************************************\n");
rc = fclose(debug_fp) ? 0 : -1; debug_fp = NULL;
}
return rc;
}
int debug(unsigned long what, const char *str, ...)
{
char buf[40];
va_list args;
if( (what == 0 && debug_current_debuglevel)
|| (debug_current_debuglevel & what) )
{
if( debug_fp == NULL && debug_invalid_name == FALSE )
{
debug_open(NULL);
}
if( debug_fp )
{
fprintf(debug_fp, "%s ", time_string_log(buf, sizeof(buf), 0));
va_start(args, str);
vfprintf(debug_fp, str, args);
va_end(args);
putc('\n', debug_fp);
fflush(debug_fp);
}
}
return 0;
}
#endif /* DEBUG */