mirror of
https://github.com/anope/anope.git
synced 2026-06-25 09:16:38 +02:00
d5cf78e6f7
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2444 5417fbe8-f217-4b02-8779-1006273d7864
295 lines
5.5 KiB
C
295 lines
5.5 KiB
C
/* Logging routines.
|
|
*
|
|
* (C) 2003-2009 Anope Team
|
|
* Contact us at team@anope.org
|
|
*
|
|
* Please read COPYING and README for further details.
|
|
*
|
|
* Based on the original code of Epona by Lara.
|
|
* Based on the original code of Services by Andy Church.
|
|
*
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "services.h"
|
|
#include "pseudo.h"
|
|
|
|
static FILE *logfile;
|
|
|
|
static int curday = 0;
|
|
|
|
/*************************************************************************/
|
|
|
|
static int get_logname(char *name, int count, struct tm *tm)
|
|
{
|
|
char timestamp[32];
|
|
time_t t;
|
|
|
|
|
|
if (!tm) {
|
|
time(&t);
|
|
tm = localtime(&t);
|
|
}
|
|
|
|
/* fix bug 577 */
|
|
strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
|
|
snprintf(name, count, "logs/%s.%s", log_filename, timestamp);
|
|
curday = tm->tm_yday;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
static void remove_log()
|
|
{
|
|
time_t t;
|
|
struct tm tm;
|
|
|
|
char name[PATH_MAX];
|
|
|
|
if (!KeepLogs)
|
|
return;
|
|
|
|
time(&t);
|
|
t -= (60 * 60 * 24 * KeepLogs);
|
|
tm = *localtime(&t);
|
|
|
|
/* removed if from here cause get_logchan is always 1 */
|
|
get_logname(name, sizeof(name), &tm);
|
|
#ifndef _WIN32
|
|
unlink(name);
|
|
#else
|
|
DeleteFile(name);
|
|
#endif
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
static void checkday()
|
|
{
|
|
time_t t;
|
|
struct tm tm;
|
|
|
|
time(&t);
|
|
tm = *localtime(&t);
|
|
|
|
if (curday != tm.tm_yday) {
|
|
close_log();
|
|
remove_log();
|
|
open_log();
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Open the log file. Return -1 if the log file could not be opened, else
|
|
* return 0. */
|
|
|
|
int open_log()
|
|
{
|
|
char name[PATH_MAX];
|
|
|
|
if (logfile)
|
|
return 0;
|
|
|
|
/* if removed again.. get_logname is always 1 */
|
|
get_logname(name, sizeof(name), NULL);
|
|
logfile = fopen(name, "a");
|
|
|
|
if (logfile)
|
|
setbuf(logfile, NULL);
|
|
return logfile != NULL ? 0 : -1;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Close the log file. */
|
|
|
|
void close_log()
|
|
{
|
|
if (!logfile)
|
|
return;
|
|
fclose(logfile);
|
|
logfile = NULL;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* added cause this is used over and over in the code */
|
|
char *log_gettimestamp()
|
|
{
|
|
time_t t;
|
|
struct tm tm;
|
|
static char tbuf[256];
|
|
|
|
time(&t);
|
|
tm = *localtime(&t);
|
|
#if HAVE_GETTIMEOFDAY
|
|
if (debug) {
|
|
char *s;
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
strftime(tbuf, sizeof(tbuf) - 1, "[%b %d %H:%M:%S", &tm);
|
|
s = tbuf + strlen(tbuf);
|
|
s += snprintf(s, sizeof(tbuf) - (s - tbuf), ".%06d",
|
|
static_cast<int>(tv.tv_usec));
|
|
strftime(s, sizeof(tbuf) - (s - tbuf) - 1, " %Y]", &tm);
|
|
} else {
|
|
#endif
|
|
strftime(tbuf, sizeof(tbuf) - 1, "[%b %d %H:%M:%S %Y]", &tm);
|
|
#if HAVE_GETTIMEOFDAY
|
|
}
|
|
#endif
|
|
return tbuf;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Log stuff to the log file with a datestamp. Note that errno is
|
|
* preserved by this routine and log_perror().
|
|
*/
|
|
|
|
void alog(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
char *buf;
|
|
int errno_save = errno;
|
|
char str[BUFSIZE];
|
|
|
|
checkday();
|
|
|
|
if (!fmt) {
|
|
return;
|
|
}
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(str, sizeof(str), fmt, args);
|
|
va_end(args);
|
|
|
|
buf = log_gettimestamp();
|
|
|
|
if (logfile) {
|
|
fprintf(logfile, "%s %s\n", buf, str);
|
|
}
|
|
if (nofork) {
|
|
fprintf(stderr, "%s %s\n", buf, str);
|
|
}
|
|
if (LogChannel && logchan && !debug && findchan(LogChannel)) {
|
|
ircdproto->SendPrivmsg(findbot(s_GlobalNoticer), LogChannel, "%s", str);
|
|
}
|
|
errno = errno_save;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Like alog(), but tack a ": " and a system error message (as returned by
|
|
* strerror()) onto the end.
|
|
*/
|
|
|
|
void log_perror(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
char *buf;
|
|
int errno_save = errno;
|
|
char str[BUFSIZE];
|
|
|
|
checkday();
|
|
|
|
if (!fmt) {
|
|
return;
|
|
}
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(str, sizeof(str), fmt, args);
|
|
va_end(args);
|
|
|
|
buf = log_gettimestamp();
|
|
|
|
if (logfile) {
|
|
fprintf(logfile, "%s %s : %s\n", buf, str, strerror(errno_save));
|
|
}
|
|
if (nofork) {
|
|
fprintf(stderr, "%s %s : %s\n", buf, str, strerror(errno_save));
|
|
}
|
|
errno = errno_save;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* We've hit something we can't recover from. Let people know what
|
|
* happened, then go down.
|
|
*/
|
|
|
|
void fatal(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
char *buf;
|
|
char buf2[4096];
|
|
|
|
checkday();
|
|
|
|
if (!fmt) {
|
|
return;
|
|
}
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(buf2, sizeof(buf2), fmt, args);
|
|
va_end(args);
|
|
|
|
buf = log_gettimestamp();
|
|
|
|
if (logfile)
|
|
fprintf(logfile, "%s FATAL: %s\n", buf, buf2);
|
|
if (nofork)
|
|
fprintf(stderr, "%s FATAL: %s\n", buf, buf2);
|
|
if (servsock >= 0)
|
|
ircdproto->SendGlobops(NULL, "FATAL ERROR! %s", buf2);
|
|
|
|
/* one of the many places this needs to be called from */
|
|
ModuleRunTimeDirCleanUp();
|
|
|
|
exit(1);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Same thing, but do it like perror(). */
|
|
|
|
void fatal_perror(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
char *buf;
|
|
char buf2[4096];
|
|
int errno_save = errno;
|
|
|
|
checkday();
|
|
|
|
if (!fmt) {
|
|
return;
|
|
}
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(buf2, sizeof(buf2), fmt, args);
|
|
va_end(args);
|
|
|
|
buf = log_gettimestamp();
|
|
|
|
if (logfile)
|
|
fprintf(logfile, "%s FATAL: %s: %s\n", buf, buf2,
|
|
strerror(errno_save));
|
|
if (nofork)
|
|
fprintf(stderr, "%s FATAL: %s: %s\n", buf, buf2,
|
|
strerror(errno_save));
|
|
if (servsock >= 0)
|
|
ircdproto->SendGlobops(NULL, "FATAL ERROR! %s: %s", buf2,
|
|
strerror(errno_save));
|
|
|
|
/* one of the many places this needs to be called from */
|
|
ModuleRunTimeDirCleanUp();
|
|
|
|
exit(1);
|
|
}
|
|
|