[tracker/merge-control-status] tracker-control: Split options in groups and files
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/merge-control-status] tracker-control: Split options in groups and files
- Date: Wed, 2 Feb 2011 16:35:04 +0000 (UTC)
commit 6d0f582f8343d1088c062f37003cdd5dd1718a57
Author: Aleksander Morgado <aleksander lanedo com>
Date: Wed Feb 2 17:33:00 2011 +0100
tracker-control: Split options in groups and files
src/tracker-control/Makefile.am | 19 +-
src/tracker-control/tracker-control-general.c | 554 ++++++++++
src/tracker-control/tracker-control-miners.c | 323 ++++++
src/tracker-control/tracker-control-status.c | 632 +++++++++++
src/tracker-control/tracker-control.c | 1390 +------------------------
src/tracker-control/tracker-control.h | 38 +
6 files changed, 1593 insertions(+), 1363 deletions(-)
---
diff --git a/src/tracker-control/Makefile.am b/src/tracker-control/Makefile.am
index 80d97d2..2f2c6bd 100644
--- a/src/tracker-control/Makefile.am
+++ b/src/tracker-control/Makefile.am
@@ -1,21 +1,24 @@
include $(top_srcdir)/Makefile.decl
-AM_CPPFLAGS = \
- $(BUILD_CFLAGS) \
- -DLOCALEDIR=\""$(localedir)"\" \
- -I$(top_srcdir)/src \
- -I$(top_builddir)/src \
+AM_CPPFLAGS = \
+ $(BUILD_CFLAGS) \
+ -DLOCALEDIR=\""$(localedir)"\" \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
$(TRACKER_CONTROL_CFLAGS)
bin_PROGRAMS = tracker-control
-tracker_control_SOURCES = \
+tracker_control_SOURCES = \
+ tracker-control-general.c \
+ tracker-control-miners.c \
+ tracker-control-status.c \
tracker-control.c
-tracker_control_LDADD = \
+tracker_control_LDADD = \
$(top_builddir)/src/libtracker-miner/libtracker-miner- TRACKER_API_VERSION@.la \
$(top_builddir)/src/libtracker-sparql/libtracker-sparql- TRACKER_API_VERSION@.la \
$(top_builddir)/src/libtracker-data/libtracker-data.la \
$(top_builddir)/src/libtracker-common/libtracker-common.la \
- $(BUILD_LIBS) \
+ $(BUILD_LIBS) \
$(TRACKER_CONTROL_LIBS)
diff --git a/src/tracker-control/tracker-control-general.c b/src/tracker-control/tracker-control-general.c
new file mode 100644
index 0000000..93f667e
--- /dev/null
+++ b/src/tracker-control/tracker-control-general.c
@@ -0,0 +1,554 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * 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 the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <locale.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-data/tracker-db-config.h>
+#include <libtracker-data/tracker-db-journal.h>
+#include <libtracker-data/tracker-db-manager.h>
+#include <libtracker-miner/tracker-miner.h>
+
+#include "tracker-control.h"
+
+#define OPTION_TERM_ALL "all"
+#define OPTION_TERM_STORE "store"
+#define OPTION_TERM_MINERS "miners"
+
+typedef enum {
+ TERM_NONE,
+ TERM_ALL,
+ TERM_STORE,
+ TERM_MINERS
+} TermOption;
+
+/* Note:
+ * Every time a new option is added, make sure it is considered in the
+ * 'ENABLED' macro below
+ */
+static gboolean list_processes;
+static TermOption kill_option = TERM_NONE;
+static TermOption terminate_option = TERM_NONE;
+static gboolean hard_reset;
+static gboolean soft_reset;
+static gboolean remove_config;
+static gboolean start;
+#define ENABLED() \
+ (list_processes || \
+ kill_option != TERM_NONE || \
+ terminate_option != TERM_NONE || \
+ hard_reset || \
+ soft_reset || \
+ remove_config || \
+ start)
+
+static gboolean term_option_arg_func (const gchar *option_value,
+ const gchar *value,
+ gpointer data,
+ GError **error);
+
+static GOptionEntry entries[] = {
+ { "list-processes", 'p', 0, G_OPTION_ARG_NONE, &list_processes,
+ N_("List all Tracker processes") },
+ { "kill", 'k', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, term_option_arg_func,
+ N_("Use SIGKILL to stop all matching processes, either \"store\", \"miners\" or \"all\" may be used, no parameter equals \"all\""),
+ N_("APPS") },
+ { "terminate", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, term_option_arg_func,
+ N_("Use SIGTERM to stop all matching processes, either \"store\", \"miners\" or \"all\" may be used, no parameter equals \"all\""),
+ N_("APPS") },
+ { "hard-reset", 'r', 0, G_OPTION_ARG_NONE, &hard_reset,
+ N_("Kill all Tracker processes and remove all databases"),
+ NULL },
+ { "soft-reset", 'e', 0, G_OPTION_ARG_NONE, &soft_reset,
+ N_("Same as --hard-reset but the backup & journal are restored after restart"),
+ NULL },
+ { "remove-config", 'c', 0, G_OPTION_ARG_NONE, &remove_config,
+ N_("Remove all configuration files so they are re-generated on next start"),
+ NULL },
+ { "start", 's', 0, G_OPTION_ARG_NONE, &start,
+ N_("Starts miners (which indirectly starts tracker-store too)"),
+ NULL },
+ { NULL }
+};
+
+gboolean
+tracker_control_general_options_enabled (void)
+{
+ return ENABLED ();
+}
+
+static GSList *
+get_pids (void)
+{
+ GError *error = NULL;
+ GDir *dir;
+ GSList *pids = NULL;
+ const gchar *name;
+
+ dir = g_dir_open ("/proc", 0, &error);
+ if (error) {
+ g_printerr ("%s, %s\n",
+ _("Could not open /proc"),
+ error ? error->message : _("no error given"));
+ g_clear_error (&error);
+ return NULL;
+ }
+
+ while ((name = g_dir_read_name (dir)) != NULL) {
+ gchar c;
+ gboolean is_pid = TRUE;
+
+ for (c = *name; c && c != ':' && is_pid; c++) {
+ is_pid &= g_ascii_isdigit (c);
+ }
+
+ if (!is_pid) {
+ continue;
+ }
+
+ pids = g_slist_prepend (pids, g_strdup (name));
+ }
+
+ g_dir_close (dir);
+
+ return g_slist_reverse (pids);
+}
+
+static void
+log_handler (const gchar *domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ switch (log_level) {
+ case G_LOG_LEVEL_WARNING:
+ case G_LOG_LEVEL_CRITICAL:
+ case G_LOG_LEVEL_ERROR:
+ case G_LOG_FLAG_RECURSION:
+ case G_LOG_FLAG_FATAL:
+ g_fprintf (stderr, "%s\n", message);
+ fflush (stderr);
+ break;
+ case G_LOG_LEVEL_MESSAGE:
+ case G_LOG_LEVEL_INFO:
+ case G_LOG_LEVEL_DEBUG:
+ case G_LOG_LEVEL_MASK:
+ default:
+ g_fprintf (stdout, "%s\n", message);
+ fflush (stdout);
+ break;
+ }
+}
+
+static gboolean
+crawler_check_file_cb (TrackerCrawler *crawler,
+ GFile *file,
+ gpointer user_data)
+{
+ const gchar **suffix;
+ gchar *path;
+ gboolean should_remove;
+
+ suffix = user_data;
+ path = g_file_get_path (file);
+
+ if (suffix) {
+ should_remove = g_str_has_suffix (path, *suffix);
+ } else {
+ should_remove = TRUE;
+ }
+
+ if (!should_remove) {
+ g_free (path);
+ return FALSE;
+ }
+
+ /* Remove file */
+ if (g_unlink (path) == 0) {
+ g_print (" %s\n", path);
+ }
+
+ g_free (path);
+
+ return should_remove;
+}
+
+static void
+crawler_finished_cb (TrackerCrawler *crawler,
+ gboolean was_interrupted,
+ gpointer user_data)
+{
+ g_main_loop_quit (user_data);
+}
+
+static gboolean
+term_option_arg_func (const gchar *option_value,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ TermOption option;
+
+ if (!value) {
+ value = OPTION_TERM_ALL;
+ }
+
+ if (strcmp (value, OPTION_TERM_ALL) == 0) {
+ option = TERM_ALL;
+ } else if (strcmp (value, OPTION_TERM_STORE) == 0) {
+ option = TERM_STORE;
+ } else if (strcmp (value, OPTION_TERM_MINERS) == 0) {
+ option = TERM_MINERS;
+ } else {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ "Only one of 'all', 'store' and 'miners' are allowed");
+ return FALSE;
+ }
+
+ if (strcmp (option_value, "-k") == 0 ||
+ strcmp (option_value, "--kill") == 0) {
+ kill_option = option;
+ } else if (strcmp (option_value, "-t") == 0 ||
+ strcmp (option_value, "--terminate") == 0) {
+ terminate_option = option;
+ }
+
+ return TRUE;
+}
+
+gint
+tracker_control_general_run (void)
+{
+ GError *error = NULL;
+ GSList *pids;
+ GSList *l;
+ gchar *str;
+
+ /* Constraints */
+
+ if (kill_option != TERM_NONE && terminate_option != TERM_NONE) {
+ g_printerr ("%s\n",
+ _("You can not use the --kill and --terminate arguments together"));
+ return EXIT_FAILURE;
+ }
+
+ if ((hard_reset || soft_reset) && terminate_option != TERM_NONE) {
+ g_printerr ("%s\n",
+ _("You can not use the --terminate with --hard-reset or --soft-reset, --kill is implied"));
+ return EXIT_FAILURE;
+ }
+
+ if (hard_reset && soft_reset) {
+ g_printerr ("%s\n",
+ _("You can not use the --hard-reset and --soft-reset arguments together"));
+ return EXIT_FAILURE;
+ }
+
+ if (hard_reset || soft_reset) {
+ /* Imply --kill */
+ kill_option = TERM_ALL;
+ }
+
+ /* Unless we are stopping processes or listing processes,
+ * don't iterate them.
+ */
+ if (kill_option != TERM_NONE ||
+ terminate_option != TERM_NONE ||
+ list_processes) {
+ pids = get_pids ();
+ str = g_strdup_printf (g_dngettext (NULL,
+ "Found %d PIDâ?¦",
+ "Found %d PIDsâ?¦",
+ g_slist_length (pids)),
+ g_slist_length (pids));
+ g_print ("%s\n", str);
+ g_free (str);
+
+ for (l = pids; l; l = l->next) {
+ gchar *filename;
+ gchar *contents = NULL;
+ gchar **strv;
+
+ filename = g_build_filename ("/proc", l->data, "cmdline", NULL);
+ if (!g_file_get_contents (filename, &contents, NULL, &error)) {
+ str = g_strdup_printf (_("Could not open '%s'"), filename);
+ g_printerr ("%s, %s\n",
+ str,
+ error ? error->message : _("no error given"));
+ g_free (str);
+ g_clear_error (&error);
+ g_free (contents);
+ g_free (filename);
+
+ continue;
+ }
+
+ strv = g_strsplit (contents, "^@", 2);
+ if (strv && strv[0]) {
+ gchar *basename;
+
+ basename = g_path_get_basename (strv[0]);
+
+ if ((g_str_has_prefix (basename, "tracker") == TRUE ||
+ g_str_has_prefix (basename, "lt-tracker") == TRUE) &&
+ g_str_has_suffix (basename, "-control") == FALSE &&
+ g_str_has_suffix (basename, "-status-icon") == FALSE) {
+ pid_t pid;
+
+ pid = atoi (l->data);
+ str = g_strdup_printf (_("Found process ID %d for '%s'"), pid, basename);
+ g_print ("%s\n", str);
+ g_free (str);
+
+ if (terminate_option != TERM_NONE) {
+ if ((terminate_option == TERM_STORE &&
+ !g_str_has_suffix (basename, "tracker-store")) ||
+ (terminate_option == TERM_MINERS &&
+ !strstr (basename, "tracker-miner"))) {
+ continue;
+ }
+
+ if (kill (pid, SIGTERM) == -1) {
+ const gchar *errstr = g_strerror (errno);
+
+ str = g_strdup_printf (_("Could not terminate process %d"), pid);
+ g_printerr (" %s, %s\n",
+ str,
+ errstr ? errstr : _("no error given"));
+ g_free (str);
+ } else {
+ str = g_strdup_printf (_("Terminated process %d"), pid);
+ g_print (" %s\n", str);
+ g_free (str);
+ }
+ } else if (kill_option != TERM_NONE) {
+ if ((kill_option == TERM_STORE &&
+ !g_str_has_suffix (basename, "tracker-store")) ||
+ (kill_option == TERM_MINERS &&
+ !strstr (basename, "tracker-miner"))) {
+ continue;
+ }
+
+ if (kill (pid, SIGKILL) == -1) {
+ const gchar *errstr = g_strerror (errno);
+
+ str = g_strdup_printf (_("Could not kill process %d"), pid);
+ g_printerr (" %s, %s\n",
+ str,
+ errstr ? errstr : _("no error given"));
+ g_free (str);
+ } else {
+ str = g_strdup_printf (_("Killed process %d"), pid);
+ g_print (" %s\n", str);
+ g_free (str);
+ }
+ }
+ }
+
+ g_free (basename);
+ }
+
+ g_strfreev (strv);
+ g_free (contents);
+ g_free (filename);
+ }
+
+ g_slist_foreach (pids, (GFunc) g_free, NULL);
+ g_slist_free (pids);
+
+ /* If we just wanted to list processes, all done */
+ if (list_processes &&
+ terminate_option == TERM_NONE &&
+ kill_option == TERM_NONE) {
+ return EXIT_SUCCESS;
+ }
+ }
+
+ if (hard_reset || soft_reset) {
+ guint log_handler_id;
+ const gchar *rotate_to = NULL;
+ TrackerDBConfig *db_config;
+ gsize chunk_size;
+ gint chunk_size_mb;
+
+
+ db_config = tracker_db_config_new ();
+
+ /* Set log handler for library messages */
+ log_handler_id = g_log_set_handler (NULL,
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL,
+ log_handler,
+ NULL);
+
+ g_log_set_default_handler (log_handler, NULL);
+
+ chunk_size_mb = tracker_db_config_get_journal_chunk_size (db_config);
+ chunk_size = (gsize) ((gsize) chunk_size_mb * (gsize) 1024 * (gsize) 1024);
+ rotate_to = tracker_db_config_get_journal_rotate_destination (db_config);
+
+ /* This call is needed to set the journal's filename */
+
+ tracker_db_journal_set_rotating ((chunk_size_mb != -1),
+ chunk_size, rotate_to);
+
+
+ g_object_unref (db_config);
+
+ /* Clean up (select_cache_size and update_cache_size don't matter here) */
+ if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL,
+ NULL,
+ FALSE,
+ 100,
+ 100,
+ NULL,
+ NULL,
+ NULL)) {
+ return EXIT_FAILURE;
+ }
+
+ tracker_db_journal_init (NULL, FALSE);
+
+ tracker_db_manager_remove_all (hard_reset);
+ tracker_db_manager_shutdown ();
+ tracker_db_journal_shutdown ();
+
+ /* Unset log handler */
+ g_log_remove_handler (NULL, log_handler_id);
+ }
+
+ if (remove_config) {
+ GMainLoop *main_loop;
+ GFile *file;
+ TrackerCrawler *crawler;
+ const gchar *suffix = ".cfg";
+ const gchar *home_conf_dir;
+ gchar *path;
+
+ crawler = tracker_crawler_new ();
+ main_loop = g_main_loop_new (NULL, FALSE);
+
+ g_signal_connect (crawler, "check-file",
+ G_CALLBACK (crawler_check_file_cb),
+ &suffix);
+ g_signal_connect (crawler, "finished",
+ G_CALLBACK (crawler_finished_cb),
+ main_loop);
+
+ /* Go through service files */
+
+
+ /* Check the default XDG_DATA_HOME location */
+ home_conf_dir = g_getenv ("XDG_CONFIG_HOME");
+
+ if (home_conf_dir && tracker_path_has_write_access_or_was_created (home_conf_dir)) {
+ path = g_build_path (G_DIR_SEPARATOR_S, home_conf_dir, "tracker", NULL);
+ } else {
+ home_conf_dir = g_getenv ("HOME");
+
+ if (!home_conf_dir || !tracker_path_has_write_access_or_was_created (home_conf_dir)) {
+ home_conf_dir = g_get_home_dir ();
+ }
+ path = g_build_path (G_DIR_SEPARATOR_S, home_conf_dir, ".config", "tracker", NULL);
+ }
+
+
+ file = g_file_new_for_path (path);
+ g_free (path);
+
+ g_print ("%s\n", _("Removing configuration filesâ?¦"));
+
+ tracker_crawler_start (crawler, file, FALSE);
+ g_object_unref (file);
+
+ g_main_loop_run (main_loop);
+ g_object_unref (crawler);
+ }
+
+ if (start) {
+ TrackerMinerManager *manager;
+ GSList *miners, *l;
+
+ if (hard_reset || soft_reset) {
+ g_print ("%s\n", _("Waiting one second before starting minersâ?¦"));
+
+ /* Give a second's grace to avoid race conditions */
+ g_usleep (G_USEC_PER_SEC);
+ }
+
+ g_print ("%s\n", _("Starting minersâ?¦"));
+
+ manager = tracker_miner_manager_new ();
+ miners = tracker_miner_manager_get_available (manager);
+
+ /* Get the status of all miners, this will start all
+ * miners not already running.
+ */
+
+ for (l = miners; l; l = l->next) {
+ const gchar *display_name;
+ gdouble progress = 0.0;
+
+ display_name = tracker_miner_manager_get_display_name (manager, l->data);
+
+ if (!tracker_miner_manager_get_status (manager, l->data, NULL, &progress)) {
+ g_printerr (" â?? %s (%s)\n",
+ display_name,
+ _("perhaps a disabled plugin?"));
+ } else {
+ g_print (" â?? %s\n",
+ display_name);
+ }
+
+ g_free (l->data);
+ }
+
+ g_slist_free (miners);
+ g_object_unref (manager);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+GOptionGroup *
+tracker_control_general_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ /* Status options */
+ group = g_option_group_new ("general",
+ _("General options"),
+ _("Show general options"),
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+ return group;
+}
diff --git a/src/tracker-control/tracker-control-miners.c b/src/tracker-control/tracker-control-miners.c
new file mode 100644
index 0000000..fdb76f4
--- /dev/null
+++ b/src/tracker-control/tracker-control-miners.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Nokia <ivan frade nokia com>
+ *
+ * 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 the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <locale.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-miner/tracker-miner.h>
+
+#include "tracker-control.h"
+
+/* Note:
+ * Every time a new option is added, make sure it is considered in the
+ * 'ENABLED' macro below
+ */
+static const gchar **reindex_mime_types;
+static gchar *index_file;
+static gchar *miner_name;
+static gchar *pause_reason;
+static gint resume_cookie = -1;
+static gboolean list_miners_running;
+static gboolean list_miners_available;
+static gboolean pause_details;
+#define ENABLED() \
+ (reindex_mime_types || \
+ index_file || \
+ miner_name || \
+ pause_reason || \
+ resume_cookie != -1 || \
+ list_miners_running || \
+ list_miners_available || \
+ pause_details)
+
+static GOptionEntry entries[] = {
+ { "reindex-mime-type", 'm', 0, G_OPTION_ARG_STRING_ARRAY, &reindex_mime_types,
+ N_("Tell miners to reindex files which match the mime type supplied (for new extractors), use -m MIME1 -m MIME2"),
+ N_("MIME") },
+ { "index-file", 'f', 0, G_OPTION_ARG_FILENAME, &index_file,
+ N_("Tell miners to (re)index a given file"),
+ N_("FILE") },
+ { "pause", 0 , 0, G_OPTION_ARG_STRING, &pause_reason,
+ N_("Pause a miner (you must use this with --miner)"),
+ N_("REASON")
+ },
+ { "resume", 0 , 0, G_OPTION_ARG_INT, &resume_cookie,
+ N_("Resume a miner (you must use this with --miner)"),
+ N_("COOKIE")
+ },
+ { "miner", 0 , 0, G_OPTION_ARG_STRING, &miner_name,
+ N_("Miner to use with --resume or --pause (you can use suffixes, e.g. Files or Applications)"),
+ N_("MINER")
+ },
+ { "list-miners-running", 'L', 0, G_OPTION_ARG_NONE, &list_miners_running,
+ N_("List all miners currently running"),
+ NULL
+ },
+ { "list-miners-available", 'A', 0, G_OPTION_ARG_NONE, &list_miners_available,
+ N_("List all miners installed"),
+ NULL
+ },
+ { "pause-details", 'I', 0, G_OPTION_ARG_NONE, &pause_details,
+ N_("List pause reasons"),
+ NULL
+ },
+ { NULL }
+};
+
+gboolean
+tracker_control_miners_options_enabled (void)
+{
+ return ENABLED ();
+}
+
+static gint
+miner_pause (const gchar *miner,
+ const gchar *reason)
+{
+ TrackerMinerManager *manager;
+ gchar *str;
+ gint cookie;
+
+ manager = tracker_miner_manager_new ();
+ str = g_strdup_printf (_("Attempting to pause miner '%s' with reason '%s'"),
+ miner,
+ reason);
+ g_print ("%s\n", str);
+ g_free (str);
+
+ if (!tracker_miner_manager_pause (manager, miner, reason, &cookie)) {
+ g_printerr (_("Could not pause miner: %s"), miner);
+ g_printerr ("\n");
+ return EXIT_FAILURE;
+ }
+
+ str = g_strdup_printf (_("Cookie is %d"), cookie);
+ g_print (" %s\n", str);
+ g_free (str);
+ g_object_unref (manager);
+
+ return EXIT_SUCCESS;
+}
+
+static gint
+miner_resume (const gchar *miner,
+ gint cookie)
+{
+ TrackerMinerManager *manager;
+ gchar *str;
+
+ manager = tracker_miner_manager_new ();
+ str = g_strdup_printf (_("Attempting to resume miner %s with cookie %d"),
+ miner,
+ cookie);
+ g_print ("%s\n", str);
+ g_free (str);
+
+ if (!tracker_miner_manager_resume (manager, miner, cookie)) {
+ g_printerr (_("Could not resume miner: %s"), miner);
+ return EXIT_FAILURE;
+ }
+
+ g_print (" %s\n", _("Done"));
+
+ g_object_unref (manager);
+
+ return EXIT_SUCCESS;
+}
+
+static gint
+miner_reindex_mime_types (const gchar **mime_types)
+{
+ GError *error = NULL;
+ TrackerMinerManager *manager;
+
+ manager = tracker_miner_manager_new ();
+ tracker_miner_manager_reindex_by_mimetype (manager, (GStrv)reindex_mime_types, &error);
+ if (error) {
+ g_printerr ("%s: %s\n",
+ _("Could not reindex mimetypes"),
+ error->message);
+ g_error_free (error);
+ return EXIT_FAILURE;
+ }
+
+ g_print ("%s\n", _("Reindexing mime types was successful"));
+ g_object_unref (manager);
+
+ return EXIT_SUCCESS;
+}
+
+static gint
+miner_index_file (const gchar *filepath)
+{
+ TrackerMinerManager *manager;
+ GError *error = NULL;
+ GFile *file;
+
+ file = g_file_new_for_commandline_arg (index_file);
+ manager = tracker_miner_manager_new ();
+
+ tracker_miner_manager_index_file (manager, file, &error);
+
+ if (error) {
+ g_printerr ("%s: %s\n",
+ _("Could not (re)index file"),
+ error->message);
+ g_error_free (error);
+ return EXIT_FAILURE;
+ }
+
+ g_print ("%s\n", _("(Re)indexing file was successful"));
+
+ g_object_unref (manager);
+ g_object_unref (file);
+
+ return EXIT_SUCCESS;
+}
+
+static gint
+miner_list (gboolean available,
+ gboolean running)
+{
+ TrackerMinerManager *manager;
+
+ manager = tracker_miner_manager_new ();
+
+ if (available) {
+ GSList *miners_available;
+ gchar *str;
+ GSList *l;
+
+ miners_available = tracker_miner_manager_get_available (manager);
+
+ str = g_strdup_printf (_("Found %d miners installed"),
+ g_slist_length (miners_available));
+ g_print ("%s%s\n", str, g_slist_length (miners_available) > 0 ? ":" : "");
+ g_free (str);
+
+ for (l = miners_available; l; l = l->next) {
+ g_print (" %s\n", (gchar*) l->data);
+ }
+
+ g_slist_foreach (miners_available, (GFunc) g_free, NULL);
+ g_slist_free (miners_available);
+ }
+
+ if (running) {
+ GSList *miners_running;
+ gchar *str;
+ GSList *l;
+
+ miners_running = tracker_miner_manager_get_running (manager);
+
+ str = g_strdup_printf (_("Found %d miners running"),
+ g_slist_length (miners_running));
+ g_print ("%s%s\n", str, g_slist_length (miners_running) > 0 ? ":" : "");
+ g_free (str);
+
+ for (l = miners_running; l; l = l->next) {
+ g_print (" %s\n", (gchar*) l->data);
+ }
+
+ g_slist_foreach (miners_running, (GFunc) g_free, NULL);
+ g_slist_free (miners_running);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+gint
+tracker_control_miners_run (void)
+{
+ /* Constraints */
+
+ if (pause_reason && resume_cookie != -1) {
+ g_printerr ("%s\n",
+ _("You can not use miner pause and resume switches together"));
+ return EXIT_FAILURE;
+ }
+
+ if ((pause_reason || resume_cookie != -1) && !miner_name) {
+ g_printerr ("%s\n",
+ _("You must provide the miner for pause or resume commands"));
+ return EXIT_FAILURE;
+ }
+
+ if ((!pause_reason && resume_cookie == -1) && miner_name) {
+ g_printerr ("%s\n",
+ _("You must provide a pause or resume command for the miner"));
+ return EXIT_FAILURE;
+ }
+
+ /* Known actions */
+
+ if (list_miners_running || list_miners_available) {
+ return miner_list (list_miners_available,
+ list_miners_running);
+ }
+
+ if (reindex_mime_types) {
+ return miner_reindex_mime_types (reindex_mime_types);
+ }
+
+ if (index_file) {
+ return miner_index_file (index_file);
+ }
+
+ if (pause_reason) {
+ return miner_pause (miner_name, pause_reason);
+ }
+
+ if (resume_cookie != -1) {
+ return miner_resume (miner_name, resume_cookie);
+ }
+
+ /* All known options have their own exit points */
+ g_warn_if_reached();
+
+ return EXIT_FAILURE;
+}
+
+GOptionGroup *
+tracker_control_miners_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ /* Status options */
+ group = g_option_group_new ("miners",
+ _("Miners options"),
+ _("Show miners options"),
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+ return group;
+}
diff --git a/src/tracker-control/tracker-control-status.c b/src/tracker-control/tracker-control-status.c
new file mode 100644
index 0000000..2afe3b1
--- /dev/null
+++ b/src/tracker-control/tracker-control-status.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * 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 the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <locale.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+
+#include <libtracker-common/tracker-common.h>
+#include <libtracker-miner/tracker-miner.h>
+
+#include "tracker-control.h"
+
+static GDBusConnection *connection = NULL;
+static GDBusProxy *proxy = NULL;
+static GMainLoop *main_loop;
+static GHashTable *miners_progress;
+static GHashTable *miners_status;
+static gint longest_miner_name_length = 0;
+static gint paused_length = 0;
+
+/* Note:
+ * Every time a new option is added, make sure it is considered in the
+ * 'ENABLED' macro below
+ */
+static gboolean status;
+static gboolean follow;
+static gboolean detailed;
+static gboolean list_common_statuses;
+#define ENABLED() \
+ (status || \
+ follow || \
+ detailed || \
+ list_common_statuses)
+
+
+/* Make sure our statuses are translated (all from libtracker-miner except one) */
+static const gchar *statuses[7] = {
+ N_("Initializing"),
+ N_("Processingâ?¦"),
+ N_("Fetchingâ?¦"), /* miner/rss */
+ N_("Crawling single directory '%s'"),
+ N_("Crawling recursively directory '%s'"),
+ N_("Paused"),
+ N_("Idle")
+};
+
+/* ---- STATUS options ---- */
+static GOptionEntry entries[] = {
+ { "status", 'S', 0, G_OPTION_ARG_NONE, &status,
+ N_("Show current status"),
+ NULL
+ },
+ { "follow", 'F', 0, G_OPTION_ARG_NONE, &follow,
+ N_("Follow status changes as they happen"),
+ NULL
+ },
+ { "detailed", 'D', 0, G_OPTION_ARG_NONE, &detailed,
+ N_("Include details with state updates (only applies to --follow)"),
+ NULL
+ },
+ { "list-common-statuses", 'C', 0, G_OPTION_ARG_NONE, &list_common_statuses,
+ N_("List common statuses for miners and the store"),
+ NULL
+ },
+ { NULL }
+};
+
+gboolean
+tracker_control_status_options_enabled (void)
+{
+ return ENABLED ();
+}
+
+static void
+signal_handler (int signo)
+{
+ static gboolean in_loop = FALSE;
+
+ /* Die if we get re-entrant signals handler calls */
+ if (in_loop) {
+ exit (EXIT_FAILURE);
+ }
+
+ switch (signo) {
+ case SIGTERM:
+ case SIGINT:
+ in_loop = TRUE;
+ g_main_loop_quit (main_loop);
+
+ /* Fall through */
+ default:
+ if (g_strsignal (signo)) {
+ g_print ("\n");
+ g_print ("Received signal:%d->'%s'\n",
+ signo,
+ g_strsignal (signo));
+ }
+ break;
+ }
+}
+
+static void
+initialize_signal_handler (void)
+{
+ struct sigaction act;
+ sigset_t empty_mask;
+
+ sigemptyset (&empty_mask);
+ act.sa_handler = signal_handler;
+ act.sa_mask = empty_mask;
+ act.sa_flags = 0;
+
+ sigaction (SIGTERM, &act, NULL);
+ sigaction (SIGINT, &act, NULL);
+ sigaction (SIGHUP, &act, NULL);
+}
+
+static gboolean
+miner_get_details (TrackerMinerManager *manager,
+ const gchar *miner,
+ gchar **status,
+ gdouble *progress,
+ GStrv *pause_applications,
+ GStrv *pause_reasons)
+{
+ if ((status || progress) &&
+ !tracker_miner_manager_get_status (manager, miner,
+ status, progress)) {
+ g_printerr (_("Could not get status from miner: %s"), miner);
+ return FALSE;
+ }
+
+ tracker_miner_manager_is_paused (manager, miner,
+ pause_applications,
+ pause_reasons);
+
+ return TRUE;
+}
+
+static void
+miner_print_state (TrackerMinerManager *manager,
+ const gchar *miner_name,
+ const gchar *status,
+ gdouble progress,
+ gboolean is_running,
+ gboolean is_paused)
+{
+ const gchar *name;
+ time_t now;
+ gchar time_str[64];
+ size_t len;
+ struct tm *local_time;
+ gchar *progress_str;
+
+ if (detailed) {
+ now = time ((time_t *) NULL);
+ local_time = localtime (&now);
+ len = strftime (time_str,
+ sizeof (time_str) - 1,
+ "%d %b %Y, %H:%M:%S:",
+ local_time);
+ time_str[len] = '\0';
+ } else {
+ time_str[0] = '\0';
+ }
+
+ name = tracker_miner_manager_get_display_name (manager, miner_name);
+
+ if (!is_running) {
+ progress_str = g_strdup_printf ("â?? ");
+ } else if (progress > 0.0 && progress < 1.0) {
+ progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
+ } else {
+ progress_str = g_strdup_printf ("â?? ");
+ }
+
+ if (is_running) {
+ g_print ("%s %s %-*.*s %s%-*.*s%s %s %s\n",
+ time_str,
+ progress_str,
+ longest_miner_name_length,
+ longest_miner_name_length,
+ name,
+ is_paused ? "(" : " ",
+ paused_length,
+ paused_length,
+ is_paused ? _("PAUSED") : " ",
+ is_paused ? ")" : " ",
+ status ? "-" : "",
+ status ? _(status) : "");
+ } else {
+ g_print ("%s %s %-*.*s %-*.*s - %s\n",
+ time_str,
+ progress_str,
+ longest_miner_name_length,
+ longest_miner_name_length,
+ name,
+ paused_length,
+ paused_length,
+ " ",
+ _("Not running or is a disabled plugin"));
+ }
+
+ g_free (progress_str);
+}
+
+static void
+store_print_state (const gchar *status,
+ gdouble progress)
+{
+ gchar *operation = NULL;
+ gchar *operation_status = NULL;
+ gchar time_str[64];
+ gchar *progress_str;
+
+ if (status && strstr (status, "-")) {
+ gchar **status_split;
+
+ status_split = g_strsplit (status, "-", 2);
+ if (status_split[0] && status_split[1]) {
+ operation = status_split[0];
+ operation_status = status_split[1];
+ /* Free the array, not the contents */
+ g_free (status_split);
+ } else {
+ /* Free everything */
+ g_strfreev (status_split);
+ }
+ }
+
+ if (detailed) {
+ struct tm *local_time;
+ time_t now;
+ size_t len;
+
+ now = time ((time_t *) NULL);
+ local_time = localtime (&now);
+ len = strftime (time_str,
+ sizeof (time_str) - 1,
+ "%d %b %Y, %H:%M:%S:",
+ local_time);
+ time_str[len] = '\0';
+ } else {
+ time_str[0] = '\0';
+ }
+
+ if (progress > 0.0 && progress < 1.0) {
+ progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
+ } else {
+ progress_str = g_strdup_printf ("â?? ");
+ }
+
+ g_print ("%s %s %-*.*s %s %s\n",
+ time_str,
+ progress_str,
+ longest_miner_name_length + paused_length,
+ longest_miner_name_length + paused_length,
+ operation ? _(operation) : _(status),
+ operation_status ? "-" : "",
+ operation_status ? _(operation_status) : "");
+
+ g_free (progress_str);
+ g_free (operation);
+ g_free (operation_status);
+}
+
+static void
+store_get_and_print_state (void)
+{
+ GVariant *v_status, *v_progress;
+ const gchar *status = NULL;
+ gdouble progress = -1.0;
+ GError *error = NULL;
+
+ /* Status */
+ v_status = g_dbus_proxy_call_sync (proxy,
+ "GetStatus",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_variant_get (v_status, "(&s)", &status);
+
+ if (!status || error) {
+ g_critical ("Could not retrieve tracker-store status: %s",
+ error ? error->message : "no error given");
+ g_clear_error (&error);
+ return;
+ }
+
+ /* Progress */
+ v_progress = g_dbus_proxy_call_sync (proxy,
+ "GetProgress",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_variant_get (v_progress, "(d)", &progress);
+
+ if (progress < 0.0 || error) {
+ g_critical ("Could not retrieve tracker-store progress: %s",
+ error ? error->message : "no error given");
+ g_clear_error (&error);
+ return;
+ }
+
+ /* Print */
+ store_print_state (status, progress);
+
+ g_variant_unref (v_progress);
+ g_variant_unref (v_status);
+}
+
+static void
+manager_miner_progress_cb (TrackerMinerManager *manager,
+ const gchar *miner_name,
+ const gchar *status,
+ gdouble progress)
+{
+ GValue *gvalue;
+
+ gvalue = g_slice_new0 (GValue);
+
+ g_value_init (gvalue, G_TYPE_DOUBLE);
+ g_value_set_double (gvalue, progress);
+
+ miner_print_state (manager, miner_name, status, progress, TRUE, FALSE);
+
+ g_hash_table_replace (miners_status,
+ g_strdup (miner_name),
+ g_strdup (status));
+ g_hash_table_replace (miners_progress,
+ g_strdup (miner_name),
+ gvalue);
+}
+
+static void
+manager_miner_paused_cb (TrackerMinerManager *manager,
+ const gchar *miner_name)
+{
+ GValue *gvalue;
+
+ gvalue = g_hash_table_lookup (miners_progress, miner_name);
+
+ miner_print_state (manager, miner_name,
+ g_hash_table_lookup (miners_status, miner_name),
+ gvalue ? g_value_get_double (gvalue) : 0.0,
+ TRUE,
+ TRUE);
+}
+
+static void
+manager_miner_resumed_cb (TrackerMinerManager *manager,
+ const gchar *miner_name)
+{
+ GValue *gvalue;
+
+ gvalue = g_hash_table_lookup (miners_progress, miner_name);
+
+ miner_print_state (manager, miner_name,
+ g_hash_table_lookup (miners_status, miner_name),
+ gvalue ? g_value_get_double (gvalue) : 0.0,
+ TRUE,
+ FALSE);
+}
+
+static void
+miners_progress_destroy_notify (gpointer data)
+{
+ GValue *value;
+
+ value = data;
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+static void
+store_progress (GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ const gchar *status = NULL;
+ gdouble progress = 0.0;
+
+ g_variant_get (parameters, "(sd)", &status, &progress);
+ store_print_state (status, progress);
+}
+
+static gboolean
+store_init (void)
+{
+ GError *error = NULL;
+
+ if (connection && proxy) {
+ return TRUE;
+ }
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+
+ if (!connection) {
+ g_critical ("Could not connect to the D-Bus session bus, %s",
+ error ? error->message : "no error given.");
+ g_clear_error (&error);
+ return FALSE;
+ }
+
+ proxy = g_dbus_proxy_new_sync (connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.Tracker1",
+ "/org/freedesktop/Tracker1/Status",
+ "org.freedesktop.Tracker1.Status",
+ NULL,
+ &error);
+
+ if (error) {
+ g_critical ("Could not create proxy on the D-Bus session bus, %s",
+ error ? error->message : "no error given.");
+ g_clear_error (&error);
+ return FALSE;
+ }
+
+ g_dbus_connection_signal_subscribe (connection,
+ "org.freedesktop.Tracker1",
+ "org.freedesktop.Tracker1.Status",
+ "Progress",
+ "/org/freedesktop/Tracker1/Status",
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ store_progress,
+ NULL,
+ NULL);
+
+ return TRUE;
+}
+
+gint
+tracker_control_status_run (void)
+{
+ TrackerMinerManager *manager;
+ GSList *miners_available;
+ GSList *miners_running;
+ GSList *l;
+
+ /* --follow implies --status */
+ if (follow) {
+ status = TRUE;
+ }
+
+ manager = tracker_miner_manager_new ();
+ miners_available = tracker_miner_manager_get_available (manager);
+ miners_running = tracker_miner_manager_get_running (manager);
+
+ if (list_common_statuses) {
+ gint i;
+
+ g_print ("%s:\n", _("Common statuses include"));
+
+ for (i = 0; i < G_N_ELEMENTS(statuses); i++) {
+ g_print (" %s\n", _(statuses[i]));
+ }
+
+ return EXIT_SUCCESS;
+ }
+
+ if (status) {
+ /* Work out lengths for output spacing */
+ paused_length = strlen (_("PAUSED"));
+
+ for (l = miners_available; l; l = l->next) {
+ const gchar *name;
+
+ name = tracker_miner_manager_get_display_name (manager, l->data);
+ longest_miner_name_length = MAX (longest_miner_name_length, strlen (name));
+ }
+
+ /* Display states */
+ g_print ("%s:\n", _("Store"));
+ store_init ();
+ store_get_and_print_state ();
+
+ g_print ("\n");
+
+ g_print ("%s:\n", _("Miners"));
+
+ for (l = miners_available; l; l = l->next) {
+ const gchar *name;
+ gboolean is_running;
+
+ name = tracker_miner_manager_get_display_name (manager, l->data);
+ if (!name) {
+ g_critical ("Could not get name for '%s'", (gchar *) l->data);
+ continue;
+ }
+
+ is_running = tracker_string_in_gslist (l->data, miners_running);
+
+ if (is_running) {
+ GStrv pause_applications, pause_reasons;
+ gchar *status = NULL;
+ gdouble progress;
+ gboolean is_paused;
+
+ if (!miner_get_details (manager,
+ l->data,
+ &status,
+ &progress,
+ &pause_applications,
+ &pause_reasons)) {
+ continue;
+ }
+
+ is_paused = *pause_applications || *pause_reasons;
+
+ miner_print_state (manager, l->data, status, progress, TRUE, is_paused);
+
+ g_strfreev (pause_applications);
+ g_strfreev (pause_reasons);
+ g_free (status);
+ } else {
+ miner_print_state (manager, l->data, NULL, 0.0, FALSE, FALSE);
+ }
+ }
+
+ g_slist_foreach (miners_available, (GFunc) g_free, NULL);
+ g_slist_free (miners_available);
+
+ g_slist_foreach (miners_running, (GFunc) g_free, NULL);
+ g_slist_free (miners_running);
+
+ if (!follow) {
+ /* Do nothing further */
+ if (proxy) {
+ g_object_unref (proxy);
+ }
+ g_print ("\n");
+ return EXIT_SUCCESS;
+ }
+
+ g_print ("Press Ctrl+C to end follow of Tracker state\n");
+
+ g_signal_connect (manager, "miner-progress",
+ G_CALLBACK (manager_miner_progress_cb), NULL);
+ g_signal_connect (manager, "miner-paused",
+ G_CALLBACK (manager_miner_paused_cb), NULL);
+ g_signal_connect (manager, "miner-resumed",
+ G_CALLBACK (manager_miner_resumed_cb), NULL);
+
+ initialize_signal_handler ();
+
+ miners_progress = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) miners_progress_destroy_notify);
+ miners_status = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (main_loop);
+ g_main_loop_unref (main_loop);
+
+ g_hash_table_unref (miners_progress);
+ g_hash_table_unref (miners_status);
+
+ if (proxy) {
+ g_object_unref (proxy);
+ }
+
+ if (manager) {
+ g_object_unref (manager);
+ }
+
+ return EXIT_SUCCESS;
+ }
+
+ /* All known options have their own exit points */
+ g_warn_if_reached();
+
+ return EXIT_FAILURE;
+}
+
+GOptionGroup *
+tracker_control_status_get_option_group (void)
+{
+ GOptionGroup *group;
+
+ /* Status options */
+ group = g_option_group_new ("status",
+ _("Status options"),
+ _("Show status options"),
+ NULL,
+ NULL);
+ g_option_group_add_entries (group, entries);
+ return group;
+}
diff --git a/src/tracker-control/tracker-control.c b/src/tracker-control/tracker-control.c
index ca5756e..0fa8a8d 100644
--- a/src/tracker-control/tracker-control.c
+++ b/src/tracker-control/tracker-control.c
@@ -34,11 +34,7 @@
#include <libtracker-common/tracker-common.h>
-#include <libtracker-data/tracker-db-config.h>
-#include <libtracker-data/tracker-db-journal.h>
-#include <libtracker-data/tracker-db-manager.h>
-
-#include <libtracker-miner/tracker-miner.h>
+#include "tracker-control.h"
#define ABOUT \
"Tracker " PACKAGE_VERSION "\n"
@@ -50,161 +46,8 @@
"\n" \
" http://www.gnu.org/licenses/gpl.txt\n"
-#define OPTION_TERM_ALL "all"
-#define OPTION_TERM_STORE "store"
-#define OPTION_TERM_MINERS "miners"
-
-typedef enum {
- TERM_NONE,
- TERM_ALL,
- TERM_STORE,
- TERM_MINERS
-} TermOption;
-
-static GDBusConnection *connection = NULL;
-static GDBusProxy *proxy = NULL;
-static GMainLoop *main_loop;
-static GHashTable *miners_progress;
-static GHashTable *miners_status;
-static gint longest_miner_name_length = 0;
-static gint paused_length = 0;
-
-/* Control options */
-static TermOption kill_option = TERM_NONE;
-static TermOption terminate_option = TERM_NONE;
-static gboolean hard_reset;
-static gboolean soft_reset;
-static gboolean remove_config;
-static gboolean start;
-static const gchar **reindex_mime_types;
-static gchar *index_file;
-static gchar *miner_name;
-static gchar *pause_reason;
-static gint resume_cookie = -1;
-#define CONTROL_OPTION_ENABLED() \
- (kill_option != TERM_NONE || \
- terminate_option != TERM_NONE || \
- hard_reset || \
- soft_reset || \
- remove_config || \
- start || \
- reindex_mime_types != NULL || \
- index_file != NULL || \
- miner_name != NULL || \
- pause_reason != NULL || \
- resume_cookie >= 0)
-
-/* Status options */
-static gboolean status_details;
-static gboolean follow;
-static gboolean detailed;
-static gboolean list_common_statuses;
-static gboolean list_miners_running;
-static gboolean list_miners_available;
-static gboolean pause_details;
-#define STATUS_OPTION_ENABLED() \
- (status_details || \
- follow || \
- detailed || \
- list_common_statuses || \
- list_miners_running || \
- list_miners_available || \
- pause_details)
-
-/* Common options */
static gboolean print_version;
-/* Make sure our statuses are translated (all from libtracker-miner except one) */
-static const gchar *statuses[7] = {
- N_("Initializing"),
- N_("Processingâ?¦"),
- N_("Fetchingâ?¦"), /* miner/rss */
- N_("Crawling single directory '%s'"),
- N_("Crawling recursively directory '%s'"),
- N_("Paused"),
- N_("Idle")
-};
-
-static gboolean term_option_arg_func (const gchar *option_value,
- const gchar *value,
- gpointer data,
- GError **error);
-
-/* ---- CONTROL options ---- */
-static GOptionEntry control_entries[] = {
- { "kill", 'k', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, term_option_arg_func,
- N_("Use SIGKILL to stop all matching processes, either \"store\", \"miners\" or \"all\" may be used, no parameter equals \"all\""),
- N_("APPS") },
- { "terminate", 't', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, term_option_arg_func,
- N_("Use SIGTERM to stop all matching processes, either \"store\", \"miners\" or \"all\" may be used, no parameter equals \"all\""),
- N_("APPS") },
- { "hard-reset", 'r', 0, G_OPTION_ARG_NONE, &hard_reset,
- N_("Kill all Tracker processes and remove all databases"),
- NULL },
- { "soft-reset", 'e', 0, G_OPTION_ARG_NONE, &soft_reset,
- N_("Same as --hard-reset but the backup & journal are restored after restart"),
- NULL },
- { "remove-config", 'c', 0, G_OPTION_ARG_NONE, &remove_config,
- N_("Remove all configuration files so they are re-generated on next start"),
- NULL },
- { "start", 's', 0, G_OPTION_ARG_NONE, &start,
- N_("Starts miners (which indirectly starts tracker-store too)"),
- NULL },
- { "reindex-mime-type", 'm', 0, G_OPTION_ARG_STRING_ARRAY, &reindex_mime_types,
- N_("Reindex files which match the mime type supplied (for new extractors), use -m MIME1 -m MIME2"),
- N_("MIME") },
- { "index-file", 'f', 0, G_OPTION_ARG_FILENAME, &index_file,
- N_("(Re)Index a given file"),
- N_("FILE") },
- { "pause", 0 , 0, G_OPTION_ARG_STRING, &pause_reason,
- N_("Pause a miner (you must use this with --miner)"),
- N_("REASON")
- },
- { "resume", 0 , 0, G_OPTION_ARG_INT, &resume_cookie,
- N_("Resume a miner (you must use this with --miner)"),
- N_("COOKIE")
- },
- { "miner", 0 , 0, G_OPTION_ARG_STRING, &miner_name,
- N_("Miner to use with --resume or --pause (you can use suffixes, e.g. Files or Applications)"),
- N_("MINER")
- },
- { NULL }
-};
-
-/* ---- STATUS options ---- */
-static GOptionEntry status_entries[] = {
- { "status-details", 'S', 0, G_OPTION_ARG_NONE, &status_details,
- N_("Show current status"),
- NULL
- },
- { "follow", 'F', 0, G_OPTION_ARG_NONE, &follow,
- N_("Follow status changes as they happen"),
- NULL
- },
- { "detailed", 'D', 0, G_OPTION_ARG_NONE, &detailed,
- N_("Include details with state updates (only applies to --follow)"),
- NULL
- },
- { "list-common-statuses", 'C', 0, G_OPTION_ARG_NONE, &list_common_statuses,
- N_("List common statuses for miners and the store"),
- NULL
- },
- { "list-miners-running", 'L', 0, G_OPTION_ARG_NONE, &list_miners_running,
- N_("List all miners currently running"),
- NULL
- },
- { "list-miners-available", 'A', 0, G_OPTION_ARG_NONE, &list_miners_available,
- N_("List all miners installed"),
- NULL
- },
- { "pause-details", 'I', 0, G_OPTION_ARG_NONE, &pause_details,
- N_("List pause reasons"),
- NULL
- },
- { NULL }
-};
-
-/* ---- COMMON options ---- */
static GOptionEntry common_entries[] = {
{ "version", 'V', 0, G_OPTION_ARG_NONE, &print_version,
N_("Print version"),
@@ -212,1183 +55,10 @@ static GOptionEntry common_entries[] = {
{ NULL }
};
-static void
-signal_handler (int signo)
-{
- static gboolean in_loop = FALSE;
-
- /* Die if we get re-entrant signals handler calls */
- if (in_loop) {
- exit (EXIT_FAILURE);
- }
-
- switch (signo) {
- case SIGTERM:
- case SIGINT:
- in_loop = TRUE;
- g_main_loop_quit (main_loop);
-
- /* Fall through */
- default:
- if (g_strsignal (signo)) {
- g_print ("\n");
- g_print ("Received signal:%d->'%s'\n",
- signo,
- g_strsignal (signo));
- }
- break;
- }
-}
-
-static void
-initialize_signal_handler (void)
-{
- struct sigaction act;
- sigset_t empty_mask;
-
- sigemptyset (&empty_mask);
- act.sa_handler = signal_handler;
- act.sa_mask = empty_mask;
- act.sa_flags = 0;
-
- sigaction (SIGTERM, &act, NULL);
- sigaction (SIGINT, &act, NULL);
- sigaction (SIGHUP, &act, NULL);
-}
-
-static int
-miner_pause (const gchar *miner,
- const gchar *reason)
-{
- TrackerMinerManager *manager;
- gchar *str;
- gint cookie;
-
- manager = tracker_miner_manager_new ();
- str = g_strdup_printf (_("Attempting to pause miner '%s' with reason '%s'"),
- miner,
- reason);
- g_print ("%s\n", str);
- g_free (str);
-
- if (!tracker_miner_manager_pause (manager, miner, reason, &cookie)) {
- g_printerr (_("Could not pause miner: %s"), miner);
- g_printerr ("\n");
- return EXIT_FAILURE;
- }
-
- str = g_strdup_printf (_("Cookie is %d"), cookie);
- g_print (" %s\n", str);
- g_free (str);
- g_object_unref (manager);
-
- return EXIT_SUCCESS;
-}
-
-static int
-miner_resume (const gchar *miner,
- gint cookie)
-{
- TrackerMinerManager *manager;
- gchar *str;
-
- manager = tracker_miner_manager_new ();
- str = g_strdup_printf (_("Attempting to resume miner %s with cookie %d"),
- miner,
- cookie);
- g_print ("%s\n", str);
- g_free (str);
-
- if (!tracker_miner_manager_resume (manager, miner, cookie)) {
- g_printerr (_("Could not resume miner: %s"), miner);
- return EXIT_FAILURE;
- }
-
- g_print (" %s\n", _("Done"));
-
- g_object_unref (manager);
-
- return EXIT_SUCCESS;
-}
-
-static gboolean
-miner_get_details (TrackerMinerManager *manager,
- const gchar *miner,
- gchar **status,
- gdouble *progress,
- GStrv *pause_applications,
- GStrv *pause_reasons)
-{
- if ((status || progress) &&
- !tracker_miner_manager_get_status (manager, miner,
- status, progress)) {
- g_printerr (_("Could not get status from miner: %s"), miner);
- return FALSE;
- }
-
- tracker_miner_manager_is_paused (manager, miner,
- pause_applications,
- pause_reasons);
-
- return TRUE;
-}
-
-static void
-miner_print_state (TrackerMinerManager *manager,
- const gchar *miner_name,
- const gchar *status,
- gdouble progress,
- gboolean is_running,
- gboolean is_paused)
-{
- const gchar *name;
- time_t now;
- gchar time_str[64];
- size_t len;
- struct tm *local_time;
- gchar *progress_str;
-
- if (detailed) {
- now = time ((time_t *) NULL);
- local_time = localtime (&now);
- len = strftime (time_str,
- sizeof (time_str) - 1,
- "%d %b %Y, %H:%M:%S:",
- local_time);
- time_str[len] = '\0';
- } else {
- time_str[0] = '\0';
- }
-
- name = tracker_miner_manager_get_display_name (manager, miner_name);
-
- if (!is_running) {
- progress_str = g_strdup_printf ("â?? ");
- } else if (progress > 0.0 && progress < 1.0) {
- progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
- } else {
- progress_str = g_strdup_printf ("â?? ");
- }
-
- if (is_running) {
- g_print ("%s %s %-*.*s %s%-*.*s%s %s %s\n",
- time_str,
- progress_str,
- longest_miner_name_length,
- longest_miner_name_length,
- name,
- is_paused ? "(" : " ",
- paused_length,
- paused_length,
- is_paused ? _("PAUSED") : " ",
- is_paused ? ")" : " ",
- status ? "-" : "",
- status ? _(status) : "");
- } else {
- g_print ("%s %s %-*.*s %-*.*s - %s\n",
- time_str,
- progress_str,
- longest_miner_name_length,
- longest_miner_name_length,
- name,
- paused_length,
- paused_length,
- " ",
- _("Not running or is a disabled plugin"));
- }
-
- g_free (progress_str);
-}
-
-static void
-store_print_state (const gchar *status,
- gdouble progress)
-{
- gchar *operation = NULL;
- gchar *operation_status = NULL;
- gchar time_str[64];
- gchar *progress_str;
-
- if (status && strstr (status, "-")) {
- gchar **status_split;
-
- status_split = g_strsplit (status, "-", 2);
- if (status_split[0] && status_split[1]) {
- operation = status_split[0];
- operation_status = status_split[1];
- /* Free the array, not the contents */
- g_free (status_split);
- } else {
- /* Free everything */
- g_strfreev (status_split);
- }
- }
-
- if (detailed) {
- struct tm *local_time;
- time_t now;
- size_t len;
-
- now = time ((time_t *) NULL);
- local_time = localtime (&now);
- len = strftime (time_str,
- sizeof (time_str) - 1,
- "%d %b %Y, %H:%M:%S:",
- local_time);
- time_str[len] = '\0';
- } else {
- time_str[0] = '\0';
- }
-
- if (progress > 0.0 && progress < 1.0) {
- progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
- } else {
- progress_str = g_strdup_printf ("â?? ");
- }
-
- g_print ("%s %s %-*.*s %s %s\n",
- time_str,
- progress_str,
- longest_miner_name_length + paused_length,
- longest_miner_name_length + paused_length,
- operation ? _(operation) : _(status),
- operation_status ? "-" : "",
- operation_status ? _(operation_status) : "");
-
- g_free (progress_str);
- g_free (operation);
- g_free (operation_status);
-}
-
-static void
-store_get_and_print_state (void)
-{
- GVariant *v_status, *v_progress;
- const gchar *status = NULL;
- gdouble progress = -1.0;
- GError *error = NULL;
-
- /* Status */
- v_status = g_dbus_proxy_call_sync (proxy,
- "GetStatus",
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
-
- g_variant_get (v_status, "(&s)", &status);
-
- if (!status || error) {
- g_critical ("Could not retrieve tracker-store status: %s",
- error ? error->message : "no error given");
- g_clear_error (&error);
- return;
- }
-
- /* Progress */
- v_progress = g_dbus_proxy_call_sync (proxy,
- "GetProgress",
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
-
- g_variant_get (v_progress, "(d)", &progress);
-
- if (progress < 0.0 || error) {
- g_critical ("Could not retrieve tracker-store progress: %s",
- error ? error->message : "no error given");
- g_clear_error (&error);
- return;
- }
-
- /* Print */
- store_print_state (status, progress);
-
- g_variant_unref (v_progress);
- g_variant_unref (v_status);
-}
-
-static void
-manager_miner_progress_cb (TrackerMinerManager *manager,
- const gchar *miner_name,
- const gchar *status,
- gdouble progress)
-{
- GValue *gvalue;
-
- gvalue = g_slice_new0 (GValue);
-
- g_value_init (gvalue, G_TYPE_DOUBLE);
- g_value_set_double (gvalue, progress);
-
- miner_print_state (manager, miner_name, status, progress, TRUE, FALSE);
-
- g_hash_table_replace (miners_status,
- g_strdup (miner_name),
- g_strdup (status));
- g_hash_table_replace (miners_progress,
- g_strdup (miner_name),
- gvalue);
-}
-
-static void
-manager_miner_paused_cb (TrackerMinerManager *manager,
- const gchar *miner_name)
-{
- GValue *gvalue;
-
- gvalue = g_hash_table_lookup (miners_progress, miner_name);
-
- miner_print_state (manager, miner_name,
- g_hash_table_lookup (miners_status, miner_name),
- gvalue ? g_value_get_double (gvalue) : 0.0,
- TRUE,
- TRUE);
-}
-
-static void
-manager_miner_resumed_cb (TrackerMinerManager *manager,
- const gchar *miner_name)
-{
- GValue *gvalue;
-
- gvalue = g_hash_table_lookup (miners_progress, miner_name);
-
- miner_print_state (manager, miner_name,
- g_hash_table_lookup (miners_status, miner_name),
- gvalue ? g_value_get_double (gvalue) : 0.0,
- TRUE,
- FALSE);
-}
-
-static void
-miners_progress_destroy_notify (gpointer data)
-{
- GValue *value;
-
- value = data;
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static void
-store_progress (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- const gchar *status = NULL;
- gdouble progress = 0.0;
-
- g_variant_get (parameters, "(sd)", &status, &progress);
- store_print_state (status, progress);
-}
-
-static gboolean
-store_init (void)
-{
- GError *error = NULL;
-
- if (connection && proxy) {
- return TRUE;
- }
-
- connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-
- if (!connection) {
- g_critical ("Could not connect to the D-Bus session bus, %s",
- error ? error->message : "no error given.");
- g_clear_error (&error);
- return FALSE;
- }
-
- proxy = g_dbus_proxy_new_sync (connection,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- "org.freedesktop.Tracker1",
- "/org/freedesktop/Tracker1/Status",
- "org.freedesktop.Tracker1.Status",
- NULL,
- &error);
-
- if (error) {
- g_critical ("Could not create proxy on the D-Bus session bus, %s",
- error ? error->message : "no error given.");
- g_clear_error (&error);
- return FALSE;
- }
-
- g_dbus_connection_signal_subscribe (connection,
- "org.freedesktop.Tracker1",
- "org.freedesktop.Tracker1.Status",
- "Progress",
- "/org/freedesktop/Tracker1/Status",
- NULL,
- G_DBUS_SIGNAL_FLAGS_NONE,
- store_progress,
- NULL,
- NULL);
-
- return TRUE;
-}
-
-static GSList *
-get_pids (void)
-{
- GError *error = NULL;
- GDir *dir;
- GSList *pids = NULL;
- const gchar *name;
-
- dir = g_dir_open ("/proc", 0, &error);
- if (error) {
- g_printerr ("%s, %s\n",
- _("Could not open /proc"),
- error ? error->message : _("no error given"));
- g_clear_error (&error);
- return NULL;
- }
-
- while ((name = g_dir_read_name (dir)) != NULL) {
- gchar c;
- gboolean is_pid = TRUE;
-
- for (c = *name; c && c != ':' && is_pid; c++) {
- is_pid &= g_ascii_isdigit (c);
- }
-
- if (!is_pid) {
- continue;
- }
-
- pids = g_slist_prepend (pids, g_strdup (name));
- }
-
- g_dir_close (dir);
-
- return g_slist_reverse (pids);
-}
-
-static void
-log_handler (const gchar *domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer user_data)
-{
- switch (log_level) {
- case G_LOG_LEVEL_WARNING:
- case G_LOG_LEVEL_CRITICAL:
- case G_LOG_LEVEL_ERROR:
- case G_LOG_FLAG_RECURSION:
- case G_LOG_FLAG_FATAL:
- g_fprintf (stderr, "%s\n", message);
- fflush (stderr);
- break;
- case G_LOG_LEVEL_MESSAGE:
- case G_LOG_LEVEL_INFO:
- case G_LOG_LEVEL_DEBUG:
- case G_LOG_LEVEL_MASK:
- default:
- g_fprintf (stdout, "%s\n", message);
- fflush (stdout);
- break;
- }
-}
-
-static gboolean
-crawler_check_file_cb (TrackerCrawler *crawler,
- GFile *file,
- gpointer user_data)
-{
- const gchar **suffix;
- gchar *path;
- gboolean should_remove;
-
- suffix = user_data;
- path = g_file_get_path (file);
-
- if (suffix) {
- should_remove = g_str_has_suffix (path, *suffix);
- } else {
- should_remove = TRUE;
- }
-
- if (!should_remove) {
- g_free (path);
- return FALSE;
- }
-
- /* Remove file */
- if (g_unlink (path) == 0) {
- g_print (" %s\n", path);
- }
-
- g_free (path);
-
- return should_remove;
-}
-
-static void
-crawler_finished_cb (TrackerCrawler *crawler,
- gboolean was_interrupted,
- gpointer user_data)
-{
- g_main_loop_quit (user_data);
-}
-
-static gboolean
-term_option_arg_func (const gchar *option_value,
- const gchar *value,
- gpointer data,
- GError **error)
-{
- TermOption option;
-
- if (!value) {
- value = OPTION_TERM_ALL;
- }
-
- if (strcmp (value, OPTION_TERM_ALL) == 0) {
- option = TERM_ALL;
- } else if (strcmp (value, OPTION_TERM_STORE) == 0) {
- option = TERM_STORE;
- } else if (strcmp (value, OPTION_TERM_MINERS) == 0) {
- option = TERM_MINERS;
- } else {
- g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
- "Only one of 'all', 'store' and 'miners' are allowed");
- return FALSE;
- }
-
- if (strcmp (option_value, "-k") == 0 ||
- strcmp (option_value, "--kill") == 0) {
- kill_option = option;
- } else if (strcmp (option_value, "-t") == 0 ||
- strcmp (option_value, "--terminate") == 0) {
- terminate_option = option;
- }
-
- return TRUE;
-}
-
-static int
-control_actions (void)
-{
- GError *error = NULL;
- GSList *pids;
- GSList *l;
- gchar *str;
-
- if (kill_option != TERM_NONE && terminate_option != TERM_NONE) {
- g_printerr ("%s\n",
- _("You can not use the --kill and --terminate arguments together"));
- return EXIT_FAILURE;
- } else if ((hard_reset || soft_reset) && terminate_option != TERM_NONE) {
- g_printerr ("%s\n",
- _("You can not use the --terminate with --hard-reset or --soft-reset, --kill is implied"));
- return EXIT_FAILURE;
- } else if (hard_reset && soft_reset) {
- g_printerr ("%s\n",
- _("You can not use the --hard-reset and --soft-reset arguments together"));
- return EXIT_FAILURE;
- } else if (pause_reason && resume_cookie != -1) {
- g_printerr ("%s\n",
- _("You can not use miner pause and resume switches together"));
- return EXIT_FAILURE;
- } else if ((pause_reason || resume_cookie != -1) && !miner_name) {
- g_printerr ("%s\n",
- _("You must provide the miner for pause or resume commands"));
- return EXIT_FAILURE;
- } else if ((!pause_reason && resume_cookie == -1) && miner_name) {
- g_printerr ("%s\n",
- _("You must provide a pause or resume command for the miner"));
- return EXIT_FAILURE;
- }
-
- if (hard_reset || soft_reset) {
- /* Imply --kill */
- kill_option = TERM_ALL;
- }
-
- /* Unless we are stopping processes or listing processes,
- * don't iterate them.
- */
- if (kill_option != TERM_NONE ||
- terminate_option != TERM_NONE ||
- (!start && !remove_config && !reindex_mime_types &&
- !print_version && !index_file)) {
- pids = get_pids ();
- str = g_strdup_printf (g_dngettext (NULL,
- "Found %d PIDâ?¦",
- "Found %d PIDsâ?¦",
- g_slist_length (pids)),
- g_slist_length (pids));
- g_print ("%s\n", str);
- g_free (str);
-
- for (l = pids; l; l = l->next) {
- gchar *filename;
- gchar *contents = NULL;
- gchar **strv;
-
- filename = g_build_filename ("/proc", l->data, "cmdline", NULL);
- if (!g_file_get_contents (filename, &contents, NULL, &error)) {
- str = g_strdup_printf (_("Could not open '%s'"), filename);
- g_printerr ("%s, %s\n",
- str,
- error ? error->message : _("no error given"));
- g_free (str);
- g_clear_error (&error);
- g_free (contents);
- g_free (filename);
-
- continue;
- }
-
- strv = g_strsplit (contents, "^@", 2);
- if (strv && strv[0]) {
- gchar *basename;
-
- basename = g_path_get_basename (strv[0]);
-
- if ((g_str_has_prefix (basename, "tracker") == TRUE ||
- g_str_has_prefix (basename, "lt-tracker") == TRUE) &&
- g_str_has_suffix (basename, "-control") == FALSE &&
- g_str_has_suffix (basename, "-status-icon") == FALSE) {
- pid_t pid;
-
- pid = atoi (l->data);
- str = g_strdup_printf (_("Found process ID %d for '%s'"), pid, basename);
- g_print ("%s\n", str);
- g_free (str);
-
- if (terminate_option != TERM_NONE) {
- if ((terminate_option == TERM_STORE &&
- !g_str_has_suffix (basename, "tracker-store")) ||
- (terminate_option == TERM_MINERS &&
- !strstr (basename, "tracker-miner"))) {
- continue;
- }
-
- if (kill (pid, SIGTERM) == -1) {
- const gchar *errstr = g_strerror (errno);
-
- str = g_strdup_printf (_("Could not terminate process %d"), pid);
- g_printerr (" %s, %s\n",
- str,
- errstr ? errstr : _("no error given"));
- g_free (str);
- } else {
- str = g_strdup_printf (_("Terminated process %d"), pid);
- g_print (" %s\n", str);
- g_free (str);
- }
- } else if (kill_option != TERM_NONE) {
- if ((kill_option == TERM_STORE &&
- !g_str_has_suffix (basename, "tracker-store")) ||
- (kill_option == TERM_MINERS &&
- !strstr (basename, "tracker-miner"))) {
- continue;
- }
-
- if (kill (pid, SIGKILL) == -1) {
- const gchar *errstr = g_strerror (errno);
-
- str = g_strdup_printf (_("Could not kill process %d"), pid);
- g_printerr (" %s, %s\n",
- str,
- errstr ? errstr : _("no error given"));
- g_free (str);
- } else {
- str = g_strdup_printf (_("Killed process %d"), pid);
- g_print (" %s\n", str);
- g_free (str);
- }
- }
- }
-
- g_free (basename);
- }
-
- g_strfreev (strv);
- g_free (contents);
- g_free (filename);
- }
-
- g_slist_foreach (pids, (GFunc) g_free, NULL);
- g_slist_free (pids);
- }
-
- if (hard_reset || soft_reset) {
- guint log_handler_id;
- const gchar *rotate_to = NULL;
- TrackerDBConfig *db_config;
- gsize chunk_size;
- gint chunk_size_mb;
-
-
- db_config = tracker_db_config_new ();
-
- /* Set log handler for library messages */
- log_handler_id = g_log_set_handler (NULL,
- G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL,
- log_handler,
- NULL);
-
- g_log_set_default_handler (log_handler, NULL);
-
- chunk_size_mb = tracker_db_config_get_journal_chunk_size (db_config);
- chunk_size = (gsize) ((gsize) chunk_size_mb * (gsize) 1024 * (gsize) 1024);
- rotate_to = tracker_db_config_get_journal_rotate_destination (db_config);
-
- /* This call is needed to set the journal's filename */
-
- tracker_db_journal_set_rotating ((chunk_size_mb != -1),
- chunk_size, rotate_to);
-
-
- g_object_unref (db_config);
-
- /* Clean up (select_cache_size and update_cache_size don't matter here) */
- if (!tracker_db_manager_init (TRACKER_DB_MANAGER_REMOVE_ALL,
- NULL,
- FALSE,
- 100,
- 100,
- NULL,
- NULL,
- NULL)) {
- return EXIT_FAILURE;
- }
-
- tracker_db_journal_init (NULL, FALSE);
-
- tracker_db_manager_remove_all (hard_reset);
- tracker_db_manager_shutdown ();
- tracker_db_journal_shutdown ();
-
- /* Unset log handler */
- g_log_remove_handler (NULL, log_handler_id);
- }
-
- if (remove_config) {
- GMainLoop *main_loop;
- GFile *file;
- TrackerCrawler *crawler;
- const gchar *suffix = ".cfg";
- const gchar *home_conf_dir;
- gchar *path;
-
- crawler = tracker_crawler_new ();
- main_loop = g_main_loop_new (NULL, FALSE);
-
- g_signal_connect (crawler, "check-file",
- G_CALLBACK (crawler_check_file_cb),
- &suffix);
- g_signal_connect (crawler, "finished",
- G_CALLBACK (crawler_finished_cb),
- main_loop);
-
- /* Go through service files */
-
-
- /* Check the default XDG_DATA_HOME location */
- home_conf_dir = g_getenv ("XDG_CONFIG_HOME");
-
- if (home_conf_dir && tracker_path_has_write_access_or_was_created (home_conf_dir)) {
- path = g_build_path (G_DIR_SEPARATOR_S, home_conf_dir, "tracker", NULL);
- } else {
- home_conf_dir = g_getenv ("HOME");
-
- if (!home_conf_dir || !tracker_path_has_write_access_or_was_created (home_conf_dir)) {
- home_conf_dir = g_get_home_dir ();
- }
- path = g_build_path (G_DIR_SEPARATOR_S, home_conf_dir, ".config", "tracker", NULL);
- }
-
-
- file = g_file_new_for_path (path);
- g_free (path);
-
- g_print ("%s\n", _("Removing configuration filesâ?¦"));
-
- tracker_crawler_start (crawler, file, FALSE);
- g_object_unref (file);
-
- g_main_loop_run (main_loop);
- g_object_unref (crawler);
- }
-
- if (start) {
- TrackerMinerManager *manager;
- GSList *miners, *l;
-
- if (hard_reset || soft_reset) {
- g_print ("%s\n", _("Waiting one second before starting minersâ?¦"));
-
- /* Give a second's grace to avoid race conditions */
- g_usleep (G_USEC_PER_SEC);
- }
-
- g_print ("%s\n", _("Starting minersâ?¦"));
-
- manager = tracker_miner_manager_new ();
- miners = tracker_miner_manager_get_available (manager);
-
- /* Get the status of all miners, this will start all
- * miners not already running.
- */
-
- for (l = miners; l; l = l->next) {
- const gchar *display_name;
- gdouble progress = 0.0;
-
- display_name = tracker_miner_manager_get_display_name (manager, l->data);
-
- if (!tracker_miner_manager_get_status (manager, l->data, NULL, &progress)) {
- g_printerr (" â?? %s (%s)\n",
- display_name,
- _("perhaps a disabled plugin?"));
- } else {
- g_print (" â?? %s\n",
- display_name);
- }
-
- g_free (l->data);
- }
-
- g_slist_free (miners);
- g_object_unref (manager);
- }
-
- if (reindex_mime_types) {
- TrackerMinerManager *manager;
-
- manager = tracker_miner_manager_new ();
- tracker_miner_manager_reindex_by_mimetype (manager, (GStrv)reindex_mime_types, &error);
-
- if (error) {
- g_printerr ("%s: %s\n",
- _("Could not reindex mimetypes"),
- error->message);
- g_error_free (error);
- return EXIT_FAILURE;
- }
-
- g_print ("%s\n", _("Reindexing mime types was successful"));
-
- g_object_unref (manager);
- }
-
- if (index_file) {
- TrackerMinerManager *manager;
- GError *error = NULL;
- GFile *file;
-
- file = g_file_new_for_commandline_arg (index_file);
- manager = tracker_miner_manager_new ();
-
- tracker_miner_manager_index_file (manager, file, &error);
-
- if (error) {
- g_printerr ("%s: %s\n",
- _("Could not (re)index file"),
- error->message);
- g_error_free (error);
- return EXIT_FAILURE;
- }
-
- g_print ("%s\n", _("(Re)indexing file was successful"));
-
- g_object_unref (manager);
- g_object_unref (file);
- }
-
- if (pause_reason) {
- return miner_pause (miner_name, pause_reason);
- }
-
- if (resume_cookie != -1) {
- return miner_resume (miner_name, resume_cookie);
- }
-
- return EXIT_SUCCESS;
-}
-
-static int
-status_actions (void)
-{
- TrackerMinerManager *manager;
- GSList *miners_available;
- GSList *miners_running;
- GSList *l;
-
- /* --follow implies --status-details */
- if (follow) {
- status_details = TRUE;
- }
-
- manager = tracker_miner_manager_new ();
- miners_available = tracker_miner_manager_get_available (manager);
- miners_running = tracker_miner_manager_get_running (manager);
-
- if (list_common_statuses) {
- gint i;
-
- g_print ("%s:\n", _("Common statuses include"));
-
- for (i = 0; i < G_N_ELEMENTS(statuses); i++) {
- g_print (" %s\n", _(statuses[i]));
- }
-
- return EXIT_SUCCESS;
- }
-
- if (list_miners_available) {
- gchar *str;
-
- str = g_strdup_printf (_("Found %d miners installed"), g_slist_length (miners_available));
- g_print ("%s%s\n", str, g_slist_length (miners_available) > 0 ? ":" : "");
- g_free (str);
-
- for (l = miners_available; l; l = l->next) {
- g_print (" %s\n", (gchar*) l->data);
- }
- }
-
- if (list_miners_running) {
- gchar *str;
-
- str = g_strdup_printf (_("Found %d miners running"), g_slist_length (miners_running));
- g_print ("%s%s\n", str, g_slist_length (miners_running) > 0 ? ":" : "");
- g_free (str);
-
- for (l = miners_running; l; l = l->next) {
- g_print (" %s\n", (gchar*) l->data);
- }
- }
-
- if (list_miners_available || list_miners_running) {
- /* Don't list miners be request AND then anyway later */
- g_slist_foreach (miners_available, (GFunc) g_free, NULL);
- g_slist_free (miners_available);
-
- g_slist_foreach (miners_running, (GFunc) g_free, NULL);
- g_slist_free (miners_running);
-
- if (proxy) {
- g_object_unref (proxy);
- }
-
- return EXIT_SUCCESS;
- }
-
- if (pause_details) {
- gint paused_miners = 0;
-
- if (!miners_running) {
- g_print ("%s\n", _("No miners are running"));
-
- g_slist_foreach (miners_available, (GFunc) g_free, NULL);
- g_slist_free (miners_available);
-
- g_slist_foreach (miners_running, (GFunc) g_free, NULL);
- g_slist_free (miners_running);
-
- return EXIT_SUCCESS;
- }
-
- for (l = miners_running; l; l = l->next) {
- const gchar *name;
- GStrv pause_applications, pause_reasons;
- gint i;
-
- name = tracker_miner_manager_get_display_name (manager, l->data);
-
- if (!name) {
- g_critical ("Could not get name for '%s'", (gchar *) l->data);
- continue;
- }
-
- if (!miner_get_details (manager,
- l->data,
- NULL,
- NULL,
- &pause_applications,
- &pause_reasons)) {
- continue;
- }
-
- if (!(*pause_applications) || !(*pause_reasons)) {
- g_strfreev (pause_applications);
- g_strfreev (pause_reasons);
- continue;
- }
-
- paused_miners++;
- if (paused_miners == 1) {
- g_print ("%s:\n", _("Miners"));
- }
-
- g_print (" %s:\n", name);
-
- for (i = 0; pause_applications[i] != NULL; i++) {
- g_print (" %s: '%s', %s: '%s'\n",
- _("Application"),
- pause_applications[i],
- _("Reason"),
- pause_reasons[i]);
- }
-
- g_strfreev (pause_applications);
- g_strfreev (pause_reasons);
- }
-
- if (paused_miners < 1) {
- g_print ("%s\n", _("No miners are paused"));
- }
-
- g_slist_foreach (miners_available, (GFunc) g_free, NULL);
- g_slist_free (miners_available);
-
- g_slist_foreach (miners_running, (GFunc) g_free, NULL);
- g_slist_free (miners_running);
-
- return EXIT_SUCCESS;
- }
-
-
- if (status_details) {
- /* Work out lengths for output spacing */
- paused_length = strlen (_("PAUSED"));
-
- for (l = miners_available; l; l = l->next) {
- const gchar *name;
-
- name = tracker_miner_manager_get_display_name (manager, l->data);
- longest_miner_name_length = MAX (longest_miner_name_length, strlen (name));
- }
-
- /* Display states */
- g_print ("%s:\n", _("Store"));
- store_init ();
- store_get_and_print_state ();
-
- g_print ("\n");
-
- g_print ("%s:\n", _("Miners"));
-
- for (l = miners_available; l; l = l->next) {
- const gchar *name;
- gboolean is_running;
-
- name = tracker_miner_manager_get_display_name (manager, l->data);
-
- if (!name) {
- g_critical ("Could not get name for '%s'", (gchar *) l->data);
- continue;
- }
-
- is_running = tracker_string_in_gslist (l->data, miners_running);
-
- if (is_running) {
- GStrv pause_applications, pause_reasons;
- gchar *status = NULL;
- gdouble progress;
- gboolean is_paused;
-
- if (!miner_get_details (manager,
- l->data,
- &status,
- &progress,
- &pause_applications,
- &pause_reasons)) {
- continue;
- }
-
- is_paused = *pause_applications || *pause_reasons;
-
- miner_print_state (manager, l->data, status, progress, TRUE, is_paused);
-
- g_strfreev (pause_applications);
- g_strfreev (pause_reasons);
- g_free (status);
- } else {
- miner_print_state (manager, l->data, NULL, 0.0, FALSE, FALSE);
- }
- }
-
- g_slist_foreach (miners_available, (GFunc) g_free, NULL);
- g_slist_free (miners_available);
-
- g_slist_foreach (miners_running, (GFunc) g_free, NULL);
- g_slist_free (miners_running);
-
- if (!follow) {
- /* Do nothing further */
- if (proxy) {
- g_object_unref (proxy);
- }
- g_print ("\n");
- return EXIT_SUCCESS;
- }
-
- g_print ("Press Ctrl+C to end follow of Tracker state\n");
-
- g_signal_connect (manager, "miner-progress",
- G_CALLBACK (manager_miner_progress_cb), NULL);
- g_signal_connect (manager, "miner-paused",
- G_CALLBACK (manager_miner_paused_cb), NULL);
- g_signal_connect (manager, "miner-resumed",
- G_CALLBACK (manager_miner_resumed_cb), NULL);
-
- initialize_signal_handler ();
-
- miners_progress = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) miners_progress_destroy_notify);
- miners_status = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_free);
-
- main_loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (main_loop);
- g_main_loop_unref (main_loop);
-
- g_hash_table_unref (miners_progress);
- g_hash_table_unref (miners_status);
-
- if (proxy) {
- g_object_unref (proxy);
- }
-
- if (manager) {
- g_object_unref (manager);
- }
-
- return EXIT_SUCCESS;
- }
-
- /* All known options have their own exit points */
- g_warn_if_reached();
-
- return EXIT_FAILURE;
-}
-
int
main (int argc, char **argv)
{
GOptionContext *context;
- GOptionGroup *control_group;
- GOptionGroup *status_group;
setlocale (LC_ALL, "");
@@ -1405,22 +75,14 @@ main (int argc, char **argv)
/* Translators: this messagge will apper immediately after the */
/* usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE> */
context = g_option_context_new (_(" - Manage Tracker processes and data"));
- /* Control options */
- control_group = g_option_group_new ("control",
- _("Control options"),
- _("Show control options"),
- NULL,
- NULL);
- g_option_group_add_entries (control_group, control_entries);
- g_option_context_add_group (context, control_group);
- /* Status options */
- status_group = g_option_group_new ("status",
- _("Status options"),
- _("Show status options"),
- NULL,
- NULL);
- g_option_group_add_entries (status_group, status_entries);
- g_option_context_add_group (context, status_group);
+
+ /* Groups */
+ g_option_context_add_group (context,
+ tracker_control_general_get_option_group ());
+ g_option_context_add_group (context,
+ tracker_control_status_get_option_group ());
+ g_option_context_add_group (context,
+ tracker_control_miners_get_option_group ());
/* Common options */
g_option_context_add_main_entries (context, common_entries, NULL);
@@ -1432,22 +94,40 @@ main (int argc, char **argv)
return EXIT_SUCCESS;
}
- /* Run control actions? */
- if (CONTROL_OPTION_ENABLED ()) {
- if (STATUS_OPTION_ENABLED ()) {
+ /* General options? */
+ if (tracker_control_general_options_enabled ()) {
+ if (tracker_control_status_options_enabled ()) {
+ g_printerr ("%s\n",
+ _("General and Status options cannot be used together"));
+ return EXIT_FAILURE;
+ }
+
+ if (tracker_control_miners_options_enabled ()) {
+ g_printerr ("%s\n",
+ _("General and Miners options cannot be used together"));
+ return EXIT_FAILURE;
+ }
+
+ return tracker_control_general_run ();
+ }
+
+ /* Status options? */
+ if (tracker_control_status_options_enabled ()) {
+ if (tracker_control_miners_options_enabled ()) {
g_printerr ("%s\n",
- _("You can not use status and control arguments together"));
+ _("Status and Miners options cannot be used together"));
return EXIT_FAILURE;
}
- return control_actions ();
+ return tracker_control_status_run ();
}
- /* Run status actions? */
- if (STATUS_OPTION_ENABLED ()) {
- return status_actions ();
+ /* Miners options? */
+ if (tracker_control_miners_options_enabled ()) {
+ return tracker_control_miners_run ();
}
+
if (argc > 1) {
gint i = 1;
diff --git a/src/tracker-control/tracker-control.h b/src/tracker-control/tracker-control.h
new file mode 100644
index 0000000..dfa0333
--- /dev/null
+++ b/src/tracker-control/tracker-control.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010, Nokia <ivan frade nokia com>
+ *
+ * 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 the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <glib.h>
+
+#ifndef __TRACKER_CONTROL_H__
+#define __TRACKER_CONTROL_H__
+
+GOptionGroup *tracker_control_general_get_option_group (void);
+gint tracker_control_general_run (void);
+gboolean tracker_control_general_options_enabled (void);
+
+GOptionGroup *tracker_control_status_get_option_group (void);
+gint tracker_control_status_run (void);
+gboolean tracker_control_status_options_enabled (void);
+
+GOptionGroup *tracker_control_miners_get_option_group (void);
+gint tracker_control_miners_run (void);
+gboolean tracker_control_miners_options_enabled (void);
+
+
+#endif /* __TRACKER_CONTROL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]