#include <freeradius-devel/ident.h>
RCSID("$Id$")
#include <freeradius-devel/radiusd.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
static int openlog_run = 0;
#endif
static int can_update_log_fp = TRUE;
static FILE *log_fp = NULL;
static const FR_NAME_NUMBER levels[] = {
{ ": Debug: ", L_DBG },
{ ": Auth: ", L_AUTH },
{ ": Proxy: ", L_PROXY },
{ ": Info: ", L_INFO },
{ ": Acct: ", L_ACCT },
{ ": Error: ", L_ERR },
{ NULL, 0 }
};
int vradlog(int lvl, const char *fmt, va_list ap)
{
struct main_config_t *myconfig = &mainconfig;
int fd = myconfig->radlog_fd;
FILE *fp = NULL;
unsigned char *p;
char buffer[8192];
int len, print_timestamp = 0;
if (!debug_flag && (lvl == L_DBG)) {
return 0;
}
if (myconfig->radlog_dest == RADLOG_NULL) {
return 0;
}
if ((myconfig->radlog_dest != RADLOG_SYSLOG) &&
(debug_flag != 1) && (debug_flag != 2)) {
print_timestamp = 1;
}
if ((fd != -1) &&
(myconfig->radlog_dest != RADLOG_STDOUT) &&
(myconfig->radlog_dest != RADLOG_STDERR)) {
myconfig->radlog_fd = -1;
fd = -1;
}
*buffer = '\0';
len = 0;
if (fd != -1) {
#ifdef HAVE_SYSLOG_H
} else if (myconfig->radlog_dest == RADLOG_SYSLOG) {
if(!openlog_run) {
openlog(progname, LOG_PID, myconfig->syslog_facility);
openlog_run = 1;
}
#endif
} else if (myconfig->radlog_dest == RADLOG_FILES) {
if (!myconfig->log_file) {
if (lvl & L_ERR) {
fd = STDERR_FILENO;
print_timestamp = 0;
snprintf(buffer, sizeof(buffer), "%s: ", progname);
len = strlen(buffer);
} else {
return 0;
}
} else if (log_fp) {
struct stat buf;
if (stat(myconfig->log_file, &buf) < 0) {
fclose(log_fp);
log_fp = fr_log_fp = NULL;
}
}
if (!log_fp && myconfig->log_file) {
fp = fopen(myconfig->log_file, "a");
if (!fp) {
fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
progname, myconfig->log_file, strerror(errno));
fprintf(stderr, " (");
vfprintf(stderr, fmt, ap);
fprintf(stderr, ")\n");
return -1;
}
setlinebuf(fp);
}
if (can_update_log_fp && fp) fr_log_fp = log_fp = fp;
}
if (print_timestamp) {
const char *s;
time_t timeval;
timeval = time(NULL);
CTIME_R(&timeval, buffer + len, sizeof(buffer) - len - 1);
s = fr_int2str(levels, (lvl & ~L_CONS), ": ");
strcat(buffer, s);
len = strlen(buffer);
}
vsnprintf(buffer + len, sizeof(buffer) - len - 1, fmt, ap);
for (p = (unsigned char *)buffer; *p != '\0'; p++) {
if (*p == '\r' || *p == '\n')
*p = ' ';
else if (*p == '\t') continue;
else if (*p < 32 || (*p >= 128 && *p <= 160))
*p = '?';
}
strcat(buffer, "\n");
#ifdef HAVE_SYSLOG_H
if (myconfig->radlog_dest == RADLOG_SYSLOG) {
switch(lvl & ~L_CONS) {
case L_DBG:
lvl = LOG_DEBUG;
break;
case L_AUTH:
lvl = LOG_NOTICE;
break;
case L_PROXY:
lvl = LOG_NOTICE;
break;
case L_ACCT:
lvl = LOG_NOTICE;
break;
case L_INFO:
lvl = LOG_INFO;
break;
case L_ERR:
lvl = LOG_ERR;
break;
}
syslog(lvl, "%s", buffer);
} else
#endif
if (log_fp != NULL) {
fputs(buffer, log_fp);
} else if (fp != NULL) {
fputs(buffer, fp);
fclose(fp);
} else if (fd >= 0) {
write(fd, buffer, strlen(buffer));
}
return 0;
}
int log_debug(const char *msg, ...)
{
va_list ap;
int r;
va_start(ap, msg);
r = vradlog(L_DBG, msg, ap);
va_end(ap);
return r;
}
int radlog(int lvl, const char *msg, ...)
{
va_list ap;
int r;
va_start(ap, msg);
r = vradlog(lvl, msg, ap);
va_end(ap);
return r;
}
void vp_listdebug(VALUE_PAIR *vp)
{
char tmpPair[70];
for (; vp; vp = vp->next) {
vp_prints(tmpPair, sizeof(tmpPair), vp);
DEBUG2(" %s", tmpPair);
}
}
void force_log_reopen(void)
{
can_update_log_fp = 0;
if (mainconfig.radlog_dest != RADLOG_FILES) return;
if (log_fp) fclose(log_fp);
fr_log_fp = log_fp = NULL;
}
extern char *request_log_file;
extern char *debug_log_file;
void radlog_request(int lvl, int priority, REQUEST *request, const char *msg, ...)
{
size_t len = 0;
const char *filename = request_log_file;
FILE *fp = NULL;
va_list ap;
char buffer[1024];
va_start(ap, msg);
if (lvl == L_DBG) {
if ((request && request->radlog &&
(priority > request->options)) ||
((debug_flag != 0) && (priority > debug_flag))) {
va_end(ap);
return;
}
if (debug_log_file) filename = debug_log_file;
if (!filename) lvl = L_INFO;
}
if (request && filename) {
char *p;
radlog_func_t rl = request->radlog;
request->radlog = NULL;
radius_xlat(buffer, sizeof(buffer), filename,
request, NULL);
request->radlog = rl;
p = strrchr(buffer, FR_DIR_SEP);
if (p) {
*p = '\0';
if (rad_mkdir(buffer, S_IRWXU) < 0) {
radlog(L_ERR, "Failed creating %s: %s",
buffer,strerror(errno));
va_end(ap);
return;
}
*p = FR_DIR_SEP;
}
fp = fopen(buffer, "a");
}
if (fp) {
char *s;
time_t timeval;
timeval = time(NULL);
CTIME_R(&timeval, buffer + len, sizeof(buffer) - len - 1);
s = strrchr(buffer, '\n');
if (s) {
s[0] = ' ';
s[1] = '\0';
}
s = fr_int2str(levels, (lvl & ~L_CONS), ": ");
strcat(buffer, s);
len = strlen(buffer);
}
if (request && request->module[0]) {
snprintf(buffer + len, sizeof(buffer) + len, "[%s] ", request->module);
len = strlen(buffer);
}
vsnprintf(buffer + len, sizeof(buffer) - len, msg, ap);
if (!fp) {
radlog(lvl, "%s", buffer);
} else {
fputs(buffer, fp);
fputc('\n', fp);
fclose(fp);
}
va_end(ap);
}