2008-02-18 [colin] 3.3.0cvs16
[claws.git] / src / main.c
index 97fc09957c55813cbce1e08a3b7d802a22d40708..cc949cd25fada5e17f9ee2ee2af0518236a31cf1 100644 (file)
 #include <sys/types.h>
 #ifdef G_OS_UNIX
 #  include <signal.h>
+#  include <errno.h>
+#  include <fcntl.h>
 #endif
 #ifdef HAVE_LIBSM
 #include <X11/SM/SMlib.h>
-#include <fcntl.h>
 #endif
 
 #include "wizard.h"
@@ -213,6 +214,9 @@ static void send_queue                      (void);
 static void initial_processing         (FolderItem *item, gpointer data);
 static void quit_signal_handler         (int sig);
 static void install_basic_sighandlers   (void);
+#if (defined linux && defined SIGIO)
+static void install_memory_sighandler   (void);
+#endif
 static void exit_claws                 (MainWindow *mainwin);
 
 #ifdef HAVE_NETWORKMANAGER_SUPPORT
@@ -814,59 +818,95 @@ static void win32_close_log(void)
 }              
 #endif
 
-static void main_dump_debug_print(const gchar *format, ...)
-/* wrapper function to debug_print macro */
+static void main_dump_features_list(gboolean show_debug_only)
+/* display compiled-in features list */
 {
-       va_list args;
-
-       va_start(args, format);
-       debug_print(format, args);
-       va_end(args);
-}
+       if (show_debug_only && !debug_get_mode())
+               return;
 
-static void main_dump_features_list(int (*output_func) (const gchar *, ...))
-/* display compiled-in features list using output_func (commonly any
-   g_print-like function) */
-{
-       output_func("GTK+ %d.%d.%d / GLib %d.%d.%d\n",
-                  gtk_major_version, gtk_minor_version, gtk_micro_version,
-                  glib_major_version, glib_minor_version, glib_micro_version);
-       output_func("Compiled-in features:\n");
+       if (show_debug_only)
+               debug_print("GTK+ %d.%d.%d / GLib %d.%d.%d\n",
+                          gtk_major_version, gtk_minor_version, gtk_micro_version,
+                          glib_major_version, glib_minor_version, glib_micro_version);
+       else
+               g_print("GTK+ %d.%d.%d / GLib %d.%d.%d\n",
+                          gtk_major_version, gtk_minor_version, gtk_micro_version,
+                          glib_major_version, glib_minor_version, glib_micro_version);
+       if (show_debug_only)
+               debug_print("Compiled-in features:\n");
+       else
+               g_print("Compiled-in features:\n");
 #if HAVE_LIBCOMPFACE
-       output_func(" compface\n");
+       if (show_debug_only)
+               debug_print(" compface\n");
+       else
+               g_print(" compface\n");
 #endif
 #if USE_ASPELL
-       output_func(" aspell\n");
+       if (show_debug_only)
+               debug_print(" aspell\n");
+       else
+               g_print(" aspell\n");
 #endif
 #if USE_GNUTLS
-       output_func(" gnutls\n");
+       if (show_debug_only)
+               debug_print(" gnutls\n");
+       else
+               g_print(" gnutls\n");
 #endif
 #if INET6
-       output_func(" ipv6\n");
+       if (show_debug_only)
+               debug_print(" ipv6\n");
+       else
+               g_print(" ipv6\n");
 #endif
 #if HAVE_ICONV
-       output_func(" iconv\n");
+       if (show_debug_only)
+               debug_print(" iconv\n");
+       else
+               g_print(" iconv\n");
 #endif
 #if USE_JPILOT
-       output_func(" jpilot\n");
+       if (show_debug_only)
+               debug_print(" jpilot\n");
+       else
+               g_print(" jpilot\n");
 #endif
 #if USE_LDAP
-       output_func(" ldap\n");
+       if (show_debug_only)
+               debug_print(" ldap\n");
+       else
+               g_print(" ldap\n");
 #endif
 #if HAVE_LIBETPAN
-       output_func(" libetpan %d.%d\n", LIBETPAN_VERSION_MAJOR, LIBETPAN_VERSION_MINOR);
+       if (show_debug_only)
+               debug_print(" libetpan %d.%d\n", LIBETPAN_VERSION_MAJOR, LIBETPAN_VERSION_MINOR);
+       else
+               g_print(" libetpan %d.%d\n", LIBETPAN_VERSION_MAJOR, LIBETPAN_VERSION_MINOR);
 #endif
 #if USE_GNOMEPRINT
-       output_func(" gnomeprint\n");
+       if (show_debug_only)
+               debug_print(" gnomeprint\n");
+       else
+               g_print(" gnomeprint\n");
 #endif
 #if HAVE_LIBSM
-       output_func(" libsm\n");
+       if (show_debug_only)
+               debug_print(" libsm\n");
+       else
+               g_print(" libsm\n");
 #endif
 #if HAVE_NETWORKMANAGER_SUPPORT
-       output_func(" NetworkManager\n");
+       if (show_debug_only)
+               debug_print(" NetworkManager\n");
+       else
+               g_print(" NetworkManager\n");
 #endif
 #if USE_OPENSSL
-       output_func(" openssl\n");
+       if (show_debug_only)
+               debug_print(" openssl\n");
+       else
+               g_print(" openssl\n");
 #endif
 }
 
@@ -904,7 +944,7 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       main_dump_features_list(main_dump_debug_print);
+       main_dump_features_list(TRUE);
 
        prog_version = PROG_VERSION;
        argv0 = g_strdup(argv[0]);
@@ -926,6 +966,9 @@ int main(int argc, char *argv[])
        crash_install_handlers();
 #endif
        install_basic_sighandlers();
+#if (defined linux && defined SIGIO)
+       install_memory_sighandler();
+#endif
        sock_init();
 
        /* check and create unix domain socket for remote operation */
@@ -971,8 +1014,8 @@ int main(int argc, char *argv[])
                                                                                                                                                        "org.freedesktop.NetworkManager");
                dbus_g_proxy_add_signal(proxy,"StateChange", G_TYPE_UINT, G_TYPE_INVALID);
                dbus_g_proxy_connect_signal(proxy, "StateChange",
-                                                                                                                               G_CALLBACK(networkmanager_state_change_cb),
-                                                                                                                               NULL,NULL);
+                       G_CALLBACK(networkmanager_state_change_cb),
+                       NULL,NULL);
        }
 #endif
 
@@ -1431,9 +1474,8 @@ int main(int argc, char *argv[])
        } else if (cmd.receive && !cmd.target) {
                start_done = FALSE;
                g_timeout_add(1000, defer_check, NULL);
-       } else {
-               gtk_widget_grab_focus(folderview->ctree);
-       }
+       } 
+       gtk_widget_grab_focus(folderview->ctree);
 
        if (cmd.compose) {
                open_compose_new(cmd.compose_mailto, cmd.attach_files);
@@ -1655,7 +1697,7 @@ static void parse_cmd_opt(int argc, char *argv[])
                } else if (!strncmp(argv[i], "--version-full", 14) ||
                           !strncmp(argv[i], "-V", 2)) {
                        g_print("Claws Mail version " VERSION "\n");
-                       main_dump_features_list(g_print);
+                       main_dump_features_list(FALSE);
                        exit(0);
                } else if (!strncmp(argv[i], "--version", 9) ||
                           !strncmp(argv[i], "-v", 2)) {
@@ -1751,6 +1793,8 @@ static void parse_cmd_opt(int argc, char *argv[])
                                                cmd.compose_mailto = p;
                                        }
                                }
+                       } else if (!strncmp(argv[i], "file://", 7)) {
+                               cmd.target = argv[i];
                        } else if (strstr(argv[i], "://")) {
                                const gchar *p = argv[i];
                                if (p && *p != '\0' && *p != '-') {
@@ -1759,6 +1803,8 @@ static void parse_cmd_opt(int argc, char *argv[])
                                }
                        } else if (!strcmp(argv[i], "--sync")) {
                                /* gtk debug */
+                       } else if (is_dir_exist(argv[i]) || is_file_exist(argv[i])) {
+                               cmd.target = argv[i];
                        } else {
                                g_print(_("Unknown option\n"));
                                exit(1);
@@ -2247,6 +2293,57 @@ static void install_basic_sighandlers()
 #endif /* !G_OS_WIN32 */
 }
 
+#if (defined linux && defined SIGIO)
+static int mem_notify_fd = 0;
+
+static gboolean clean_caches(gpointer unused)
+{
+       if (static_mainwindow && static_mainwindow->lock_count > 0)
+               return TRUE;
+       debug_print("/dev/mem_notify: callback: Freeing some memory now!\n");
+       folder_clean_cache_memory_force();
+       return FALSE;
+}
+
+static void memory_signal_handler(int sig)
+{
+       debug_print("/dev/mem_notify: Kernel says we should free up some memory!\n");
+       g_timeout_add(10, clean_caches, NULL); 
+}
+
+static void install_memory_sighandler()
+{
+       sigset_t    mask;
+       struct sigaction act;
+       int flags;
+
+       mem_notify_fd = open("/dev/mem_notify", O_RDONLY|O_NONBLOCK);
+       if (mem_notify_fd == -1) {
+               debug_print("/dev/mem_notify not available (%s)\n", 
+                       strerror(errno));
+               return;
+       }
+       
+       fcntl(mem_notify_fd, F_SETOWN, getpid());
+       flags = fcntl(mem_notify_fd, F_GETFL);
+       fcntl(mem_notify_fd, flags|FASYNC);
+
+       sigemptyset(&mask);
+
+       sigaddset(&mask, SIGIO);
+
+       act.sa_handler = memory_signal_handler;
+       act.sa_mask    = mask;
+       act.sa_flags   = 0;
+
+       sigaction(SIGIO, &act, 0);
+
+       sigprocmask(SIG_UNBLOCK, &mask, 0);
+
+       debug_print("/dev/mem_notify: installed handler\n");
+}
+#endif /* linux && SIGIO */
+
 #ifdef MAEMO
 osso_context_t *get_osso_context(void)
 {
@@ -2257,17 +2354,20 @@ osso_context_t *get_osso_context(void)
 
 #ifdef HAVE_NETWORKMANAGER_SUPPORT
 static void networkmanager_state_change_cb(DBusGProxy *proxy, gchar *dev,
-                                                                                                                                                                        gpointer data)
+                                        gpointer data)
 {
        MainWindow *mainWin;
 
        mainWin = NULL;
-       if(static_mainwindow)
+       if (static_mainwindow)
                mainWin = static_mainwindow;
-       else if(data)
+       else if (data)
                mainWin = (MainWindow*)data;
        
-       if(mainWin) {
+       if (!prefs_common.use_networkmanager)
+               return;
+
+       if (mainWin) {
                GError *error;
                gboolean online;
 
@@ -2278,11 +2378,13 @@ static void networkmanager_state_change_cb(DBusGProxy *proxy, gchar *dev,
                                went_offline_nm = FALSE;
                                main_window_toggle_work_offline(mainWin, FALSE, FALSE);
                                debug_print("NetworkManager: Went online\n");
+                               log_message(LOG_PROTOCOL, _("NetworkManager: network is online."));
                        }
                        else if(!online) {
                                went_offline_nm = TRUE;
                                main_window_toggle_work_offline(mainWin, TRUE, FALSE);
                                debug_print("NetworkManager: Went offline\n");
+                               log_message(LOG_PROTOCOL, _("NetworkManager: network is offline."));
                        }
                }
                else {
@@ -2300,16 +2402,19 @@ static void networkmanager_state_change_cb(DBusGProxy *proxy, gchar *dev,
 gboolean networkmanager_is_online(GError **error)
 {
        DBusGConnection *connection;
-  DBusGProxy *proxy;
+       DBusGProxy *proxy;
        GError *tmp_error;
        gboolean retVal;
        guint32 state;
 
+       if (!prefs_common.use_networkmanager)
+               return TRUE;
+
        tmp_error = NULL;
        proxy = NULL;
-  connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &tmp_error);
+       connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &tmp_error);
 
-  if(!connection) {
+       if(!connection) {
                /* If calling code doesn't do error checking, at least print some debug */
                if((error == NULL) || (*error == NULL))
                        debug_print("Failed to open connection to system bus: %s\n",
@@ -2319,12 +2424,12 @@ gboolean networkmanager_is_online(GError **error)
        }
 
        proxy = dbus_g_proxy_new_for_name(connection,
-                                                                                                                                               "org.freedesktop.NetworkManager",
-                                                                                                                                               "/org/freedesktop/NetworkManager",
-                                                                                                                                               "org.freedesktop.NetworkManager");
+                       "org.freedesktop.NetworkManager",
+                       "/org/freedesktop/NetworkManager",
+                       "org.freedesktop.NetworkManager");
 
-       retVal = dbus_g_proxy_call(proxy,"state",&tmp_error,G_TYPE_INVALID,
-                                                                                                                G_TYPE_UINT,&state,G_TYPE_INVALID);
+       retVal = dbus_g_proxy_call(proxy,"state",&tmp_error, G_TYPE_INVALID,
+                       G_TYPE_UINT, &state, G_TYPE_INVALID);
 
        if(proxy)
                g_object_unref(proxy);
@@ -2340,6 +2445,6 @@ gboolean networkmanager_is_online(GError **error)
                return TRUE;
        }
 
-       return (state == NM_STATE_CONNECTED);
+       return (state == NM_STATE_CONNECTED || state == NM_STATE_UNKNOWN);
 }
 #endif