static Status
register_client_callback (SmsConn    conn,
                          SmPointer  manager_data,
                          char      *previous_id)
{
        GsmXSMPClient *client = manager_data;
        gboolean       handled;
        char          *id;

        g_debug ("GsmXSMPClient: Client '%s' received RegisterClient(%s)",
                 client->priv->description,
                 previous_id ? previous_id : "NULL");


        /* There are three cases:
         * 1. id is NULL - we'll use a new one
         * 2. id is known - we'll use known one
         * 3. id is unknown - this is an error
         */
        id = g_strdup (previous_id);

        handled = FALSE;
        g_signal_emit (client, signals[REGISTER_REQUEST], 0, &id, &handled);
        if (! handled) {
                g_debug ("GsmXSMPClient:  RegisterClient not handled!");
                g_free (id);
                free (previous_id);
                g_assert_not_reached ();
                return FALSE;
        }

        if (IS_STRING_EMPTY (id)) {
                g_debug ("GsmXSMPClient:   rejected: invalid previous_id");
                free (previous_id);
                return FALSE;
        }

        g_object_set (client, "startup-id", id, NULL);

        set_description (client);

        g_debug ("GsmXSMPClient: Sending RegisterClientReply to '%s'", client->priv->description);

        SmsRegisterClientReply (conn, id);

        if (IS_STRING_EMPTY (previous_id)) {
                /* Send the initial SaveYourself. */
                g_debug ("GsmXSMPClient: Sending initial SaveYourself");
                SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False);
                client->priv->current_save_yourself = SmSaveLocal;
        }

        gsm_client_set_status (GSM_CLIENT (client), GSM_CLIENT_REGISTERED);

        g_free (id);
        free (previous_id);

        return TRUE;
}
Exemple #2
0
static void
create_manager (void)
{
        GsmStore *client_store;

        client_store = gsm_store_new ();
        manager = gsm_manager_new (client_store, failsafe);
        g_object_unref (client_store);

        g_unix_signal_add (SIGTERM, term_or_int_signal_cb, manager);
        g_unix_signal_add (SIGINT, term_or_int_signal_cb, manager);
        g_unix_signal_add (SIGUSR1, sigusr1_cb, manager);
        g_unix_signal_add (SIGUSR2, sigusr2_cb, manager);

        if (IS_STRING_EMPTY (session_name)) {
                session_name = _gsm_manager_get_default_session (manager);
        }

        if (!gsm_session_fill (manager, session_name)) {
                gsm_fail_whale_dialog_we_failed (FALSE, TRUE, NULL);
        }

        _gsm_manager_set_renderer (manager, gl_renderer);
        gsm_manager_start (manager);
}
/* This doesn't contain the required components, so we need to always
 * call append_required_apps() after a call to append_default_apps(). */
static void append_default_apps(GsmManager* manager, const char* default_session_key, char** autostart_dirs)
{
	gint i;
	gchar** default_apps;
	GSettings* settings;

	g_debug("main: *** Adding default apps");

	g_assert(default_session_key != NULL);
	g_assert(autostart_dirs != NULL);

	settings = g_settings_new (GSM_SCHEMA);
	default_apps = g_settings_get_strv (settings, default_session_key);
	g_object_unref(settings);

	for (i = 0; default_apps[i]; i++)
	{
		char* app_path;

		if (IS_STRING_EMPTY((char*) default_apps[i]))
		{
			continue;
		}

		app_path = gsm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs);

		if (app_path != NULL)
		{
			gsm_manager_add_autostart_app(manager, app_path, NULL);
			g_free(app_path);
		}
	}

	g_strfreev (default_apps);
}
static void
handle_end_session_response (GsmDBusClient *client,
                             DBusMessage   *message)
{
        const char     *sender;
        DBusMessage    *reply;
        DBusError       error;
        dbus_bool_t     is_ok;
        const char     *reason;

        dbus_error_init (&error);
        if (! dbus_message_get_args (message, &error,
                                     DBUS_TYPE_BOOLEAN, &is_ok,
                                     DBUS_TYPE_STRING, &reason,
                                     DBUS_TYPE_INVALID)) {
                if (dbus_error_is_set (&error)) {
                        g_warning ("Invalid method call: %s", error.message);
                        dbus_error_free (&error);
                }
                raise_error (client->priv->connection,
                             message,
                             DBUS_ERROR_FAILED,
                             "There is a syntax error in the invocation of the method EndSessionResponse");
                return;
        }

        g_debug ("GsmDBusClient: got EndSessionResponse is-ok:%d reason=%s", is_ok, reason);

        /* make sure it is from our client */
        sender = dbus_message_get_sender (message);
        if (sender == NULL
            || IS_STRING_EMPTY (client->priv->bus_name)
            || strcmp (sender, client->priv->bus_name) != 0) {

                raise_error (client->priv->connection,
                             message,
                             DBUS_ERROR_FAILED,
                             "Caller not recognized as the client");
                return;
        }

        reply = dbus_message_new_method_return (message);
        if (reply == NULL) {
                g_error ("No memory");
        }

        gsm_client_end_session_response (GSM_CLIENT (client),
                                         is_ok, FALSE, FALSE, reason);


        if (! dbus_connection_send (client->priv->connection, reply, NULL)) {
                g_error ("No memory");
        }

        dbus_message_unref (reply);
}
Exemple #5
0
static gboolean
inhibitor_has_bus_name (gpointer          key,
                        GsmInhibitor     *inhibitor,
                        RemoveClientData *data)
{
    gboolean    matches;
    const char *bus_name_b;

    bus_name_b = gsm_inhibitor_peek_bus_name (inhibitor);

    matches = FALSE;
    if (! IS_STRING_EMPTY (data->service_name) && ! IS_STRING_EMPTY (bus_name_b)) {
        matches = (strcmp (data->service_name, bus_name_b) == 0);
        if (matches) {
            g_debug ("GsmManager: removing inhibitor from %s for reason '%s' on connection %s",
                     gsm_inhibitor_peek_app_id (inhibitor),
                     gsm_inhibitor_peek_reason (inhibitor),
                     gsm_inhibitor_peek_bus_name (inhibitor));
        }
    }

    return matches;
}
gboolean
csm_inhibitor_get_client_id (CsmInhibitor *inhibitor,
                             char        **id,
                             GError      **error)
{
        g_return_val_if_fail (CSM_IS_INHIBITOR (inhibitor), FALSE);

        /* object paths are not allowed to be NULL or blank */
        if (IS_STRING_EMPTY (inhibitor->priv->client_id)) {
                g_set_error (error,
                             CSM_INHIBITOR_ERROR,
                             CSM_INHIBITOR_ERROR_NOT_SET,
                             "Value is not set");
                return FALSE;
        }

        *id = g_strdup (inhibitor->priv->client_id);

        g_debug ("CsmInhibitor: getting client-id = '%s'", *id);

        return TRUE;
}
Exemple #7
0
static GKeyFile *
get_session_keyfile (const char *session,
                     char      **actual_session,
                     gboolean   *is_fallback)
{
        GKeyFile *keyfile;
        gboolean  session_runnable;
        char     *value;
        GError *error = NULL;

        *actual_session = NULL;

        g_debug ("fill: *** Getting session '%s'", session);

        keyfile = find_valid_session_keyfile (session);

        if (!keyfile)
                return NULL;

        session_runnable = TRUE;

        value = g_key_file_get_string (keyfile,
                                       GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_RUNNABLE_KEY,
                                       NULL);
        if (!IS_STRING_EMPTY (value)) {
                g_debug ("fill: *** Launching helper '%s' to know if session is runnable", value);
                session_runnable = gsm_process_helper (value, GSM_RUNNABLE_HELPER_TIMEOUT, &error);
                if (!session_runnable) {
                        g_warning ("Session '%s' runnable check failed: %s", session,
                                   error->message);
                        g_clear_error (&error);
                }
        }
        g_free (value);

        if (session_runnable) {
                session_runnable = check_required (keyfile);
        }

        if (session_runnable) {
                *actual_session = g_strdup (session);
                if (is_fallback)
                        *is_fallback = FALSE;
                return keyfile;
        }

        g_debug ("fill: *** Session is not runnable");

        /* We can't run this session, so try to use the fallback */
        value = g_key_file_get_string (keyfile,
                                       GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_FALLBACK_KEY,
                                       NULL);

        g_key_file_free (keyfile);
        keyfile = NULL;

        if (!IS_STRING_EMPTY (value)) {
                if (is_fallback)
                        *is_fallback = TRUE;
                keyfile = get_session_keyfile (value, actual_session, NULL);
        }
        g_free (value);

        return keyfile;
}
Exemple #8
0
gboolean
gsm_manager_inhibit (GsmManager            *manager,
                     const char            *app_id,
                     guint                  toplevel_xid,
                     const char            *reason,
                     guint                  flags,
                     DBusGMethodInvocation *context)
{
    GsmInhibitor *inhibitor;
    guint         cookie;

    g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);

    g_debug ("GsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u",
             toplevel_xid,
             app_id,
             reason,
             flags);

    if (IS_STRING_EMPTY (app_id)) {
        GError *new_error;

        new_error = g_error_new (GSM_MANAGER_ERROR,
                                 GSM_MANAGER_ERROR_GENERAL,
                                 "Application ID not specified");
        g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
        dbus_g_method_return_error (context, new_error);
        g_error_free (new_error);
        return FALSE;
    }

    if (IS_STRING_EMPTY (reason)) {
        GError *new_error;

        new_error = g_error_new (GSM_MANAGER_ERROR,
                                 GSM_MANAGER_ERROR_GENERAL,
                                 "Reason not specified");
        g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
        dbus_g_method_return_error (context, new_error);
        g_error_free (new_error);
        return FALSE;
    }

    if (flags == 0) {
        GError *new_error;

        new_error = g_error_new (GSM_MANAGER_ERROR,
                                 GSM_MANAGER_ERROR_GENERAL,
                                 "Invalid inhibit flags");
        g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
        dbus_g_method_return_error (context, new_error);
        g_error_free (new_error);
        return FALSE;
    }

    cookie = _generate_unique_cookie (manager);
    inhibitor = gsm_inhibitor_new (app_id,
                                   toplevel_xid,
                                   flags,
                                   reason,
                                   dbus_g_method_get_sender (context),
                                   cookie);
    gsm_store_add (manager->priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor));
    g_object_unref (inhibitor);

    dbus_g_method_return (context, cookie);

    return TRUE;
}
int
main (int argc, char **argv)
{
        struct sigaction  sa;
        GError           *error;
        char             *display_str;
        CsmManager       *manager;
        CsmStore         *client_store;
        MdmSignalHandler *signal_handler;
        static char     **override_autostart_dirs = NULL;
        static char      *session_name = NULL;
        static GOptionEntry entries[] = {
                { "autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories"), N_("AUTOSTART_DIR") },
                { "session", 0, 0, G_OPTION_ARG_STRING, &session_name, N_("Session to use"), N_("SESSION_NAME") },
                { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL },
                { "failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications"), NULL },
                { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL },
                /* Translators: the 'fail whale' is the black dialog we show when something goes seriously wrong */
                { "whale", 0, 0, G_OPTION_ARG_NONE, &please_fail, N_("Show the fail whale dialog for testing"), NULL },
                { NULL, 0, 0, 0, NULL, NULL, NULL }
        };

        /* Make sure that we have a session bus */
        if (!require_dbus_session (argc, argv, &error)) {
                csm_util_init_error (TRUE, "%s", error->message);
        }

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

        GSettings *settings = g_settings_new ("org.cinnamon.SessionManager");
        if (g_settings_get_boolean (settings, "debug")) {
            debug = TRUE;
        }
        g_object_unref(settings);

        sa.sa_handler = SIG_IGN;
        sa.sa_flags = 0;
        sigemptyset (&sa.sa_mask);
        sigaction (SIGPIPE, &sa, 0);

        error = NULL;
        gtk_init_with_args (&argc, &argv,
                            (char *) _(" - the Cinnamon session manager"),
                            entries, GETTEXT_PACKAGE,
                            &error);
        if (error != NULL) {
                g_warning ("%s", error->message);
                exit (1);
        }

        if (show_version) {
                g_print ("%s %s\n", argv [0], VERSION);
                exit (1);
        }

        if (please_fail) {
                csm_fail_whale_dialog_we_failed (TRUE, TRUE);
                gtk_main ();
                exit (1);
        }

        mdm_log_init ();
        mdm_log_set_debug (debug);

        /* Set DISPLAY explicitly for all our children, in case --display
         * was specified on the command line.
         */
        display_str = gdk_get_display ();
        csm_util_setenv ("DISPLAY", display_str);
        g_free (display_str);

        const gchar *gtk_modules;
        gchar *new_gtk_modules = NULL;

        gtk_modules = g_getenv ("GTK_MODULES");

        if (gtk_modules != NULL && g_strstr_len (gtk_modules, -1, "overlay-scrollbar")) {
            int i = 0;
            new_gtk_modules = g_strconcat ("", NULL);

            gchar **module_list = g_strsplit (gtk_modules, ":", -1);

            for (i = 0; i < g_strv_length (module_list); i++) {
                if (!g_strstr_len (module_list[i], -1, "overlay-scrollbar")) {
                    gchar *tmp = new_gtk_modules;
                    new_gtk_modules = g_strconcat (tmp, ":", module_list[i], NULL);
                    g_free (tmp);
                }
            }

            g_strfreev (module_list);
        }

        if (new_gtk_modules) {
            csm_util_setenv ("GTK_MODULES", new_gtk_modules);
        }

        g_free (new_gtk_modules);

        /* Some third-party programs rely on GNOME_DESKTOP_SESSION_ID to
         * detect if GNOME is running. We keep this for compatibility reasons.
         */
        csm_util_setenv ("GNOME_DESKTOP_SESSION_ID", "this-is-deprecated");

        /* Make QT5 apps follow the GTK style */
        csm_util_setenv ("QT_STYLE_OVERRIDE", "gtk");

        client_store = csm_store_new ();

        /* Talk to logind before acquiring a name, since it does synchronous
         * calls at initialization time that invoke a main loop and if we
         * already owned a name, then we would service too early during
         * that main loop.
         */
        g_object_unref (csm_get_system ());

        if (!acquire_name ()) {
                csm_fail_whale_dialog_we_failed (TRUE, TRUE);
                gtk_main ();
                exit (1);
        }

        manager = csm_manager_new (client_store, failsafe);
        /*
        signal_handler = mdm_signal_handler_new ();
        mdm_signal_handler_add_fatal (signal_handler);
        mdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL);
        mdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL);
        mdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL);
        mdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, manager);
        mdm_signal_handler_add (signal_handler, SIGINT, signal_cb, manager);
        mdm_signal_handler_set_fatal_func (signal_handler, shutdown_cb, manager);
        */
        if (IS_STRING_EMPTY (session_name))
                session_name = _csm_manager_get_default_session (manager);

        csm_util_set_autostart_dirs (override_autostart_dirs);

        if (!csm_session_fill (manager, session_name)) {
                csm_util_init_error (TRUE, "Failed to load session \"%s\"", session_name ? session_name : "(null)");
        }

        csm_manager_start (manager);

        gtk_main ();

        if (manager != NULL) {
                g_debug ("Unreffing manager");
                g_object_unref (manager);
        }

        if (client_store != NULL) {
                g_object_unref (client_store);
        }

        if (bus_proxy != NULL) {
                g_object_unref (bus_proxy);
        }

        mdm_log_shutdown ();

        return 0;
}
static void append_required_apps(GsmManager* manager)
{
	gchar** required_components;
	gint i;
	GSettings* settings;
	GSettings* settings_required_components;

	g_debug("main: *** Adding required apps");

	settings = g_settings_new (GSM_SCHEMA);
	settings_required_components = g_settings_new (GSM_REQUIRED_COMPONENTS_SCHEMA);

	required_components = g_settings_get_strv(settings, GSM_REQUIRED_COMPONENTS_LIST_KEY);

	if (required_components == NULL)
	{
		g_warning("No required applications specified");
	}

	for (i = 0; required_components[i]; i++)
	{
			char* default_provider;
			const char* component;

			if (IS_STRING_EMPTY((char*) required_components[i]))
			{
					continue;
			}

			component = required_components[i];

			default_provider = g_settings_get_string (settings_required_components, component);

			g_debug ("main: %s looking for component: '%s'", component, default_provider);

			if (default_provider != NULL)
			{
				char* app_path;

				app_path = gsm_util_find_desktop_file_for_app_name(default_provider, NULL);

				if (app_path != NULL)
				{
					gsm_manager_add_autostart_app(manager, app_path, component);
				}
				else
				{
					g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component);
				}

				g_free(app_path);
			}

			g_free(default_provider);
	}

	g_debug("main: *** Done adding required apps");

	g_strfreev(required_components);

	g_object_unref(settings);
	g_object_unref(settings_required_components);
}