Don't add "Go to last error" to filtering log window's context menu.
[claws.git] / src / common / log.c
index e44b86f2c30e2284844806226460f2d9e42415ec..8b21061a1db8a2e8a05a9102798fee2a5193295a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
  *
  * 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
@@ -19,6 +19,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
+#include "claws-features.h"
 #endif
 
 #include "defs.h"
 #include "log.h"
 #include "hooks.h"
 
+#define FWRITE(_b,_s,_n,_f)    if (fwrite(_b,_s,_n,_f) != _n) { \
+                                       g_message("log fwrite failed!\n"); \
+                                       return; \
+                               }
+#define FPUTS(_b,_f)           if (fputs(_b,_f) == EOF) { \
+                                       g_message("log fputs failed!\n"); \
+                                       return; \
+                               }
+#define FFLUSH(_f)             if (fflush(_f) != 0) { \
+                                       g_message("log fflush failed!\n"); \
+                                       return; \
+                               }
+
 static FILE *log_fp[LOG_INSTANCE_MAX] = {
        NULL,
        NULL
 };
 
+static size_t log_size[LOG_INSTANCE_MAX] = {
+       0,
+       0
+};
+
+static gchar *log_filename[LOG_INSTANCE_MAX] = {
+       NULL,
+       NULL
+};
+
+/* read-only */
+static gchar *log_error_capability[LOG_INSTANCE_MAX] = {
+       TRUE,
+       FALSE
+};
+
 typedef struct _LogInstanceData LogInstanceData;
 
 struct _LogInstanceData {
@@ -70,22 +100,37 @@ static gboolean invoke_hook_cb (gpointer data)
 
 void set_log_file(LogInstance instance, const gchar *filename)
 {
+       gchar *fullname = NULL;
        if (log_fp[instance])
                return;
 
+       if (!g_path_is_absolute(filename)) {
+               fullname = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
+                                       filename, NULL);
+       } else {
+               fullname = g_strdup(filename);
+       }
        /* backup old logfile if existing */
-       if (is_file_exist(filename)) {
+       if (is_file_exist(fullname)) {
                gchar *backupname;
                
-               backupname = g_strconcat(filename, ".bak", NULL);
-               if (rename(filename, backupname) < 0)
-                       FILE_OP_ERROR(filename, "rename");
+               backupname = g_strconcat(fullname, ".bak", NULL);
+               claws_unlink(backupname);
+               if (g_rename(fullname, backupname) < 0)
+                       FILE_OP_ERROR(fullname, "rename");
                g_free(backupname);
        }
 
-       log_fp[instance] = g_fopen(filename, "wb");
-       if (!log_fp[instance])
-               FILE_OP_ERROR(filename, "fopen");
+       log_fp[instance] = g_fopen(fullname, "wb");
+       if (!log_fp[instance]) {
+               FILE_OP_ERROR(fullname, "fopen");
+               log_filename[instance] = NULL;
+               g_free(fullname);
+               return;
+       }
+       log_filename[instance] = g_strdup(fullname);
+       log_size[instance] = 0;
+       g_free(fullname);
 }
 
 void close_log_file(LogInstance instance)
@@ -93,6 +138,20 @@ void close_log_file(LogInstance instance)
        if (log_fp[instance]) {
                fclose(log_fp[instance]);
                log_fp[instance] = NULL;
+               log_size[instance] = 0;
+               g_free(log_filename[instance]);
+               log_filename[instance] = NULL;
+       }
+}
+
+static void rotate_log(LogInstance instance)
+{
+       if (log_size[instance] > 10 * 1024* 1024) {
+               gchar *filename = g_strdup(log_filename[instance]);
+               debug_print("rotating %s\n", filename);
+               close_log_file(instance);
+               set_log_file(instance, filename);
+               g_free(filename);
        }
 }
 
@@ -125,6 +184,12 @@ void get_log_prefs(LogInstance instance, int** logwin_width, int** logwin_height
                *logwin_height = log_instances[instance].prefs_logwin_height;
 }
 
+gboolean get_log_error_capability(LogInstance instance)
+{
+       return log_error_capability[instance];
+
+}
+
 void log_print(LogInstance instance, const gchar *format, ...)
 {
        va_list args;
@@ -140,7 +205,7 @@ void log_print(LogInstance instance, const gchar *format, ...)
        g_vsnprintf(buf + LOG_TIME_LEN, BUFFSIZE, format, args);
        va_end(args);
 
-       if (debug_get_mode()) fputs(buf, stdout);
+       if (debug_get_mode()) g_print("%s", buf);
 
        logtext->instance = instance;
        logtext->text = g_strdup(buf);
@@ -149,8 +214,10 @@ void log_print(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_standard()) {
-               fputs(buf, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FPUTS(buf, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -178,10 +245,13 @@ void log_message(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_standard()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("* message: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("* message: ", log_fp[instance])
+               log_size[instance] += strlen("* message: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -209,10 +279,13 @@ void log_warning(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_warning()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("** warning: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("** warning: ", log_fp[instance])
+               log_size[instance] += strlen("** warning: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -240,10 +313,13 @@ void log_error(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_error()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("*** error: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("*** error: ", log_fp[instance])
+               log_size[instance] += strlen("*** error: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -271,10 +347,13 @@ void log_status_ok(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_status()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("* OK: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("* OK: ", log_fp[instance])
+               log_size[instance] += strlen("* OK: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -302,10 +381,13 @@ void log_status_nok(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_status()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("* NOT OK: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("* NOT OK: ", log_fp[instance])
+               log_size[instance] += strlen("* NOT OK: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
 
@@ -333,9 +415,17 @@ void log_status_skip(LogInstance instance, const gchar *format, ...)
        g_timeout_add(0, invoke_hook_cb, logtext);
 
        if (log_fp[instance] && prefs_common_enable_log_status()) {
-               fwrite(buf, 1, LOG_TIME_LEN, log_fp[instance]);
-               fputs("* SKIPPED: ", log_fp[instance]);
-               fputs(buf + LOG_TIME_LEN, log_fp[instance]);
-               fflush(log_fp[instance]);
+               FWRITE(buf, 1, LOG_TIME_LEN, log_fp[instance])
+               FPUTS("* SKIPPED: ", log_fp[instance])
+               log_size[instance] += strlen("* SKIPPED: ");
+               FPUTS(buf + LOG_TIME_LEN, log_fp[instance])
+               log_size[instance] += strlen(buf);
+               FFLUSH(log_fp[instance])
+               rotate_log(instance);
        }
 }
+
+#undef FWRITE
+#undef FPUTS
+#undef FFLUSH
+