Esempio n. 1
0
static void
shell_xdg_migrate_config_dir_mail (EShell *shell,
                                   const gchar *old_base_dir)
{
	const gchar *user_config_dir;
	gchar *old_config_dir;
	gchar *new_config_dir;
	gchar *old_filename;
	gchar *new_filename;

	user_config_dir = e_get_user_config_dir ();

	old_config_dir = g_build_filename (old_base_dir, "mail", NULL);
	new_config_dir = g_build_filename (user_config_dir, "mail", NULL);

	old_filename = g_build_filename (old_config_dir, "filters.xml", NULL);
	new_filename = g_build_filename (new_config_dir, "filters.xml", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	old_filename = g_build_filename (old_config_dir, "vfolders.xml", NULL);
	new_filename = g_build_filename (new_config_dir, "vfolders.xml", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* I hate this file.  GtkHtml uses style properties for fonts. */
	old_filename = g_build_filename (
		old_config_dir, "config", "gtkrc-mail-fonts", NULL);
	new_filename = g_build_filename (
		new_config_dir, "gtkrc-mail-fonts", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* This file is no longer used.  Try removing it. */
	old_filename = g_build_filename (
		old_config_dir, "config",
		"folder-tree-expand-state.xml", NULL);
	g_unlink (old_filename);
	g_free (old_filename);

	/* Everything else in the "config" directory just should be
	 * per-folder ETree files recording the expanded state of mail
	 * threads.  Rename this directory to "folders". */
	old_filename = g_build_filename (old_config_dir, "config", NULL);
	new_filename = g_build_filename (new_config_dir, "folders", NULL);
	shell_xdg_migrate_rename_files (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	g_free (old_config_dir);
	g_free (new_config_dir);
}
Esempio n. 2
0
static GString *
replace_variables (const gchar *str,
                   gboolean remove_dir_sep)
{
	GString *res = NULL, *use;
	const gchar *strip_datadir, *strip_configdir;

	g_return_val_if_fail (str != NULL, NULL);

	strip_datadir = strip_home_dir (e_get_user_data_dir ());
	strip_configdir = strip_home_dir (e_get_user_config_dir ());

	#define repl(_find, _replace)							\
		use = e_str_replace_string (res ? res->str : str, _find, _replace);	\
		g_return_val_if_fail (use != NULL, NULL);				\
		if (res)								\
			g_string_free (res, TRUE);					\
		res = use;

	repl ("$HOME", g_get_home_dir ());
	repl ("$TMP", g_get_tmp_dir ());
	repl ("$DATADIR", e_get_user_data_dir ());
	repl ("$CONFIGDIR", e_get_user_config_dir ());
	repl ("$STRIPDATADIR", strip_datadir);
	repl ("$STRIPCONFIGDIR", strip_configdir);
	repl ("$DBUSDATADIR", DBUS_SERVICES_DIR);

	#undef repl

	g_return_val_if_fail (res != NULL, NULL);

	if (remove_dir_sep) {
		/* remove trailing dir separator */
		while (res->len > 0 && res->str[res->len - 1] == G_DIR_SEPARATOR) {
			g_string_truncate (res, res->len - 1);
		}
	}

	return res;
}
Esempio n. 3
0
static void
shell_xdg_migrate_config_dir (EShell *shell,
                              const gchar *old_base_dir)
{
	const gchar *old_config_dir;
	const gchar *new_config_dir;
	gchar *old_filename;
	gchar *new_filename;
	gint ii;

	g_print ("Migrating config data\n");

	/* Some files are common to all shell backends. */
	for (ii = 0; shell_backend_names[ii] != NULL; ii++)
		shell_xdg_migrate_config_dir_common (
			shell, old_base_dir, shell_backend_names[ii]);

	/* Handle backend-specific files. */
	shell_xdg_migrate_config_dir_mail (shell, old_base_dir);

	/* Remove leftover config directories. */
	for (ii = 0; shell_backend_names[ii] != NULL; ii++) {
		shell_xdg_migrate_dir_cleanup (
			shell, old_base_dir, shell_backend_names[ii], "config");
		shell_xdg_migrate_dir_cleanup (
			shell, old_base_dir, shell_backend_names[ii], "views");
	}

	/*** Miscellaneous configuration files. ***/

	old_config_dir = old_base_dir;
	new_config_dir = e_get_user_config_dir ();

	/* Subtle name change: datetime-formats --> datetime-formats.ini */
	old_filename = g_build_filename (old_config_dir, "datetime-formats", NULL);
	new_filename = g_build_filename (new_config_dir, "datetime-formats.ini", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* Subtle name change: printing --> printing.ini */
	old_filename = g_build_filename (old_config_dir, "printing", NULL);
	new_filename = g_build_filename (new_config_dir, "printing.ini", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);
}
Esempio n. 4
0
static void
restore (const gchar *filename,
         GCancellable *cancellable)
{
	gchar *command;
	gchar *quotedfname;
	gboolean is_new_format = FALSE;

	g_return_if_fail (filename && *filename);

	if (!check (filename, &is_new_format)) {
		g_message ("Cannot restore from an incorrect archive '%s'.", filename);
		goto end;
	}

	quotedfname = g_shell_quote (filename);

	if (g_cancellable_is_cancelled (cancellable))
		return;

	/* FIXME Will the versioned setting always work? */
	txt = _("Shutting down Evolution");
	run_cmd (EVOLUTION " --quit");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Back up current Evolution data");
	run_cmd ("mv $DATADIR $DATADIR_old");
	run_cmd ("mv $CONFIGDIR $CONFIGDIR_old");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Extracting files from back up");

	if (is_new_format) {
		GString *dir_fn;
		gchar *data_dir = NULL;
		gchar *config_dir = NULL;
		gchar *restored_version = NULL;
		const gchar *tar_opts;

		if (get_filename_is_xz (filename))
			tar_opts = "-xJf";
		else
			tar_opts = "-xzf";

		command = g_strdup_printf (
			"cd $TMP && tar %s %s " EVOLUTION_DIR_FILE,
			tar_opts, quotedfname);
		run_cmd (command);
		g_free (command);

		dir_fn = replace_variables ("$TMP" G_DIR_SEPARATOR_S EVOLUTION_DIR_FILE, TRUE);
		if (!dir_fn) {
			g_warning ("Failed to create evolution's dir filename");
			goto end;
		}

		/* data_dir and config_dir are quoted inside extract_backup_data */
		extract_backup_data (
			dir_fn->str,
			&restored_version,
			&data_dir,
			&config_dir);

		g_unlink (dir_fn->str);
		g_string_free (dir_fn, TRUE);

		if (!data_dir || !config_dir) {
			g_warning (
				"Failed to get old data_dir (%p)/"
				"config_dir (%p)", data_dir, config_dir);
			g_free (data_dir);
			g_free (config_dir);
			goto end;
		}

		g_mkdir_with_parents (e_get_user_data_dir (), 0700);
		g_mkdir_with_parents (e_get_user_config_dir (), 0700);

		command = g_strdup_printf (
			"cd $DATADIR && tar --strip-components %d %s %s %s",
			 get_dir_level (data_dir), tar_opts, quotedfname, data_dir);
		run_cmd (command);
		g_free (command);

		command = g_strdup_printf (
			"cd $CONFIGDIR && tar --strip-components %d %s %s %s",
			get_dir_level (config_dir), tar_opts, quotedfname, config_dir);
		run_cmd (command);
		g_free (command);

		/* If the back file had version information, set the last
		 * used version in GSettings before restarting Evolution. */
		if (restored_version != NULL && *restored_version != '\0') {
			GSettings *settings;

			settings = e_util_ref_settings ("org.gnome.evolution");
			g_settings_set_string (
				settings, "version", restored_version);
			g_object_unref (settings);
		}

		g_free (data_dir);
		g_free (config_dir);
		g_free (restored_version);
	} else {
		const gchar *decr_opts;

		if (get_filename_is_xz (filename))
			decr_opts = "xz -cd";
		else
			decr_opts = "gzip -cd";

		run_cmd ("mv $HOME/.evolution $HOME/.evolution_old");

		command = g_strdup_printf (
			"cd $HOME && %s %s | tar xf -", decr_opts, quotedfname);
		run_cmd (command);
		g_free (command);
	}

	g_free (quotedfname);

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Loading Evolution settings");

	if (is_new_format) {
		/* new format has it in DATADIR... */
		GString *file = replace_variables (EVOLUTION_DIR ANCIENT_GCONF_DUMP_FILE, TRUE);
		if (file && g_file_test (file->str, G_FILE_TEST_EXISTS)) {
			unset_eds_migrated_flag ();

			/* ancient backup */
			replace_in_file (
				EVOLUTION_DIR ANCIENT_GCONF_DUMP_FILE,
				EVOUSERDATADIR_MAGIC, e_get_user_data_dir ());
			run_cmd ("gconftool-2 --load " EVOLUTION_DIR ANCIENT_GCONF_DUMP_FILE);

			/* give a chance to GConf to save what was loaded into a disk */
			g_usleep (G_USEC_PER_SEC * 5);

			/* do not forget to convert GConf keys into GSettings */
			run_cmd ("gsettings-data-convert");
			run_cmd ("rm " EVOLUTION_DIR ANCIENT_GCONF_DUMP_FILE);
		} else {
			replace_in_file (
				EVOLUTION_DIR DCONF_DUMP_FILE_EDS,
				EVOUSERDATADIR_MAGIC, e_get_user_data_dir ());
			run_cmd ("cat " EVOLUTION_DIR DCONF_DUMP_FILE_EDS " | dconf load " DCONF_PATH_EDS);
			run_cmd ("rm " EVOLUTION_DIR DCONF_DUMP_FILE_EDS);

			replace_in_file (
				EVOLUTION_DIR DCONF_DUMP_FILE_EVO,
				EVOUSERDATADIR_MAGIC, e_get_user_data_dir ());
			run_cmd ("cat " EVOLUTION_DIR DCONF_DUMP_FILE_EVO " | dconf load " DCONF_PATH_EVO);
			run_cmd ("rm " EVOLUTION_DIR DCONF_DUMP_FILE_EVO);
		}

		g_string_free (file, TRUE);
	} else {
		gchar *gconf_dump_file;

		unset_eds_migrated_flag ();

		/* ... old format in ~/.evolution */
		gconf_dump_file = g_build_filename (
			"$HOME", ".evolution", ANCIENT_GCONF_DUMP_FILE, NULL);

		replace_in_file (
			gconf_dump_file,
			EVOUSERDATADIR_MAGIC,
			e_get_user_data_dir ());

		command = g_strconcat (
			"gconftool-2 --load ", gconf_dump_file, NULL);
		run_cmd (command);
		g_free (command);

		/* give a chance to GConf to save what was loaded into a disk */
		g_usleep (G_USEC_PER_SEC * 5);

		/* do not forget to convert GConf keys into GSettings */
		run_cmd ("gsettings-data-convert");

		command = g_strconcat ("rm ", gconf_dump_file, NULL);
		run_cmd (command);
		g_free (command);

		g_free (gconf_dump_file);
	}

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Removing temporary back up files");
	run_cmd ("rm -rf $DATADIR_old");
	run_cmd ("rm -rf $CONFIGDIR_old");
	run_cmd ("rm $DATADIR/.running");

	if (!is_new_format)
		run_cmd ("rm -rf $HOME/.evolution_old");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	/* Make full-restart background processes after restore */
	run_cmd (EVOLUTION " --force-shutdown");

	txt = _("Reloading registry service");

	/* wait few seconds, till changes settle */
	g_usleep (G_USEC_PER_SEC * 5);

	command = get_source_manager_reload_command ();
	/* This runs migration routines on the newly-restored data. */
	run_cmd (command);
	g_free (command);

end:
	if (restart_arg) {
		if (g_cancellable_is_cancelled (cancellable))
			return;

		txt = _("Restarting Evolution");

		/* wait 5 seconds before restarting evolution, thus any
		 * changes being done are updated in source registry too */
		g_usleep (G_USEC_PER_SEC * 5);

		run_evolution_no_wait ();
	}
}
static gchar *
ep_key_file_get_filename (void)
{
	return g_build_filename (
		e_get_user_config_dir (), "credentials", "Passwords", NULL);
}
Esempio n. 6
0
static void
shell_xdg_migrate_config_dir_common (EShell *shell,
                                     const gchar *old_base_dir,
                                     const gchar *backend_name)
{
	GDir *dir;
	const gchar *user_config_dir;
	gchar *old_config_dir;
	gchar *new_config_dir;
	gchar *old_filename;
	gchar *new_filename;
	gchar *dirname;

	user_config_dir = e_get_user_config_dir ();

	old_config_dir = g_build_filename (old_base_dir, backend_name, NULL);
	new_config_dir = g_build_filename (user_config_dir, backend_name, NULL);

	g_mkdir_with_parents (new_config_dir, 0700);

	old_filename = g_build_filename (old_config_dir, "views", NULL);
	new_filename = g_build_filename (new_config_dir, "views", NULL);
	shell_xdg_migrate_rename_files (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	old_filename = g_build_filename (old_config_dir, "searches.xml", NULL);
	new_filename = g_build_filename (new_config_dir, "searches.xml", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* This one only occurs in calendar and memos.
	 * For other backends this will just be a no-op. */
	old_filename = g_build_filename (
		old_config_dir, "config", "MemoPad", NULL);
	new_filename = g_build_filename (new_config_dir, "MemoPad", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* This one only occurs in calendar and tasks.
	 * For other backends this will just be a no-op. */
	old_filename = g_build_filename (
		old_config_dir, "config", "TaskPad", NULL);
	new_filename = g_build_filename (new_config_dir, "TaskPad", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* Subtle name change: config/state --> state.ini */
	old_filename = g_build_filename (old_config_dir, "config", "state", NULL);
	new_filename = g_build_filename (new_config_dir, "state.ini", NULL);
	shell_xdg_migrate_rename (old_filename, new_filename);
	g_free (old_filename);
	g_free (new_filename);

	/* GIO had a bug for awhile where it would leave behind an empty
	 * temp file with the pattern .goutputstream-XXXXXX if an output
	 * stream operation was cancelled.  We've had several reports of
	 * these files in config directories, so remove any we find. */
	dirname = g_build_filename (old_config_dir, "config", NULL);
	dir = g_dir_open (dirname, 0, NULL);
	if (dir != NULL) {
		const gchar *basename;

		while ((basename = g_dir_read_name (dir)) != NULL) {
			gchar *filename;
			struct stat st;

			if (!g_str_has_prefix (basename, ".goutputstream"))
				continue;

			filename = g_build_filename (dirname, basename, NULL);

			/* Verify the file is indeed empty. */
			if (g_stat (filename, &st) == 0 && st.st_size == 0)
				g_unlink (filename);

			g_free (filename);
		}

		g_dir_close (dir);
	}
	g_free (dirname);

	g_free (old_config_dir);
	g_free (new_config_dir);
}
Esempio n. 7
0
static void
restore (const gchar *filename,
         GCancellable *cancellable)
{
	gchar *command;
	gchar *quotedfname;
	gboolean is_new_format = FALSE;

	g_return_if_fail (filename && *filename);

	if (!check (filename, &is_new_format)) {
		g_message ("Cannot restore from an incorrect archive '%s'.", filename);
		goto end;
	}

	quotedfname = g_shell_quote (filename);

	if (g_cancellable_is_cancelled (cancellable))
		return;

	/* FIXME Will the versioned setting always work? */
	txt = _("Shutting down Evolution");
	run_cmd (EVOLUTION " --quit");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Back up current Evolution data");
	run_cmd ("mv $DATADIR $DATADIR_old");
	run_cmd ("mv $CONFIGDIR $CONFIGDIR_old");
	run_cmd ("mv $HOME/.camel_certs $HOME/.camel_certs_old");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Extracting files from back up");

	if (is_new_format) {
		GString *dir_fn;
		gchar *data_dir = NULL, *config_dir = NULL;

		command = g_strdup_printf (
			"cd $TMP && tar xzf %s "
			EVOLUTION_DIR_FILE, quotedfname);
		run_cmd (command);
		g_free (command);

		dir_fn = replace_variables ("$TMP" G_DIR_SEPARATOR_S EVOLUTION_DIR_FILE);
		if (!dir_fn) {
			g_warning ("Failed to create evolution's dir filename");
			goto end;
		}

		/* data_dir and config_dir are quoted inside extract_backup_dirs */
		extract_backup_dirs (dir_fn->str, &data_dir, &config_dir);

		g_unlink (dir_fn->str);
		g_string_free (dir_fn, TRUE);

		if (!data_dir || !config_dir) {
			g_warning ("Failed to get old data_dir (%p)/config_dir (%p)", data_dir, config_dir);
			g_free (data_dir);
			g_free (config_dir);
			goto end;
		}

		g_mkdir_with_parents (e_get_user_data_dir (), 0700);
		g_mkdir_with_parents (e_get_user_config_dir (), 0700);

		command = g_strdup_printf (
			"cd $DATADIR && tar xzf %s %s --strip-components=%d",
			quotedfname, data_dir, get_dir_level (data_dir));
		run_cmd (command);
		g_free (command);

		command = g_strdup_printf (
			"cd $CONFIGDIR && tar xzf %s %s --strip-components=%d",
			quotedfname, config_dir, get_dir_level (config_dir));
		run_cmd (command);
		g_free (command);

		command = g_strdup_printf (
			"cd $HOME && tar xzf %s .camel_certs", quotedfname);
		run_cmd (command);
		g_free (command);

		g_free (data_dir);
		g_free (config_dir);
	} else {
		run_cmd ("mv $HOME/.evolution $HOME/.evolution_old");

		command = g_strdup_printf (
			"cd $HOME && gzip -cd %s | tar xf -", quotedfname);
		run_cmd (command);
		g_free (command);
	}

	g_free (quotedfname);

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Loading Evolution settings");

	if (is_new_format) {
		/* new format has it in DATADIR... */
		replace_in_file (
			EVOLUTION_DIR GCONF_DUMP_FILE,
			EVOUSERDATADIR_MAGIC, e_get_user_data_dir ());
		run_cmd ("gconftool-2 --load " EVOLUTION_DIR GCONF_DUMP_FILE);
		run_cmd ("rm " EVOLUTION_DIR GCONF_DUMP_FILE);
	} else {
		gchar *gconf_dump_file;

		/* ... old format in ~/.evolution */
		gconf_dump_file = g_build_filename (
			"$HOME", ".evolution", GCONF_DUMP_FILE, NULL);

		replace_in_file (
			gconf_dump_file,
			EVOUSERDATADIR_MAGIC,
			e_get_user_data_dir ());

		command = g_strconcat (
			"gconftool-2 --load ", gconf_dump_file, NULL);
		run_cmd (command);
		g_free (command);

		command = g_strconcat ("rm ", gconf_dump_file, NULL);
		run_cmd (command);
		g_free (command);

		g_free (gconf_dump_file);
	}

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Removing temporary back up files");
	run_cmd ("rm -rf $DATADIR_old");
	run_cmd ("rm -rf $CONFIGDIR_old");
	run_cmd ("rm -rf $HOME/.camel_certs_old");
	run_cmd ("rm $DATADIR/.running");

	if (!is_new_format)
		run_cmd ("rm -rf $HOME/.evolution_old");

	if (g_cancellable_is_cancelled (cancellable))
		return;

	txt = _("Ensuring local sources");

end:
	if (restart_arg) {
		if (g_cancellable_is_cancelled (cancellable))
			return;

		txt = _("Restarting Evolution");
		run_evolution_no_wait ();
	}
}
Esempio n. 8
0
gint
main (gint argc,
      gchar **argv)
{
	GFile *pid_file;
	GFileMonitor *monitor;
	const gchar *user_config_dir;
	gchar *filename;
	GError *error = NULL;

	bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	g_type_init ();

	user_config_dir = e_get_user_config_dir ();
	filename = g_build_filename (user_config_dir, ".running", NULL);
	pid_file = g_file_new_for_path (filename);
	g_free (filename);

	if (!get_evolution_pid (pid_file)) {
		g_printerr ("Could not find Evolution's process ID\n");
		kill_factories ();
		exit (EXIT_FAILURE);
	}

	if (g_getenv ("DISPLAY") == NULL) {
		#ifdef KILL_PROCESS_CMD

		system (KILL_PROCESS_CMD " -QUIT evolution 2> /dev/null");

		#endif
	} else {
		/* Play it safe here and bail if something goes wrong.  We don't
		 * want to just skip to the killing if we can't ask Evolution to
		 * terminate gracefully.  Despite our name we actually want to
		 * -avoid- killing Evolution if at all possible. */
		if (!g_spawn_command_line_async ("evolution --quit", &error)) {
			g_printerr ("%s", error->message);
			g_error_free (error);
			kill_factories ();
			exit (EXIT_FAILURE);
		}
	}

	/* Now we set up a monitor on Evolution's .running file.
	 * If Evolution is still responsive it will delete this
	 * file just before terminating and we'll be notified. */
	monitor = g_file_monitor_file (pid_file, 0, NULL, &error);
	if (error != NULL) {
		g_printerr ("%s", error->message);
		g_error_free (error);
		kill_factories ();
		exit (EXIT_FAILURE);
	}

	g_signal_connect (
		monitor, "changed",
		G_CALLBACK (file_monitor_changed_cb), NULL);

	g_timeout_add_seconds (
		EVOLUTION_SHUTDOWN_TIMEOUT, (GSourceFunc)
		evolution_not_responding_cb, NULL);

	/* Start the clock. */

	main_loop = g_main_loop_new (NULL, TRUE);
	g_main_loop_run (main_loop);
	g_main_loop_unref (main_loop);

	g_object_unref (monitor);

	kill_factories ();

	return EXIT_SUCCESS;
}