/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * save-session.c - Small program to talk to session manager. Copyright (C) 1998 Tom Tromey Copyright (C) 2008 Red Hat, Inc. 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, 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, see . */ #include #include #include #include #include #include #include #include #include #define GSM_SERVICE_DBUS "org.gnome.SessionManager" #define GSM_PATH_DBUS "/org/gnome/SessionManager" #define GSM_INTERFACE_DBUS "org.gnome.SessionManager" enum { GSM_LOGOUT_MODE_NORMAL = 0, GSM_LOGOUT_MODE_NO_CONFIRMATION, GSM_LOGOUT_MODE_FORCE }; static gboolean opt_logout = FALSE; static gboolean opt_power_off = FALSE; static gboolean opt_reboot = FALSE; static gboolean opt_no_prompt = FALSE; static gboolean opt_force = FALSE; static GOptionEntry options[] = { {"logout", '\0', 0, G_OPTION_ARG_NONE, &opt_logout, N_("Log out"), NULL}, {"power-off", '\0', 0, G_OPTION_ARG_NONE, &opt_power_off, N_("Power off"), NULL}, {"reboot", '\0', 0, G_OPTION_ARG_NONE, &opt_reboot, N_("Reboot"), NULL}, {"force", '\0', 0, G_OPTION_ARG_NONE, &opt_force, N_("Ignoring any existing inhibitors"), NULL}, {"no-prompt", '\0', 0, G_OPTION_ARG_NONE, &opt_no_prompt, N_("Don’t prompt for user confirmation"), NULL}, {NULL} }; static void display_error (const char *message) { g_printerr ("%s\n", message); } static GDBusConnection * get_session_bus (void) { GDBusConnection *bus; GError *error = NULL; bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); if (bus == NULL) { g_warning ("Couldn't connect to session bus: %s", error->message); g_error_free (error); } return bus; } static GDBusProxy * get_sm_proxy (void) { GDBusConnection *connection; GDBusProxy *sm_proxy; connection = get_session_bus (); if (connection == NULL) { display_error (_("Could not connect to the session manager")); return NULL; } sm_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL, GSM_SERVICE_DBUS, GSM_PATH_DBUS, GSM_INTERFACE_DBUS, NULL, NULL); g_object_unref (connection); if (sm_proxy == NULL) { display_error (_("Could not connect to the session manager")); return NULL; } return sm_proxy; } static void do_logout (unsigned int mode) { GDBusProxy *sm_proxy; GVariant *reply; GError *error; sm_proxy = get_sm_proxy (); if (sm_proxy == NULL) { return; } error = NULL; reply = g_dbus_proxy_call_sync (sm_proxy, "Logout", g_variant_new ("(u)", mode), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_warning ("Failed to call logout: %s", error->message); g_error_free (error); } else { g_variant_unref (reply); } g_clear_object (&sm_proxy); } static void do_power_off (const char *action) { GDBusProxy *sm_proxy; GVariant *reply; GError *error; sm_proxy = get_sm_proxy (); if (sm_proxy == NULL) { return; } error = NULL; reply = g_dbus_proxy_call_sync (sm_proxy, action, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error != NULL) { g_warning ("Failed to call %s: %s", action, error->message); g_error_free (error); } else { g_variant_unref (reply); } g_clear_object (&sm_proxy); } int main (int argc, char *argv[]) { GError *error; int conflicting_options; GOptionContext *ctx; /* Initialize the i18n stuff */ setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); error = NULL; ctx = g_option_context_new (""); g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE); if (! g_option_context_parse (ctx, &argc, &argv, &error)) { g_warning ("Unable to start: %s", error->message); g_error_free (error); exit (1); } g_option_context_free (ctx); conflicting_options = 0; if (opt_logout) conflicting_options++; if (opt_power_off) conflicting_options++; if (opt_reboot) conflicting_options++; if (conflicting_options > 1) display_error (_("Program called with conflicting options")); if (opt_power_off) { do_power_off ("Shutdown"); } else if (opt_reboot) { do_power_off ("Reboot"); } else { /* default to logout */ if (opt_force) do_logout (GSM_LOGOUT_MODE_FORCE); else if (opt_no_prompt) do_logout (GSM_LOGOUT_MODE_NO_CONFIRMATION); else do_logout (GSM_LOGOUT_MODE_NORMAL); } return 0; }