/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2011 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
#ifdef HAVE_CONFIG_H
# include "config.h"
+#include "claws-features.h"
#endif
#include "defs.h"
#include <X11/SM/SMlib.h>
#endif
+#if HAVE_FLOCK
+#include <sys/file.h>
+#endif
+
#include "wizard.h"
#ifdef HAVE_STARTUP_NOTIFICATION
# define SN_API_NOT_YET_FROZEN
#include "manage_window.h"
#include "alertpanel.h"
#include "statusbar.h"
-#include "addressbook.h"
+#ifndef USE_NEW_ADDRBOOK
+ #include "addressbook.h"
+#else
+ #include "addressbook-dbus.h"
+#endif
#include "compose.h"
#include "folder.h"
+#include "folder_item_prefs.h"
#include "setup.h"
#include "utils.h"
#include "gtkutils.h"
#include "hooks.h"
#include "menu.h"
#include "quicksearch.h"
+#include "advsearch.h"
#ifdef HAVE_LIBETPAN
#include "imap-thread.h"
static struct RemoteCmd {
gboolean receive;
gboolean receive_all;
+ gboolean cancel_receiving;
gboolean compose;
const gchar *compose_mailto;
GList *attach_files;
gboolean search_recursive;
gboolean status;
gboolean status_full;
+ gboolean statistics;
+ gboolean reset_statistics;
GPtrArray *status_folders;
GPtrArray *status_full_folders;
gboolean send;
const gchar *target;
} cmd;
+SessionStats session_stats;
+
+static void reset_statistics(void);
+
static void parse_cmd_opt(int argc, char *argv[]);
static gint prohibit_duplicate_launch (void);
}
#endif
+static void reset_statistics(void)
+{
+ /* (re-)initialize session statistics */
+ session_stats.received = 0;
+ session_stats.sent = 0;
+ session_stats.replied = 0;
+ session_stats.forwarded = 0;
+ session_stats.time_started = time(NULL);
+}
+
int main(int argc, char *argv[])
{
#ifdef MAEMO
gint num_folder_class = 0;
gboolean asked_for_migration = FALSE;
gboolean start_done = TRUE;
- GtkUIManager *gui_manager = NULL;
GSList *plug_list = NULL;
gboolean never_ran = FALSE;
+ gboolean mainwin_shown = FALSE;
+
START_TIMING("startup");
sc_starting = TRUE;
return 0;
}
- main_dump_features_list(TRUE);
-
prog_version = PROG_VERSION;
argv0 = g_strdup(argv[0]);
parse_cmd_opt(argc, argv);
+ sock_init();
+
+ /* check and create unix domain socket for remote operation */
+ lock_socket = prohibit_duplicate_launch();
+ if (lock_socket < 0) {
+#ifdef HAVE_STARTUP_NOTIFICATION
+ if(gtk_init_check(&argc, &argv))
+ startup_notification_complete(TRUE);
+#endif
+ return 0;
+ }
+
+ main_dump_features_list(TRUE);
prefs_prepare_cache();
#ifdef CRASH_DIALOG
#if (defined linux && defined SIGIO)
install_memory_sighandler();
#endif
- sock_init();
- /* check and create unix domain socket for remote operation */
- lock_socket = prohibit_duplicate_launch();
- if (lock_socket < 0) {
-#ifdef HAVE_STARTUP_NOTIFICATION
- if(gtk_init_check(&argc, &argv))
- startup_notification_complete(TRUE);
-#endif
- return 0;
- }
-
- if (cmd.status || cmd.status_full || cmd.search) {
+ if (cmd.status || cmd.status_full || cmd.search ||
+ cmd.statistics || cmd.reset_statistics || cmd.cancel_receiving) {
puts("0 Claws Mail not running.");
lock_socket_remove();
return 0;
if (!g_thread_supported())
g_thread_init(NULL);
+ reset_statistics();
+
gtk_set_locale();
gtk_init(&argc, &argv);
gdk_screen_get_system_colormap(
gdk_screen_get_default()));
- gui_manager = gtkut_create_ui_manager();
+ gtkut_create_ui_manager();
/* Create container for all the menus we will be adding */
MENUITEM_ADDUI("/", "Menus", NULL, GTK_UI_MANAGER_MENUBAR);
prefs_receive_init();
prefs_send_init();
tags_read_tags();
+ matcher_init();
#ifdef USE_ENCHANT
gtkaspell_checkers_init();
prefs_spelling_init();
prefs_actions_read_config();
prefs_display_header_read_config();
/* prefs_filtering_read_config(); */
+#ifndef USE_NEW_ADDRBOOK
addressbook_read_file();
-
+#else
+ g_clear_error(&error);
+ if (! addressbook_start_service(&error)) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+ else {
+ addressbook_install_hooks(&error);
+ }
+#endif
gtkut_widget_init();
stock_pixbuf_gdk(NULL, STOCK_PIXMAP_CLAWS_MAIL_ICON, &icon);
gtk_window_set_default_icon(icon);
gtk_cmclist_freeze(GTK_CMCLIST(mainwin->folderview->ctree));
folder_item_update_freeze();
- /* register the callback of unix domain socket input */
- lock_socket_tag = claws_input_add(lock_socket,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
- lock_socket_input_cb,
- mainwin, TRUE);
-
-
prefs_account_init();
account_read_config_all();
/* if crashed, show window early so that the user
* sees what's happening */
- if (claws_crashed())
+ if (claws_crashed()) {
main_window_popup(mainwin);
+ mainwin_shown = TRUE;
+ }
account_set_missing_folder();
folder_set_missing_folders();
}
main_window_cursor_normal(mainwin);
main_window_popup(mainwin);
+ mainwin_shown = TRUE;
alertpanel_warning(ngettext(
"The following plugin failed to load. "
"Check the Plugins configuration "
plugin_load_standard_plugins ();
}
/* if not crashed, show window now */
- if (!claws_crashed()) {
+ if (!mainwin_shown) {
/* apart if something told not to show */
if (show_at_startup)
main_window_popup(mainwin);
main_window_set_menu_sensitive(mainwin);
toolbar_main_set_sensitive(mainwin);
}
+
+ /* register the callback of unix domain socket input */
+ lock_socket_tag = claws_input_add(lock_socket,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
+ lock_socket_input_cb,
+ mainwin, TRUE);
+
END_TIMING();
gtk_main();
prefs_common_write_config();
account_write_config_all();
+#ifndef USE_NEW_ADDRBOOK
addressbook_export_to_file();
-
+#endif
filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, MENU_RC, NULL);
gtk_accel_map_save(filename);
g_free(filename);
plugin_unload_all("GTK2");
+ matcher_done();
prefs_toolbar_done();
+#ifndef USE_NEW_ADDRBOOK
addressbook_destroy();
-
+#endif
prefs_themes_done();
prefs_fonts_done();
prefs_ext_prog_done();
cmd.receive_all = TRUE;
} else if (!strncmp(argv[i], "--receive", 9)) {
cmd.receive = TRUE;
+ } else if (!strncmp(argv[i], "--cancel-receiving", 18)) {
+ cmd.cancel_receiving = TRUE;
} else if (!strncmp(argv[i], "--compose-from-file", 19)) {
const gchar *p = (i+1 < argc)?argv[i+1]:NULL;
cmd.online_mode = ONLINE_MODE_ONLINE;
} else if (!strncmp(argv[i], "--offline", 9)) {
cmd.online_mode = ONLINE_MODE_OFFLINE;
+ } else if (!strncmp(argv[i], "--statistics", 12)) {
+ cmd.statistics = TRUE;
+ } else if (!strncmp(argv[i], "--reset-statistics", 18)) {
+ cmd.reset_statistics = TRUE;
} else if (!strncmp(argv[i], "--help", 6) ||
!strncmp(argv[i], "-h", 2)) {
gchar *base = g_path_get_basename(argv[0]);
" attached"));
g_print("%s\n", _(" --receive receive new messages"));
g_print("%s\n", _(" --receive-all receive new messages of all accounts"));
+ g_print("%s\n", _(" --cancel-receiving cancel receiving of messages"));
g_print("%s\n", _(" --search folder type request [recursive]\n"
" searches mail\n"
" folder ex.: \"#mh/Mailbox/inbox\" or \"Mail\"\n"
g_print("%s\n", _(" --status [folder]... show the total number of messages"));
g_print("%s\n", _(" --status-full [folder]...\n"
" show the status of each folder"));
+ g_print("%s\n", _(" --statistics show session statistics"));
+ g_print("%s\n", _(" --reset-statistics reset session statistics"));
g_print("%s\n", _(" --select folder[/msg] jumps to the specified folder/message\n"
" folder is a folder id like 'folder/sub_folder'"));
g_print("%s\n", _(" --online switch to online mode"));
gchar *path;
path = claws_get_socket_name();
+ /* Try to connect to the control socket */
uxsock = fd_connect_unix(path);
if (x_display == NULL)
x_display = g_strdup(g_getenv("DISPLAY"));
if (uxsock < 0) {
+#if HAVE_FLOCK
+ gchar *socket_lock;
+ gint lock_fd;
+ gint ret;
+ /* If connect failed, no other process is running.
+ * Unlink the potentially existing socket, then
+ * open it. This has to be done locking a temporary
+ * file to avoid the race condition where another
+ * process could have created the socket just in
+ * between.
+ */
+ socket_lock = g_strconcat(path, ".lock",
+ NULL);
+ lock_fd = g_open(socket_lock, O_RDWR|O_CREAT, 0);
+ if (lock_fd < 0) {
+ debug_print("Couldn't open %s: %s (%d)\n", socket_lock,
+ strerror(errno), errno);
+ g_free(socket_lock);
+ return -1;
+ }
+ if (flock(lock_fd, LOCK_EX) < 0) {
+ debug_print("Couldn't lock %s: %s (%d)\n", socket_lock,
+ strerror(errno), errno);
+ close(lock_fd);
+ g_free(socket_lock);
+ return -1;
+ }
+#endif
+
claws_unlink(path);
- return fd_open_unix(path);
+ debug_print("Opening socket %s\n", path);
+ ret = fd_open_unix(path);
+#if HAVE_FLOCK
+ flock(lock_fd, LOCK_UN);
+ claws_unlink(socket_lock);
+ g_free(socket_lock);
+#endif
+ return ret;
}
#else
HANDLE hmutex;
fd_write_all(uxsock, "receive_all\n", 12);
} else if (cmd.receive) {
fd_write_all(uxsock, "receive\n", 8);
+ } else if (cmd.cancel_receiving) {
+ fd_write_all(uxsock, "cancel_receiving\n", 17);
} else if (cmd.compose && cmd.attach_files) {
gchar *str, *compose_str;
}
} else if (cmd.exit) {
fd_write_all(uxsock, "exit\n", 5);
+ } else if (cmd.statistics) {
+ gchar buf[BUFSIZ];
+ fd_write(uxsock, "statistics\n", 11);
+ for (;;) {
+ fd_gets(uxsock, buf, sizeof(buf));
+ if (!strncmp(buf, ".\n", 2)) break;
+ fputs(buf, stdout);
+ }
+ } else if (cmd.reset_statistics) {
+ fd_write(uxsock, "reset_statistics\n", 17);
} else if (cmd.target) {
gchar *str = g_strdup_printf("select %s\n", cmd.target);
fd_write_all(uxsock, str, strlen(str));
MainWindow *mainwin = (MainWindow *)data;
gint sock;
gchar buf[BUFFSIZE];
- /* re-use the same quicksearch (& avoid matcher_list mem.leaks) */
- static QuickSearch *quicksearch = NULL;
sock = fd_accept(source);
fd_gets(sock, buf, sizeof(buf));
prefs_common.newmail_notify_manu);
} else if (!strncmp(buf, "receive", 7)) {
inc_mail(mainwin, prefs_common.newmail_notify_manu);
+ } else if (!strncmp(buf, "cancel_receiving", 16)) {
+ inc_cancel_all();
+ imap_cancel_all();
} else if (!strncmp(buf, "compose_attach", 14)) {
GList *files = NULL, *curr;
AttachInfo *ainfo;
fd_write_all(sock, ".\n", 2);
g_free(status);
if (folders) g_ptr_array_free(folders, TRUE);
+ } else if (!strncmp(buf, "statistics", 10)) {
+ gchar tmp[BUFSIZ];
+
+ g_snprintf(tmp, sizeof(tmp), _("Session statistics\n"));
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ if (prefs_common.date_format) {
+ struct tm *lt;
+ gint len = 100;
+ gchar date[len];
+
+ lt = localtime(&session_stats.time_started);
+ fast_strftime(date, len, prefs_common.date_format, lt);
+ g_snprintf(tmp, sizeof(tmp), _("Started: %s\n"),
+ lt ? date : ctime(&session_stats.time_started));
+ } else
+ g_snprintf(tmp, sizeof(tmp), _("Started: %s\n"),
+ ctime(&session_stats.time_started));
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ fd_write_all(sock, "\n", 1);
+
+ g_snprintf(tmp, sizeof(tmp), _("Incoming traffic\n"));
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ g_snprintf(tmp, sizeof(tmp), _("Received messages: %d\n"),
+ session_stats.received);
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ fd_write_all(sock, "\n", 1);
+
+ g_snprintf(tmp, sizeof(tmp), _("Outgoing traffic\n"));
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ g_snprintf(tmp, sizeof(tmp), _("New/redirected messages: %d\n"),
+ session_stats.sent);
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ g_snprintf(tmp, sizeof(tmp), _("Replied messages: %d\n"),
+ session_stats.replied);
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ g_snprintf(tmp, sizeof(tmp), _("Forwarded messages: %d\n"),
+ session_stats.forwarded);
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ g_snprintf(tmp, sizeof(tmp), _("Total outgoing messages: %d\n"),
+ (session_stats.sent + session_stats.replied +
+ session_stats.forwarded));
+ fd_write_all(sock, tmp, strlen(tmp));
+
+ fd_write_all(sock, ".\n", 2);
+ } else if (!strncmp(buf, "reset_statistics", 16)) {
+ reset_statistics();
} else if (!strncmp(buf, "select ", 7)) {
const gchar *target = buf+7;
mainwindow_jump_to(target, TRUE);
} else if (!strncmp(buf, "search ", 7)) {
FolderItem* folderItem = NULL;
GSList *messages = NULL;
- gchar *folder_name, *request;
- QuickSearchType searchType = QUICK_SEARCH_EXTENDED;
+ gchar *folder_name = NULL;
+ gchar *request = NULL;
+ AdvancedSearch *search;
gboolean recursive;
-
- if (quicksearch==NULL)
- quicksearch = quicksearch_new_nogui();
+ AdvancedSearchType searchType = ADVANCED_SEARCH_EXTENDED;
+ search = advsearch_new();
+
folder_name = g_strdup(buf+7);
strretchomp(folder_name);
- if (fd_gets(sock, buf, sizeof(buf)) <= 0) {
- g_free(folder_name);
- folder_name=NULL;
- }
- searchType = quicksearch_type(buf);
- if (fd_gets(sock, buf, sizeof(buf)) <= 0) {
- g_free(folder_name);
- folder_name=NULL;
+ if (fd_gets(sock, buf, sizeof(buf)) <= 0)
+ goto search_exit;
+
+ switch (toupper(buf[0])) {
+ case 'S': searchType = ADVANCED_SEARCH_SUBJECT; break;
+ case 'F': searchType = ADVANCED_SEARCH_FROM; break;
+ case 'T': searchType = ADVANCED_SEARCH_TO; break;
+ case 'M': searchType = ADVANCED_SEARCH_MIXED; break;
+ case 'G': searchType = ADVANCED_SEARCH_TAG; break;
+ case 'E': searchType = ADVANCED_SEARCH_EXTENDED; break;
}
+
+ if (fd_gets(sock, buf, sizeof(buf)) <= 0)
+ goto search_exit;
+
request = g_strdup(buf);
strretchomp(request);
recursive = TRUE;
if (fd_gets(sock, buf, sizeof(buf)) > 0)
- if (buf[0]=='0')
- recursive = FALSE;
+ recursive = buf[0] != '0';
- debug_print("search: %s %i %s %i\n",folder_name,searchType,request,recursive);
+ debug_print("search: %s %i %s %i\n", folder_name, searchType, request, recursive);
if (folder_name)
folderItem = folder_find_item_from_identifier(folder_name);
+
if (folder_name && folderItem == NULL) {
- debug_print("Unknow folder item : '%s', searching folder\n",folder_name);
+ debug_print("Unknown folder item : '%s', searching folder\n",folder_name);
Folder* folder = folder_find_from_path(folder_name);
if (folder != NULL)
folderItem = FOLDER_ITEM(folder->node->data);
} else {
debug_print("%s %s\n",folderItem->name, folderItem->path);
}
+
if (folderItem != NULL) {
- quicksearch_set(quicksearch, searchType, request);
- quicksearch_set_recursive(quicksearch, recursive);
- search_msgs_in_folders(&messages, quicksearch, folderItem);
+ advsearch_set(search, searchType, request);
+ advsearch_search_msgs_in_folders(search, &messages, folderItem, recursive);
} else {
g_print("Folder '%s' not found.\n'", folder_name);
}
GSList *cur;
- for (cur=messages; cur != NULL; cur = cur->next) {
+ for (cur = messages; cur != NULL; cur = cur->next) {
MsgInfo* msg = (MsgInfo *)cur->data;
gchar *file = procmsg_get_message_file_path(msg);
fd_write_all(sock, file, strlen(file));
}
fd_write_all(sock, ".\n", 2);
- if (messages != NULL)
- procmsg_msg_list_free(messages);
+search_exit:
g_free(folder_name);
g_free(request);
+ advsearch_free(search);
+ if (messages != NULL)
+ procmsg_msg_list_free(messages);
} else if (!strncmp(buf, "exit", 4)) {
if (prefs_common.clean_on_exit && !prefs_common.ask_on_clean) {
procmsg_empty_all_trash();