#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"
# include <gdk/gdkx.h>
#endif
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+#include <dbus/dbus-glib.h>
+#include <NetworkManager.h>
+#endif
+
#include "claws.h"
#include "main.h"
#include "mainwindow.h"
#include "tags.h"
#ifdef HAVE_LIBETPAN
#include "imap-thread.h"
+#include "nntp-thread.h"
#endif
#include "stock_pixmap.h"
#ifdef HAVE_VALGRIND
#include "valgrind.h"
#endif
-#if USE_OPENSSL
+#if (defined(USE_OPENSSL) || defined (USE_GNUTLS))
# include "ssl.h"
#endif
#include "timing.h"
#ifdef MAEMO
+#ifdef CHINOOK
+#include <hildon/hildon-banner.h>
+#include <hildon/hildon-program.h>
+#else
#include <hildon-widgets/hildon-banner.h>
#include <hildon-widgets/hildon-program.h>
+#endif
#include <gtk/gtkmain.h>
#include <libosso.h>
#include <libgnomevfs/gnome-vfs-volume.h>
static GnomeVFSVolumeMonitor *volmon;
#endif
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+/* Went offline due to NetworkManager */
+static gboolean went_offline_nm;
+#endif
+
gchar *prog_version;
gchar *argv0;
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
+static void networkmanager_state_change_cb(DBusGProxy *proxy, gchar *dev,
+ gpointer data);
+#endif
+
#define MAKE_DIR_IF_NOT_EXIST(dir) \
{ \
if (!is_dir_exist(dir)) { \
}
+/* Callback for hardware D-BUS events */
+void hw_event_handler(osso_hw_state_t *state, gpointer data)
+{
+ AppData *appdata;
+ appdata = (AppData *) data;
+
+ if (state->shutdown_ind) {
+ exit_claws(static_mainwindow);
+ hildon_banner_show_information(GTK_WIDGET(appdata->window), NULL,
+ _("Exiting..."));
+ }
+}
+
/* Callback for normal D-BUS messages */
gint dbus_req_handler(const gchar * interface, const gchar * method,
GArray * arguments, gpointer data,
}
#endif
+static void main_dump_features_list(gboolean show_debug_only)
+/* display compiled-in features list */
+{
+ if (show_debug_only && !debug_get_mode())
+ return;
+
+ 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
+ if (show_debug_only)
+ debug_print(" compface\n");
+ else
+ g_print(" compface\n");
+#endif
+#if USE_ASPELL
+ if (show_debug_only)
+ debug_print(" aspell\n");
+ else
+ g_print(" aspell\n");
+#endif
+#if USE_GNUTLS
+ if (show_debug_only)
+ debug_print(" gnutls\n");
+ else
+ g_print(" gnutls\n");
+#endif
+#if INET6
+ if (show_debug_only)
+ debug_print(" ipv6\n");
+ else
+ g_print(" ipv6\n");
+#endif
+#if HAVE_ICONV
+ if (show_debug_only)
+ debug_print(" iconv\n");
+ else
+ g_print(" iconv\n");
+#endif
+#if USE_JPILOT
+ if (show_debug_only)
+ debug_print(" jpilot\n");
+ else
+ g_print(" jpilot\n");
+#endif
+#if USE_LDAP
+ if (show_debug_only)
+ debug_print(" ldap\n");
+ else
+ g_print(" ldap\n");
+#endif
+#if HAVE_LIBETPAN
+ 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
+ if (show_debug_only)
+ debug_print(" gnomeprint\n");
+ else
+ g_print(" gnomeprint\n");
+#endif
+#if HAVE_LIBSM
+ if (show_debug_only)
+ debug_print(" libsm\n");
+ else
+ g_print(" libsm\n");
+#endif
+#if HAVE_NETWORKMANAGER_SUPPORT
+ if (show_debug_only)
+ debug_print(" NetworkManager\n");
+ else
+ g_print(" NetworkManager\n");
+#endif
+#if USE_OPENSSL
+ if (show_debug_only)
+ debug_print(" openssl\n");
+ else
+ g_print(" openssl\n");
+#endif
+}
+
int main(int argc, char *argv[])
{
#ifdef MAEMO
osso_context_t *osso_context;
osso_return_t result;
+#endif
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+ DBusGConnection *connection;
+ GError *error;
+ DBusGProxy *proxy;
#endif
gchar *userrc;
MainWindow *mainwin;
return 0;
}
+ main_dump_features_list(TRUE);
+
prog_version = PROG_VERSION;
argv0 = g_strdup(argv[0]);
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 */
gtk_set_locale();
gtk_init(&argc, &argv);
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+ went_offline_nm = FALSE;
+ error = NULL;
+ proxy = NULL;
+ connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+
+ if(!connection) {
+ debug_print("Failed to open connection to system bus: %s\n", error->message);
+ g_error_free(error);
+ }
+ else {
+ proxy = dbus_g_proxy_new_for_name(connection,
+ "org.freedesktop.NetworkManager",
+ "/org/freedesktop/NetworkManager",
+ "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);
+ }
+#endif
+
+
#ifdef MAEMO
osso_context = osso_initialize(OSSO_SERVICE, "2.8.1", TRUE, NULL);
if (osso_context == NULL) {
news_gtk_init();
mainwin = main_window_create();
+
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+ networkmanager_state_change_cb(proxy,NULL,mainwin);
+#endif
+
#ifdef MAEMO
AppData *appdata;
appdata = g_new0(AppData, 1);
return OSSO_ERROR;
}
+#ifndef CHINOOK
/* Add handler for Exit D-BUS messages */
result = osso_application_set_exit_cb(appdata->osso_context,
exit_event_handler,
if (result != OSSO_OK) {
return OSSO_ERROR;
}
+#endif
+ osso_hw_set_event_cb( appdata->osso_context,
+ NULL, hw_event_handler, (gpointer) appdata );
#endif
manage_window_focus_in(mainwin->window, NULL, NULL);
folderview = mainwin->folderview;
mainwin);
#endif
+
prefs_account_init();
account_read_config_all();
#ifdef HAVE_LIBETPAN
imap_main_init(prefs_common.skip_ssl_cert_check);
imap_main_set_timeout(prefs_common.io_timeout_secs);
+ nntp_main_init(prefs_common.skip_ssl_cert_check);
#endif
account_set_missing_folder();
folder_set_missing_folders();
if (show_at_startup)
main_window_popup(mainwin);
}
-
+
if (!folder_have_mailbox()) {
prefs_destroy_cache();
main_window_cursor_normal(mainwin);
#ifdef HAVE_LIBSM
sc_session_manager_connect(mainwin);
#endif
+
folder_item_update_thaw();
gtk_clist_thaw(GTK_CLIST(mainwin->folderview->ctree));
main_window_cursor_normal(mainwin);
} 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);
#ifdef MAEMO
osso_deinitialize(osso_context);
#endif
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+ if(proxy)
+ g_object_unref(proxy);
+ if(connection)
+ dbus_g_connection_unref(connection);
+#endif
#ifdef G_OS_WIN32
win32_close_log();
#endif
+ utils_free_regex();
exit_claws(mainwin);
return 0;
main_window_empty_trash(mainwin, prefs_common.ask_on_clean);
}
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+ if (prefs_common.work_offline && went_offline_nm)
+ prefs_common.work_offline = FALSE;
+#endif
+
/* save prefs for opened folder */
if(mainwin->folderview->opened) {
FolderItem *item;
#ifdef HAVE_LIBETPAN
imap_main_done();
+ nntp_main_done();
#endif
/* delete crashfile */
if (!cmd.crash)
}
} else if (!strncmp(argv[i], "--send", 6)) {
cmd.send = TRUE;
+ } else if (!strncmp(argv[i], "--version-full", 14) ||
+ !strncmp(argv[i], "-V", 2)) {
+ g_print("Claws Mail version " VERSION "\n");
+ main_dump_features_list(FALSE);
+ exit(0);
} else if (!strncmp(argv[i], "--version", 9) ||
!strncmp(argv[i], "-v", 2)) {
g_print("Claws Mail version " VERSION "\n");
g_print("%s\n", _(" --debug debug mode"));
g_print("%s\n", _(" --help -h display this help and exit"));
g_print("%s\n", _(" --version -v output version information and exit"));
+ g_print("%s\n", _(" --version-full -V output version and built-in features information and exit"));
g_print("%s\n", _(" --config-dir output configuration directory"));
g_print("%s\n", _(" --alternate-config-dir [dir]\n"
" use specified configuration directory"));
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 != '-') {
}
} 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);
if (item->prefs->enable_processing) {
+ item->processing_pending = TRUE;
folder_item_apply_processing(item);
+ item->processing_pending = FALSE;
}
STATUSBAR_POP(mainwin);
#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)
{
return static_osso_context;
}
#endif
+
+
+#ifdef HAVE_NETWORKMANAGER_SUPPORT
+static void networkmanager_state_change_cb(DBusGProxy *proxy, gchar *dev,
+ gpointer data)
+{
+ MainWindow *mainWin;
+
+ mainWin = NULL;
+ if (static_mainwindow)
+ mainWin = static_mainwindow;
+ else if (data)
+ mainWin = (MainWindow*)data;
+
+ if (!prefs_common.use_networkmanager)
+ return;
+
+ if (mainWin) {
+ GError *error;
+ gboolean online;
+
+ error = NULL;
+ online = networkmanager_is_online(&error);
+ if(!error) {
+ if(online && went_offline_nm) {
+ 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 {
+ debug_print("Failed to get online information from NetworkManager: %s\n",
+ error->message);
+ g_error_free(error);
+ }
+ }
+ else
+ debug_print("NetworkManager: Cannot change connection state because "
+ "main window does not exist\n");
+}
+
+/* Returns true (and sets error appropriately, if given) in case of error */
+gboolean networkmanager_is_online(GError **error)
+{
+ DBusGConnection *connection;
+ 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);
+
+ 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",
+ tmp_error->message);
+ g_propagate_error(error, tmp_error);
+ return TRUE;
+ }
+
+ proxy = dbus_g_proxy_new_for_name(connection,
+ "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);
+
+ if(proxy)
+ g_object_unref(proxy);
+ if(connection)
+ dbus_g_connection_unref(connection);
+
+ if(!retVal) {
+ /* If calling code doesn't do error checking, at least print some debug */
+ if((error == NULL) || (*error == NULL))
+ debug_print("Failed to get state info from NetworkManager: %s\n",
+ tmp_error->message);
+ g_propagate_error(error, tmp_error);
+ return TRUE;
+ }
+
+ return (state == NM_STATE_CONNECTED || state == NM_STATE_UNKNOWN);
+}
+#endif