evolution-3.6.4/shell/main.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Ettore Perazzoli <ettore@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #include <config.h>
 24 
 25 #include <gtk/gtk.h>
 26 #include <glib/gi18n.h>
 27 #include <glib/gstdio.h>
 28 
 29 #ifdef G_OS_UNIX
 30 #include <glib-unix.h>
 31 #endif
 32 
 33 #ifdef WITH_CONTACT_MAPS
 34 #include <clutter-gtk/clutter-gtk.h>
 35 #endif
 36 
 37 #ifdef G_OS_WIN32
 38 #define WIN32_LEAN_AND_MEAN
 39 #ifdef DATADIR
 40 #undef DATADIR
 41 #endif
 42 #define _WIN32_WINNT 0x0601
 43 #include <windows.h>
 44 #include <conio.h>
 45 #include <io.h>
 46 #ifndef PROCESS_DEP_ENABLE
 47 #define PROCESS_DEP_ENABLE 0x00000001
 48 #endif
 49 #ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION
 50 #define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002
 51 #endif
 52 #endif
 53 
 54 #include <libxml/xmlmemory.h>
 55 #include <libxml/parser.h>
 56 #include <libxml/tree.h>
 57 
 58 #include <libedataserverui/libedataserverui.h>
 59 
 60 #include <webkit/webkit.h>
 61 
 62 #include "e-shell.h"
 63 #include "e-shell-migrate.h"
 64 #include "e-shell-meego.h"
 65 #include "es-event.h"
 66 
 67 #include "e-util/e-dialog-utils.h"
 68 #include "e-util/e-import.h"
 69 #include "e-util/e-plugin.h"
 70 #include "e-util/e-plugin-ui.h"
 71 #include "e-util/e-util-private.h"
 72 #include "e-util/e-util.h"
 73 #ifdef G_OS_WIN32
 74 #include "e-util/e-win32-defaults.h"
 75 #endif
 76 
 77 #include <fcntl.h>
 78 #include <signal.h>
 79 #include <string.h>
 80 #include <sys/types.h>
 81 #include <sys/stat.h>
 82 #include <unistd.h>
 83 
 84 #ifdef HAVE_ICAL_UNKNOWN_TOKEN_HANDLING
 85 #include <libical/ical.h>
 86 #endif
 87 
 88 #define APPLICATION_ID "org.gnome.Evolution"
 89 
 90 /* STABLE_VERSION is only defined for development versions. */
 91 #ifdef STABLE_VERSION
 92 #define DEVELOPMENT 1
 93 #endif
 94 
 95 /* Command-line options.  */
 96 #ifdef G_OS_WIN32
 97 static gboolean register_handlers = FALSE;
 98 static gboolean reinstall = FALSE;
 99 static gboolean show_icons = FALSE;
100 static gboolean hide_icons = FALSE;
101 static gboolean unregister_handlers = FALSE;
102 #endif /* G_OS_WIN32 */
103 static gboolean express_mode = FALSE;
104 static gboolean force_online = FALSE;
105 static gboolean start_online = FALSE;
106 static gboolean start_offline = FALSE;
107 static gboolean setup_only = FALSE;
108 static gboolean force_shutdown = FALSE;
109 static gboolean disable_eplugin = FALSE;
110 static gboolean disable_preview = FALSE;
111 static gboolean import_uris = FALSE;
112 static gboolean quit = FALSE;
113 
114 static gchar *geometry = NULL;
115 static gchar *requested_view = NULL;
116 static gchar **remaining_args;
117 
118 /* Forward declarations */
119 void e_convert_local_mail (EShell *shell);
120 
121 static void
122 categories_icon_theme_hack (void)
123 {
124 	GtkIconTheme *icon_theme;
125 	const gchar *category_name;
126 	const gchar *filename;
127 	gchar *dirname;
128 
129 	/* XXX Allow the category icons to be referenced as named
130 	 *     icons, since GtkAction does not support GdkPixbufs. */
131 
132 	/* Get the icon file for some default category.  Doesn't matter
133 	 * which, so long as it has an icon.  We're just interested in
134 	 * the directory components. */
135 	category_name = _("Birthday");
136 	filename = e_categories_get_icon_file_for (category_name);
137 	g_return_if_fail (filename != NULL && *filename != '\0');
138 
139 	/* Extract the directory components. */
140 	dirname = g_path_get_dirname (filename);
141 
142 	/* Add it to the icon theme's search path.  This relies on
143 	 * GtkIconTheme's legacy feature of using image files found
144 	 * directly in the search path. */
145 	icon_theme = gtk_icon_theme_get_default ();
146 	gtk_icon_theme_append_search_path (icon_theme, dirname);
147 
148 	g_free (dirname);
149 }
150 
151 #ifdef DEVELOPMENT
152 
153 /* Warning dialog to scare people off a little bit.  */
154 
155 static gboolean
156 show_development_warning (void)
157 {
158 	GtkWidget *action_area;
159 	GtkWidget *content_area;
160 	GtkWidget *vbox;
161 	GtkWidget *label;
162 	GtkWidget *warning_dialog;
163 	GtkWidget *checkbox;
164 	GtkWidget *alignment;
165 	gboolean skip;
166 	gchar *text;
167 
168 	warning_dialog = gtk_dialog_new ();
169 	gtk_window_set_title (
170 		GTK_WINDOW (warning_dialog), "Evolution " VERSION);
171 	gtk_window_set_modal (
172 		GTK_WINDOW (warning_dialog), TRUE);
173 	gtk_dialog_add_button (
174 		GTK_DIALOG (warning_dialog),
175 		GTK_STOCK_OK, GTK_RESPONSE_OK);
176 
177 	action_area = gtk_dialog_get_action_area (GTK_DIALOG (warning_dialog));
178 	content_area = gtk_dialog_get_content_area (GTK_DIALOG (warning_dialog));
179 
180 	gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
181 	gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
182 
183 	vbox = gtk_vbox_new (FALSE, 12);
184 	gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
185 	gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
186 
187 	text = g_strdup_printf (
188 		/* xgettext:no-c-format */
189 		/* Preview/Alpha/Beta version warning message */
190 		_("Hi.  Thanks for taking the time to download this preview release\n"
191 		"of the Evolution groupware suite.\n"
192 		"\n"
193 		"This version of Evolution is not yet complete. It is getting close,\n"
194 		"but some features are either unfinished or do not work properly.\n"
195 		"\n"
196 		"If you want a stable version of Evolution, we urge you to uninstall\n"
197 		"this version, and install version %s instead.\n"
198 		"\n"
199 		"If you find bugs, please report them to us at bugzilla.gnome.org.\n"
200 		"This product comes with no warranty and is not intended for\n"
201 		"individuals prone to violent fits of anger.\n"
202 		"\n"
203 		"We hope that you enjoy the results of our hard work, and we\n"
204 		"eagerly await your contributions!\n"),
205 		STABLE_VERSION);
206 	label = gtk_label_new (text);
207 	g_free (text);
208 
209 	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
210 	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
211 
212 	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
213 
214 	label = gtk_label_new (_("Thanks\nThe Evolution Team\n"));
215 	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
216 	gtk_misc_set_alignment (GTK_MISC (label), 1, .5);
217 
218 	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
219 
220 	checkbox = gtk_check_button_new_with_label (_("Do not tell me again"));
221 
222 	alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
223 
224 	gtk_container_add (GTK_CONTAINER (alignment), checkbox);
225 	gtk_box_pack_start (GTK_BOX (vbox), alignment, TRUE, TRUE, 0);
226 
227 	gtk_widget_show_all (warning_dialog);
228 
229 	gtk_dialog_run (GTK_DIALOG (warning_dialog));
230 
231 	skip = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox));
232 
233 	gtk_widget_destroy (warning_dialog);
234 
235 	return skip;
236 }
237 
238 #endif /* DEVELOPMENT */
239 
240 /* This is for doing stuff that requires the GTK+ loop to be running already.  */
241 
242 static gboolean
243 idle_cb (const gchar * const *uris)
244 {
245 	EShell *shell;
246 
247 	shell = e_shell_get_default ();
248 
249 	/* These calls do the right thing when another Evolution
250 	 * process is running. */
251 	if (uris != NULL && *uris != NULL) {
252 		if (e_shell_handle_uris (shell, uris, import_uris) == 0)
253 			gtk_main_quit ();
254 	} else {
255 		if (express_mode && requested_view == NULL)
256 			requested_view = (gchar *) "mail";
257 		e_shell_create_shell_window (shell, requested_view);
258 	}
259 
260 	/* If another Evolution process is running, we're done. */
261 	if (g_application_get_is_remote (G_APPLICATION (shell)))
262 		gtk_main_quit ();
263 
264 	return FALSE;
265 }
266 
267 #ifdef G_OS_UNIX
268 static gboolean
269 handle_term_signal (gpointer data)
270 {
271 	EShell *shell;
272 
273 	g_print ("Received terminate signal...\n");
274 
275 	shell = e_shell_get_default ();
276 
277 	if (shell != NULL)
278 		e_shell_quit (shell, E_SHELL_QUIT_OPTION);
279 
280 	return FALSE;
281 }
282 #endif
283 
284 G_GNUC_NORETURN static gboolean
285 option_version_cb (const gchar *option_name,
286                    const gchar *option_value,
287                    gpointer data,
288                    GError **error)
289 {
290 	g_print ("%s\n", PACKAGE_STRING);
291 
292 	exit (0);
293 }
294 
295 static GOptionEntry entries[] = {
296 #ifdef G_OS_WIN32
297 	{ "register-handlers", '\0', G_OPTION_FLAG_HIDDEN,
298 	  G_OPTION_ARG_NONE, &register_handlers, NULL, NULL },
299 	{ "reinstall", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &reinstall,
300 	  NULL, NULL },
301 	{ "show-icons", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &show_icons,
302 	  NULL, NULL },
303 	{ "hide-icons", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &hide_icons,
304 	  NULL, NULL },
305 	{ "unregister-handlers", '\0', G_OPTION_FLAG_HIDDEN,
306 	  G_OPTION_ARG_NONE, &unregister_handlers, NULL, NULL },
307 #endif /* G_OS_WIN32 */
308 	{ "component", 'c', 0, G_OPTION_ARG_STRING, &requested_view,
309 	/* Translators: Do NOT translate the five component
310 	 * names, they MUST remain in English! */
311 	  N_("Start Evolution showing the specified component. "
312 	     "Available options are 'mail', 'calendar', 'contacts', "
313 	     "'tasks', and 'memos'"), NULL },
314 	{ "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry,
315 	  N_("Apply the given geometry to the main window"), "GEOMETRY" },
316 	{ "offline", '\0', 0, G_OPTION_ARG_NONE, &start_offline,
317 	  N_("Start in offline mode"), NULL },
318 	{ "online", '\0', 0, G_OPTION_ARG_NONE, &start_online,
319 	  N_("Start in online mode"), NULL },
320 	{ "force-online", '\0', 0, G_OPTION_ARG_NONE, &force_online,
321 	  N_("Ignore network availability"), NULL },
322 	{ "express", '\0', 0, G_OPTION_ARG_NONE, &express_mode,
323 	  N_("Start in \"express\" mode"), NULL },
324 #ifdef KILL_PROCESS_CMD
325 	{ "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown,
326 	  N_("Forcibly shut down Evolution"), NULL },
327 #endif
328 	{ "disable-eplugin", '\0', 0, G_OPTION_ARG_NONE, &disable_eplugin,
329 	  N_("Disable loading of any plugins."), NULL },
330 	{ "disable-preview", '\0', 0, G_OPTION_ARG_NONE, &disable_preview,
331 	  N_("Disable preview pane of Mail, Contacts and Tasks."), NULL },
332 	{ "setup-only", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
333 	  &setup_only, NULL, NULL },
334 	{ "import", 'i', 0, G_OPTION_ARG_NONE, &import_uris,
335 	  N_("Import URIs or filenames given as rest of arguments."), NULL },
336 	{ "quit", 'q', 0, G_OPTION_ARG_NONE, &quit,
337 	  N_("Request a running Evolution process to quit"), NULL },
338 	{ "version", 'v', G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
339 	  G_OPTION_ARG_CALLBACK, option_version_cb, NULL, NULL },
340 	{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
341 	  &remaining_args, NULL, NULL },
342 	{ NULL }
343 };
344 
345 static void G_GNUC_NORETURN
346 shell_force_shutdown (void)
347 {
348 	gchar *filename;
349 
350 	filename = g_build_filename (EVOLUTION_TOOLSDIR, "killev", NULL);
351 	execl (filename, "killev", NULL);
352 
353 	g_assert_not_reached ();
354 }
355 
356 static EShell *
357 create_default_shell (void)
358 {
359 	EShell *shell;
360 	GSettings *settings;
361 	GApplicationFlags flags;
362 	gboolean online = TRUE;
363 	gboolean is_meego = FALSE;
364 	gboolean small_screen = FALSE;
365 	GError *error = NULL;
366 
367 	settings = g_settings_new ("org.gnome.evolution.shell");
368 
369 	/* Requesting online or offline mode from the command-line
370 	 * should be persistent, just like selecting it in the UI. */
371 
372 	if (start_online || force_online) {
373 		online = TRUE;
374 		g_settings_set_boolean (settings, "start-offline", FALSE);
375 	} else if (start_offline) {
376 		online = FALSE;
377 		g_settings_set_boolean (settings, "start-offline", TRUE);
378 	} else {
379 		gboolean value;
380 
381 		value = g_settings_get_boolean (settings, "start-offline");
382 		if (error == NULL)
383 			online = !value;
384 	}
385 
386 	if (error != NULL) {
387 		g_warning ("%s", error->message);
388 		g_clear_error (&error);
389 	}
390 
391 	/* Determine whether to run Evolution in "express" mode. */
392 
393 	if (!express_mode)
394 		express_mode = g_settings_get_boolean (settings, "express-mode");
395 
396 	if (!express_mode)
397 		e_shell_detect_meego (&is_meego, &small_screen);
398 
399 	if (is_meego)
400 		express_mode = TRUE;
401 
402 	if (error != NULL) {
403 		g_warning ("%s", error->message);
404 		g_clear_error (&error);
405 	}
406 
407 	flags = G_APPLICATION_HANDLES_OPEN |
408 		G_APPLICATION_HANDLES_COMMAND_LINE;
409 
410 	shell = g_initable_new (
411 		E_TYPE_SHELL, NULL, &error,
412 		"application-id", APPLICATION_ID,
413 		"flags", flags,
414 		"geometry", geometry,
415 		"module-directory", EVOLUTION_MODULEDIR,
416 		"meego-mode", is_meego,
417 		"express-mode", express_mode,
418 		"small-screen-mode", small_screen,
419 		"online", online,
420 		NULL);
421 
422 	/* Failure to register is fatal. */
423 	if (error != NULL) {
424 		g_warning (
425 			"Cannot start Evolution.  Another Evolution "
426 			"instance may be unresponsive. System error: %s",
427 			error->message);
428 		g_clear_error (&error);
429 	}
430 
431 	if (force_online && shell)
432 		e_shell_lock_network_available (shell);
433 
434 	g_object_unref (settings);
435 
436 	return shell;
437 }
438 
439 /* this workarounds https://bugzilla.gnome.org/show_bug.cgi?id=683548
440  * and is a replacement of g_type_ensure(), which is part of GLib 2.34,
441  * on which Evolution doesn't depend yet
442 */
443 static void
444 e_ensure_type (GType type)
445 {
446 	if (G_UNLIKELY (type == (GType) -1))
447 		g_warning ("can't happen");
448 }
449 
450 gint
451 main (gint argc,
452       gchar **argv)
453 {
454 	EShell *shell;
455 	GSettings *settings;
456 #ifdef DEVELOPMENT
457 	gboolean skip_warning_dialog;
458 #endif
459 	GError *error = NULL;
460 
461 #ifdef G_OS_WIN32
462 	gchar *path;
463 
464 	/* Reduce risks */
465 	{
466 		typedef BOOL (WINAPI *t_SetDllDirectoryA) (LPCSTR lpPathName);
467 		t_SetDllDirectoryA p_SetDllDirectoryA;
468 
469 		p_SetDllDirectoryA = GetProcAddress (
470 			GetModuleHandle ("kernel32.dll"),
471 			"SetDllDirectoryA");
472 		if (p_SetDllDirectoryA)
473 			(*p_SetDllDirectoryA) ("");
474 	}
475 #ifndef _WIN64
476 	{
477 		typedef BOOL (WINAPI *t_SetProcessDEPPolicy) (DWORD dwFlags);
478 		t_SetProcessDEPPolicy p_SetProcessDEPPolicy;
479 
480 		p_SetProcessDEPPolicy = GetProcAddress (
481 			GetModuleHandle ("kernel32.dll"),
482 			"SetProcessDEPPolicy");
483 		if (p_SetProcessDEPPolicy)
484 			(*p_SetProcessDEPPolicy) (
485 				PROCESS_DEP_ENABLE |
486 				PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
487 	}
488 #endif
489 
490 	if (fileno (stdout) != -1 && _get_osfhandle (fileno (stdout)) != -1) {
491 		/* stdout is fine, presumably redirected to a file or pipe */
492 	} else {
493 		typedef BOOL (* WINAPI AttachConsole_t) (DWORD);
494 
495 		AttachConsole_t p_AttachConsole =
496 			(AttachConsole_t) GetProcAddress (
497 			GetModuleHandle ("kernel32.dll"), "AttachConsole");
498 
499 		if (p_AttachConsole && p_AttachConsole (ATTACH_PARENT_PROCESS)) {
500 			freopen ("CONOUT$", "w", stdout);
501 			dup2 (fileno (stdout), 1);
502 			freopen ("CONOUT$", "w", stderr);
503 			dup2 (fileno (stderr), 2);
504 		}
505 	}
506 #endif
507 
508 	/* Make ElectricFence work.  */
509 	free (malloc (10));
510 
511 	bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
512 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
513 	textdomain (GETTEXT_PACKAGE);
514 
515 	g_type_init ();
516 
517 	/* do not require Gtk+ for --force-shutdown */
518 	if (argc == 2 && argv[1] && g_str_equal (argv[1], "--force-shutdown")) {
519 		shell_force_shutdown ();
520 
521 		return 0;
522 	}
523 
524 	/* The contact maps feature uses clutter-gtk. */
525 #ifdef WITH_CONTACT_MAPS
526 	gtk_clutter_init_with_args (
527 		&argc, &argv,
528 		_("- The Evolution PIM and Email Client"),
529 		entries, (gchar *) GETTEXT_PACKAGE, &error);
530 #else
531 	gtk_init_with_args (
532 		&argc, &argv,
533 		_("- The Evolution PIM and Email Client"),
534 		entries, (gchar *) GETTEXT_PACKAGE, &error);
535 #endif /* WITH_CONTACT_MAPS */
536 
537 	if (error != NULL) {
538 		g_printerr ("%s\n", error->message);
539 		g_error_free (error);
540 		exit (1);
541 	}
542 
543 #ifdef HAVE_ICAL_UNKNOWN_TOKEN_HANDLING
544 	ical_set_unknown_token_handling_setting (ICAL_DISCARD_TOKEN);
545 #endif
546 
547 	e_gdbus_templates_init_main_thread ();
548 
549 #ifdef G_OS_WIN32
550 	path = g_build_path (";", _e_get_bindir (), g_getenv ("PATH"), NULL);
551 
552 	if (!g_setenv ("PATH", path, TRUE))
553 		g_warning ("Could not set PATH for Evolution and its child processes");
554 
555 	g_free (path);
556 
557 	if (register_handlers || reinstall || show_icons) {
558 		_e_win32_register_mailer ();
559 		_e_win32_register_addressbook ();
560 	}
561 
562 	if (register_handlers)
563 		exit (0);
564 
565 	if (reinstall) {
566 		_e_win32_set_default_mailer ();
567 		exit (0);
568 	}
569 
570 	if (show_icons) {
571 		_e_win32_set_default_mailer ();
572 		exit (0);
573 	}
574 
575 	if (hide_icons) {
576 		_e_win32_unset_default_mailer ();
577 		exit (0);
578 	}
579 
580 	if (unregister_handlers) {
581 		_e_win32_unregister_mailer ();
582 		_e_win32_unregister_addressbook ();
583 		exit (0);
584 	}
585 
586 	if (strcmp (gettext (""), "") == 0) {
587 		/* No message catalog installed for the current locale
588 		 * language, so don't bother with the localisations
589 		 * provided by other things then either. Reset thread
590 		 * locale to "en-US" and C library locale to "C". */
591 		SetThreadLocale (
592 			MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US),
593 			SORT_DEFAULT));
594 		setlocale (LC_ALL, "C");
595 	}
596 #endif
597 
598 	if (start_online && start_offline) {
599 		g_printerr (
600 			_("%s: --online and --offline cannot be used "
601 			"together.\n  Run '%s --help' for more "
602 			"information.\n"), argv[0], argv[0]);
603 		exit (1);
604 	} else if (force_online && start_offline) {
605 		g_printerr (
606 			_("%s: --force-online and --offline cannot be used "
607 			"together.\n  Run '%s --help' for more "
608 			"information.\n"), argv[0], argv[0]);
609 		exit (1);
610 	}
611 
612 	if (force_shutdown)
613 		shell_force_shutdown ();
614 
615 	if (disable_preview) {
616 		settings = g_settings_new ("org.gnome.evolution.mail");
617 		g_settings_set_boolean (settings, "safe-list", TRUE);
618 		g_object_unref (settings);
619 
620 		settings = g_settings_new ("org.gnome.evolution.addressbook");
621 		g_settings_set_boolean (settings, "show-preview", FALSE);
622 		g_object_unref (settings);
623 
624 		settings = g_settings_new ("org.gnome.evolution.calendar");
625 		g_settings_set_boolean (settings, "show-memo-preview", FALSE);
626 		g_settings_set_boolean (settings, "show-task-preview", FALSE);
627 		g_object_unref (settings);
628 	}
629 
630 #ifdef G_OS_UNIX
631 	g_unix_signal_add_full (
632 		G_PRIORITY_DEFAULT, SIGTERM,
633 		handle_term_signal, NULL, NULL);
634 #endif
635 
636 	e_passwords_init ();
637 
638 	gtk_window_set_default_icon_name ("evolution");
639 
640 	if (setup_only)
641 		exit (0);
642 
643 	categories_icon_theme_hack ();
644 	gtk_accel_map_load (e_get_accels_filename ());
645 
646 #ifdef DEVELOPMENT
647 	settings = g_settings_new ("org.gnome.evolution.shell");
648 	skip_warning_dialog = g_settings_get_boolean (
649 		settings, "skip-warning-dialog");
650 
651 	if (!skip_warning_dialog && !getenv ("EVOLVE_ME_HARDER"))
652 		g_settings_set_boolean (
653 			settings, "skip-warning-dialog",
654 			show_development_warning ());
655 
656 	g_object_unref (settings);
657 #endif
658 
659 	/* Workaround https://bugzilla.gnome.org/show_bug.cgi?id=683548 */
660 	if (!quit)
661 		e_ensure_type (WEBKIT_TYPE_WEB_VIEW);
662 
663 	shell = create_default_shell ();
664 	if (!shell)
665 		return 1;
666 
667 	if (quit) {
668 		e_shell_quit (shell, E_SHELL_QUIT_OPTION);
669 		goto exit;
670 	}
671 
672 	/* This routine converts the local mail store from mbox format to
673 	 * Maildir format as needed.  The reason the code is here and not
674 	 * in the mail module is because we inform the user at startup of
675 	 * the impending mail conversion by displaying a popup dialog and
676 	 * waiting for confirmation before proceeding.
677 	 *
678 	 * This has to be done before we load modules because some of the
679 	 * EShellBackends immediately add GMainContext sources that would
680 	 * otherwise get dispatched during gtk_dialog_run(), and we don't
681 	 * want them dispatched until after the conversion is complete. */
682 	e_convert_local_mail (shell);
683 
684 	e_shell_load_modules (shell);
685 
686 	if (!disable_eplugin) {
687 		/* Register built-in plugin hook types. */
688 		es_event_hook_get_type ();
689 		e_import_hook_get_type ();
690 		e_plugin_ui_hook_get_type ();
691 
692 		/* All EPlugin and EPluginHook subclasses should be
693 		 * registered in GType now, so load plugins now. */
694 		e_plugin_load_plugins ();
695 	}
696 
697 	if (requested_view)
698 		e_shell_set_startup_view (shell, requested_view);
699 	else if (express_mode)
700 		e_shell_set_startup_view (shell, "mail");
701 
702 	/* Attempt migration -after- loading all modules and plugins,
703 	 * as both shell backends and certain plugins hook into this. */
704 	e_shell_migrate_attempt (shell);
705 
706 	/* This is an alternative to the "upgrade.done" EEvent. */
707 	e_shell_event (shell, "ready-to-start", NULL);
708 
709 	g_idle_add ((GSourceFunc) idle_cb, remaining_args);
710 
711 	gtk_main ();
712 
713 exit:
714 	/* Drop what should be the last reference to the shell.
715 	 * That will cause e_shell_get_default() to henceforth
716 	 * return NULL.  Use that to check for reference leaks. */
717 	g_object_unref (shell);
718 
719 	if (e_shell_get_default () != NULL)
720 		g_warning ("Shell not finalized on exit");
721 
722 	gtk_accel_map_save (e_get_accels_filename ());
723 
724 	return 0;
725 }