diff --git a/src/core/log.c b/src/core/log.c index 481c6b96..1ca26a73 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -34,14 +34,6 @@ static struct flock lock; #endif -const char *rotate_strings[] = { - "never", - "hourly", - "daily", - "weekly", - "monthly" -}; - GSList *logs; const char *log_timestamp; @@ -66,27 +58,34 @@ static void log_write_timestamp(int handle, const char *format, if (suffix != NULL) write(handle, suffix, strlen(suffix)); } -int log_start_logging(LOG_REC *log) +static char *log_filename(LOG_REC *log) { char *str, fname[1024]; struct tm *tm; time_t now; + now = time(NULL); + tm = localtime(&now); + + str = convert_home(log->fname); + strftime(fname, sizeof(fname), str, tm); + g_free(str); + + return g_strdup(fname); +} + +int log_start_logging(LOG_REC *log) +{ g_return_val_if_fail(log != NULL, FALSE); if (log->handle != -1) return TRUE; - now = time(NULL); - tm = localtime(&now); - /* Append/create log file */ - str = convert_home(log->fname); - strftime(fname, sizeof(fname), str, tm); - log->handle = open(fname, O_WRONLY | O_APPEND | O_CREAT, + g_free_not_null(log->real_fname); + log->real_fname = log_filename(log); + log->handle = open(log->real_fname, O_WRONLY | O_APPEND | O_CREAT, log_file_create_mode); - g_free(str); - if (log->handle == -1) { signal_emit("log create failed", 1, log); return FALSE; @@ -135,11 +134,29 @@ void log_stop_logging(LOG_REC *log) log->handle = -1; } +static void log_rotate_check(LOG_REC *log) +{ + char *new_fname; + + g_return_if_fail(log != NULL); + + if (log->handle == -1 || log->real_fname == NULL) + return; + + new_fname = log_filename(log); + if (strcmp(new_fname, log->real_fname) != 0) { + /* rotate log */ + log_stop_logging(log); + log_start_logging(log); + } + g_free(new_fname); +} + void log_write_rec(LOG_REC *log, const char *str) { struct tm *tm; time_t now; - int day; + int hour, day; g_return_if_fail(log != NULL); g_return_if_fail(str != NULL); @@ -149,9 +166,15 @@ void log_write_rec(LOG_REC *log, const char *str) now = time(NULL); tm = localtime(&now); + hour = tm->tm_hour; day = tm->tm_mday; tm = localtime(&log->last); + if (tm->tm_hour != hour) { + /* hour changed, check if we need to rotate log file */ + log_rotate_check(log); + } + if (tm->tm_mday != day) { /* day changed */ log_write_timestamp(log->handle, @@ -224,33 +247,6 @@ LOG_REC *log_find(const char *fname) return NULL; } -const char *log_rotate2str(int rotate) -{ - g_return_val_if_fail(rotate >= 0 && rotate <= LOG_ROTATE_MONTHLY, NULL); - - return rotate_strings[rotate]; -} - -int log_str2rotate(const char *str) -{ - if (str == NULL) - return -1; - - if (g_strncasecmp(str, "hour", 4) == 0) - return LOG_ROTATE_HOURLY; - if (g_strncasecmp(str, "day", 3) == 0 || - g_strncasecmp(str, "daily", 5) == 0) - return LOG_ROTATE_DAILY; - if (g_strncasecmp(str, "week", 4) == 0) - return LOG_ROTATE_WEEKLY; - if (g_strncasecmp(str, "month", 5) == 0) - return LOG_ROTATE_MONTHLY; - if (g_strncasecmp(str, "never", 5) == 0) - return LOG_ROTATE_NEVER; - - return -1; -} - static void log_set_config(LOG_REC *log) { CONFIG_NODE *node; @@ -267,8 +263,6 @@ static void log_set_config(LOG_REC *log) else iconfig_node_set_str(node, "auto_open", NULL); - iconfig_node_set_str(node, "rotate", log_rotate2str(log->rotate)); - levelstr = bits2level(log->level); iconfig_node_set_str(node, "level", levelstr); g_free(levelstr); @@ -332,6 +326,7 @@ static void log_destroy(LOG_REC *log) if (log->items != NULL) g_strfreev(log->items); g_free(log->fname); + g_free_not_null(log->real_fname); g_free(log); } @@ -370,38 +365,16 @@ static void sig_printtext_stripped(void *window, void *server, static int sig_rotate_check(void) { static int last_hour = -1; - struct tm tm_now, *tm; - GSList *tmp; + struct tm tm; time_t now; /* don't do anything until hour is changed */ now = time(NULL); - memcpy(&tm_now, localtime(&now), sizeof(tm_now)); - if (tm_now.tm_hour == last_hour) return 1; - last_hour = tm_now.tm_hour; - - for (tmp = logs; tmp != NULL; tmp = tmp->next) { - LOG_REC *rec = tmp->data; - - if (rec->handle == -1 || rec->rotate == LOG_ROTATE_NEVER) - continue; - - tm = localtime(&rec->opened); - if (rec->rotate == LOG_ROTATE_MONTHLY) { - if (tm->tm_mon == tm_now.tm_mon) - continue; - } else if (rec->rotate == LOG_ROTATE_WEEKLY) { - if (tm->tm_wday != 1 || tm->tm_mday == tm_now.tm_mday) - continue; - } else if (rec->rotate == LOG_ROTATE_DAILY) { - if (tm->tm_mday == tm_now.tm_mday) - continue; - } - - log_stop_logging(rec); - log_start_logging(rec); + memcpy(&tm, localtime(&now), sizeof(tm)); + if (tm.tm_hour != last_hour) { + last_hour = tm.tm_hour; + g_slist_foreach(logs, (GFunc) log_rotate_check, NULL); } - return 1; } @@ -441,9 +414,6 @@ static void log_read_config(void) log->fname = g_strdup(node->key); log->autoopen = config_node_get_bool(node, "auto_open", FALSE); log->level = level2bits(config_node_get_str(node, "level", 0)); - log->rotate = log_str2rotate(config_node_get_str( - node, "rotate", NULL)); - if (log->rotate < 0) log->rotate = LOG_ROTATE_NEVER; node = config_node_section(node, "items", -1); if (node != NULL) log->items = config_node_get_list(node); diff --git a/src/core/log.h b/src/core/log.h index 184f5ace..5be51852 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -1,16 +1,9 @@ #ifndef __LOG_H #define __LOG_H -enum { - LOG_ROTATE_NEVER, - LOG_ROTATE_HOURLY, - LOG_ROTATE_DAILY, - LOG_ROTATE_WEEKLY, - LOG_ROTATE_MONTHLY -}; - typedef struct { - char *fname; /* file name */ + char *fname; /* file name, in strftime() format */ + char *real_fname; /* the current expanded file name */ int handle; /* file handle */ time_t opened; @@ -18,7 +11,6 @@ typedef struct { char **items; /* log only on these items (channels, queries, window refnums) */ time_t last; /* when last message was written */ - int rotate; int autoopen:1; /* automatically start logging at startup */ int temp:1; /* don't save this to config file */ @@ -37,9 +29,6 @@ LOG_REC *log_find(const char *fname); void log_write(const char *item, int level, const char *str); void log_write_rec(LOG_REC *log, const char *str); -const char *log_rotate2str(int rotate); -int log_str2rotate(const char *str); - int log_start_logging(LOG_REC *log); void log_stop_logging(LOG_REC *log); diff --git a/src/fe-common/core/fe-log.c b/src/fe-common/core/fe-log.c index 2c87d87f..4a563709 100644 --- a/src/fe-common/core/fe-log.c +++ b/src/fe-common/core/fe-log.c @@ -41,32 +41,25 @@ static int autolog_level; static int autoremove_tag; static const char *autolog_path; -/* SYNTAX: LOG OPEN [-noopen] [-autoopen] [-targets ] [-window] - [-rotate hourly|daily|weekly|monthly] [] */ +/* SYNTAX: LOG OPEN [-noopen] [-autoopen] [-targets ] + [-window] [] */ static void cmd_log_open(const char *data) { GHashTable *optlist; - char *targetarg, *rotatearg, *fname, *levels; + char *targetarg, *fname, *levels; void *free_arg; char window[MAX_INT_STRLEN]; LOG_REC *log; - int level, rotate; + int level; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, "log open", &optlist, &fname, &levels)) return; targetarg = g_hash_table_lookup(optlist, "targets"); - rotatearg = g_hash_table_lookup(optlist, "rotate"); if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); - rotate = LOG_ROTATE_NEVER; - if (rotatearg != NULL) { - rotate = log_str2rotate(rotatearg); - if (rotate < 0) rotate = LOG_ROTATE_NEVER; - } - level = level2bits(levels); if (level == 0) level = MSGLEVEL_ALL; @@ -80,7 +73,6 @@ static void cmd_log_open(const char *data) if (log != NULL) { if (g_hash_table_lookup(optlist, "autoopen")) log->autoopen = TRUE; - log->rotate = rotate; log_update(log); if (log->handle == -1 && g_hash_table_lookup(optlist, "noopen") == NULL) { @@ -153,7 +145,7 @@ static void cmd_log_stop(const char *data) static void cmd_log_list(void) { GSList *tmp; - char *levelstr, *items, *rotate; + char *levelstr, *items; int index; printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_LOG_LIST_HEADER); @@ -163,15 +155,11 @@ static void cmd_log_list(void) levelstr = bits2level(rec->level); items = rec->items == NULL ? NULL : g_strjoinv(",", rec->items); - rotate = rec->rotate == 0 ? NULL : - g_strdup_printf(" -rotate %s", log_rotate2str(rec->rotate)); printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, IRCTXT_LOG_LIST, index, rec->fname, items != NULL ? items : "", - levelstr, rotate != NULL ? rotate : "", - rec->autoopen ? " -autoopen" : ""); + levelstr, rec->autoopen ? " -autoopen" : ""); - g_free_not_null(rotate); g_free_not_null(items); g_free(levelstr); } @@ -468,7 +456,7 @@ void fe_log_init(void) signal_add("awaylog show", (SIGNAL_FUNC) sig_awaylog_show); signal_add("setup changed", (SIGNAL_FUNC) read_settings); - command_set_options("log open", "noopen autoopen -targets window -rotate"); + command_set_options("log open", "noopen autoopen -targets window"); } void fe_log_deinit(void) diff --git a/src/fe-common/core/module-formats.c b/src/fe-common/core/module-formats.c index bb853dbf..6d79e2fb 100644 --- a/src/fe-common/core/module-formats.c +++ b/src/fe-common/core/module-formats.c @@ -80,7 +80,7 @@ FORMAT_REC fecommon_core_formats[] = { { "log_started", "Started logging to file %_$0", 1, { 0 } }, { "log_stopped", "Stopped logging to file %_$0", 1, { 0 } }, { "log_list_header", "Logs:", 0 }, - { "log_list", "$0 $1: $2 $3$4$5", 6, { 1, 0, 0, 0, 0, 0 } }, + { "log_list", "$0 $1: $2 $3$4", 5, { 1, 0, 0, 0, 0, 0 } }, { "log_list_footer", "", 0 }, { "windowlog_file", "Window LOGFILE set to $0", 1, { 0 } }, { "windowlog_file_logging", "Can't change window's logfile while log is on", 0 },