From dea7b930918892e2140eeaba37deacfbe089239c Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" Date: Fri, 16 Feb 2024 17:31:37 +0000 Subject: Deploy mate-desktop/mate-session-manager to github.com/mate-desktop/mate-session-manager.git:gh-pages --- .../index.html | 173 + .../report-0bc662.html | 780 ++++ .../report-156f0d.html | 967 ++++ .../report-16cb4d.html | 967 ++++ .../report-1f1edf.html | 1756 +++++++ .../report-1f463e.html | 967 ++++ .../report-27b446.html | 1314 ++++++ .../report-37d955.html | 1217 +++++ .../report-3d2264.html | 1525 ++++++ .../report-4cf1eb.html | 967 ++++ .../report-5ded7d.html | 967 ++++ .../report-615882.html | 1217 +++++ .../report-7c304e.html | 1309 ++++++ .../report-836628.html | 1229 +++++ .../report-88d32f.html | 1197 +++++ .../report-a80670.html | 4937 ++++++++++++++++++++ .../report-abdc03.html | 1486 ++++++ .../report-b8f564.html | 2089 +++++++++ .../report-bd4e55.html | 1197 +++++ .../report-cd0613.html | 967 ++++ .../report-cf3974.html | 2089 +++++++++ .../report-d9bc25.html | 967 ++++ .../report-e4efad.html | 1197 +++++ .../report-f05804.html | 915 ++++ .../report-f291f4.html | 1477 ++++++ .../report-fc5e64.html | 4937 ++++++++++++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 ++ 28 files changed, 39364 insertions(+) create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/index.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-0bc662.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-156f0d.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-16cb4d.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f1edf.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f463e.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-27b446.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-37d955.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-3d2264.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-4cf1eb.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-5ded7d.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-615882.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-7c304e.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-836628.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-88d32f.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-a80670.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-abdc03.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-b8f564.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-bd4e55.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-cd0613.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-cf3974.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-d9bc25.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-e4efad.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-f05804.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-f291f4.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/report-fc5e64.html create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/scanview.css create mode 100644 2023-09-04-022211-5825-1@c70944f84e08_revert/sorttable.js (limited to '2023-09-04-022211-5825-1@c70944f84e08_revert') diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/index.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/index.html new file mode 100644 index 0000000..f4453fb --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/index.html @@ -0,0 +1,173 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@4ecbf50346e8
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 16.0.6 (Fedora 16.0.6-2.fc38) +
Date:Mon Sep 4 02:22:11 2023
+

Bug Summary

+ + + + + + + + + + + +
Bug TypeQuantityDisplay?
All Bugs25
Logic error
Cast from non-struct type to struct type2
Dereference of undefined pointer value1
Out-of-bound access1
Uninitialized argument value1
Use fixed address1
Unused code
Dead assignment5
Unreachable code14
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typemate-submodules/libegg/eggsmclient-xsmp.carray_prop11991View Report
Logic errorCast from non-struct type to struct typemate-submodules/libegg/eggsmclient-xsmp.cptrarray_prop12321View Report
Unused codeDead assignmentmate-session/gsm-consolekit.cget_current_seat_id6751View Report
Unused codeDead assignmentmate-session/gsm-logout-dialog.cgsm_logout_supports_system_suspend1971View Report
Unused codeDead assignmentmate-session/gsm-logout-dialog.cgsm_logout_supports_system_hibernate2111View Report
Unused codeDead assignmentmate-session/main.csignal_cb4411View Report
Unused codeDead assignmentmate-session/gsm-manager.cmaybe_restart_user_bus9191View Report
Logic errorDereference of undefined pointer valuecapplet/gsm-app-dialog.cgsm_app_dialog_run57610View Report
Logic errorOut-of-bound accessmate-session/main.crequire_dbus_session52115View Report
Logic errorUninitialized argument valuecapplet/gsm-app-dialog.cgsm_app_dialog_run58312View Report
Unused codeUnreachable codecapplet/main.cmain891View Report
Unused codeUnreachable codetools/mate-session-save.cmain2751View Report
Unused codeUnreachable codetools/mate-session-save.cmain2291View Report
Unused codeUnreachable codetools/mate-session-save.cmain2541View Report
Unused codeUnreachable codetools/mate-session-save.cmain2591View Report
Unused codeUnreachable codetools/mate-session-save.cmain2791View Report
Unused codeUnreachable codemate-session/mdm-signal-handler.csignal_handler2791View Report
Unused codeUnreachable codetools/mate-session-check-accelerated-gl-helper.cmain5051View Report
Unused codeUnreachable codemate-session/gsm-manager.cgsm_manager_new29321View Report
Unused codeUnreachable codetools/mate-session-check-accelerated-gl-helper.cmain4621View Report
Unused codeUnreachable codetools/mate-session-save.cmain2831View Report
Unused codeUnreachable codetools/mate-session-save.cmain2711View Report
Unused codeUnreachable codetools/mate-session-check-accelerated-gl-helper.cmain5081View Report
Unused codeUnreachable codetools/mate-session-check-accelerated-gles-helper.cmain2231View Report
Logic errorUse fixed addressmate-session/main.cmain6313View Report
+ + diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-0bc662.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-0bc662.html new file mode 100644 index 0000000..6fa64f6 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-0bc662.html @@ -0,0 +1,780 @@ + + + +main.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:capplet/main.c
Warning:line 89, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/capplet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-session -D LOCALE_DIR="/usr/local/share/locale" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/capplet -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c main.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * main.c
3 * Copyright (C) 1999 Free Software Foundation, Inc.
4 * Copyright (C) 2008 Lucas Rocha.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23#include <config.h>
24
25#include <unistd.h>
26#include <stdlib.h>
27
28#include <glib/gi18n.h>
29#include <gtk/gtk.h>
30
31#include "gsm-properties-dialog.h"
32
33static gboolean show_version = FALSE(0);
34
35static GOptionEntry options[] = {
36 {"version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application")("Version of this application"), NULL((void*)0)},
37 {NULL((void*)0), 0, 0, 0, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
38};
39
40static void dialog_response(GsmPropertiesDialog* dialog, guint response_id, gpointer data)
41{
42 GError* error;
43
44 if (response_id == GTK_RESPONSE_HELP)
45 {
46 error = NULL((void*)0);
47 gtk_show_uri_on_window (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, "help:mate-user-guide/gosstartsession-2",
48 gtk_get_current_event_time (), &error);
49
50 if (error != NULL((void*)0))
51 {
52 GtkWidget* d = gtk_message_dialog_new(GTK_WINDOW(dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _("Could not display help document")gettext ("Could not display help document"));
53 gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(d)((((GtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((d)), ((gtk_message_dialog_get_type ()))))))
, "%s", error->message);
54 g_error_free(error);
55
56 gtk_dialog_run(GTK_DIALOG (d)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((d)), ((gtk_dialog_get_type ()))))))
);
57 gtk_widget_destroy(d);
58 }
59 }
60 else
61 {
62 gtk_widget_destroy(GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
);
63 gtk_main_quit();
64 }
65}
66
67int main(int argc, char* argv[])
68{
69 GError* error;
70 GtkWidget* dialog;
71
72#ifdef ENABLE_NLS1
73 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
74 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
75 textdomain(GETTEXT_PACKAGE"mate-session-manager");
76#endif /* ENABLE_NLS */
77
78 error = NULL((void*)0);
79
80 if (!gtk_init_with_args(&argc, &argv, _("- MATE Session Properties")gettext ("- MATE Session Properties"), options, GETTEXT_PACKAGE"mate-session-manager", &error))
81 {
82 g_warning("Unable to start: %s", error->message);
83 g_error_free(error);
84 return 1;
85 }
86
87 if (show_version)
88 {
89 g_print("%s %s\n", argv[0], VERSION"1.27.0");
This statement is never executed
90 return 0;
91 }
92
93 dialog = gsm_properties_dialog_new();
94 g_signal_connect(dialog, "response", G_CALLBACK(dialog_response), NULL)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
dialog_response))), (((void*)0)), ((void*)0), (GConnectFlags)
0)
;
95 gtk_widget_show(dialog);
96
97 gtk_main();
98
99 return 0;
100}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-156f0d.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-156f0d.html new file mode 100644 index 0000000..805e3ab --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-156f0d.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 275, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
This statement is never executed
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-16cb4d.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-16cb4d.html new file mode 100644 index 0000000..c3e5c67 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-16cb4d.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 229, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
This statement is never executed
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f1edf.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f1edf.html new file mode 100644 index 0000000..d5ec90f --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f1edf.html @@ -0,0 +1,1756 @@ + + + +gsm-consolekit.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/gsm-consolekit.c
Warning:line 675, column 17
Value stored to 'res' is never read
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-consolekit.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-consolekit.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2008 Jon McCann <jmccann@redhat.com>
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301, USA.
20 */
21
22#include "config.h"
23
24#include <errno(*__errno_location ()).h>
25#include <string.h>
26#include <unistd.h>
27
28#include <glib.h>
29#include <glib-object.h>
30#include <glib/gi18n.h>
31
32#include <dbus/dbus-glib.h>
33#include <dbus/dbus-glib-lowlevel.h>
34
35#include "gsm-marshal.h"
36#include "gsm-consolekit.h"
37
38#define CK_NAME"org.freedesktop.ConsoleKit" "org.freedesktop.ConsoleKit"
39#define CK_PATH"/org/freedesktop/ConsoleKit" "/org/freedesktop/ConsoleKit"
40#define CK_INTERFACE"org.freedesktop.ConsoleKit" "org.freedesktop.ConsoleKit"
41
42#define CK_MANAGER_PATH"/org/freedesktop/ConsoleKit/Manager" "/org/freedesktop/ConsoleKit/Manager"
43#define CK_MANAGER_INTERFACE"org.freedesktop.ConsoleKit.Manager" "org.freedesktop.ConsoleKit.Manager"
44#define CK_SEAT_INTERFACE"org.freedesktop.ConsoleKit.Seat" "org.freedesktop.ConsoleKit.Seat"
45#define CK_SESSION_INTERFACE"org.freedesktop.ConsoleKit.Session" "org.freedesktop.ConsoleKit.Session"
46
47typedef struct
48{
49 DBusGConnection *dbus_connection;
50 DBusGProxy *bus_proxy;
51 DBusGProxy *ck_proxy;
52 guint32 is_connected : 1;
53} GsmConsolekitPrivate;
54
55enum {
56 PROP_0,
57 PROP_IS_CONNECTED
58};
59
60enum {
61 REQUEST_COMPLETED = 0,
62 PRIVILEGES_COMPLETED,
63 LAST_SIGNAL
64};
65
66static guint signals[LAST_SIGNAL] = { 0 };
67
68static void gsm_consolekit_finalize (GObject *object);
69
70static void gsm_consolekit_free_dbus (GsmConsolekit *manager);
71
72static DBusHandlerResult gsm_consolekit_dbus_filter (DBusConnection *connection,
73 DBusMessage *message,
74 void *user_data);
75
76static void gsm_consolekit_on_name_owner_changed (DBusGProxy *bus_proxy,
77 const char *name,
78 const char *prev_owner,
79 const char *new_owner,
80 GsmConsolekit *manager);
81
82G_DEFINE_TYPE_WITH_PRIVATE (GsmConsolekit, gsm_consolekit, G_TYPE_OBJECT)static void gsm_consolekit_init (GsmConsolekit *self); static
void gsm_consolekit_class_init (GsmConsolekitClass *klass); static
GType gsm_consolekit_get_type_once (void); static gpointer gsm_consolekit_parent_class
= ((void*)0); static gint GsmConsolekit_private_offset; static
void gsm_consolekit_class_intern_init (gpointer klass) { gsm_consolekit_parent_class
= g_type_class_peek_parent (klass); if (GsmConsolekit_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &GsmConsolekit_private_offset
); gsm_consolekit_class_init ((GsmConsolekitClass*) klass); }
__attribute__ ((__unused__)) static inline gpointer gsm_consolekit_get_instance_private
(GsmConsolekit *self) { return (((gpointer) ((guint8*) (self
) + (glong) (GsmConsolekit_private_offset)))); } GType gsm_consolekit_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_consolekit_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_consolekit_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("GsmConsolekit"
), sizeof (GsmConsolekitClass), (GClassInitFunc)(void (*)(void
)) gsm_consolekit_class_intern_init, sizeof (GsmConsolekit), (
GInstanceInitFunc)(void (*)(void)) gsm_consolekit_init, (GTypeFlags
) 0); { {{ GsmConsolekit_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (GsmConsolekitPrivate)); };} } return
g_define_type_id; }
;
83
84static void
85gsm_consolekit_get_property (GObject *object,
86 guint prop_id,
87 GValue *value,
88 GParamSpec *pspec)
89{
90 GsmConsolekit *manager = GSM_CONSOLEKIT (object);
91 GsmConsolekitPrivate *priv;
92
93 priv = gsm_consolekit_get_instance_private (manager);
94
95 switch (prop_id) {
96 case PROP_IS_CONNECTED:
97 g_value_set_boolean (value,
98 priv->is_connected);
99 break;
100
101 default:
102 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-consolekit.c", 104, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
103 prop_id,do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-consolekit.c", 104, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
104 pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-consolekit.c", 104, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
105 }
106}
107
108static void
109gsm_consolekit_class_init (GsmConsolekitClass *manager_class)
110{
111 GObjectClass *object_class;
112 GParamSpec *param_spec;
113
114 object_class = G_OBJECT_CLASS (manager_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((manager_class)), (((GType) ((20) << (2))))))))
;
115
116 object_class->finalize = gsm_consolekit_finalize;
117 object_class->get_property = gsm_consolekit_get_property;
118
119 param_spec = g_param_spec_boolean ("is-connected",
120 "Is connected",
121 "Whether the session is connected to ConsoleKit",
122 FALSE(0),
123 G_PARAM_READABLE);
124
125 g_object_class_install_property (object_class, PROP_IS_CONNECTED,
126 param_spec);
127
128 signals [REQUEST_COMPLETED] =
129 g_signal_new ("request-completed",
130 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
131 G_SIGNAL_RUN_LAST,
132 G_STRUCT_OFFSET (GsmConsolekitClass, request_completed)((glong) __builtin_offsetof(GsmConsolekitClass, request_completed
))
,
133 NULL((void*)0),
134 NULL((void*)0),
135 g_cclosure_marshal_VOID__POINTER,
136 G_TYPE_NONE((GType) ((1) << (2))),
137 1, G_TYPE_POINTER((GType) ((17) << (2))));
138
139 signals [PRIVILEGES_COMPLETED] =
140 g_signal_new ("privileges-completed",
141 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
142 G_SIGNAL_RUN_LAST,
143 G_STRUCT_OFFSET (GsmConsolekitClass, privileges_completed)((glong) __builtin_offsetof(GsmConsolekitClass, privileges_completed
))
,
144 NULL((void*)0),
145 NULL((void*)0),
146 gsm_marshal_VOID__BOOLEAN_BOOLEAN_POINTER,
147 G_TYPE_NONE((GType) ((1) << (2))),
148 3, G_TYPE_BOOLEAN((GType) ((5) << (2))), G_TYPE_BOOLEAN((GType) ((5) << (2))), G_TYPE_POINTER((GType) ((17) << (2))));
149
150}
151
152static DBusHandlerResult
153gsm_consolekit_dbus_filter (DBusConnection *connection,
154 DBusMessage *message,
155 void *user_data)
156{
157 GsmConsolekit *manager;
158
159 manager = GSM_CONSOLEKIT (user_data);
160
161 if (dbus_message_is_signal (message,
162 DBUS_INTERFACE_LOCAL"org.freedesktop.DBus.Local", "Disconnected") &&
163 strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL"/org/freedesktop/DBus/Local") == 0) {
164 gsm_consolekit_free_dbus (manager);
165 /* let other filters get this disconnected signal, so that they
166 * can handle it too */
167 }
168
169 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
170}
171
172static gboolean
173gsm_consolekit_ensure_ck_connection (GsmConsolekit *manager,
174 GError **error)
175{
176 GError *connection_error;
177 gboolean is_connected;
178 GsmConsolekitPrivate *priv;
179
180 connection_error = NULL((void*)0);
181 priv = gsm_consolekit_get_instance_private (manager);
182
183 if (priv->dbus_connection == NULL((void*)0)) {
184 DBusConnection *connection;
185
186 priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
187 &connection_error);
188
189 if (priv->dbus_connection == NULL((void*)0)) {
190 g_propagate_error (error, connection_error);
191 is_connected = FALSE(0);
192 goto out;
193 }
194
195 connection = dbus_g_connection_get_connection (priv->dbus_connection);
196 dbus_connection_set_exit_on_disconnect (connection, FALSE(0));
197 dbus_connection_add_filter (connection,
198 gsm_consolekit_dbus_filter,
199 manager, NULL((void*)0));
200 }
201
202 if (priv->bus_proxy == NULL((void*)0)) {
203 priv->bus_proxy =
204 dbus_g_proxy_new_for_name_owner (priv->dbus_connection,
205 DBUS_SERVICE_DBUS"org.freedesktop.DBus",
206 DBUS_PATH_DBUS"/org/freedesktop/DBus",
207 DBUS_INTERFACE_DBUS"org.freedesktop.DBus",
208 &connection_error);
209
210 if (priv->bus_proxy == NULL((void*)0)) {
211 g_propagate_error (error, connection_error);
212 is_connected = FALSE(0);
213 goto out;
214 }
215
216 dbus_g_proxy_add_signal (priv->bus_proxy,
217 "NameOwnerChanged",
218 G_TYPE_STRING((GType) ((16) << (2))),
219 G_TYPE_STRING((GType) ((16) << (2))),
220 G_TYPE_STRING((GType) ((16) << (2))),
221 G_TYPE_INVALID((GType) ((0) << (2))));
222
223 dbus_g_proxy_connect_signal (priv->bus_proxy,
224 "NameOwnerChanged",
225 G_CALLBACK (gsm_consolekit_on_name_owner_changed)((GCallback) (gsm_consolekit_on_name_owner_changed)),
226 manager, NULL((void*)0));
227 }
228
229 if (priv->ck_proxy == NULL((void*)0)) {
230 priv->ck_proxy =
231 dbus_g_proxy_new_for_name_owner (priv->dbus_connection,
232 "org.freedesktop.ConsoleKit",
233 "/org/freedesktop/ConsoleKit/Manager",
234 "org.freedesktop.ConsoleKit.Manager",
235 &connection_error);
236
237 if (priv->ck_proxy == NULL((void*)0)) {
238 g_propagate_error (error, connection_error);
239 is_connected = FALSE(0);
240 goto out;
241 }
242 }
243
244 is_connected = TRUE(!(0));
245
246out:
247 if (priv->is_connected != is_connected) {
248 priv->is_connected = (is_connected != FALSE(0));
249 g_object_notify (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
, "is-connected");
250 }
251
252 if (!is_connected) {
253 if (priv->dbus_connection == NULL((void*)0)) {
254 if (priv->bus_proxy != NULL((void*)0)) {
255 g_object_unref (priv->bus_proxy);
256 priv->bus_proxy = NULL((void*)0);
257 }
258
259 if (priv->ck_proxy != NULL((void*)0)) {
260 g_object_unref (priv->ck_proxy);
261 priv->ck_proxy = NULL((void*)0);
262 }
263 } else if (priv->bus_proxy == NULL((void*)0)) {
264 if (priv->ck_proxy != NULL((void*)0)) {
265 g_object_unref (priv->ck_proxy);
266 priv->ck_proxy = NULL((void*)0);
267 }
268 }
269 }
270
271 return is_connected;
272}
273
274static void
275gsm_consolekit_on_name_owner_changed (DBusGProxy *bus_proxy,
276 const char *name,
277 const char *prev_owner,
278 const char *new_owner,
279 GsmConsolekit *manager)
280{
281 GsmConsolekitPrivate *priv;
282
283 if (name != NULL((void*)0) && strcmp (name, "org.freedesktop.ConsoleKit") != 0) {
284 return;
285 }
286
287 priv = gsm_consolekit_get_instance_private (manager);
288
289 if (priv->ck_proxy != NULL((void*)0)) {
290 g_object_unref (priv->ck_proxy);
291 priv->ck_proxy = NULL((void*)0);
292 }
293
294 gsm_consolekit_ensure_ck_connection (manager, NULL((void*)0));
295}
296
297static void
298gsm_consolekit_init (GsmConsolekit *manager)
299{
300 GError *error;
301
302 error = NULL((void*)0);
303
304 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
305 g_warning ("Could not connect to ConsoleKit: %s",
306 error->message);
307 g_error_free (error);
308 }
309}
310
311static void
312gsm_consolekit_free_dbus (GsmConsolekit *manager)
313{
314 GsmConsolekitPrivate *priv;
315
316 priv = gsm_consolekit_get_instance_private (manager);
317 if (priv->bus_proxy != NULL((void*)0)) {
318 g_object_unref (priv->bus_proxy);
319 priv->bus_proxy = NULL((void*)0);
320 }
321
322 if (priv->ck_proxy != NULL((void*)0)) {
323 g_object_unref (priv->ck_proxy);
324 priv->ck_proxy = NULL((void*)0);
325 }
326
327 if (priv->dbus_connection != NULL((void*)0)) {
328 DBusConnection *connection;
329 connection = dbus_g_connection_get_connection (priv->dbus_connection);
330 dbus_connection_remove_filter (connection,
331 gsm_consolekit_dbus_filter,
332 manager);
333
334 dbus_g_connection_unref (priv->dbus_connection);
335 priv->dbus_connection = NULL((void*)0);
336 }
337}
338
339static void
340gsm_consolekit_finalize (GObject *object)
341{
342 GsmConsolekit *manager;
343 GObjectClass *parent_class;
344
345 manager = GSM_CONSOLEKIT (object);
346
347 parent_class = G_OBJECT_CLASS (gsm_consolekit_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_consolekit_parent_class)), (((GType) ((20) << (
2))))))))
;
348
349 gsm_consolekit_free_dbus (manager);
350
351 if (parent_class->finalize != NULL((void*)0)) {
352 parent_class->finalize (object);
353 }
354}
355
356GQuark
357gsm_consolekit_error_quark (void)
358{
359 static GQuark error_quark = 0;
360
361 if (error_quark == 0) {
362 error_quark = g_quark_from_static_string ("gsm-consolekit-error");
363 }
364
365 return error_quark;
366}
367
368GsmConsolekit *
369gsm_consolekit_new (void)
370{
371 GsmConsolekit *manager;
372
373 manager = g_object_new (GSM_TYPE_CONSOLEKIT(gsm_consolekit_get_type ()), NULL((void*)0));
374
375 return manager;
376}
377
378static void
379emit_restart_complete (GsmConsolekit *manager,
380 GError *error)
381{
382 GError *call_error;
383
384 call_error = NULL((void*)0);
385
386 if (error != NULL((void*)0)) {
387 call_error = g_error_new_literal (GSM_CONSOLEKIT_ERROR(gsm_consolekit_error_quark ()),
388 GSM_CONSOLEKIT_ERROR_RESTARTING,
389 error->message);
390 }
391
392 g_signal_emit (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
,
393 signals [REQUEST_COMPLETED],
394 0, call_error);
395
396 if (call_error != NULL((void*)0)) {
397 g_error_free (call_error);
398 }
399}
400
401static void
402emit_stop_complete (GsmConsolekit *manager,
403 GError *error)
404{
405 GError *call_error;
406
407 call_error = NULL((void*)0);
408
409 if (error != NULL((void*)0)) {
410 call_error = g_error_new_literal (GSM_CONSOLEKIT_ERROR(gsm_consolekit_error_quark ()),
411 GSM_CONSOLEKIT_ERROR_STOPPING,
412 error->message);
413 }
414
415 g_signal_emit (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
,
416 signals [REQUEST_COMPLETED],
417 0, call_error);
418
419 if (call_error != NULL((void*)0)) {
420 g_error_free (call_error);
421 }
422}
423
424void
425gsm_consolekit_attempt_restart (GsmConsolekit *manager)
426{
427 gboolean res;
428 GError *error;
429 GsmConsolekitPrivate *priv;
430
431 error = NULL((void*)0);
432 priv = gsm_consolekit_get_instance_private (manager);
433
434 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
435 g_warning ("Could not connect to ConsoleKit: %s",
436 error->message);
437 emit_restart_complete (manager, error);
438 g_error_free (error);
439 return;
440 }
441
442 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
443 "Restart",
444 INT_MAX2147483647,
445 &error,
446 G_TYPE_INVALID((GType) ((0) << (2))),
447 G_TYPE_INVALID((GType) ((0) << (2))));
448
449 if (!res) {
450 g_warning ("Unable to restart system: %s", error->message);
451 emit_restart_complete (manager, error);
452 g_error_free (error);
453 } else {
454 emit_restart_complete (manager, NULL((void*)0));
455 }
456}
457
458void
459gsm_consolekit_attempt_stop (GsmConsolekit *manager)
460{
461 gboolean res;
462 GError *error;
463 GsmConsolekitPrivate *priv;
464
465 error = NULL((void*)0);
466 priv = gsm_consolekit_get_instance_private (manager);
467
468 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
469 g_warning ("Could not connect to ConsoleKit: %s",
470 error->message);
471 emit_stop_complete (manager, error);
472 g_error_free (error);
473 return;
474 }
475
476 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
477 "Stop",
478 INT_MAX2147483647,
479 &error,
480 G_TYPE_INVALID((GType) ((0) << (2))),
481 G_TYPE_INVALID((GType) ((0) << (2))));
482
483 if (!res) {
484 g_warning ("Unable to stop system: %s", error->message);
485 emit_stop_complete (manager, error);
486 g_error_free (error);
487 } else {
488 emit_stop_complete (manager, NULL((void*)0));
489 }
490}
491
492void
493gsm_consolekit_attempt_suspend (GsmConsolekit *manager)
494{
495 gboolean res;
496 GError *error;
497 GsmConsolekitPrivate *priv;
498
499 error = NULL((void*)0);
500 priv = gsm_consolekit_get_instance_private (manager);
501
502 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
503 g_warning ("Could not connect to ConsoleKit: %s",
504 error->message);
505 g_error_free (error);
506 return;
507 }
508
509 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
510 "Suspend",
511 INT_MAX2147483647,
512 &error,
513 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), /* interactive */
514 G_TYPE_INVALID((GType) ((0) << (2))),
515 G_TYPE_INVALID((GType) ((0) << (2))));
516
517 if (!res) {
518 g_warning ("Unable to suspend system: %s", error->message);
519 g_error_free (error);
520 }
521}
522
523void
524gsm_consolekit_attempt_hibernate (GsmConsolekit *manager)
525{
526 gboolean res;
527 GError *error;
528 GsmConsolekitPrivate *priv;
529
530 error = NULL((void*)0);
531 priv = gsm_consolekit_get_instance_private (manager);
532
533 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
534 g_warning ("Could not connect to ConsoleKit: %s",
535 error->message);
536 g_error_free (error);
537 return;
538 }
539
540 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
541 "Hibernate",
542 INT_MAX2147483647,
543 &error,
544 G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), /* interactive */
545 G_TYPE_INVALID((GType) ((0) << (2))),
546 G_TYPE_INVALID((GType) ((0) << (2))));
547
548 if (!res) {
549 g_warning ("Unable to hibernate system: %s", error->message);
550 g_error_free (error);
551 }
552}
553
554static gboolean
555get_current_session_id (DBusConnection *connection,
556 char **session_id)
557{
558 DBusError local_error;
559 DBusMessage *message;
560 DBusMessage *reply;
561 gboolean ret;
562 DBusMessageIter iter;
563 const char *value;
564
565 ret = FALSE(0);
566 reply = NULL((void*)0);
567
568 dbus_error_init (&local_error);
569 message = dbus_message_new_method_call (CK_NAME"org.freedesktop.ConsoleKit",
570 CK_MANAGER_PATH"/org/freedesktop/ConsoleKit/Manager",
571 CK_MANAGER_INTERFACE"org.freedesktop.ConsoleKit.Manager",
572 "GetCurrentSession");
573 if (message == NULL((void*)0)) {
574 goto out;
575 }
576
577 dbus_error_init (&local_error);
578 reply = dbus_connection_send_with_reply_and_block (connection,
579 message,
580 -1,
581 &local_error);
582 if (reply == NULL((void*)0)) {
583 if (dbus_error_is_set (&local_error)) {
584 g_warning ("Unable to determine session: %s", local_error.message);
585 dbus_error_free (&local_error);
586 goto out;
587 }
588 }
589
590 dbus_message_iter_init (reply, &iter);
591 dbus_message_iter_get_basic (&iter, &value);
592 if (session_id != NULL((void*)0)) {
593 *session_id = g_strdup (value)g_strdup_inline (value);
594 }
595
596 ret = TRUE(!(0));
597out:
598 if (message != NULL((void*)0)) {
599 dbus_message_unref (message);
600 }
601 if (reply != NULL((void*)0)) {
602 dbus_message_unref (reply);
603 }
604
605 return ret;
606}
607
608static gboolean
609get_seat_id_for_session (DBusConnection *connection,
610 const char *session_id,
611 char **seat_id)
612{
613 DBusError local_error;
614 DBusMessage *message;
615 DBusMessage *reply;
616 gboolean ret;
617 DBusMessageIter iter;
618 const char *value;
619
620 ret = FALSE(0);
621 reply = NULL((void*)0);
622
623 dbus_error_init (&local_error);
624 message = dbus_message_new_method_call (CK_NAME"org.freedesktop.ConsoleKit",
625 session_id,
626 CK_SESSION_INTERFACE"org.freedesktop.ConsoleKit.Session",
627 "GetSeatId");
628 if (message == NULL((void*)0)) {
629 goto out;
630 }
631
632 dbus_error_init (&local_error);
633 reply = dbus_connection_send_with_reply_and_block (connection,
634 message,
635 -1,
636 &local_error);
637 if (reply == NULL((void*)0)) {
638 if (dbus_error_is_set (&local_error)) {
639 g_warning ("Unable to determine seat: %s", local_error.message);
640 dbus_error_free (&local_error);
641 goto out;
642 }
643 }
644
645 dbus_message_iter_init (reply, &iter);
646 dbus_message_iter_get_basic (&iter, &value);
647 if (seat_id != NULL((void*)0)) {
648 *seat_id = g_strdup (value)g_strdup_inline (value);
649 }
650
651 ret = TRUE(!(0));
652out:
653 if (message != NULL((void*)0)) {
654 dbus_message_unref (message);
655 }
656 if (reply != NULL((void*)0)) {
657 dbus_message_unref (reply);
658 }
659
660 return ret;
661}
662
663static char *
664get_current_seat_id (DBusConnection *connection)
665{
666 gboolean res;
667 char *session_id;
668 char *seat_id;
669
670 session_id = NULL((void*)0);
671 seat_id = NULL((void*)0);
672
673 res = get_current_session_id (connection, &session_id);
674 if (res) {
675 res = get_seat_id_for_session (connection, session_id, &seat_id);
Value stored to 'res' is never read
676 }
677 g_free (session_id);
678
679 return seat_id;
680}
681
682void
683gsm_consolekit_set_session_idle (GsmConsolekit *manager,
684 gboolean is_idle)
685{
686 gboolean res;
687 GError *error;
688 char *session_id;
689 DBusMessage *message;
690 DBusMessage *reply;
691 DBusError dbus_error;
692 DBusMessageIter iter;
693 GsmConsolekitPrivate *priv;
694
695 error = NULL((void*)0);
696 priv = gsm_consolekit_get_instance_private (manager);
697
698 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
699 g_warning ("Could not connect to ConsoleKit: %s",
700 error->message);
701 g_error_free (error);
702 return;
703 }
704
705 session_id = NULL((void*)0);
706 res = get_current_session_id (dbus_g_connection_get_connection (priv->dbus_connection),
707 &session_id);
708 if (!res) {
709 goto out;
710 }
711
712 g_debug ("Updating ConsoleKit idle status: %d", is_idle);
713 message = dbus_message_new_method_call (CK_NAME"org.freedesktop.ConsoleKit",
714 session_id,
715 CK_SESSION_INTERFACE"org.freedesktop.ConsoleKit.Session",
716 "SetIdleHint");
717 if (message == NULL((void*)0)) {
718 g_debug ("Couldn't allocate the D-Bus message");
719 return;
720 }
721
722 dbus_message_iter_init_append (message, &iter);
723 dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN((int) 'b'), &is_idle);
724
725 /* FIXME: use async? */
726 dbus_error_init (&dbus_error);
727 reply = dbus_connection_send_with_reply_and_block (dbus_g_connection_get_connection (priv->dbus_connection),
728 message,
729 -1,
730 &dbus_error);
731 dbus_message_unref (message);
732
733 if (reply != NULL((void*)0)) {
734 dbus_message_unref (reply);
735 }
736
737 if (dbus_error_is_set (&dbus_error)) {
738 g_debug ("%s raised:\n %s\n\n", dbus_error.name, dbus_error.message);
739 dbus_error_free (&dbus_error);
740 }
741
742out:
743 g_free (session_id);
744}
745
746static gboolean
747seat_can_activate_sessions (DBusConnection *connection,
748 const char *seat_id)
749{
750 DBusError local_error;
751 DBusMessage *message;
752 DBusMessage *reply;
753 DBusMessageIter iter;
754 gboolean can_activate;
755
756 can_activate = FALSE(0);
757 reply = NULL((void*)0);
758
759 dbus_error_init (&local_error);
760 message = dbus_message_new_method_call (CK_NAME"org.freedesktop.ConsoleKit",
761 seat_id,
762 CK_SEAT_INTERFACE"org.freedesktop.ConsoleKit.Seat",
763 "CanActivateSessions");
764 if (message == NULL((void*)0)) {
765 goto out;
766 }
767
768 dbus_error_init (&local_error);
769 reply = dbus_connection_send_with_reply_and_block (connection,
770 message,
771 -1,
772 &local_error);
773 if (reply == NULL((void*)0)) {
774 if (dbus_error_is_set (&local_error)) {
775 g_warning ("Unable to activate session: %s", local_error.message);
776 dbus_error_free (&local_error);
777 goto out;
778 }
779 }
780
781 dbus_message_iter_init (reply, &iter);
782 dbus_message_iter_get_basic (&iter, &can_activate);
783
784out:
785 if (message != NULL((void*)0)) {
786 dbus_message_unref (message);
787 }
788 if (reply != NULL((void*)0)) {
789 dbus_message_unref (reply);
790 }
791
792 return can_activate;
793}
794
795gboolean
796gsm_consolekit_can_switch_user (GsmConsolekit *manager)
797{
798 GError *error;
799 char *seat_id;
800 gboolean ret;
801 GsmConsolekitPrivate *priv;
802
803 error = NULL((void*)0);
804 priv = gsm_consolekit_get_instance_private (manager);
805
806 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
807 g_warning ("Could not connect to ConsoleKit: %s",
808 error->message);
809 g_error_free (error);
810 return FALSE(0);
811 }
812
813 seat_id = get_current_seat_id (dbus_g_connection_get_connection (priv->dbus_connection));
814 if (seat_id == NULL((void*)0) || seat_id[0] == '\0') {
815 g_debug ("seat id is not set; can't switch sessions");
816 return FALSE(0);
817 }
818
819 ret = seat_can_activate_sessions (dbus_g_connection_get_connection (priv->dbus_connection),
820 seat_id);
821 g_free (seat_id);
822
823 return ret;
824}
825
826gboolean
827gsm_consolekit_get_restart_privileges (GsmConsolekit *manager)
828{
829 g_signal_emit (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
,
830 signals [PRIVILEGES_COMPLETED],
831 0, TRUE(!(0)), TRUE(!(0)), NULL((void*)0));
832
833 return TRUE(!(0));
834}
835
836gboolean
837gsm_consolekit_get_stop_privileges (GsmConsolekit *manager)
838{
839 g_signal_emit (G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
,
840 signals [PRIVILEGES_COMPLETED],
841 0, TRUE(!(0)), TRUE(!(0)), NULL((void*)0));
842
843 return TRUE(!(0));
844}
845
846gboolean
847gsm_consolekit_can_restart (GsmConsolekit *manager)
848{
849 gboolean res;
850 gboolean can_restart;
851 GError *error;
852 GsmConsolekitPrivate *priv;
853
854 error = NULL((void*)0);
855 priv = gsm_consolekit_get_instance_private (manager);
856
857 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
858 g_warning ("Could not connect to ConsoleKit: %s",
859 error->message);
860 g_error_free (error);
861 return FALSE(0);
862 }
863
864 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
865 "CanRestart",
866 INT_MAX2147483647,
867 &error,
868 G_TYPE_INVALID((GType) ((0) << (2))),
869 G_TYPE_BOOLEAN((GType) ((5) << (2))), &can_restart,
870 G_TYPE_INVALID((GType) ((0) << (2))));
871 if (res == FALSE(0)) {
872 g_warning ("Could not make DBUS call: %s",
873 error->message);
874 g_error_free (error);
875 return FALSE(0);
876 }
877
878 return can_restart;
879}
880
881gboolean
882gsm_consolekit_can_stop (GsmConsolekit *manager)
883{
884 gboolean res;
885 gboolean can_stop;
886 GError *error;
887 GsmConsolekitPrivate *priv;
888
889 error = NULL((void*)0);
890 priv = gsm_consolekit_get_instance_private (manager);
891
892 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
893 g_warning ("Could not connect to ConsoleKit: %s",
894 error->message);
895 g_error_free (error);
896 return FALSE(0);
897 }
898
899 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
900 "CanStop",
901 INT_MAX2147483647,
902 &error,
903 G_TYPE_INVALID((GType) ((0) << (2))),
904 G_TYPE_BOOLEAN((GType) ((5) << (2))), &can_stop,
905 G_TYPE_INVALID((GType) ((0) << (2))));
906
907 if (res == FALSE(0)) {
908 g_warning ("Could not make DBUS call: %s",
909 error->message);
910 g_error_free (error);
911 return FALSE(0);
912 }
913
914 return can_stop;
915}
916
917gboolean
918gsm_consolekit_can_suspend (GsmConsolekit *manager)
919{
920 gboolean res;
921 gboolean can_suspend;
922 gchar *retval;
923 GError *error = NULL((void*)0);
924 GsmConsolekitPrivate *priv;
925
926 priv = gsm_consolekit_get_instance_private (manager);
927
928 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
929 g_warning ("Could not connect to ConsoleKit: %s",
930 error->message);
931 g_error_free (error);
932 return FALSE(0);
933 }
934
935 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
936 "CanSuspend",
937 INT_MAX2147483647,
938 &error,
939 G_TYPE_INVALID((GType) ((0) << (2))),
940 G_TYPE_STRING((GType) ((16) << (2))), &retval,
941 G_TYPE_INVALID((GType) ((0) << (2))));
942
943 if (res == FALSE(0)) {
944 g_warning ("Could not make DBUS call: %s",
945 error->message);
946 g_error_free (error);
947 return FALSE(0);
948 }
949
950 can_suspend = g_strcmp0 (retval, "yes") == 0 ||
951 g_strcmp0 (retval, "challenge") == 0;
952
953 g_free (retval);
954 return can_suspend;
955}
956
957gboolean
958gsm_consolekit_can_hibernate (GsmConsolekit *manager)
959{
960 gboolean res;
961 gboolean can_hibernate;
962 gchar *retval;
963 GError *error = NULL((void*)0);
964 GsmConsolekitPrivate *priv;
965
966 priv = gsm_consolekit_get_instance_private (manager);
967
968 if (!gsm_consolekit_ensure_ck_connection (manager, &error)) {
969 g_warning ("Could not connect to ConsoleKit: %s",
970 error->message);
971 g_error_free (error);
972 return FALSE(0);
973 }
974
975 res = dbus_g_proxy_call_with_timeout (priv->ck_proxy,
976 "CanHibernate",
977 INT_MAX2147483647,
978 &error,
979 G_TYPE_INVALID((GType) ((0) << (2))),
980 G_TYPE_STRING((GType) ((16) << (2))), &retval,
981 G_TYPE_INVALID((GType) ((0) << (2))));
982
983 if (res == FALSE(0)) {
984 g_warning ("Could not make DBUS call: %s",
985 error->message);
986 g_error_free (error);
987 return FALSE(0);
988 }
989
990 can_hibernate = g_strcmp0 (retval, "yes") == 0 ||
991 g_strcmp0 (retval, "challenge") == 0;
992
993 g_free (retval);
994 return can_hibernate;
995}
996
997gchar *
998gsm_consolekit_get_current_session_type (GsmConsolekit *manager)
999{
1000 GError *gerror;
1001 DBusConnection *connection;
1002 DBusError error;
1003 DBusMessage *message = NULL((void*)0);
1004 DBusMessage *reply = NULL((void*)0);
1005 gchar *session_id;
1006 gchar *ret;
1007 DBusMessageIter iter;
1008 const char *value;
1009 GsmConsolekitPrivate *priv;
1010
1011 session_id = NULL((void*)0);
1012 ret = NULL((void*)0);
1013 gerror = NULL((void*)0);
1014 priv = gsm_consolekit_get_instance_private (manager);
1015
1016 if (!gsm_consolekit_ensure_ck_connection (manager, &gerror)) {
1017 g_warning ("Could not connect to ConsoleKit: %s",
1018 gerror->message);
1019 g_error_free (gerror);
1020 goto out;
1021 }
1022
1023 connection = dbus_g_connection_get_connection (priv->dbus_connection);
1024 if (!get_current_session_id (connection, &session_id)) {
1025 goto out;
1026 }
1027
1028 dbus_error_init (&error);
1029 message = dbus_message_new_method_call (CK_NAME"org.freedesktop.ConsoleKit",
1030 session_id,
1031 CK_SESSION_INTERFACE"org.freedesktop.ConsoleKit.Session",
1032 "GetSessionType");
1033 if (message == NULL((void*)0)) {
1034 goto out;
1035 }
1036
1037 reply = dbus_connection_send_with_reply_and_block (connection,
1038 message,
1039 -1,
1040 &error);
1041
1042 if (reply == NULL((void*)0)) {
1043 if (dbus_error_is_set (&error)) {
1044 g_warning ("Unable to determine session type: %s", error.message);
1045 dbus_error_free (&error);
1046 }
1047 goto out;
1048 }
1049
1050 dbus_message_iter_init (reply, &iter);
1051 dbus_message_iter_get_basic (&iter, &value);
1052 ret = g_strdup (value)g_strdup_inline (value);
1053
1054out:
1055 if (message != NULL((void*)0)) {
1056 dbus_message_unref (message);
1057 }
1058 if (reply != NULL((void*)0)) {
1059 dbus_message_unref (reply);
1060 }
1061 g_free (session_id);
1062
1063 return ret;
1064}
1065
1066GsmConsolekit *
1067gsm_get_consolekit (void)
1068{
1069 static GsmConsolekit *manager = NULL((void*)0);
1070
1071 if (manager == NULL((void*)0)) {
1072 manager = gsm_consolekit_new ();
1073 }
1074
1075 return g_object_ref (manager)((__typeof__ (manager)) (g_object_ref) (manager));
1076}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f463e.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f463e.html new file mode 100644 index 0000000..8e5317e --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-1f463e.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 254, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
This statement is never executed
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-27b446.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-27b446.html new file mode 100644 index 0000000..a284318 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-27b446.html @@ -0,0 +1,1314 @@ + + + +gsm-app-dialog.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:capplet/gsm-app-dialog.c
Warning:line 583, column 17
1st function call argument is an uninitialized value
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-app-dialog.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/capplet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-session -D LOCALE_DIR="/usr/local/share/locale" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/capplet -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-app-dialog.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "config.h"
23
24#include <glib.h>
25#include <glib/gi18n.h>
26#include <gtk/gtk.h>
27
28#include "gsm-util.h"
29
30#include "gsm-app-dialog.h"
31
32#define GTKBUILDER_FILE"session-properties.ui" "session-properties.ui"
33
34#define CAPPLET_NAME_ENTRY_WIDGET_NAME"session_properties_name_entry" "session_properties_name_entry"
35#define CAPPLET_COMMAND_ENTRY_WIDGET_NAME"session_properties_command_entry" "session_properties_command_entry"
36#define CAPPLET_COMMENT_ENTRY_WIDGET_NAME"session_properties_comment_entry" "session_properties_comment_entry"
37#define CAPPLET_DELAY_SPIN_WIDGET_NAME"session_properties_delay_spin" "session_properties_delay_spin"
38#define CAPPLET_BROWSE_WIDGET_NAME"session_properties_browse_button" "session_properties_browse_button"
39
40#ifdef __GNUC__4
41#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
42#else
43#define UNUSED_VARIABLE__attribute__ ((unused))
44#endif
45
46struct _GsmAppDialog
47{
48 GtkDialog parent;
49 GtkWidget *name_entry;
50 GtkWidget *command_entry;
51 GtkWidget *comment_entry;
52 GtkWidget *delay_spin;
53 GtkWidget *browse_button;
54 char *name;
55 char *command;
56 char *comment;
57 guint delay;
58};
59
60enum {
61 PROP_0,
62 PROP_NAME,
63 PROP_COMMAND,
64 PROP_COMMENT,
65 PROP_DELAY
66};
67
68G_DEFINE_TYPE (GsmAppDialog, gsm_app_dialog, GTK_TYPE_DIALOG)static void gsm_app_dialog_init (GsmAppDialog *self); static void
gsm_app_dialog_class_init (GsmAppDialogClass *klass); static
GType gsm_app_dialog_get_type_once (void); static gpointer gsm_app_dialog_parent_class
= ((void*)0); static gint GsmAppDialog_private_offset; static
void gsm_app_dialog_class_intern_init (gpointer klass) { gsm_app_dialog_parent_class
= g_type_class_peek_parent (klass); if (GsmAppDialog_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &GsmAppDialog_private_offset
); gsm_app_dialog_class_init ((GsmAppDialogClass*) klass); } __attribute__
((__unused__)) static inline gpointer gsm_app_dialog_get_instance_private
(GsmAppDialog *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (GsmAppDialog_private_offset)))); } GType gsm_app_dialog_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_app_dialog_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_app_dialog_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((gtk_dialog_get_type ()), g_intern_static_string ("GsmAppDialog"
), sizeof (GsmAppDialogClass), (GClassInitFunc)(void (*)(void
)) gsm_app_dialog_class_intern_init, sizeof (GsmAppDialog), (
GInstanceInitFunc)(void (*)(void)) gsm_app_dialog_init, (GTypeFlags
) 0); { {{};} } return g_define_type_id; }
69
70static char *
71make_exec_uri (const char *exec)
72{
73 GString *str;
74 const char *c;
75
76 if (exec == NULL((void*)0)) {
77 return g_strdup ("")g_strdup_inline ("");
78 }
79
80 if (strchr (exec, ' ') == NULL((void*)0)) {
81 return g_strdup (exec)g_strdup_inline (exec);
82 }
83
84 str = g_string_new_len (NULL((void*)0), strlen (exec));
85
86 str = g_string_append_c (str, '"')g_string_append_c_inline (str, '"');
87 for (c = exec; *c != '\0'; c++) {
88 /* FIXME: GKeyFile will add an additional backslach so we'll
89 * end up with toto\\" instead of toto\"
90 * We could use g_key_file_set_value(), but then we don't
91 * benefit from the other escaping that glib is doing...
92 */
93 if (*c == '"') {
94 str = g_string_append (str, "\\\"")(__builtin_constant_p ("\\\"") ? __extension__ ({ const char *
const __val = ("\\\""); g_string_append_len_inline (str, __val
, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val
))) : (gssize) -1); }) : g_string_append_len_inline (str, "\\\""
, (gssize) -1))
;
95 } else {
96 str = g_string_append_c (str, *c)g_string_append_c_inline (str, *c);
97 }
98 }
99 str = g_string_append_c (str, '"')g_string_append_c_inline (str, '"');
100
101 return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str)
, ((0))) : g_string_free_and_steal (str)) : (g_string_free) (
(str), ((0))))
;
102}
103
104static void
105on_browse_button_clicked (GtkWidget *widget,
106 GsmAppDialog *dialog)
107{
108 GtkWidget *chooser;
109 int response;
110
111 chooser = gtk_file_chooser_dialog_new ("",
112 GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
113 GTK_FILE_CHOOSER_ACTION_OPEN,
114 "gtk-cancel",
115 GTK_RESPONSE_CANCEL,
116 "gtk-open",
117 GTK_RESPONSE_ACCEPT,
118 NULL((void*)0));
119
120 gtk_window_set_transient_for (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
,
121 GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
);
122
123 gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
124
125 gtk_window_set_title (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
, _("Select Command")gettext ("Select Command"));
126
127 gtk_widget_show (chooser);
128
129 response = gtk_dialog_run (GTK_DIALOG (chooser)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_dialog_get_type ()))))))
);
130
131 if (response == GTK_RESPONSE_ACCEPT) {
132 char *text;
133 char *uri;
134
135 text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)((((GtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_file_chooser_get_type ()))))))
);
136
137 uri = make_exec_uri (text);
138
139 g_free (text);
140
141 gtk_entry_set_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
, uri);
142
143 g_free (uri);
144 }
145
146 gtk_widget_destroy (chooser);
147}
148
149static void
150on_entry_activate (GtkEntry *entry,
151 GsmAppDialog *dialog)
152{
153 gtk_dialog_response (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
, GTK_RESPONSE_OK);
154}
155
156static gboolean
157on_spin_output (GtkSpinButton *spin, GsmAppDialog *dialog)
158{
159 GtkAdjustment *adjustment;
160 gchar *text;
161 int value;
162
163 adjustment = gtk_spin_button_get_adjustment (spin);
164 value = gtk_adjustment_get_value (adjustment);
165 dialog->delay = value;
166
167 if (value == 1)
168 text = g_strdup_printf ("%d %s", value, _("second")gettext ("second"));
169 else if (value > 1)
170 text = g_strdup_printf ("%d %s", value, _("seconds")gettext ("seconds"));
171 else
172 text = g_strdup_printf ("%d", value);
173
174 gtk_entry_set_text (GTK_ENTRY (spin)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((spin)), ((gtk_entry_get_type ()))))))
, text);
175 g_free (text);
176
177 return TRUE(!(0));
178}
179
180static void
181setup_dialog (GsmAppDialog *dialog)
182{
183 GtkWidget *content_area;
184 GtkWidget *widget;
185 GtkBuilder *xml;
186 GError *error;
187
188 xml = gtk_builder_new ();
189#ifdef ENABLE_NLS1
190 gtk_builder_set_translation_domain (xml, GETTEXT_PACKAGE"mate-session-manager");
191#endif /* ENABLE_NLS */
192
193 error = NULL((void*)0);
194 if (!gtk_builder_add_from_file (xml,
195 GTKBUILDER_DIR"/usr/local/share/mate-session-manager" "/" GTKBUILDER_FILE"session-properties.ui",
196 &error)) {
197 if (error) {
198 g_warning ("Could not load capplet UI file: %s",
199 error->message);
200 g_error_free (error);
201 } else {
202 g_warning ("Could not load capplet UI file.");
203 }
204 }
205
206 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
207 widget = GTK_WIDGET (gtk_builder_get_object (xml, "main-table"))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "main-table"))), ((gtk_widget_get_type
()))))))
;
208 gtk_container_add (GTK_CONTAINER (content_area)((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((content_area)), ((gtk_container_get_type ()))))))
, widget);
209
210 gtk_container_set_border_width (GTK_CONTAINER (dialog)((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_container_get_type ()))))))
, 6);
211 gtk_window_set_icon_name (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, "mate-session-properties");
212
213 g_object_set (dialog,
214 "resizable", FALSE(0),
215 NULL((void*)0));
216
217 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
218 _("_Cancel")gettext ("_Cancel"), "process-stop",
219 GTK_RESPONSE_CANCEL);
220
221 if (dialog->name == NULL((void*)0)
222 && dialog->command == NULL((void*)0)
223 && dialog->comment == NULL((void*)0)) {
224 gtk_window_set_title (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, _("Add Startup Program")gettext ("Add Startup Program"));
225 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
226 _("_Add")gettext ("_Add"), "list-add",
227 GTK_RESPONSE_OK);
228 } else {
229 gtk_window_set_title (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, _("Edit Startup Program")gettext ("Edit Startup Program"));
230 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
231 _("_Save")gettext ("_Save"), "document-save",
232 GTK_RESPONSE_OK);
233 }
234
235 dialog->name_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_NAME_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_name_entry"
))), ((gtk_widget_get_type ()))))))
;
236 g_signal_connect (dialog->name_entry,g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
237 "activate",g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
238 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
239 dialog)g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
;
240 if (dialog->name != NULL((void*)0)) {
241 gtk_entry_set_text (GTK_ENTRY (dialog->name_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->name_entry)), ((gtk_entry_get_type ()))))))
, dialog->name);
242 }
243
244 dialog->browse_button = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_BROWSE_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_browse_button"
))), ((gtk_widget_get_type ()))))))
;
245 g_signal_connect (dialog->browse_button,g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
246 "clicked",g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
247 G_CALLBACK (on_browse_button_clicked),g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
248 dialog)g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
;
249
250 dialog->command_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMAND_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_command_entry"
))), ((gtk_widget_get_type ()))))))
;
251 g_signal_connect (dialog->command_entry,g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
252 "activate",g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
253 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
254 dialog)g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
;
255 if (dialog->command != NULL((void*)0)) {
256 gtk_entry_set_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
, dialog->command);
257 }
258
259 dialog->comment_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMENT_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_comment_entry"
))), ((gtk_widget_get_type ()))))))
;
260 g_signal_connect (dialog->comment_entry,g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
261 "activate",g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
262 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
263 dialog)g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
;
264 if (dialog->comment != NULL((void*)0)) {
265 gtk_entry_set_text (GTK_ENTRY (dialog->comment_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->comment_entry)), ((gtk_entry_get_type ())))))
)
, dialog->comment);
266 }
267
268 dialog->delay_spin = GTK_WIDGET(gtk_builder_get_object (xml, CAPPLET_DELAY_SPIN_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_delay_spin"
))), ((gtk_widget_get_type ()))))))
;
269 g_signal_connect (dialog->delay_spin,g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
270 "output",g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
271 G_CALLBACK (on_spin_output),g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
272 dialog)g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
;
273 if (dialog->delay > 0) {
274 GtkAdjustment *adjustment;
275 adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(dialog->delay_spin)((((GtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->delay_spin)), ((gtk_spin_button_get_type ()))
))))
);
276 gtk_adjustment_set_value (adjustment, (gdouble) dialog->delay);
277 }
278
279 if (xml != NULL((void*)0)) {
280 g_object_unref (xml);
281 }
282}
283
284static GObject *
285gsm_app_dialog_constructor (GType type,
286 guint n_construct_app,
287 GObjectConstructParam *construct_app)
288{
289 GsmAppDialog *dialog;
290
291 dialog = GSM_APP_DIALOG (G_OBJECT_CLASS (gsm_app_dialog_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_app_dialog_parent_class)), (((GType) ((20) << (
2))))))))
->constructor (type,
292 n_construct_app,
293 construct_app));
294
295 setup_dialog (dialog);
296
297 return G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
;
298}
299
300static void
301gsm_app_dialog_dispose (GObject *object)
302{
303 GsmAppDialog *dialog;
304
305 g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
306 g_return_if_fail (GSM_IS_APP_DIALOG (object))do { if ((GSM_IS_APP_DIALOG (object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (object)"
); return; } } while (0)
;
307
308 dialog = GSM_APP_DIALOG (object);
309
310 g_free (dialog->name);
311 dialog->name = NULL((void*)0);
312 g_free (dialog->command);
313 dialog->command = NULL((void*)0);
314 g_free (dialog->comment);
315 dialog->comment = NULL((void*)0);
316
317 G_OBJECT_CLASS (gsm_app_dialog_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_app_dialog_parent_class)), (((GType) ((20) << (
2))))))))
->dispose (object);
318}
319
320static void
321gsm_app_dialog_set_name (GsmAppDialog *dialog,
322 const char *name)
323{
324 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
325
326 g_free (dialog->name);
327
328 dialog->name = g_strdup (name)g_strdup_inline (name);
329 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "name");
330}
331
332static void
333gsm_app_dialog_set_command (GsmAppDialog *dialog,
334 const char *name)
335{
336 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
337
338 g_free (dialog->command);
339
340 dialog->command = g_strdup (name)g_strdup_inline (name);
341 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "command");
342}
343
344static void
345gsm_app_dialog_set_comment (GsmAppDialog *dialog,
346 const char *name)
347{
348 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
349
350 g_free (dialog->comment);
351
352 dialog->comment = g_strdup (name)g_strdup_inline (name);
353 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "comment");
354}
355
356static void
357gsm_app_dialog_set_delay (GsmAppDialog *dialog,
358 guint delay)
359{
360 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
361
362 dialog->delay = delay;
363 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "delay");
364}
365
366const char *
367gsm_app_dialog_get_name (GsmAppDialog *dialog)
368{
369 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
370 return gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->name_entry)), ((gtk_entry_get_type ()))))))
);
371}
372
373const char *
374gsm_app_dialog_get_command (GsmAppDialog *dialog)
375{
376 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
377 return gtk_entry_get_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
);
378}
379
380const char *
381gsm_app_dialog_get_comment (GsmAppDialog *dialog)
382{
383 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
384 return gtk_entry_get_text (GTK_ENTRY (dialog->comment_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->comment_entry)), ((gtk_entry_get_type ())))))
)
);
385}
386
387guint
388gsm_app_dialog_get_delay (GsmAppDialog *dialog)
389{
390 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), 0)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (0); } } while (0)
;
391 return dialog->delay;
392}
393
394static void
395gsm_app_dialog_set_property (GObject *object,
396 guint prop_id,
397 const GValue *value,
398 GParamSpec *pspec)
399{
400 GsmAppDialog *dialog = GSM_APP_DIALOG (object);
401
402 switch (prop_id) {
403 case PROP_NAME:
404 gsm_app_dialog_set_name (dialog, g_value_get_string (value));
405 break;
406 case PROP_COMMAND:
407 gsm_app_dialog_set_command (dialog, g_value_get_string (value));
408 break;
409 case PROP_COMMENT:
410 gsm_app_dialog_set_comment (dialog, g_value_get_string (value));
411 break;
412 case PROP_DELAY:
413 gsm_app_dialog_set_delay (dialog, g_value_get_uint (value));
414 break;
415 default:
416 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-app-dialog.c", 416, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
417 break;
418 }
419}
420
421static void
422gsm_app_dialog_get_property (GObject *object,
423 guint prop_id,
424 GValue *value,
425 GParamSpec *pspec)
426{
427 GsmAppDialog *dialog = GSM_APP_DIALOG (object);
428
429 switch (prop_id) {
430 case PROP_NAME:
431 g_value_set_string (value, dialog->name);
432 break;
433 case PROP_COMMAND:
434 g_value_set_string (value, dialog->command);
435 break;
436 case PROP_COMMENT:
437 g_value_set_string (value, dialog->comment);
438 break;
439 case PROP_DELAY:
440 g_value_set_uint (value, dialog->delay);
441 break;
442 default:
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-app-dialog.c", 443, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
444 break;
445 }
446}
447
448static void
449gsm_app_dialog_class_init (GsmAppDialogClass *klass)
450{
451 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
452
453 object_class->get_property = gsm_app_dialog_get_property;
454 object_class->set_property = gsm_app_dialog_set_property;
455 object_class->constructor = gsm_app_dialog_constructor;
456 object_class->dispose = gsm_app_dialog_dispose;
457
458 g_object_class_install_property (object_class,
459 PROP_NAME,
460 g_param_spec_string ("name",
461 "name",
462 "name",
463 NULL((void*)0),
464 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
465 g_object_class_install_property (object_class,
466 PROP_COMMAND,
467 g_param_spec_string ("command",
468 "command",
469 "command",
470 NULL((void*)0),
471 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
472 g_object_class_install_property (object_class,
473 PROP_COMMENT,
474 g_param_spec_string ("comment",
475 "comment",
476 "comment",
477 NULL((void*)0),
478 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
479 g_object_class_install_property (object_class,
480 PROP_DELAY,
481 g_param_spec_uint ("delay",
482 "delay",
483 "delay",
484 0,
485 100,
486 0,
487 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
488}
489
490static void
491gsm_app_dialog_init (GsmAppDialog *dialog)
492{
493
494}
495
496GtkWidget *
497gsm_app_dialog_new (const char *name,
498 const char *command,
499 const char *comment,
500 guint delay)
501{
502 GObject *object;
503
504 object = g_object_new (GSM_TYPE_APP_DIALOG(gsm_app_dialog_get_type ()),
505 "name", name,
506 "command", command,
507 "comment", comment,
508 "delay", delay,
509 NULL((void*)0));
510
511 return GTK_WIDGET (object)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((gtk_widget_get_type ()))))))
;
512}
513
514gboolean
515gsm_app_dialog_run (GsmAppDialog *dialog,
516 char **name_p,
517 char **command_p,
518 char **comment_p,
519 guint *delay_p)
520{
521 gboolean retval;
522
523 retval = FALSE(0);
524
525 while (gtk_dialog_run (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
) == GTK_RESPONSE_OK
) {
1
Assuming the condition is true
2
Loop condition is true. Entering loop body
526 const char *name;
527 const char *exec;
528 const char *comment;
529 guint delay;
530 const char *error_msg;
531 GError *error;
532 char **argv;
3
'argv' declared without an initial value
533 int argc;
534
535 name = gsm_app_dialog_get_name (GSM_APP_DIALOG (dialog));
536 exec = gsm_app_dialog_get_command (GSM_APP_DIALOG (dialog));
537 comment = gsm_app_dialog_get_comment (GSM_APP_DIALOG (dialog));
538 delay = gsm_app_dialog_get_delay (GSM_APP_DIALOG (dialog));
539
540 error = NULL((void*)0);
541 error_msg = NULL((void*)0);
542
543 if (gsm_util_text_is_blank (exec)) {
4
Assuming the condition is true
5
Taking true branch
544 error_msg = _("The startup command cannot be empty")gettext ("The startup command cannot be empty");
545 } else {
546 if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
547 if (error != NULL((void*)0)) {
548 error_msg = error->message;
549 } else {
550 error_msg = _("The startup command is not valid")gettext ("The startup command is not valid");
551 }
552 }
553 }
554
555 if (error_msg != NULL((void*)0)) {
6
Assuming 'error_msg' is equal to NULL
7
Taking false branch
556 GtkWidget *msgbox;
557
558 msgbox = gtk_message_dialog_new (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
559 GTK_DIALOG_MODAL,
560 GTK_MESSAGE_ERROR,
561 GTK_BUTTONS_CLOSE,
562 "%s", error_msg);
563
564 if (error != NULL((void*)0)) {
565 g_error_free (error);
566 }
567
568 gtk_dialog_run (GTK_DIALOG (msgbox)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((msgbox)), ((gtk_dialog_get_type ()))))))
);
569
570 gtk_widget_destroy (msgbox);
571
572 continue;
573 }
574
575 if (gsm_util_text_is_blank (name)) {
8
Assuming the condition is false
9
Taking false branch
576 name = argv[0];
577 }
578
579 if (name_p) {
10
Assuming 'name_p' is null
11
Taking false branch
580 *name_p = g_strdup (name)g_strdup_inline (name);
581 }
582
583 g_strfreev (argv);
12
1st function call argument is an uninitialized value
584
585 if (command_p) {
586 *command_p = g_strdup (exec)g_strdup_inline (exec);
587 }
588
589 if (comment_p) {
590 *comment_p = g_strdup (comment)g_strdup_inline (comment);
591 }
592
593 if (delay_p) {
594 *delay_p = delay;
595 }
596
597 retval = TRUE(!(0));
598 break;
599 }
600
601 gtk_widget_destroy (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
);
602
603 return retval;
604}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-37d955.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-37d955.html new file mode 100644 index 0000000..5c9efe6 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-37d955.html @@ -0,0 +1,1217 @@ + + + +gsm-logout-dialog.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/gsm-logout-dialog.c
Warning:line 197, column 9
Value stored to 'ret' is never read
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-logout-dialog.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-logout-dialog.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Vincent Untz
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 * Authors:
23 * Vincent Untz <vuntz@gnome.org>
24 */
25
26#include <config.h>
27
28#include <glib/gi18n.h>
29#include <gtk/gtk.h>
30
31#include "gsm-logout-dialog.h"
32#ifdef HAVE_SYSTEMD1
33#include "gsm-systemd.h"
34#endif
35#include "gsm-consolekit.h"
36#include "mdm.h"
37#include "gsm-util.h"
38
39#define GSM_ICON_LOGOUT"system-log-out" "system-log-out"
40#define GSM_ICON_SHUTDOWN"system-shutdown" "system-shutdown"
41
42#define SESSION_SCHEMA"org.mate.session" "org.mate.session"
43#define KEY_LOGOUT_TIMEOUT"logout-timeout" "logout-timeout"
44
45#define LOCKDOWN_SCHEMA"org.mate.lockdown" "org.mate.lockdown"
46#define KEY_USER_SWITCHING_DISABLE"disable-user-switching" "disable-user-switching"
47
48typedef enum {
49 GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
50 GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
51} GsmDialogLogoutType;
52
53struct _GsmLogoutDialog
54{
55 GtkMessageDialog parent;
56 GsmDialogLogoutType type;
57#ifdef HAVE_SYSTEMD1
58 GsmSystemd *systemd;
59#endif
60 GsmConsolekit *consolekit;
61
62 GtkWidget *progressbar;
63
64 int timeout;
65 unsigned int timeout_id;
66
67 unsigned int default_response;
68};
69
70static GsmLogoutDialog *current_dialog = NULL((void*)0);
71
72static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
73
74static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
75 gpointer data);
76
77static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
78 gpointer data);
79
80enum {
81 PROP_0,
82 PROP_MESSAGE_TYPE
83};
84
85G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_MESSAGE_DIALOG)static void gsm_logout_dialog_init (GsmLogoutDialog *self); static
void gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass
); static GType gsm_logout_dialog_get_type_once (void); static
gpointer gsm_logout_dialog_parent_class = ((void*)0); static
gint GsmLogoutDialog_private_offset; static void gsm_logout_dialog_class_intern_init
(gpointer klass) { gsm_logout_dialog_parent_class = g_type_class_peek_parent
(klass); if (GsmLogoutDialog_private_offset != 0) g_type_class_adjust_private_offset
(klass, &GsmLogoutDialog_private_offset); gsm_logout_dialog_class_init
((GsmLogoutDialogClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer gsm_logout_dialog_get_instance_private
(GsmLogoutDialog *self) { return (((gpointer) ((guint8*) (self
) + (glong) (GsmLogoutDialog_private_offset)))); } GType gsm_logout_dialog_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_logout_dialog_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_logout_dialog_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((gtk_message_dialog_get_type ()), g_intern_static_string ("GsmLogoutDialog"
), sizeof (GsmLogoutDialogClass), (GClassInitFunc)(void (*)(void
)) gsm_logout_dialog_class_intern_init, sizeof (GsmLogoutDialog
), (GInstanceInitFunc)(void (*)(void)) gsm_logout_dialog_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
;
86
87static void
88gsm_logout_dialog_set_property (GObject *object,
89 guint prop_id,
90 const GValue *value,
91 GParamSpec *pspec)
92{
93 switch (prop_id) {
94 case PROP_MESSAGE_TYPE:
95 break;
96 default:
97 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-logout-dialog.c", 97, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
98 break;
99 }
100}
101
102static void
103gsm_logout_dialog_get_property (GObject *object,
104 guint prop_id,
105 GValue *value,
106 GParamSpec *pspec)
107{
108 switch (prop_id) {
109 case PROP_MESSAGE_TYPE:
110 g_value_set_enum (value, GTK_MESSAGE_WARNING);
111 break;
112 default:
113 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-logout-dialog.c", 113, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
114 break;
115 }
116}
117
118static void
119gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass)
120{
121 GObjectClass *gobject_class;
122
123 gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
124
125 /* This is a workaround to avoid a stupid crash: libmateui
126 * listens for the "show" signal on all GtkMessageDialog and
127 * gets the "message-type" of the dialogs. We will crash when
128 * it accesses this property if we don't override it since we
129 * didn't define it. */
130 gobject_class->set_property = gsm_logout_dialog_set_property;
131 gobject_class->get_property = gsm_logout_dialog_get_property;
132
133 g_object_class_override_property (gobject_class,
134 PROP_MESSAGE_TYPE,
135 "message-type");
136}
137
138static void
139gsm_logout_dialog_init (GsmLogoutDialog *logout_dialog)
140{
141 logout_dialog->timeout_id = 0;
142 logout_dialog->timeout = 0;
143 logout_dialog->default_response = GTK_RESPONSE_CANCEL;
144
145 GtkStyleContext *context;
146 context = gtk_widget_get_style_context (GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
);
147 gtk_style_context_add_class (context, "logout-dialog");
148
149 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
150 gtk_window_set_keep_above (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
151 gtk_window_stick (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
);
152#ifdef HAVE_SYSTEMD1
153 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
154 logout_dialog->systemd = gsm_get_systemd ();
155 else
156#endif
157 logout_dialog->consolekit = gsm_get_consolekit ();
158
159 g_signal_connect (logout_dialog,g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
160 "destroy",g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
161 G_CALLBACK (gsm_logout_dialog_destroy),g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
162 NULL)g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
163
164 g_signal_connect (logout_dialog,g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
165 "show",g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
166 G_CALLBACK (gsm_logout_dialog_show),g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
167 NULL)g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
168}
169
170static void
171gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
172 gpointer data)
173{
174 if (logout_dialog->timeout_id != 0) {
175 g_source_remove (logout_dialog->timeout_id);
176 logout_dialog->timeout_id = 0;
177 }
178#ifdef HAVE_SYSTEMD1
179 if (logout_dialog->systemd) {
180 g_object_unref (logout_dialog->systemd);
181 logout_dialog->systemd = NULL((void*)0);
182 }
183#endif
184
185 if (logout_dialog->consolekit) {
186 g_object_unref (logout_dialog->consolekit);
187 logout_dialog->consolekit = NULL((void*)0);
188 }
189
190 current_dialog = NULL((void*)0);
191}
192
193static gboolean
194gsm_logout_supports_system_suspend (GsmLogoutDialog *logout_dialog)
195{
196 gboolean ret;
197 ret = FALSE(0);
Value stored to 'ret' is never read
198#ifdef HAVE_SYSTEMD1
199 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
200 ret = gsm_systemd_can_suspend (logout_dialog->systemd);
201 else
202#endif
203 ret = gsm_consolekit_can_suspend (logout_dialog->consolekit);
204 return ret;
205}
206
207static gboolean
208gsm_logout_supports_system_hibernate (GsmLogoutDialog *logout_dialog)
209{
210 gboolean ret;
211 ret = FALSE(0);
212#ifdef HAVE_SYSTEMD1
213 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
214 ret = gsm_systemd_can_hibernate (logout_dialog->systemd);
215 else
216#endif
217 ret = gsm_consolekit_can_hibernate (logout_dialog->consolekit);
218 return ret;
219}
220
221static gboolean
222gsm_logout_supports_switch_user (GsmLogoutDialog *logout_dialog)
223{
224 GSettings *settings;
225 gboolean ret = FALSE(0);
226 gboolean locked;
227
228 settings = g_settings_new (LOCKDOWN_SCHEMA"org.mate.lockdown");
229
230 locked = g_settings_get_boolean (settings, KEY_USER_SWITCHING_DISABLE"disable-user-switching");
231 g_object_unref (settings);
232
233 if (!locked) {
234#ifdef HAVE_SYSTEMD1
235 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
236 ret = gsm_systemd_can_switch_user (logout_dialog->systemd);
237 else
238#endif
239 ret = gsm_consolekit_can_switch_user (logout_dialog->consolekit);
240 }
241
242 return ret;
243}
244
245static gboolean
246gsm_logout_supports_reboot (GsmLogoutDialog *logout_dialog)
247{
248 gboolean ret;
249
250#ifdef HAVE_SYSTEMD1
251 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
252 ret = gsm_systemd_can_restart (logout_dialog->systemd);
253 else
254#endif
255 ret = gsm_consolekit_can_restart (logout_dialog->consolekit);
256 if (!ret) {
257 ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_REBOOT);
258 }
259
260 return ret;
261}
262
263static gboolean
264gsm_logout_supports_shutdown (GsmLogoutDialog *logout_dialog)
265{
266 gboolean ret;
267
268#ifdef HAVE_SYSTEMD1
269 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
270 ret = gsm_systemd_can_stop (logout_dialog->systemd);
271 else
272#endif
273 ret = gsm_consolekit_can_stop (logout_dialog->consolekit);
274
275 if (!ret) {
276 ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
277 }
278
279 return ret;
280}
281
282static void
283gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
284{
285 gsm_logout_dialog_set_timeout (logout_dialog);
286}
287
288static gboolean
289gsm_logout_dialog_timeout (gpointer data)
290{
291 GsmLogoutDialog *logout_dialog;
292 char *seconds_warning;
293 char *secondary_text;
294 static char *session_type = NULL((void*)0);
295 static gboolean is_not_login;
296
297 logout_dialog = (GsmLogoutDialog *) data;
298
299 if (!logout_dialog->timeout) {
300 gtk_dialog_response (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
301 logout_dialog->default_response);
302
303 return FALSE(0);
304 }
305
306 switch (logout_dialog->type) {
307 case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
308 seconds_warning = ngettext ("You will be automatically logged "
309 "out in %d second",
310 "You will be automatically logged "
311 "out in %d seconds",
312 logout_dialog->timeout);
313 break;
314
315 case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
316 seconds_warning = ngettext ("This system will be automatically "
317 "shut down in %d second",
318 "This system will be automatically "
319 "shut down in %d seconds",
320 logout_dialog->timeout);
321 break;
322
323 default:
324 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-logout-dialog.c"
, 324, ((const char*) (__func__)), ((void*)0)); } while (0)
;
325 }
326 seconds_warning = g_strdup_printf (seconds_warning, logout_dialog->timeout);
327
328 if (session_type == NULL((void*)0)) {
329#ifdef HAVE_SYSTEMD1
330 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
331 GsmSystemd *systemd;
332 systemd = gsm_get_systemd ();
333 session_type = gsm_systemd_get_current_session_type (systemd);
334 g_object_unref (systemd);
335 is_not_login = (g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") != 0);
336 }
337 else {
338#endif
339 GsmConsolekit *consolekit;
340 consolekit = gsm_get_consolekit ();
341 session_type = gsm_consolekit_get_current_session_type (consolekit);
342 g_object_unref (consolekit);
343 is_not_login = (g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") != 0);
344#ifdef HAVE_SYSTEMD1
345 }
346#endif
347 }
348
349 if (is_not_login) {
350 char *name;
351
352 name = g_locale_to_utf8 (g_get_real_name (), -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
353
354 if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0) {
355 name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL((void*)0), NULL((void*)0), NULL((void*)0));
356 }
357
358 if (!name) {
359 name = g_strdup (g_get_user_name ())g_strdup_inline (g_get_user_name ());
360 }
361
362 secondary_text = g_strdup_printf (_("You are currently logged in as \"%s\".")gettext ("You are currently logged in as \"%s\"."), name);
363
364 g_free (name);
365 } else {
366 secondary_text = g_strdup (seconds_warning)g_strdup_inline (seconds_warning);
367 }
368
369 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
,
370 logout_dialog->timeout / 60.0);
371 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
,
372 seconds_warning);
373
374 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog)((((GtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((logout_dialog)), ((gtk_message_dialog_get_type
()))))))
,
375 secondary_text,
376 NULL((void*)0));
377
378 logout_dialog->timeout--;
379
380 g_free (secondary_text);
381 g_free (seconds_warning);
382
383 return TRUE(!(0));
384}
385
386static void
387gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog)
388{
389 GSettings *settings;
390
391 settings = g_settings_new (SESSION_SCHEMA"org.mate.session");
392
393 logout_dialog->timeout = g_settings_get_int (settings, KEY_LOGOUT_TIMEOUT"logout-timeout");
394
395 if (logout_dialog->timeout > 0) {
396 /* Sets the secondary text */
397 gsm_logout_dialog_timeout (logout_dialog);
398
399 if (logout_dialog->timeout_id != 0) {
400 g_source_remove (logout_dialog->timeout_id);
401 }
402
403 logout_dialog->timeout_id = g_timeout_add (1000,
404 gsm_logout_dialog_timeout,
405 logout_dialog);
406 }
407 else {
408 gtk_widget_hide (logout_dialog->progressbar);
409 }
410
411 g_object_unref (settings);
412}
413
414static GtkWidget *
415gsm_get_dialog (GsmDialogLogoutType type,
416 GdkScreen *screen,
417 guint32 activate_time)
418{
419 GsmLogoutDialog *logout_dialog;
420 GtkWidget *hbox;
421 const char *primary_text;
422 const char *icon_name;
423
424 if (current_dialog != NULL((void*)0)) {
425 gtk_widget_destroy (GTK_WIDGET (current_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((current_dialog)), ((gtk_widget_get_type ()))))))
);
426 }
427
428 logout_dialog = g_object_new (GSM_TYPE_LOGOUT_DIALOG(gsm_logout_dialog_get_type ()), NULL((void*)0));
429
430 current_dialog = logout_dialog;
431
432 gtk_window_set_title (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, "");
433
434 logout_dialog->type = type;
435
436 icon_name = NULL((void*)0);
437 primary_text = NULL((void*)0);
438
439 switch (type) {
440 case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
441 icon_name = GSM_ICON_LOGOUT"system-log-out";
442 primary_text = _("Log out of this system now?")gettext ("Log out of this system now?");
443
444 logout_dialog->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
445
446 if (gsm_logout_supports_switch_user (logout_dialog)) {
447 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
448 _("_Switch User")gettext ("_Switch User"), "system-users",
449 GSM_LOGOUT_RESPONSE_SWITCH_USER);
450 }
451
452 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
453 _("_Cancel")gettext ("_Cancel"), "process-stop",
454 GTK_RESPONSE_CANCEL);
455
456 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
457 _("_Log Out")gettext ("_Log Out"), "system-log-out",
458 GSM_LOGOUT_RESPONSE_LOGOUT);
459
460 break;
461 case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
462 icon_name = GSM_ICON_SHUTDOWN"system-shutdown";
463 primary_text = _("Shut down this system now?")gettext ("Shut down this system now?");
464
465 logout_dialog->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
466
467 if (gsm_logout_supports_system_suspend (logout_dialog)) {
468 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
469 _("S_uspend")gettext ("S_uspend"), "battery",
470 GSM_LOGOUT_RESPONSE_SLEEP);
471 }
472
473 if (gsm_logout_supports_system_hibernate (logout_dialog)) {
474 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
475 _("_Hibernate")gettext ("_Hibernate"), "drive-harddisk",
476 GSM_LOGOUT_RESPONSE_HIBERNATE);
477 }
478
479 if (gsm_logout_supports_reboot (logout_dialog)) {
480 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
481 _("_Restart")gettext ("_Restart"), "view-refresh",
482 GSM_LOGOUT_RESPONSE_REBOOT);
483 }
484
485 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
486 _("_Cancel")gettext ("_Cancel"), "process-stop",
487 GTK_RESPONSE_CANCEL);
488
489 if (gsm_logout_supports_shutdown (logout_dialog)) {
490 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
491 _("_Shut Down")gettext ("_Shut Down"), "system-shutdown",
492 GSM_LOGOUT_RESPONSE_SHUTDOWN);
493 }
494 break;
495 default:
496 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-logout-dialog.c"
, 496, ((const char*) (__func__)), ((void*)0)); } while (0)
;
497 }
498
499 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
500 logout_dialog->progressbar = gtk_progress_bar_new ();
501 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
, TRUE(!(0)));
502 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
, 1.0);
503 gtk_box_pack_start (GTK_BOX (hbox)((((GtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((gtk_box_get_type ()))))))
,
504 logout_dialog->progressbar,
505 TRUE(!(0)), TRUE(!(0)), 12);
506 gtk_widget_show_all (hbox);
507 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog)))((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_dialog_get_content_area (((((GtkDialog*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((logout_dialog)), ((gtk_dialog_get_type (
)))))))))), ((gtk_container_get_type ()))))))
, hbox);
508
509 gtk_window_set_icon_name (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, icon_name);
510 gtk_window_set_position (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, GTK_WIN_POS_CENTER_ALWAYS);
511 gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (logout_dialog)((((GtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((logout_dialog)), ((gtk_message_dialog_get_type
()))))))
, primary_text);
512
513 gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
514 logout_dialog->default_response);
515
516 gtk_window_set_screen (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, screen);
517
518 return GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
;
519}
520
521GtkWidget *
522gsm_get_shutdown_dialog (GdkScreen *screen,
523 guint32 activate_time)
524{
525 return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN,
526 screen,
527 activate_time);
528}
529
530GtkWidget *
531gsm_get_logout_dialog (GdkScreen *screen,
532 guint32 activate_time)
533{
534 return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
535 screen,
536 activate_time);
537}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-3d2264.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-3d2264.html new file mode 100644 index 0000000..cad7b07 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-3d2264.html @@ -0,0 +1,1525 @@ + + + +main.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/main.c
Warning:line 521, column 18
Out of bound memory access (access exceeds upper limit of memory block)
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c main.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23#include <config.h>
24
25#include <signal.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <errno(*__errno_location ()).h>
30#include <time.h>
31
32#include <glib/gi18n.h>
33#include <glib.h>
34#include <gtk/gtk.h>
35#include <gio/gio.h>
36
37#include <dbus/dbus.h>
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-bindings.h>
40#include <dbus/dbus-glib-lowlevel.h>
41
42#include "mdm-signal-handler.h"
43#include "mdm-log.h"
44
45#include "gsm-consolekit.h"
46#ifdef HAVE_SYSTEMD1
47#include "gsm-systemd.h"
48#endif
49#include "gsm-util.h"
50#include "gsm-manager.h"
51#include "gsm-xsmp-server.h"
52#include "gsm-store.h"
53
54#include "msm-gnome.h"
55
56#define GSM_SCHEMA"org.mate.session" "org.mate.session"
57#define GSM_DEFAULT_SESSION_KEY"default-session" "default-session"
58#define GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components" GSM_SCHEMA"org.mate.session" ".required-components"
59#define GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list" "required-components-list"
60
61#define ACCESSIBILITY_KEY"accessibility" "accessibility"
62#define ACCESSIBILITY_SCHEMA"org.mate.interface" "org.mate.interface"
63
64#define DEBUG_SCHEMA"org.mate.debug" "org.mate.debug"
65#define DEBUG_KEY"mate-session" "mate-session"
66
67#define VISUAL_SCHEMA"org.mate.applications-at-visual" "org.mate.applications-at-visual"
68#define VISUAL_KEY"exec" "exec"
69#define VISUAL_STARTUP_KEY"startup" "startup"
70
71#define MOBILITY_SCHEMA"org.mate.applications-at-mobility" "org.mate.applications-at-mobility"
72#define MOBILITY_KEY"exec" "exec"
73#define MOBILITY_STARTUP_KEY"startup" "startup"
74
75#define MATE_INTERFACE_SCHEMA"org.mate.interface" "org.mate.interface"
76#define GTK_OVERLAY_SCROLL"gtk-overlay-scrolling" "gtk-overlay-scrolling"
77
78#define GSM_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
79
80#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
81
82static gboolean failsafe = FALSE(0);
83static gboolean show_version = FALSE(0);
84static gboolean debug = FALSE(0);
85static gboolean disable_acceleration_check = FALSE(0);
86
87static gboolean
88initialize_gsettings (void)
89{
90 GSettings* settings;
91 time_t now = time (0);
92 gboolean ret;
93
94 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
95
96 if (!settings)
97 return FALSE(0);
98
99 ret = g_settings_set_int (settings, "session-start", now);
100
101 g_settings_sync ();
102
103 g_object_unref (settings);
104
105 return ret;
106}
107
108static void on_bus_name_lost(DBusGProxy* bus_proxy, const char* name, gpointer data)
109{
110 g_warning("Lost name on bus: %s, exiting", name);
111 exit(1);
112}
113
114static gboolean acquire_name_on_proxy(DBusGProxy* bus_proxy, const char* name)
115{
116 GError* error;
117 guint result;
118 gboolean res;
119 gboolean ret;
120
121 ret = FALSE(0);
122
123 if (bus_proxy == NULL((void*)0))
124 {
125 goto out;
126 }
127
128 error = NULL((void*)0);
129 res = dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING((GType) ((16) << (2))), name, G_TYPE_UINT((GType) ((7) << (2))), 0, G_TYPE_INVALID((GType) ((0) << (2))), G_TYPE_UINT((GType) ((7) << (2))), &result, G_TYPE_INVALID((GType) ((0) << (2))));
130
131 if (! res)
132 {
133 if (error != NULL((void*)0))
134 {
135 g_warning("Failed to acquire %s: %s", name, error->message);
136 g_error_free(error);
137 }
138 else
139 {
140 g_warning ("Failed to acquire %s", name);
141 }
142
143 goto out;
144 }
145
146 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER1)
147 {
148 if (error != NULL((void*)0))
149 {
150 g_warning("Failed to acquire %s: %s", name, error->message);
151 g_error_free(error);
152 }
153 else
154 {
155 g_warning("Failed to acquire %s", name);
156 }
157
158 goto out;
159 }
160
161 /* register for name lost */
162 dbus_g_proxy_add_signal(bus_proxy, "NameLost", G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_INVALID((GType) ((0) << (2))));
163 dbus_g_proxy_connect_signal(bus_proxy, "NameLost", G_CALLBACK(on_bus_name_lost)((GCallback) (on_bus_name_lost)), NULL((void*)0), NULL((void*)0));
164
165 ret = TRUE(!(0));
166
167 out:
168
169 return ret;
170}
171
172static gboolean acquire_name(void)
173{
174 DBusGProxy* bus_proxy;
175 GError* error;
176 DBusGConnection* connection;
177
178 error = NULL((void*)0);
179 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
180
181 if (connection == NULL((void*)0))
182 {
183 gsm_util_init_error(TRUE(!(0)), "Could not connect to session bus: %s", error->message);
184 /* not reached */
185 }
186
187 bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS"org.freedesktop.DBus", DBUS_PATH_DBUS"/org/freedesktop/DBus", DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
188
189 if (!acquire_name_on_proxy(bus_proxy, GSM_DBUS_NAME"org.gnome.SessionManager"))
190 {
191 gsm_util_init_error(TRUE(!(0)), "%s", "Could not acquire name on session bus");
192 /* not reached */
193 }
194
195 g_object_unref(bus_proxy);
196
197 return TRUE(!(0));
198}
199
200/* This doesn't contain the required components, so we need to always
201 * call append_required_apps() after a call to append_default_apps(). */
202static void append_default_apps(GsmManager* manager, const char* default_session_key, char** autostart_dirs)
203{
204 gint i;
205 gchar** default_apps;
206 GSettings* settings;
207
208 g_debug("main: *** Adding default apps");
209
210 g_assert(default_session_key != NULL)do { if (default_session_key != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 210, ((const char*) (__func__)), "default_session_key != NULL"
); } while (0)
;
211 g_assert(autostart_dirs != NULL)do { if (autostart_dirs != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 211, ((const char*) (__func__)), "autostart_dirs != NULL"
); } while (0)
;
212
213 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
214 default_apps = g_settings_get_strv (settings, default_session_key);
215 g_object_unref(settings);
216
217 for (i = 0; default_apps[i]; i++)
218 {
219 char* app_path;
220
221 if (IS_STRING_EMPTY((char*) default_apps[i])(((char*) default_apps[i])==((void*)0)||((char*) default_apps
[i])[0]=='\0')
)
222 {
223 continue;
224 }
225
226 app_path = gsm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs);
227
228 if (app_path != NULL((void*)0))
229 {
230 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
231 g_free(app_path);
232 }
233 }
234
235 g_strfreev (default_apps);
236}
237
238static void append_required_apps(GsmManager* manager)
239{
240 gchar** required_components;
241 gint i;
242 GSettings* settings;
243 GSettings* settings_required_components;
244
245 g_debug("main: *** Adding required apps");
246
247 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
248 settings_required_components = g_settings_new (GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components");
249
250 required_components = g_settings_get_strv(settings, GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list");
251
252 if (required_components == NULL((void*)0))
253 {
254 g_warning("No required applications specified");
255 }
256 else
257 {
258 for (i = 0; required_components[i]; i++)
259 {
260 char* default_provider;
261 const char* component;
262
263 if (IS_STRING_EMPTY((char*) required_components[i])(((char*) required_components[i])==((void*)0)||((char*) required_components
[i])[0]=='\0')
)
264 {
265 continue;
266 }
267
268 component = required_components[i];
269
270 default_provider = g_settings_get_string (settings_required_components, component);
271
272 g_debug ("main: %s looking for component: '%s'", component, default_provider);
273
274 if (default_provider != NULL((void*)0))
275 {
276 char* app_path;
277
278 app_path = gsm_util_find_desktop_file_for_app_name(default_provider, NULL((void*)0));
279
280 if (app_path != NULL((void*)0))
281 {
282 gsm_manager_add_autostart_app(manager, app_path, component);
283 }
284 else
285 {
286 g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component);
287 }
288
289 g_free(app_path);
290 }
291
292 g_free(default_provider);
293 }
294 }
295
296 g_debug("main: *** Done adding required apps");
297
298 g_strfreev(required_components);
299
300 g_object_unref(settings);
301 g_object_unref(settings_required_components);
302}
303
304static void append_accessibility_apps(GsmManager* manager)
305{
306 GSettings* mobility_settings;
307 GSettings* visual_settings;
308
309 g_debug("main: *** Adding accesibility apps");
310
311 mobility_settings = g_settings_new (MOBILITY_SCHEMA"org.mate.applications-at-mobility");
312 visual_settings = g_settings_new (VISUAL_SCHEMA"org.mate.applications-at-visual");
313
314 if (g_settings_get_boolean (mobility_settings, MOBILITY_STARTUP_KEY"startup"))
315 {
316 gchar *mobility_exec;
317 mobility_exec = g_settings_get_string (mobility_settings, MOBILITY_KEY"exec");
318 if (mobility_exec != NULL((void*)0) && mobility_exec[0] != 0)
319 {
320 char* app_path;
321 app_path = gsm_util_find_desktop_file_for_app_name(mobility_exec, NULL((void*)0));
322 if (app_path != NULL((void*)0))
323 {
324 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
325 g_free (app_path);
326 }
327 g_free (mobility_exec);
328 }
329 }
330
331 if (g_settings_get_boolean (visual_settings, VISUAL_STARTUP_KEY"startup"))
332 {
333 gchar *visual_exec;
334 visual_exec = g_settings_get_string (visual_settings, VISUAL_KEY"exec");
335 if (visual_exec != NULL((void*)0) && visual_exec[0] != 0)
336 {
337 char* app_path;
338 app_path = gsm_util_find_desktop_file_for_app_name(visual_exec, NULL((void*)0));
339 if (app_path != NULL((void*)0))
340 {
341 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
342 g_free (app_path);
343 }
344 g_free (visual_exec);
345 }
346 }
347
348 g_object_unref (mobility_settings);
349 g_object_unref (visual_settings);
350}
351
352static void maybe_load_saved_session_apps(GsmManager* manager)
353{
354 GsmConsolekit* consolekit = NULL((void*)0);
355#ifdef HAVE_SYSTEMD1
356 GsmSystemd* systemd = NULL((void*)0);
357#endif
358 char* session_type;
359 gboolean is_login;
360
361#ifdef HAVE_SYSTEMD1
362 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
363 systemd = gsm_get_systemd();
364 session_type = gsm_systemd_get_current_session_type(systemd);
365 is_login = g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0;
366 }
367 else {
368#endif
369 consolekit = gsm_get_consolekit();
370 session_type = gsm_consolekit_get_current_session_type(consolekit);
371 is_login = g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0;
372#ifdef HAVE_SYSTEMD1
373 }
374#endif
375
376 if (!is_login)
377 {
378 GSettings* settings;
379 gboolean autostart;
380
381 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
382 autostart = g_settings_get_boolean (settings, KEY_AUTOSAVE"auto-save-session");
383 g_object_unref (settings);
384
385 if (autostart == TRUE(!(0)))
386 gsm_manager_add_autostart_apps_from_dir(manager, gsm_util_get_saved_session_dir());
387 }
388
389 if (consolekit != NULL((void*)0))
390 g_object_unref(consolekit);
391#ifdef HAVE_SYSTEMD1
392 if (systemd != NULL((void*)0))
393 g_object_unref(systemd);
394#endif
395 g_free(session_type);
396}
397
398static void load_standard_apps (GsmManager* manager, const char* default_session_key)
399{
400 char** autostart_dirs;
401 int i;
402
403 autostart_dirs = gsm_util_get_autostart_dirs();
404
405 if (!failsafe)
406 {
407 maybe_load_saved_session_apps(manager);
408
409 for (i = 0; autostart_dirs[i]; i++)
410 {
411 gsm_manager_add_autostart_apps_from_dir(manager, autostart_dirs[i]);
412 }
413 }
414
415 /* We do this at the end in case a saved session contains an
416 * application that already provides one of the components. */
417 append_default_apps(manager, default_session_key, autostart_dirs);
418 append_required_apps(manager);
419 append_accessibility_apps(manager);
420
421 g_strfreev(autostart_dirs);
422}
423
424static void load_override_apps(GsmManager* manager, char** override_autostart_dirs)
425{
426 int i;
427
428 for (i = 0; override_autostart_dirs[i]; i++)
429 {
430 gsm_manager_add_autostart_apps_from_dir(manager, override_autostart_dirs[i]);
431 }
432}
433
434static gboolean signal_cb(int signo, gpointer data)
435{
436 int ret;
437 GsmManager* manager;
438
439 g_debug("Got callback for signal %d", signo);
440
441 ret = TRUE(!(0));
442
443 switch (signo)
444 {
445 case SIGFPE8:
446 case SIGPIPE13:
447 /* let the fatal signals interrupt us */
448 g_debug ("Caught signal %d, shutting down abnormally.", signo);
449 ret = FALSE(0);
450 break;
451 case SIGINT2:
452 case SIGTERM15:
453 manager = (GsmManager*) data;
454 gsm_manager_logout(manager, GSM_MANAGER_LOGOUT_MODE_FORCE, NULL((void*)0));
455
456 /* let the fatal signals interrupt us */
457 g_debug("Caught signal %d, shutting down normally.", signo);
458 ret = TRUE(!(0));
459 break;
460 case SIGHUP1:
461 g_debug("Got HUP signal");
462 ret = TRUE(!(0));
463 break;
464 case SIGUSR110:
465 g_debug("Got USR1 signal");
466 ret = TRUE(!(0));
467 mdm_log_toggle_debug();
468 break;
469 default:
470 g_debug("Caught unhandled signal %d", signo);
471 ret = TRUE(!(0));
472
473 break;
474 }
475
476 return ret;
477}
478
479static void shutdown_cb(gpointer data)
480{
481 GsmManager* manager = (GsmManager*) data;
482 g_debug("Calling shutdown callback function");
483
484 /*
485 * When the signal handler gets a shutdown signal, it calls
486 * this function to inform GsmManager to not restart
487 * applications in the off chance a handler is already queued
488 * to dispatch following the below call to gtk_main_quit.
489 */
490 gsm_manager_set_phase(manager, GSM_MANAGER_PHASE_EXIT);
491
492 gtk_main_quit();
493}
494
495static gboolean require_dbus_session(int argc, char** argv, GError** error)
496{
497 char** new_argv;
498 int i;
499
500 if (g_getenv("DBUS_SESSION_BUS_ADDRESS"))
2
Assuming the condition is false
501 {
502 return TRUE(!(0));
503 }
504
505 /* Just a sanity check to prevent infinite recursion if
506 * dbus-launch fails to set DBUS_SESSION_BUS_ADDRESS
507 */
508 g_return_val_if_fail(!g_str_has_prefix(argv[0], "dbus-launch"), TRUE)do { if ((!(__builtin_constant_p ("dbus-launch")? __extension__
({ const char * const __str = (argv[0]); const char * const __prefix
= ("dbus-launch"); gboolean __result = (0); if (__str == ((void
*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix)
(__str, __prefix); else { const size_t __str_len = strlen ((
(__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (argv[0], "dbus-launch"
) ))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const
char*) (__func__)), "!g_str_has_prefix(argv[0], \"dbus-launch\")"
); return ((!(0))); } } while (0)
;
3
Taking false branch
4
'?' condition is true
5
Assuming '__str' is equal to null
6
Assuming the condition is true
7
Taking true branch
8
Loop condition is false. Exiting loop
509
510 /* +2 for our new arguments, +1 for NULL */
511 new_argv = g_malloc(argc + 3 * sizeof (*argv));
512
513 new_argv[0] = "dbus-launch";
514 new_argv[1] = "--exit-with-session";
515
516 for (i = 0; i
8.1
'i' is < 'argc'
< argc
; i++)
9
Loop condition is true. Entering loop body
10
Assuming 'i' is < 'argc'
11
Loop condition is true. Entering loop body
12
Assuming 'i' is >= 'argc'
13
Loop condition is false. Execution continues on line 521
517 {
518 new_argv[i + 2] = argv[i];
519 }
520
521 new_argv[i + 2] = NULL((void*)0);
14
Out of bound memory access (access exceeds upper limit of memory block)
522
523 if (!execvp("dbus-launch", new_argv))
524 {
525 g_set_error(error, G_SPAWN_ERRORg_spawn_error_quark (), G_SPAWN_ERROR_FAILED, "No session bus and could not exec dbus-launch: %s", g_strerror(errno(*__errno_location ())));
526 g_free (new_argv);
527 return FALSE(0);
528 }
529
530 g_free (new_argv);
531
532 /* Should not be reached */
533 return TRUE(!(0));
534}
535
536static void
537debug_changed (GSettings *settings, gchar *key, gpointer user_data)
538{
539 debug = g_settings_get_boolean (settings, DEBUG_KEY"mate-session");
540 mdm_log_set_debug (debug);
541}
542
543static gboolean
544schema_exists (const gchar* schema_name)
545{
546 GSettingsSchemaSource *source;
547 GSettingsSchema *schema;
548 gboolean exists;
549
550 source = g_settings_schema_source_get_default();
551 schema = g_settings_schema_source_lookup (source, schema_name, FALSE(0));
552 exists = (schema != NULL((void*)0));
553 if (schema)
554 g_settings_schema_unref (schema);
555
556 return exists;
557}
558
559static void set_overlay_scroll (void)
560{
561 GSettings *settings;
562 gboolean enabled;
563
564 settings = g_settings_new (MATE_INTERFACE_SCHEMA"org.mate.interface");
565 enabled = g_settings_get_boolean (settings, GTK_OVERLAY_SCROLL"gtk-overlay-scrolling");
566
567 if (enabled) {
568 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "1");
569 } else {
570 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "0");
571 }
572
573 g_object_unref (settings);
574}
575
576static gboolean
577check_gl (gchar **gl_renderer, GError **error)
578{
579 int status;
580 char *argv[] = { LIBEXECDIR"/usr/local/libexec" "/mate-session-check-accelerated", NULL((void*)0) };
581
582 if (getenv ("DISPLAY") == NULL((void*)0)) {
583 /* Not connected to X11, someone else will take care of checking GL */
584 return TRUE(!(0));
585 }
586
587 if (!g_spawn_sync (NULL((void*)0), (char **) argv, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), gl_renderer, NULL((void*)0),
588 &status, error)) {
589 return FALSE(0);
590 }
591
592 return g_spawn_check_exit_status (status, error);
593}
594
595int main(int argc, char** argv)
596{
597 struct sigaction sa;
598 GError* error;
599 const char* display_str;
600 GsmManager* manager;
601 GsmStore* client_store;
602 GsmXsmpServer* xsmp_server;
603 GSettings* debug_settings = NULL((void*)0);
604 GSettings* accessibility_settings;
605 MdmSignalHandler* signal_handler;
606 static char** override_autostart_dirs = NULL((void*)0);
607 char* gl_renderer = NULL((void*)0);
608 gboolean gl_failed = FALSE(0);
609
610 static GOptionEntry entries[] = {
611 {"autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories")("Override standard autostart directories"), NULL((void*)0)},
612 {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code")("Enable debugging code"), NULL((void*)0)},
613 {"failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications")("Do not load user-specified applications"), NULL((void*)0)},
614 {"version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application")("Version of this application"), NULL((void*)0)},
615 { "disable-acceleration-check", 0, 0, G_OPTION_ARG_NONE, &disable_acceleration_check, N_("Disable hardware acceleration check")("Disable hardware acceleration check"), NULL((void*)0) },
616 {NULL((void*)0), 0, 0, 0, NULL((void*)0), NULL((void*)0), NULL((void*)0) }
617 };
618
619 /* Make sure that we have a session bus */
620 if (!require_dbus_session(argc, argv, &error))
1
Calling 'require_dbus_session'
621 {
622 gsm_util_init_error(TRUE(!(0)), "%s", error->message);
623 }
624
625#ifdef ENABLE_NLS1
626 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
627 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
628 textdomain(GETTEXT_PACKAGE"mate-session-manager");
629#endif /* ENABLE_NLS */
630
631 sa.sa_handler__sigaction_handler.sa_handler = SIG_IGN((__sighandler_t) 1);
632 sa.sa_flags = 0;
633 sigemptyset(&sa.sa_mask);
634 sigaction(SIGPIPE13, &sa, 0);
635
636 error = NULL((void*)0);
637 gtk_init_with_args(&argc, &argv, (char*) _(" - the MATE session manager")gettext (" - the MATE session manager"), entries, GETTEXT_PACKAGE"mate-session-manager", &error);
638
639 if (error != NULL((void*)0))
640 {
641 g_warning("%s", error->message);
642 exit(1);
643 }
644
645 if (show_version)
646 {
647 g_print("%s %s\n", g_get_application_name(), VERSION"1.27.0");
648 exit(1);
649 }
650
651 gsm_util_export_activation_environment (NULL((void*)0));
652
653#ifdef HAVE_SYSTEMD1
654 gsm_util_export_user_environment (NULL((void*)0));
655#endif
656
657 mdm_log_init();
658
659 /* Allows to enable/disable debug from GSettings only if it is not set from argument */
660 if (!debug && schema_exists(DEBUG_SCHEMA"org.mate.debug"))
661 {
662 debug_settings = g_settings_new (DEBUG_SCHEMA"org.mate.debug");
663 g_signal_connect (debug_settings, "changed::" DEBUG_KEY, G_CALLBACK (debug_changed), NULL)g_signal_connect_data ((debug_settings), ("changed::" "mate-session"
), (((GCallback) (debug_changed))), (((void*)0)), ((void*)0),
(GConnectFlags) 0)
;
664 debug = g_settings_get_boolean (debug_settings, DEBUG_KEY"mate-session");
665 }
666
667 mdm_log_set_debug(debug);
668
669 if (disable_acceleration_check) {
670 g_debug ("hardware acceleration check is disabled");
671 } else {
672 /* Check GL, if it doesn't work out then force software fallback */
673 if (!check_gl (&gl_renderer, &error)) {
674 gl_failed = TRUE(!(0));
675
676 g_debug ("hardware acceleration check failed: %s",
677 error? error->message : "");
678 g_clear_error (&error);
679 if (g_getenv ("LIBGL_ALWAYS_SOFTWARE") == NULL((void*)0)) {
680 g_setenv ("LIBGL_ALWAYS_SOFTWARE", "1", TRUE(!(0)));
681 if (!check_gl (&gl_renderer, &error)) {
682 g_warning ("software acceleration check failed: %s",
683 error? error->message : "");
684 g_clear_error (&error);
685 } else {
686 gl_failed = FALSE(0);
687 }
688 }
689 }
690 }
691
692 if (gl_failed) {
693 g_warning ("gl_failed!");
694 }
695
696 if (g_getenv ("XDG_CURRENT_DESKTOP") == NULL((void*)0))
697 gsm_util_setenv ("XDG_CURRENT_DESKTOP", "MATE");
698
699 /* Set DISPLAY explicitly for all our children, in case --display
700 * was specified on the command line.
701 */
702 display_str = gdk_display_get_name (gdk_display_get_default());
703 gsm_util_setenv("DISPLAY", display_str);
704
705 /* Some third-party programs rely on MATE_DESKTOP_SESSION_ID to
706 * detect if MATE is running. We keep this for compatibility reasons.
707 */
708 gsm_util_setenv("MATE_DESKTOP_SESSION_ID", "this-is-deprecated");
709
710 /*
711 * Make sure gsettings is set up correctly. If not, then bail.
712 */
713
714 if (initialize_gsettings () != TRUE(!(0)))
715 exit (1);
716
717 /* Look if accessibility is enabled */
718 accessibility_settings = g_settings_new (ACCESSIBILITY_SCHEMA"org.mate.interface");
719 if (g_settings_get_boolean (accessibility_settings, ACCESSIBILITY_KEY"accessibility"))
720 {
721 gsm_util_setenv("GTK_MODULES", "gail:atk-bridge");
722 }
723 g_object_unref (accessibility_settings);
724
725 client_store = gsm_store_new();
726
727 xsmp_server = gsm_xsmp_server_new(client_store);
728
729 /* Now make sure they succeeded. (They'll call
730 * gsm_util_init_error() if they failed.)
731 */
732 acquire_name();
733
734 /* Starts gnome compat mode */
735 msm_gnome_start();
736
737 /* Set to use Gtk3 overlay scroll */
738 set_overlay_scroll ();
739
740 manager = gsm_manager_new(client_store, failsafe);
741
742 signal_handler = mdm_signal_handler_new();
743 mdm_signal_handler_add_fatal(signal_handler);
744 mdm_signal_handler_add(signal_handler, SIGFPE8, signal_cb, NULL((void*)0));
745 mdm_signal_handler_add(signal_handler, SIGHUP1, signal_cb, NULL((void*)0));
746 mdm_signal_handler_add(signal_handler, SIGUSR110, signal_cb, NULL((void*)0));
747 mdm_signal_handler_add(signal_handler, SIGTERM15, signal_cb, manager);
748 mdm_signal_handler_add(signal_handler, SIGINT2, signal_cb, manager);
749 mdm_signal_handler_set_fatal_func(signal_handler, shutdown_cb, manager);
750
751 if (override_autostart_dirs != NULL((void*)0))
752 {
753 load_override_apps(manager, override_autostart_dirs);
754 }
755 else
756 {
757 load_standard_apps(manager, GSM_DEFAULT_SESSION_KEY"default-session");
758 }
759
760 gsm_xsmp_server_start(xsmp_server);
761 _gsm_manager_set_renderer (manager, gl_renderer);
762 gsm_manager_start(manager);
763
764 gtk_main();
765
766 if (xsmp_server != NULL((void*)0))
767 {
768 g_object_unref(xsmp_server);
769 }
770
771 if (manager != NULL((void*)0))
772 {
773 g_debug("Unreffing manager");
774 g_object_unref(manager);
775 }
776
777 if (gl_renderer != NULL((void*)0))
778 {
779 g_free (gl_renderer);
780 }
781
782 if (client_store != NULL((void*)0))
783 {
784 g_object_unref(client_store);
785 }
786
787 if (debug_settings != NULL((void*)0))
788 {
789 g_object_unref(debug_settings);
790 }
791
792 msm_gnome_stop();
793 mdm_log_shutdown();
794
795 return 0;
796}
797
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-4cf1eb.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-4cf1eb.html new file mode 100644 index 0000000..f38a84f --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-4cf1eb.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 259, column 7
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
This statement is never executed
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-5ded7d.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-5ded7d.html new file mode 100644 index 0000000..1653339 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-5ded7d.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 279, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
This statement is never executed
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-615882.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-615882.html new file mode 100644 index 0000000..192a36e --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-615882.html @@ -0,0 +1,1217 @@ + + + +gsm-logout-dialog.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/gsm-logout-dialog.c
Warning:line 211, column 9
Value stored to 'ret' is never read
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-logout-dialog.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-logout-dialog.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Vincent Untz
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 * Authors:
23 * Vincent Untz <vuntz@gnome.org>
24 */
25
26#include <config.h>
27
28#include <glib/gi18n.h>
29#include <gtk/gtk.h>
30
31#include "gsm-logout-dialog.h"
32#ifdef HAVE_SYSTEMD1
33#include "gsm-systemd.h"
34#endif
35#include "gsm-consolekit.h"
36#include "mdm.h"
37#include "gsm-util.h"
38
39#define GSM_ICON_LOGOUT"system-log-out" "system-log-out"
40#define GSM_ICON_SHUTDOWN"system-shutdown" "system-shutdown"
41
42#define SESSION_SCHEMA"org.mate.session" "org.mate.session"
43#define KEY_LOGOUT_TIMEOUT"logout-timeout" "logout-timeout"
44
45#define LOCKDOWN_SCHEMA"org.mate.lockdown" "org.mate.lockdown"
46#define KEY_USER_SWITCHING_DISABLE"disable-user-switching" "disable-user-switching"
47
48typedef enum {
49 GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
50 GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN
51} GsmDialogLogoutType;
52
53struct _GsmLogoutDialog
54{
55 GtkMessageDialog parent;
56 GsmDialogLogoutType type;
57#ifdef HAVE_SYSTEMD1
58 GsmSystemd *systemd;
59#endif
60 GsmConsolekit *consolekit;
61
62 GtkWidget *progressbar;
63
64 int timeout;
65 unsigned int timeout_id;
66
67 unsigned int default_response;
68};
69
70static GsmLogoutDialog *current_dialog = NULL((void*)0);
71
72static void gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog);
73
74static void gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
75 gpointer data);
76
77static void gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog,
78 gpointer data);
79
80enum {
81 PROP_0,
82 PROP_MESSAGE_TYPE
83};
84
85G_DEFINE_TYPE (GsmLogoutDialog, gsm_logout_dialog, GTK_TYPE_MESSAGE_DIALOG)static void gsm_logout_dialog_init (GsmLogoutDialog *self); static
void gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass
); static GType gsm_logout_dialog_get_type_once (void); static
gpointer gsm_logout_dialog_parent_class = ((void*)0); static
gint GsmLogoutDialog_private_offset; static void gsm_logout_dialog_class_intern_init
(gpointer klass) { gsm_logout_dialog_parent_class = g_type_class_peek_parent
(klass); if (GsmLogoutDialog_private_offset != 0) g_type_class_adjust_private_offset
(klass, &GsmLogoutDialog_private_offset); gsm_logout_dialog_class_init
((GsmLogoutDialogClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer gsm_logout_dialog_get_instance_private
(GsmLogoutDialog *self) { return (((gpointer) ((guint8*) (self
) + (glong) (GsmLogoutDialog_private_offset)))); } GType gsm_logout_dialog_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_logout_dialog_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_logout_dialog_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((gtk_message_dialog_get_type ()), g_intern_static_string ("GsmLogoutDialog"
), sizeof (GsmLogoutDialogClass), (GClassInitFunc)(void (*)(void
)) gsm_logout_dialog_class_intern_init, sizeof (GsmLogoutDialog
), (GInstanceInitFunc)(void (*)(void)) gsm_logout_dialog_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
;
86
87static void
88gsm_logout_dialog_set_property (GObject *object,
89 guint prop_id,
90 const GValue *value,
91 GParamSpec *pspec)
92{
93 switch (prop_id) {
94 case PROP_MESSAGE_TYPE:
95 break;
96 default:
97 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-logout-dialog.c", 97, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
98 break;
99 }
100}
101
102static void
103gsm_logout_dialog_get_property (GObject *object,
104 guint prop_id,
105 GValue *value,
106 GParamSpec *pspec)
107{
108 switch (prop_id) {
109 case PROP_MESSAGE_TYPE:
110 g_value_set_enum (value, GTK_MESSAGE_WARNING);
111 break;
112 default:
113 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-logout-dialog.c", 113, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
114 break;
115 }
116}
117
118static void
119gsm_logout_dialog_class_init (GsmLogoutDialogClass *klass)
120{
121 GObjectClass *gobject_class;
122
123 gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
124
125 /* This is a workaround to avoid a stupid crash: libmateui
126 * listens for the "show" signal on all GtkMessageDialog and
127 * gets the "message-type" of the dialogs. We will crash when
128 * it accesses this property if we don't override it since we
129 * didn't define it. */
130 gobject_class->set_property = gsm_logout_dialog_set_property;
131 gobject_class->get_property = gsm_logout_dialog_get_property;
132
133 g_object_class_override_property (gobject_class,
134 PROP_MESSAGE_TYPE,
135 "message-type");
136}
137
138static void
139gsm_logout_dialog_init (GsmLogoutDialog *logout_dialog)
140{
141 logout_dialog->timeout_id = 0;
142 logout_dialog->timeout = 0;
143 logout_dialog->default_response = GTK_RESPONSE_CANCEL;
144
145 GtkStyleContext *context;
146 context = gtk_widget_get_style_context (GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
);
147 gtk_style_context_add_class (context, "logout-dialog");
148
149 gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
150 gtk_window_set_keep_above (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
151 gtk_window_stick (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
);
152#ifdef HAVE_SYSTEMD1
153 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
154 logout_dialog->systemd = gsm_get_systemd ();
155 else
156#endif
157 logout_dialog->consolekit = gsm_get_consolekit ();
158
159 g_signal_connect (logout_dialog,g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
160 "destroy",g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
161 G_CALLBACK (gsm_logout_dialog_destroy),g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
162 NULL)g_signal_connect_data ((logout_dialog), ("destroy"), (((GCallback
) (gsm_logout_dialog_destroy))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
163
164 g_signal_connect (logout_dialog,g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
165 "show",g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
166 G_CALLBACK (gsm_logout_dialog_show),g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
167 NULL)g_signal_connect_data ((logout_dialog), ("show"), (((GCallback
) (gsm_logout_dialog_show))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
168}
169
170static void
171gsm_logout_dialog_destroy (GsmLogoutDialog *logout_dialog,
172 gpointer data)
173{
174 if (logout_dialog->timeout_id != 0) {
175 g_source_remove (logout_dialog->timeout_id);
176 logout_dialog->timeout_id = 0;
177 }
178#ifdef HAVE_SYSTEMD1
179 if (logout_dialog->systemd) {
180 g_object_unref (logout_dialog->systemd);
181 logout_dialog->systemd = NULL((void*)0);
182 }
183#endif
184
185 if (logout_dialog->consolekit) {
186 g_object_unref (logout_dialog->consolekit);
187 logout_dialog->consolekit = NULL((void*)0);
188 }
189
190 current_dialog = NULL((void*)0);
191}
192
193static gboolean
194gsm_logout_supports_system_suspend (GsmLogoutDialog *logout_dialog)
195{
196 gboolean ret;
197 ret = FALSE(0);
198#ifdef HAVE_SYSTEMD1
199 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
200 ret = gsm_systemd_can_suspend (logout_dialog->systemd);
201 else
202#endif
203 ret = gsm_consolekit_can_suspend (logout_dialog->consolekit);
204 return ret;
205}
206
207static gboolean
208gsm_logout_supports_system_hibernate (GsmLogoutDialog *logout_dialog)
209{
210 gboolean ret;
211 ret = FALSE(0);
Value stored to 'ret' is never read
212#ifdef HAVE_SYSTEMD1
213 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
214 ret = gsm_systemd_can_hibernate (logout_dialog->systemd);
215 else
216#endif
217 ret = gsm_consolekit_can_hibernate (logout_dialog->consolekit);
218 return ret;
219}
220
221static gboolean
222gsm_logout_supports_switch_user (GsmLogoutDialog *logout_dialog)
223{
224 GSettings *settings;
225 gboolean ret = FALSE(0);
226 gboolean locked;
227
228 settings = g_settings_new (LOCKDOWN_SCHEMA"org.mate.lockdown");
229
230 locked = g_settings_get_boolean (settings, KEY_USER_SWITCHING_DISABLE"disable-user-switching");
231 g_object_unref (settings);
232
233 if (!locked) {
234#ifdef HAVE_SYSTEMD1
235 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
236 ret = gsm_systemd_can_switch_user (logout_dialog->systemd);
237 else
238#endif
239 ret = gsm_consolekit_can_switch_user (logout_dialog->consolekit);
240 }
241
242 return ret;
243}
244
245static gboolean
246gsm_logout_supports_reboot (GsmLogoutDialog *logout_dialog)
247{
248 gboolean ret;
249
250#ifdef HAVE_SYSTEMD1
251 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
252 ret = gsm_systemd_can_restart (logout_dialog->systemd);
253 else
254#endif
255 ret = gsm_consolekit_can_restart (logout_dialog->consolekit);
256 if (!ret) {
257 ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_REBOOT);
258 }
259
260 return ret;
261}
262
263static gboolean
264gsm_logout_supports_shutdown (GsmLogoutDialog *logout_dialog)
265{
266 gboolean ret;
267
268#ifdef HAVE_SYSTEMD1
269 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0))
270 ret = gsm_systemd_can_stop (logout_dialog->systemd);
271 else
272#endif
273 ret = gsm_consolekit_can_stop (logout_dialog->consolekit);
274
275 if (!ret) {
276 ret = mdm_supports_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
277 }
278
279 return ret;
280}
281
282static void
283gsm_logout_dialog_show (GsmLogoutDialog *logout_dialog, gpointer user_data)
284{
285 gsm_logout_dialog_set_timeout (logout_dialog);
286}
287
288static gboolean
289gsm_logout_dialog_timeout (gpointer data)
290{
291 GsmLogoutDialog *logout_dialog;
292 char *seconds_warning;
293 char *secondary_text;
294 static char *session_type = NULL((void*)0);
295 static gboolean is_not_login;
296
297 logout_dialog = (GsmLogoutDialog *) data;
298
299 if (!logout_dialog->timeout) {
300 gtk_dialog_response (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
301 logout_dialog->default_response);
302
303 return FALSE(0);
304 }
305
306 switch (logout_dialog->type) {
307 case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
308 seconds_warning = ngettext ("You will be automatically logged "
309 "out in %d second",
310 "You will be automatically logged "
311 "out in %d seconds",
312 logout_dialog->timeout);
313 break;
314
315 case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
316 seconds_warning = ngettext ("This system will be automatically "
317 "shut down in %d second",
318 "This system will be automatically "
319 "shut down in %d seconds",
320 logout_dialog->timeout);
321 break;
322
323 default:
324 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-logout-dialog.c"
, 324, ((const char*) (__func__)), ((void*)0)); } while (0)
;
325 }
326 seconds_warning = g_strdup_printf (seconds_warning, logout_dialog->timeout);
327
328 if (session_type == NULL((void*)0)) {
329#ifdef HAVE_SYSTEMD1
330 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
331 GsmSystemd *systemd;
332 systemd = gsm_get_systemd ();
333 session_type = gsm_systemd_get_current_session_type (systemd);
334 g_object_unref (systemd);
335 is_not_login = (g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") != 0);
336 }
337 else {
338#endif
339 GsmConsolekit *consolekit;
340 consolekit = gsm_get_consolekit ();
341 session_type = gsm_consolekit_get_current_session_type (consolekit);
342 g_object_unref (consolekit);
343 is_not_login = (g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") != 0);
344#ifdef HAVE_SYSTEMD1
345 }
346#endif
347 }
348
349 if (is_not_login) {
350 char *name;
351
352 name = g_locale_to_utf8 (g_get_real_name (), -1, NULL((void*)0), NULL((void*)0), NULL((void*)0));
353
354 if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0) {
355 name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL((void*)0), NULL((void*)0), NULL((void*)0));
356 }
357
358 if (!name) {
359 name = g_strdup (g_get_user_name ())g_strdup_inline (g_get_user_name ());
360 }
361
362 secondary_text = g_strdup_printf (_("You are currently logged in as \"%s\".")gettext ("You are currently logged in as \"%s\"."), name);
363
364 g_free (name);
365 } else {
366 secondary_text = g_strdup (seconds_warning)g_strdup_inline (seconds_warning);
367 }
368
369 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
,
370 logout_dialog->timeout / 60.0);
371 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
,
372 seconds_warning);
373
374 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog)((((GtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((logout_dialog)), ((gtk_message_dialog_get_type
()))))))
,
375 secondary_text,
376 NULL((void*)0));
377
378 logout_dialog->timeout--;
379
380 g_free (secondary_text);
381 g_free (seconds_warning);
382
383 return TRUE(!(0));
384}
385
386static void
387gsm_logout_dialog_set_timeout (GsmLogoutDialog *logout_dialog)
388{
389 GSettings *settings;
390
391 settings = g_settings_new (SESSION_SCHEMA"org.mate.session");
392
393 logout_dialog->timeout = g_settings_get_int (settings, KEY_LOGOUT_TIMEOUT"logout-timeout");
394
395 if (logout_dialog->timeout > 0) {
396 /* Sets the secondary text */
397 gsm_logout_dialog_timeout (logout_dialog);
398
399 if (logout_dialog->timeout_id != 0) {
400 g_source_remove (logout_dialog->timeout_id);
401 }
402
403 logout_dialog->timeout_id = g_timeout_add (1000,
404 gsm_logout_dialog_timeout,
405 logout_dialog);
406 }
407 else {
408 gtk_widget_hide (logout_dialog->progressbar);
409 }
410
411 g_object_unref (settings);
412}
413
414static GtkWidget *
415gsm_get_dialog (GsmDialogLogoutType type,
416 GdkScreen *screen,
417 guint32 activate_time)
418{
419 GsmLogoutDialog *logout_dialog;
420 GtkWidget *hbox;
421 const char *primary_text;
422 const char *icon_name;
423
424 if (current_dialog != NULL((void*)0)) {
425 gtk_widget_destroy (GTK_WIDGET (current_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((current_dialog)), ((gtk_widget_get_type ()))))))
);
426 }
427
428 logout_dialog = g_object_new (GSM_TYPE_LOGOUT_DIALOG(gsm_logout_dialog_get_type ()), NULL((void*)0));
429
430 current_dialog = logout_dialog;
431
432 gtk_window_set_title (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, "");
433
434 logout_dialog->type = type;
435
436 icon_name = NULL((void*)0);
437 primary_text = NULL((void*)0);
438
439 switch (type) {
440 case GSM_DIALOG_LOGOUT_TYPE_LOGOUT:
441 icon_name = GSM_ICON_LOGOUT"system-log-out";
442 primary_text = _("Log out of this system now?")gettext ("Log out of this system now?");
443
444 logout_dialog->default_response = GSM_LOGOUT_RESPONSE_LOGOUT;
445
446 if (gsm_logout_supports_switch_user (logout_dialog)) {
447 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
448 _("_Switch User")gettext ("_Switch User"), "system-users",
449 GSM_LOGOUT_RESPONSE_SWITCH_USER);
450 }
451
452 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
453 _("_Cancel")gettext ("_Cancel"), "process-stop",
454 GTK_RESPONSE_CANCEL);
455
456 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
457 _("_Log Out")gettext ("_Log Out"), "system-log-out",
458 GSM_LOGOUT_RESPONSE_LOGOUT);
459
460 break;
461 case GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN:
462 icon_name = GSM_ICON_SHUTDOWN"system-shutdown";
463 primary_text = _("Shut down this system now?")gettext ("Shut down this system now?");
464
465 logout_dialog->default_response = GSM_LOGOUT_RESPONSE_SHUTDOWN;
466
467 if (gsm_logout_supports_system_suspend (logout_dialog)) {
468 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
469 _("S_uspend")gettext ("S_uspend"), "battery",
470 GSM_LOGOUT_RESPONSE_SLEEP);
471 }
472
473 if (gsm_logout_supports_system_hibernate (logout_dialog)) {
474 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
475 _("_Hibernate")gettext ("_Hibernate"), "drive-harddisk",
476 GSM_LOGOUT_RESPONSE_HIBERNATE);
477 }
478
479 if (gsm_logout_supports_reboot (logout_dialog)) {
480 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
481 _("_Restart")gettext ("_Restart"), "view-refresh",
482 GSM_LOGOUT_RESPONSE_REBOOT);
483 }
484
485 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
486 _("_Cancel")gettext ("_Cancel"), "process-stop",
487 GTK_RESPONSE_CANCEL);
488
489 if (gsm_logout_supports_shutdown (logout_dialog)) {
490 gsm_util_dialog_add_button (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
491 _("_Shut Down")gettext ("_Shut Down"), "system-shutdown",
492 GSM_LOGOUT_RESPONSE_SHUTDOWN);
493 }
494 break;
495 default:
496 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-logout-dialog.c"
, 496, ((const char*) (__func__)), ((void*)0)); } while (0)
;
497 }
498
499 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
500 logout_dialog->progressbar = gtk_progress_bar_new ();
501 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
, TRUE(!(0)));
502 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (logout_dialog->progressbar)((((GtkProgressBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog->progressbar)), ((gtk_progress_bar_get_type
()))))))
, 1.0);
503 gtk_box_pack_start (GTK_BOX (hbox)((((GtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((hbox)), ((gtk_box_get_type ()))))))
,
504 logout_dialog->progressbar,
505 TRUE(!(0)), TRUE(!(0)), 12);
506 gtk_widget_show_all (hbox);
507 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (logout_dialog)))((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_dialog_get_content_area (((((GtkDialog*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((logout_dialog)), ((gtk_dialog_get_type (
)))))))))), ((gtk_container_get_type ()))))))
, hbox);
508
509 gtk_window_set_icon_name (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, icon_name);
510 gtk_window_set_position (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, GTK_WIN_POS_CENTER_ALWAYS);
511 gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (logout_dialog)((((GtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((logout_dialog)), ((gtk_message_dialog_get_type
()))))))
, primary_text);
512
513 gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_dialog_get_type ()))))))
,
514 logout_dialog->default_response);
515
516 gtk_window_set_screen (GTK_WINDOW (logout_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_window_get_type ()))))))
, screen);
517
518 return GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
;
519}
520
521GtkWidget *
522gsm_get_shutdown_dialog (GdkScreen *screen,
523 guint32 activate_time)
524{
525 return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_SHUTDOWN,
526 screen,
527 activate_time);
528}
529
530GtkWidget *
531gsm_get_logout_dialog (GdkScreen *screen,
532 guint32 activate_time)
533{
534 return gsm_get_dialog (GSM_DIALOG_LOGOUT_TYPE_LOGOUT,
535 screen,
536 activate_time);
537}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-7c304e.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-7c304e.html new file mode 100644 index 0000000..40fcc8c --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-7c304e.html @@ -0,0 +1,1309 @@ + + + +gsm-app-dialog.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:capplet/gsm-app-dialog.c
Warning:line 576, column 32
Array access (from variable 'argv') results in an undefined pointer dereference
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-app-dialog.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/capplet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-session -D LOCALE_DIR="/usr/local/share/locale" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/capplet -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-app-dialog.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
21
22#include "config.h"
23
24#include <glib.h>
25#include <glib/gi18n.h>
26#include <gtk/gtk.h>
27
28#include "gsm-util.h"
29
30#include "gsm-app-dialog.h"
31
32#define GTKBUILDER_FILE"session-properties.ui" "session-properties.ui"
33
34#define CAPPLET_NAME_ENTRY_WIDGET_NAME"session_properties_name_entry" "session_properties_name_entry"
35#define CAPPLET_COMMAND_ENTRY_WIDGET_NAME"session_properties_command_entry" "session_properties_command_entry"
36#define CAPPLET_COMMENT_ENTRY_WIDGET_NAME"session_properties_comment_entry" "session_properties_comment_entry"
37#define CAPPLET_DELAY_SPIN_WIDGET_NAME"session_properties_delay_spin" "session_properties_delay_spin"
38#define CAPPLET_BROWSE_WIDGET_NAME"session_properties_browse_button" "session_properties_browse_button"
39
40#ifdef __GNUC__4
41#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
42#else
43#define UNUSED_VARIABLE__attribute__ ((unused))
44#endif
45
46struct _GsmAppDialog
47{
48 GtkDialog parent;
49 GtkWidget *name_entry;
50 GtkWidget *command_entry;
51 GtkWidget *comment_entry;
52 GtkWidget *delay_spin;
53 GtkWidget *browse_button;
54 char *name;
55 char *command;
56 char *comment;
57 guint delay;
58};
59
60enum {
61 PROP_0,
62 PROP_NAME,
63 PROP_COMMAND,
64 PROP_COMMENT,
65 PROP_DELAY
66};
67
68G_DEFINE_TYPE (GsmAppDialog, gsm_app_dialog, GTK_TYPE_DIALOG)static void gsm_app_dialog_init (GsmAppDialog *self); static void
gsm_app_dialog_class_init (GsmAppDialogClass *klass); static
GType gsm_app_dialog_get_type_once (void); static gpointer gsm_app_dialog_parent_class
= ((void*)0); static gint GsmAppDialog_private_offset; static
void gsm_app_dialog_class_intern_init (gpointer klass) { gsm_app_dialog_parent_class
= g_type_class_peek_parent (klass); if (GsmAppDialog_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &GsmAppDialog_private_offset
); gsm_app_dialog_class_init ((GsmAppDialogClass*) klass); } __attribute__
((__unused__)) static inline gpointer gsm_app_dialog_get_instance_private
(GsmAppDialog *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (GsmAppDialog_private_offset)))); } GType gsm_app_dialog_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_app_dialog_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_app_dialog_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((gtk_dialog_get_type ()), g_intern_static_string ("GsmAppDialog"
), sizeof (GsmAppDialogClass), (GClassInitFunc)(void (*)(void
)) gsm_app_dialog_class_intern_init, sizeof (GsmAppDialog), (
GInstanceInitFunc)(void (*)(void)) gsm_app_dialog_init, (GTypeFlags
) 0); { {{};} } return g_define_type_id; }
69
70static char *
71make_exec_uri (const char *exec)
72{
73 GString *str;
74 const char *c;
75
76 if (exec == NULL((void*)0)) {
77 return g_strdup ("")g_strdup_inline ("");
78 }
79
80 if (strchr (exec, ' ') == NULL((void*)0)) {
81 return g_strdup (exec)g_strdup_inline (exec);
82 }
83
84 str = g_string_new_len (NULL((void*)0), strlen (exec));
85
86 str = g_string_append_c (str, '"')g_string_append_c_inline (str, '"');
87 for (c = exec; *c != '\0'; c++) {
88 /* FIXME: GKeyFile will add an additional backslach so we'll
89 * end up with toto\\" instead of toto\"
90 * We could use g_key_file_set_value(), but then we don't
91 * benefit from the other escaping that glib is doing...
92 */
93 if (*c == '"') {
94 str = g_string_append (str, "\\\"")(__builtin_constant_p ("\\\"") ? __extension__ ({ const char *
const __val = ("\\\""); g_string_append_len_inline (str, __val
, (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val
))) : (gssize) -1); }) : g_string_append_len_inline (str, "\\\""
, (gssize) -1))
;
95 } else {
96 str = g_string_append_c (str, *c)g_string_append_c_inline (str, *c);
97 }
98 }
99 str = g_string_append_c (str, '"')g_string_append_c_inline (str, '"');
100
101 return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str)
, ((0))) : g_string_free_and_steal (str)) : (g_string_free) (
(str), ((0))))
;
102}
103
104static void
105on_browse_button_clicked (GtkWidget *widget,
106 GsmAppDialog *dialog)
107{
108 GtkWidget *chooser;
109 int response;
110
111 chooser = gtk_file_chooser_dialog_new ("",
112 GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
113 GTK_FILE_CHOOSER_ACTION_OPEN,
114 "gtk-cancel",
115 GTK_RESPONSE_CANCEL,
116 "gtk-open",
117 GTK_RESPONSE_ACCEPT,
118 NULL((void*)0));
119
120 gtk_window_set_transient_for (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
,
121 GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
);
122
123 gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
, TRUE(!(0)));
124
125 gtk_window_set_title (GTK_WINDOW (chooser)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_window_get_type ()))))))
, _("Select Command")gettext ("Select Command"));
126
127 gtk_widget_show (chooser);
128
129 response = gtk_dialog_run (GTK_DIALOG (chooser)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_dialog_get_type ()))))))
);
130
131 if (response == GTK_RESPONSE_ACCEPT) {
132 char *text;
133 char *uri;
134
135 text = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)((((GtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((chooser)), ((gtk_file_chooser_get_type ()))))))
);
136
137 uri = make_exec_uri (text);
138
139 g_free (text);
140
141 gtk_entry_set_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
, uri);
142
143 g_free (uri);
144 }
145
146 gtk_widget_destroy (chooser);
147}
148
149static void
150on_entry_activate (GtkEntry *entry,
151 GsmAppDialog *dialog)
152{
153 gtk_dialog_response (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
, GTK_RESPONSE_OK);
154}
155
156static gboolean
157on_spin_output (GtkSpinButton *spin, GsmAppDialog *dialog)
158{
159 GtkAdjustment *adjustment;
160 gchar *text;
161 int value;
162
163 adjustment = gtk_spin_button_get_adjustment (spin);
164 value = gtk_adjustment_get_value (adjustment);
165 dialog->delay = value;
166
167 if (value == 1)
168 text = g_strdup_printf ("%d %s", value, _("second")gettext ("second"));
169 else if (value > 1)
170 text = g_strdup_printf ("%d %s", value, _("seconds")gettext ("seconds"));
171 else
172 text = g_strdup_printf ("%d", value);
173
174 gtk_entry_set_text (GTK_ENTRY (spin)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((spin)), ((gtk_entry_get_type ()))))))
, text);
175 g_free (text);
176
177 return TRUE(!(0));
178}
179
180static void
181setup_dialog (GsmAppDialog *dialog)
182{
183 GtkWidget *content_area;
184 GtkWidget *widget;
185 GtkBuilder *xml;
186 GError *error;
187
188 xml = gtk_builder_new ();
189#ifdef ENABLE_NLS1
190 gtk_builder_set_translation_domain (xml, GETTEXT_PACKAGE"mate-session-manager");
191#endif /* ENABLE_NLS */
192
193 error = NULL((void*)0);
194 if (!gtk_builder_add_from_file (xml,
195 GTKBUILDER_DIR"/usr/local/share/mate-session-manager" "/" GTKBUILDER_FILE"session-properties.ui",
196 &error)) {
197 if (error) {
198 g_warning ("Could not load capplet UI file: %s",
199 error->message);
200 g_error_free (error);
201 } else {
202 g_warning ("Could not load capplet UI file.");
203 }
204 }
205
206 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
207 widget = GTK_WIDGET (gtk_builder_get_object (xml, "main-table"))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "main-table"))), ((gtk_widget_get_type
()))))))
;
208 gtk_container_add (GTK_CONTAINER (content_area)((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((content_area)), ((gtk_container_get_type ()))))))
, widget);
209
210 gtk_container_set_border_width (GTK_CONTAINER (dialog)((((GtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_container_get_type ()))))))
, 6);
211 gtk_window_set_icon_name (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, "mate-session-properties");
212
213 g_object_set (dialog,
214 "resizable", FALSE(0),
215 NULL((void*)0));
216
217 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
218 _("_Cancel")gettext ("_Cancel"), "process-stop",
219 GTK_RESPONSE_CANCEL);
220
221 if (dialog->name == NULL((void*)0)
222 && dialog->command == NULL((void*)0)
223 && dialog->comment == NULL((void*)0)) {
224 gtk_window_set_title (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, _("Add Startup Program")gettext ("Add Startup Program"));
225 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
226 _("_Add")gettext ("_Add"), "list-add",
227 GTK_RESPONSE_OK);
228 } else {
229 gtk_window_set_title (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
, _("Edit Startup Program")gettext ("Edit Startup Program"));
230 gsm_util_dialog_add_button (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
,
231 _("_Save")gettext ("_Save"), "document-save",
232 GTK_RESPONSE_OK);
233 }
234
235 dialog->name_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_NAME_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_name_entry"
))), ((gtk_widget_get_type ()))))))
;
236 g_signal_connect (dialog->name_entry,g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
237 "activate",g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
238 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
239 dialog)g_signal_connect_data ((dialog->name_entry), ("activate"),
(((GCallback) (on_entry_activate))), (dialog), ((void*)0), (
GConnectFlags) 0)
;
240 if (dialog->name != NULL((void*)0)) {
241 gtk_entry_set_text (GTK_ENTRY (dialog->name_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->name_entry)), ((gtk_entry_get_type ()))))))
, dialog->name);
242 }
243
244 dialog->browse_button = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_BROWSE_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_browse_button"
))), ((gtk_widget_get_type ()))))))
;
245 g_signal_connect (dialog->browse_button,g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
246 "clicked",g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
247 G_CALLBACK (on_browse_button_clicked),g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
248 dialog)g_signal_connect_data ((dialog->browse_button), ("clicked"
), (((GCallback) (on_browse_button_clicked))), (dialog), ((void
*)0), (GConnectFlags) 0)
;
249
250 dialog->command_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMAND_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_command_entry"
))), ((gtk_widget_get_type ()))))))
;
251 g_signal_connect (dialog->command_entry,g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
252 "activate",g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
253 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
254 dialog)g_signal_connect_data ((dialog->command_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
;
255 if (dialog->command != NULL((void*)0)) {
256 gtk_entry_set_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
, dialog->command);
257 }
258
259 dialog->comment_entry = GTK_WIDGET (gtk_builder_get_object (xml, CAPPLET_COMMENT_ENTRY_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_comment_entry"
))), ((gtk_widget_get_type ()))))))
;
260 g_signal_connect (dialog->comment_entry,g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
261 "activate",g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
262 G_CALLBACK (on_entry_activate),g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
263 dialog)g_signal_connect_data ((dialog->comment_entry), ("activate"
), (((GCallback) (on_entry_activate))), (dialog), ((void*)0),
(GConnectFlags) 0)
;
264 if (dialog->comment != NULL((void*)0)) {
265 gtk_entry_set_text (GTK_ENTRY (dialog->comment_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->comment_entry)), ((gtk_entry_get_type ())))))
)
, dialog->comment);
266 }
267
268 dialog->delay_spin = GTK_WIDGET(gtk_builder_get_object (xml, CAPPLET_DELAY_SPIN_WIDGET_NAME))((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gtk_builder_get_object (xml, "session_properties_delay_spin"
))), ((gtk_widget_get_type ()))))))
;
269 g_signal_connect (dialog->delay_spin,g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
270 "output",g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
271 G_CALLBACK (on_spin_output),g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
272 dialog)g_signal_connect_data ((dialog->delay_spin), ("output"), (
((GCallback) (on_spin_output))), (dialog), ((void*)0), (GConnectFlags
) 0)
;
273 if (dialog->delay > 0) {
274 GtkAdjustment *adjustment;
275 adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(dialog->delay_spin)((((GtkSpinButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->delay_spin)), ((gtk_spin_button_get_type ()))
))))
);
276 gtk_adjustment_set_value (adjustment, (gdouble) dialog->delay);
277 }
278
279 if (xml != NULL((void*)0)) {
280 g_object_unref (xml);
281 }
282}
283
284static GObject *
285gsm_app_dialog_constructor (GType type,
286 guint n_construct_app,
287 GObjectConstructParam *construct_app)
288{
289 GsmAppDialog *dialog;
290
291 dialog = GSM_APP_DIALOG (G_OBJECT_CLASS (gsm_app_dialog_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_app_dialog_parent_class)), (((GType) ((20) << (
2))))))))
->constructor (type,
292 n_construct_app,
293 construct_app));
294
295 setup_dialog (dialog);
296
297 return G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
;
298}
299
300static void
301gsm_app_dialog_dispose (GObject *object)
302{
303 GsmAppDialog *dialog;
304
305 g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
306 g_return_if_fail (GSM_IS_APP_DIALOG (object))do { if ((GSM_IS_APP_DIALOG (object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (object)"
); return; } } while (0)
;
307
308 dialog = GSM_APP_DIALOG (object);
309
310 g_free (dialog->name);
311 dialog->name = NULL((void*)0);
312 g_free (dialog->command);
313 dialog->command = NULL((void*)0);
314 g_free (dialog->comment);
315 dialog->comment = NULL((void*)0);
316
317 G_OBJECT_CLASS (gsm_app_dialog_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_app_dialog_parent_class)), (((GType) ((20) << (
2))))))))
->dispose (object);
318}
319
320static void
321gsm_app_dialog_set_name (GsmAppDialog *dialog,
322 const char *name)
323{
324 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
325
326 g_free (dialog->name);
327
328 dialog->name = g_strdup (name)g_strdup_inline (name);
329 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "name");
330}
331
332static void
333gsm_app_dialog_set_command (GsmAppDialog *dialog,
334 const char *name)
335{
336 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
337
338 g_free (dialog->command);
339
340 dialog->command = g_strdup (name)g_strdup_inline (name);
341 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "command");
342}
343
344static void
345gsm_app_dialog_set_comment (GsmAppDialog *dialog,
346 const char *name)
347{
348 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
349
350 g_free (dialog->comment);
351
352 dialog->comment = g_strdup (name)g_strdup_inline (name);
353 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "comment");
354}
355
356static void
357gsm_app_dialog_set_delay (GsmAppDialog *dialog,
358 guint delay)
359{
360 g_return_if_fail (GSM_IS_APP_DIALOG (dialog))do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return; } } while (0)
;
361
362 dialog->delay = delay;
363 g_object_notify (G_OBJECT (dialog)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), (((GType) ((20) << (2))))))))
, "delay");
364}
365
366const char *
367gsm_app_dialog_get_name (GsmAppDialog *dialog)
368{
369 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
370 return gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->name_entry)), ((gtk_entry_get_type ()))))))
);
371}
372
373const char *
374gsm_app_dialog_get_command (GsmAppDialog *dialog)
375{
376 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
377 return gtk_entry_get_text (GTK_ENTRY (dialog->command_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->command_entry)), ((gtk_entry_get_type ())))))
)
);
378}
379
380const char *
381gsm_app_dialog_get_comment (GsmAppDialog *dialog)
382{
383 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), NULL)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (((void*)0)); } } while (0)
;
384 return gtk_entry_get_text (GTK_ENTRY (dialog->comment_entry)((((GtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog->comment_entry)), ((gtk_entry_get_type ())))))
)
);
385}
386
387guint
388gsm_app_dialog_get_delay (GsmAppDialog *dialog)
389{
390 g_return_val_if_fail (GSM_IS_APP_DIALOG (dialog), 0)do { if ((GSM_IS_APP_DIALOG (dialog))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_APP_DIALOG (dialog)"
); return (0); } } while (0)
;
391 return dialog->delay;
392}
393
394static void
395gsm_app_dialog_set_property (GObject *object,
396 guint prop_id,
397 const GValue *value,
398 GParamSpec *pspec)
399{
400 GsmAppDialog *dialog = GSM_APP_DIALOG (object);
401
402 switch (prop_id) {
403 case PROP_NAME:
404 gsm_app_dialog_set_name (dialog, g_value_get_string (value));
405 break;
406 case PROP_COMMAND:
407 gsm_app_dialog_set_command (dialog, g_value_get_string (value));
408 break;
409 case PROP_COMMENT:
410 gsm_app_dialog_set_comment (dialog, g_value_get_string (value));
411 break;
412 case PROP_DELAY:
413 gsm_app_dialog_set_delay (dialog, g_value_get_uint (value));
414 break;
415 default:
416 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-app-dialog.c", 416, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
417 break;
418 }
419}
420
421static void
422gsm_app_dialog_get_property (GObject *object,
423 guint prop_id,
424 GValue *value,
425 GParamSpec *pspec)
426{
427 GsmAppDialog *dialog = GSM_APP_DIALOG (object);
428
429 switch (prop_id) {
430 case PROP_NAME:
431 g_value_set_string (value, dialog->name);
432 break;
433 case PROP_COMMAND:
434 g_value_set_string (value, dialog->command);
435 break;
436 case PROP_COMMENT:
437 g_value_set_string (value, dialog->comment);
438 break;
439 case PROP_DELAY:
440 g_value_set_uint (value, dialog->delay);
441 break;
442 default:
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-app-dialog.c", 443, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
444 break;
445 }
446}
447
448static void
449gsm_app_dialog_class_init (GsmAppDialogClass *klass)
450{
451 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
452
453 object_class->get_property = gsm_app_dialog_get_property;
454 object_class->set_property = gsm_app_dialog_set_property;
455 object_class->constructor = gsm_app_dialog_constructor;
456 object_class->dispose = gsm_app_dialog_dispose;
457
458 g_object_class_install_property (object_class,
459 PROP_NAME,
460 g_param_spec_string ("name",
461 "name",
462 "name",
463 NULL((void*)0),
464 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
465 g_object_class_install_property (object_class,
466 PROP_COMMAND,
467 g_param_spec_string ("command",
468 "command",
469 "command",
470 NULL((void*)0),
471 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
472 g_object_class_install_property (object_class,
473 PROP_COMMENT,
474 g_param_spec_string ("comment",
475 "comment",
476 "comment",
477 NULL((void*)0),
478 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
479 g_object_class_install_property (object_class,
480 PROP_DELAY,
481 g_param_spec_uint ("delay",
482 "delay",
483 "delay",
484 0,
485 100,
486 0,
487 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
488}
489
490static void
491gsm_app_dialog_init (GsmAppDialog *dialog)
492{
493
494}
495
496GtkWidget *
497gsm_app_dialog_new (const char *name,
498 const char *command,
499 const char *comment,
500 guint delay)
501{
502 GObject *object;
503
504 object = g_object_new (GSM_TYPE_APP_DIALOG(gsm_app_dialog_get_type ()),
505 "name", name,
506 "command", command,
507 "comment", comment,
508 "delay", delay,
509 NULL((void*)0));
510
511 return GTK_WIDGET (object)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((gtk_widget_get_type ()))))))
;
512}
513
514gboolean
515gsm_app_dialog_run (GsmAppDialog *dialog,
516 char **name_p,
517 char **command_p,
518 char **comment_p,
519 guint *delay_p)
520{
521 gboolean retval;
522
523 retval = FALSE(0);
524
525 while (gtk_dialog_run (GTK_DIALOG (dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
) == GTK_RESPONSE_OK
) {
1
Assuming the condition is true
2
Loop condition is true. Entering loop body
526 const char *name;
527 const char *exec;
528 const char *comment;
529 guint delay;
530 const char *error_msg;
531 GError *error;
532 char **argv;
3
'argv' declared without an initial value
533 int argc;
534
535 name = gsm_app_dialog_get_name (GSM_APP_DIALOG (dialog));
536 exec = gsm_app_dialog_get_command (GSM_APP_DIALOG (dialog));
537 comment = gsm_app_dialog_get_comment (GSM_APP_DIALOG (dialog));
538 delay = gsm_app_dialog_get_delay (GSM_APP_DIALOG (dialog));
539
540 error = NULL((void*)0);
541 error_msg = NULL((void*)0);
542
543 if (gsm_util_text_is_blank (exec)) {
4
Assuming the condition is true
5
Taking true branch
544 error_msg = _("The startup command cannot be empty")gettext ("The startup command cannot be empty");
545 } else {
546 if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
547 if (error != NULL((void*)0)) {
548 error_msg = error->message;
549 } else {
550 error_msg = _("The startup command is not valid")gettext ("The startup command is not valid");
551 }
552 }
553 }
554
555 if (error_msg != NULL((void*)0)) {
6
Assuming 'error_msg' is equal to NULL
7
Taking false branch
556 GtkWidget *msgbox;
557
558 msgbox = gtk_message_dialog_new (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
559 GTK_DIALOG_MODAL,
560 GTK_MESSAGE_ERROR,
561 GTK_BUTTONS_CLOSE,
562 "%s", error_msg);
563
564 if (error != NULL((void*)0)) {
565 g_error_free (error);
566 }
567
568 gtk_dialog_run (GTK_DIALOG (msgbox)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((msgbox)), ((gtk_dialog_get_type ()))))))
);
569
570 gtk_widget_destroy (msgbox);
571
572 continue;
573 }
574
575 if (gsm_util_text_is_blank (name)) {
8
Assuming the condition is true
9
Taking true branch
576 name = argv[0];
10
Array access (from variable 'argv') results in an undefined pointer dereference
577 }
578
579 if (name_p) {
580 *name_p = g_strdup (name)g_strdup_inline (name);
581 }
582
583 g_strfreev (argv);
584
585 if (command_p) {
586 *command_p = g_strdup (exec)g_strdup_inline (exec);
587 }
588
589 if (comment_p) {
590 *comment_p = g_strdup (comment)g_strdup_inline (comment);
591 }
592
593 if (delay_p) {
594 *delay_p = delay;
595 }
596
597 retval = TRUE(!(0));
598 break;
599 }
600
601 gtk_widget_destroy (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
);
602
603 return retval;
604}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-836628.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-836628.html new file mode 100644 index 0000000..b42543e --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-836628.html @@ -0,0 +1,1229 @@ + + + +mdm-signal-handler.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/mdm-signal-handler.c
Warning:line 279, column 4
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mdm-signal-handler.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mdm-signal-handler.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Red Hat, Inc.
4 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <string.h>
30#include <signal.h>
31#if HAVE_EXECINFO_H1
32 #include <execinfo.h>
33#endif
34#include <syslog.h>
35#include <sys/wait.h>
36#include <sys/stat.h>
37
38#include <glib.h>
39#include <glib/gi18n.h>
40#include <glib/gstdio.h>
41#include <glib-object.h>
42
43#include "mdm-signal-handler.h"
44
45#ifdef __GNUC__4
46#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
47#else
48#define UNUSED_VARIABLE__attribute__ ((unused))
49#endif
50
51typedef struct {
52 int signal_number;
53 MdmSignalHandlerFunc func;
54 gpointer data;
55 guint id;
56} CallbackData;
57
58struct _MdmSignalHandler {
59 GObject parent_instance;
60 GHashTable* lookup;
61 GHashTable* id_lookup;
62 GHashTable* action_lookup;
63 guint next_id;
64 GDestroyNotify fatal_func;
65 gpointer fatal_data;
66};
67
68static void mdm_signal_handler_finalize (GObject* object);
69
70static gpointer signal_handler_object = NULL((void*)0);
71static int signal_pipes[2];
72static int signals_blocked = 0;
73static sigset_t signals_block_mask;
74static sigset_t signals_oldmask;
75
76G_DEFINE_TYPE(MdmSignalHandler, mdm_signal_handler, G_TYPE_OBJECT)static void mdm_signal_handler_init (MdmSignalHandler *self);
static void mdm_signal_handler_class_init (MdmSignalHandlerClass
*klass); static GType mdm_signal_handler_get_type_once (void
); static gpointer mdm_signal_handler_parent_class = ((void*)
0); static gint MdmSignalHandler_private_offset; static void mdm_signal_handler_class_intern_init
(gpointer klass) { mdm_signal_handler_parent_class = g_type_class_peek_parent
(klass); if (MdmSignalHandler_private_offset != 0) g_type_class_adjust_private_offset
(klass, &MdmSignalHandler_private_offset); mdm_signal_handler_class_init
((MdmSignalHandlerClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer mdm_signal_handler_get_instance_private
(MdmSignalHandler *self) { return (((gpointer) ((guint8*) (self
) + (glong) (MdmSignalHandler_private_offset)))); } GType mdm_signal_handler_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = mdm_signal_handler_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType mdm_signal_handler_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("MdmSignalHandler"
), sizeof (MdmSignalHandlerClass), (GClassInitFunc)(void (*)(
void)) mdm_signal_handler_class_intern_init, sizeof (MdmSignalHandler
), (GInstanceInitFunc)(void (*)(void)) mdm_signal_handler_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
77
78static void block_signals_push(void)
79{
80 signals_blocked++;
81
82 if (signals_blocked == 1)
83 {
84 /* Set signal mask */
85 sigemptyset(&signals_block_mask);
86 sigfillset(&signals_block_mask);
87 sigprocmask(SIG_BLOCK0, &signals_block_mask, &signals_oldmask);
88 }
89}
90
91static void block_signals_pop(void)
92{
93 signals_blocked--;
94
95 if (signals_blocked == 0)
96 {
97 /* Set signal mask */
98 sigprocmask(SIG_SETMASK2, &signals_oldmask, NULL((void*)0));
99 }
100}
101
102static gboolean signal_io_watch(GIOChannel* ioc, GIOCondition condition, MdmSignalHandler* handler)
103{
104 char buf[256];
105 gboolean is_fatal;
106 gsize bytes_read;
107 int i;
108
109 block_signals_push();
110
111 g_io_channel_read_chars(ioc, buf, sizeof(buf), &bytes_read, NULL((void*)0));
112
113 is_fatal = FALSE(0);
114
115 for (i = 0; i < bytes_read; i++)
116 {
117 int signum;
118 GSList* handlers;
119 GSList* l;
120
121 signum = (gint32) buf[i];
122
123 g_debug("MdmSignalHandler: handling signal %d", signum);
124 handlers = g_hash_table_lookup(handler->lookup, GINT_TO_POINTER(signum)((gpointer) (glong) (signum)));
125
126 g_debug("MdmSignalHandler: Found %u callbacks", g_slist_length(handlers));
127
128 for (l = handlers; l != NULL((void*)0); l = l->next)
129 {
130 gboolean res;
131 CallbackData* data;
132
133 data = g_hash_table_lookup(handler->id_lookup, l->data);
134
135 if (data != NULL((void*)0))
136 {
137 if (data->func != NULL((void*)0))
138 {
139 g_debug("MdmSignalHandler: running %d handler: %p", signum, data->func);
140
141 res = data->func(signum, data->data);
142
143 if (!res)
144 {
145 is_fatal = TRUE(!(0));
146 }
147 }
148 }
149 }
150 }
151
152 block_signals_pop();
153
154 if (is_fatal)
155 {
156 if (handler->fatal_func != NULL((void*)0))
157 {
158 g_debug("MdmSignalHandler: Caught termination signal - calling fatal func");
159 handler->fatal_func(handler->fatal_data);
160 }
161 else
162 {
163 g_debug("MdmSignalHandler: Caught termination signal - exiting");
164 exit (1);
165 }
166
167 return FALSE(0);
168 }
169
170 g_debug("MdmSignalHandler: Done handling signals");
171
172 return TRUE(!(0));
173}
174
175static void fallback_get_backtrace(void)
176{
177 #if HAVE_EXECINFO_H1
178 void* frames[64];
179 size_t size;
180 char** strings;
181 size_t i;
182
183 size = backtrace(frames, G_N_ELEMENTS(frames)(sizeof (frames) / sizeof ((frames)[0])));
184
185 if ((strings = backtrace_symbols(frames, size)))
186 {
187 syslog(LOG_CRIT2, "******************* START ********************************");
188
189 for (i = 0; i < size; i++)
190 {
191 syslog(LOG_CRIT2, "Frame %zd: %s", i, strings[i]);
192 }
193
194 free(strings);
195 syslog(LOG_CRIT2, "******************* END **********************************");
196 }
197 else
198 {
199 #endif
200 g_warning ("MDM crashed, but symbols couldn't be retrieved.");
201 #if HAVE_EXECINFO_H1
202 }
203 #endif
204}
205
206static gboolean crashlogger_get_backtrace(void)
207{
208 gboolean success = FALSE(0);
209 int pid;
210
211 pid = fork();
212
213 if (pid > 0)
214 {
215 /* Wait for the child to finish */
216 int estatus;
217
218 if (waitpid(pid, &estatus, 0) != -1)
219 {
220 /* Only succeed if the crashlogger succeeded */
221 if (WIFEXITED(estatus)(((estatus) & 0x7f) == 0) && (WEXITSTATUS(estatus)(((estatus) & 0xff00) >> 8) == 0))
222 {
223 success = TRUE(!(0));
224 }
225 }
226 }
227 else if (pid == 0)
228 {
229 /* Child process */
230 execl(LIBEXECDIR"/usr/local/libexec" "/mdm-crash-logger", LIBEXECDIR"/usr/local/libexec" "/mdm-crash-logger", NULL((void*)0));
231 }
232
233 return success;
234}
235
236static void mdm_signal_handler_backtrace(void)
237{
238 struct stat s;
239 gboolean fallback = TRUE(!(0));
240
241 /* Try to use gdb via mdm-crash-logger if it exists, since
242 * we get much better information out of it. Otherwise
243 * fall back to execinfo.
244 */
245 if (g_statstat(LIBEXECDIR"/usr/local/libexec" "/mdm-crash-logger", &s) == 0)
246 {
247 fallback = crashlogger_get_backtrace() ? FALSE(0) : TRUE(!(0));
248 }
249
250 if (fallback)
251 {
252 fallback_get_backtrace();
253 }
254}
255
256static void signal_handler(int signo)
257{
258 static int in_fatal = 0;
259 int UNUSED_VARIABLE__attribute__ ((unused)) ignore;
260 guchar signo_byte = signo;
261
262 /* avoid loops */
263 if (in_fatal > 0)
264 {
265 return;
266 }
267
268 ++in_fatal;
269
270 switch (signo)
271 {
272 case SIGSEGV11:
273 case SIGBUS7:
274 case SIGILL4:
275 case SIGABRT6:
276 case SIGTRAP5:
277 mdm_signal_handler_backtrace();
278 exit(1);
279 break;
This statement is never executed
280 case SIGFPE8:
281 case SIGPIPE13:
282 /* let the fatal signals interrupt us */
283 --in_fatal;
284 mdm_signal_handler_backtrace();
285 ignore = write(signal_pipes [1], &signo_byte, 1);
286 break;
287 default:
288 --in_fatal;
289 ignore = write(signal_pipes [1], &signo_byte, 1);
290 break;
291 }
292}
293
294static void catch_signal(MdmSignalHandler *handler, int signal_number)
295{
296 struct sigaction action;
297 struct sigaction* old_action;
298
299 g_debug("MdmSignalHandler: Registering for %d signals", signal_number);
300
301 action.sa_handler__sigaction_handler.sa_handler = signal_handler;
302 sigemptyset(&action.sa_mask);
303 action.sa_flags = 0;
304
305 old_action = g_new0(struct sigaction, 1)((struct sigaction *) g_malloc0_n ((1), sizeof (struct sigaction
)))
;
306
307 sigaction(signal_number, &action, old_action);
308
309 g_hash_table_insert(handler->action_lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)), old_action);
310}
311
312static void uncatch_signal(MdmSignalHandler* handler, int signal_number)
313{
314 struct sigaction* old_action;
315
316 g_debug("MdmSignalHandler: Unregistering for %d signals", signal_number);
317
318 old_action = g_hash_table_lookup(handler->action_lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)));
319 g_hash_table_remove(handler->action_lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)));
320
321 sigaction(signal_number, old_action, NULL((void*)0));
322
323 g_free(old_action);
324}
325
326guint mdm_signal_handler_add(MdmSignalHandler* handler, int signal_number, MdmSignalHandlerFunc callback, gpointer data)
327{
328 CallbackData* cdata;
329 GSList* list;
330
331 g_return_val_if_fail(MDM_IS_SIGNAL_HANDLER(handler), 0)do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return (0); } } while (0)
;
332
333 cdata = g_new0(CallbackData, 1)((CallbackData *) g_malloc0_n ((1), sizeof (CallbackData)));
334 cdata->signal_number = signal_number;
335 cdata->func = callback;
336 cdata->data = data;
337 cdata->id = handler->next_id++;
338
339 g_debug("MdmSignalHandler: Adding handler %u: signum=%d %p", cdata->id, cdata->signal_number, cdata->func);
340
341 if (g_hash_table_lookup(handler->action_lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number))) == NULL((void*)0))
342 {
343 catch_signal(handler, signal_number);
344 }
345
346 /* ID lookup owns the CallbackData */
347 g_hash_table_insert(handler->id_lookup, GUINT_TO_POINTER(cdata->id)((gpointer) (gulong) (cdata->id)), cdata);
348
349 list = g_hash_table_lookup(handler->lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)));
350 list = g_slist_prepend(list, GUINT_TO_POINTER (cdata->id)((gpointer) (gulong) (cdata->id)));
351
352 g_hash_table_insert(handler->lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)), list);
353
354 return cdata->id;
355}
356
357void mdm_signal_handler_add_fatal(MdmSignalHandler* handler)
358{
359 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(handler))do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return; } } while (0)
;
360
361 mdm_signal_handler_add(handler, SIGILL4, NULL((void*)0), NULL((void*)0));
362 mdm_signal_handler_add(handler, SIGBUS7, NULL((void*)0), NULL((void*)0));
363 mdm_signal_handler_add(handler, SIGSEGV11, NULL((void*)0), NULL((void*)0));
364 mdm_signal_handler_add(handler, SIGABRT6, NULL((void*)0), NULL((void*)0));
365 mdm_signal_handler_add(handler, SIGTRAP5, NULL((void*)0), NULL((void*)0));
366}
367
368static void callback_data_free(CallbackData* d)
369{
370 g_free(d);
371}
372
373static void mdm_signal_handler_remove_and_free_data(MdmSignalHandler* handler, CallbackData* cdata)
374{
375 GSList* list;
376
377 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(handler))do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return; } } while (0)
;
378
379 list = g_hash_table_lookup(handler->lookup, GINT_TO_POINTER(cdata->signal_number)((gpointer) (glong) (cdata->signal_number)));
380 list = g_slist_remove_all(list, GUINT_TO_POINTER(cdata->id)((gpointer) (gulong) (cdata->id)));
381
382 if (list == NULL((void*)0))
383 {
384 uncatch_signal(handler, cdata->signal_number);
385 }
386
387 g_debug("MdmSignalHandler: Removing handler %u: signum=%d %p", cdata->signal_number, cdata->id, cdata->func);
388 /* put changed list back in */
389 g_hash_table_insert(handler->lookup, GINT_TO_POINTER(cdata->signal_number)((gpointer) (glong) (cdata->signal_number)), list);
390
391 g_hash_table_remove(handler->id_lookup, GUINT_TO_POINTER(cdata->id)((gpointer) (gulong) (cdata->id)));
392}
393
394void mdm_signal_handler_remove(MdmSignalHandler* handler, guint id)
395{
396 CallbackData* found;
397
398 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(handler))do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return; } } while (0)
;
399
400 found = g_hash_table_lookup(handler->id_lookup, GUINT_TO_POINTER(id)((gpointer) (gulong) (id)));
401
402 if (found != NULL((void*)0))
403 {
404 mdm_signal_handler_remove_and_free_data(handler, found);
405 found = NULL((void*)0);
406 }
407}
408
409static CallbackData* find_callback_data_by_func(MdmSignalHandler* handler, guint signal_number, MdmSignalHandlerFunc callback, gpointer data)
410{
411 GSList* list;
412 GSList* l;
413 CallbackData* found;
414
415 found = NULL((void*)0);
416
417 list = g_hash_table_lookup(handler->lookup, GINT_TO_POINTER(signal_number)((gpointer) (glong) (signal_number)));
418
419 for (l = list; l != NULL((void*)0); l = l->next)
420 {
421 guint id;
422 CallbackData* d;
423
424 id = GPOINTER_TO_UINT(l->data)((guint) (gulong) (l->data));
425
426 d = g_hash_table_lookup(handler->id_lookup, GUINT_TO_POINTER (id)((gpointer) (gulong) (id)));
427
428 if (d != NULL((void*)0) && d->func == callback && d->data == data)
429 {
430 found = d;
431 break;
432 }
433 }
434
435 return found;
436}
437
438void mdm_signal_handler_remove_func(MdmSignalHandler* handler, guint signal_number, MdmSignalHandlerFunc callback, gpointer data)
439{
440 CallbackData* found;
441
442 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(handler))do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return; } } while (0)
;
443
444 found = find_callback_data_by_func(handler, signal_number, callback, data);
445
446 if (found != NULL((void*)0))
447 {
448 mdm_signal_handler_remove_and_free_data(handler, found);
449 found = NULL((void*)0);
450 }
451
452 /* FIXME: once all handlers are removed deregister signum handler */
453}
454
455static void mdm_signal_handler_class_init(MdmSignalHandlerClass* klass)
456{
457 GObjectClass* object_class = G_OBJECT_CLASS(klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
458
459 object_class->finalize = mdm_signal_handler_finalize;
460}
461
462static void signal_list_free(GSList *list)
463{
464 g_slist_free(list);
465}
466
467void mdm_signal_handler_set_fatal_func(MdmSignalHandler* handler, MdmShutdownHandlerFunc func, gpointer user_data)
468{
469 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(handler))do { if ((MDM_IS_SIGNAL_HANDLER(handler))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(handler)"
); return; } } while (0)
;
470
471 handler->fatal_func = func;
472 handler->fatal_data = user_data;
473}
474
475static void mdm_signal_handler_init(MdmSignalHandler* handler)
476{
477 GIOChannel* ioc;
478
479 handler->next_id = 1;
480
481 handler->lookup = g_hash_table_new(NULL((void*)0), NULL((void*)0));
482 handler->id_lookup = g_hash_table_new(NULL((void*)0), NULL((void*)0));
483 handler->action_lookup = g_hash_table_new(NULL((void*)0), NULL((void*)0));
484
485 if (pipe(signal_pipes) == -1)
486 {
487 g_error ("Could not create pipe() for signal handling");
488 }
489
490 ioc = g_io_channel_unix_new(signal_pipes[0]);
491 g_io_channel_set_flags(ioc, G_IO_FLAG_NONBLOCK, NULL((void*)0));
492 g_io_add_watch_full(ioc, G_PRIORITY_HIGH-100, G_IO_IN, (GIOFunc) signal_io_watch, handler, NULL((void*)0));
493 g_io_channel_set_close_on_unref(ioc, TRUE(!(0)));
494 g_io_channel_unref(ioc);
495}
496
497static void mdm_signal_handler_finalize(GObject* object)
498{
499 MdmSignalHandler* handler;
500 GList* l;
501
502 g_return_if_fail(object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
503 g_return_if_fail(MDM_IS_SIGNAL_HANDLER(object))do { if ((MDM_IS_SIGNAL_HANDLER(object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "MDM_IS_SIGNAL_HANDLER(object)"
); return; } } while (0)
;
504
505 handler = MDM_SIGNAL_HANDLER(object);
506
507 g_debug("MdmSignalHandler: Finalizing signal handler");
508
509 for (l = g_hash_table_get_values(handler->lookup); l != NULL((void*)0); l = l->next)
510 {
511 signal_list_free((GSList*) l->data);
512 }
513
514 g_hash_table_destroy(handler->lookup);
515
516 for (l = g_hash_table_get_values(handler->id_lookup); l != NULL((void*)0); l = l->next)
517 {
518 callback_data_free((CallbackData*) l->data);
519 }
520
521 g_hash_table_destroy(handler->id_lookup);
522
523 for (l = g_hash_table_get_values(handler->action_lookup); l != NULL((void*)0); l = l->next)
524 {
525 g_free(l->data);
526 }
527
528 g_hash_table_destroy(handler->action_lookup);
529
530 close(signal_pipes[0]);
531 close(signal_pipes[1]);
532
533 G_OBJECT_CLASS(mdm_signal_handler_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((mdm_signal_handler_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize(object);
534}
535
536MdmSignalHandler* mdm_signal_handler_new(void)
537{
538 if (signal_handler_object != NULL((void*)0))
539 {
540 g_object_ref(signal_handler_object)((__typeof__ (signal_handler_object)) (g_object_ref) (signal_handler_object
))
;
541 }
542 else
543 {
544 signal_handler_object = g_object_new(MDM_TYPE_SIGNAL_HANDLER(mdm_signal_handler_get_type()), NULL((void*)0));
545 g_object_add_weak_pointer(signal_handler_object, (gpointer*) &signal_handler_object);
546 }
547
548 return MDM_SIGNAL_HANDLER(signal_handler_object);
549}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-88d32f.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-88d32f.html new file mode 100644 index 0000000..fdf8c2e --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-88d32f.html @@ -0,0 +1,1197 @@ + + + +mate-session-check-accelerated-gl-helper.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-check-accelerated-gl-helper.c
Warning:line 505, column 30
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-check-accelerated-gl-helper.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -D PKGDATADIR="/usr/local/share/mate-session-manager" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-check-accelerated-gl-helper.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2010 Novell, Inc.
3 * Copyright (C) 2006-2009 Red Hat, Inc.
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Author:
21 * Vincent Untz <vuntz@gnome.org>
22 *
23 * Most of the code comes from desktop-effects [1], released under GPLv2+.
24 * desktop-effects was written by:
25 * Soren Sandmann <sandmann@redhat.com>
26 *
27 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
28 */
29
30/*
31 * Here's the rationale behind this helper, quoting Owen, in his mail to the
32 * release team:
33 * (http://mail.gnome.org/archives/release-team/2010-June/msg00079.html)
34 *
35 * """
36 * There are some limits to what we can do here automatically without
37 * knowing anything about the driver situation on the system. The basic
38 * problem is that there are all sorts of suck:
39 *
40 * * No GL at all. This typically only happens if a system is
41 * misconfigured.
42 *
43 * * Only software GL. This one is easy to detect. We have code in
44 * the Fedora desktop-effects tool, etc.
45 *
46 * * GL that isn't featureful enough. (Tiny texture size limits, no
47 * texture-from-pixmap, etc.) Possible to detect with more work, but
48 * largely a fringe case.
49 *
50 * * Buggy GL. This isn't possible to detect. Except for the case where
51 * all GL programs crash. For that reason, we probably don't want
52 * gnome-session to directly try and do any GL detection; better to
53 * use a helper binary.
54 *
55 * * Horribly slow hardware GL. We could theoretically develop some sort
56 * of benchmark, but it's a tricky area. And how slow is too slow?
57 * """
58 *
59 * Some other tools are doing similar checks:
60 * - desktop-effects (Fedora Config Tool) [1]
61 * - drak3d (Mandriva Config Tool) [2]
62 * - compiz-manager (Compiz wrapper) [3]
63 *
64 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
65 * [2] http://svn.mandriva.com/cgi-bin/viewvc.cgi/soft/drak3d/trunk/lib/Xconfig/glx.pm?view=markup
66 * [3] http://git.compiz.org/fusion/misc/compiz-manager/tree/compiz-manager
67 */
68
69/* for strcasestr */
70#define _GNU_SOURCE
71
72#include <ctype.h>
73#include <locale.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <glib.h>
78
79#include <regex.h>
80
81#ifdef __FreeBSD__
82#include <kenv.h>
83#endif
84
85#include <X11/Xlib.h>
86#include <X11/Xatom.h>
87#include <X11/extensions/Xcomposite.h>
88#include <GL/gl.h>
89#include <GL/glx.h>
90
91#include "mate-session-check-accelerated-common.h"
92
93#define SIZE_UNSET0 0
94#define SIZE_ERROR-1 -1
95static int max_texture_size = SIZE_UNSET0;
96static int max_renderbuffer_size = SIZE_UNSET0;
97static gboolean has_llvmpipe = FALSE(0);
98
99static inline void
100_print_error (const char *str)
101{
102 fprintf (stderrstderr, "mate-session-is-accelerated: %s\n", str);
103}
104
105#define CMDLINE_UNSET-1 -1
106#define CMDLINE_NON_FALLBACK_FORCED0 0
107#define CMDLINE_FALLBACK_FORCED1 1
108
109#if defined(__linux__1)
110static int
111_parse_kcmdline (void)
112{
113 int ret = CMDLINE_UNSET-1;
114 GRegex *regex;
115 GMatchInfo *match;
116 char *contents;
117 char *word;
118 const char *arg;
119
120 if (!g_file_get_contents ("/proc/cmdline", &contents, NULL((void*)0), NULL((void*)0)))
121 return ret;
122
123 regex = g_regex_new ("mate.fallback=(\\S+)", 0, G_REGEX_MATCH_NOTEMPTY, NULL((void*)0));
124 if (!g_regex_match (regex, contents, G_REGEX_MATCH_NOTEMPTY, &match))
125 goto out;
126
127 word = g_match_info_fetch (match, 0);
128 g_debug ("Found command-line match '%s'", word);
129 arg = word + strlen ("mate.fallback=");
130 if (*arg != '0' && *arg != '1')
131 fprintf (stderrstderr, "mate-session-check-accelerated: Invalid value '%s' for mate.fallback passed in kernel command line.\n", arg);
132 else
133 ret = atoi (arg);
134 g_free (word);
135
136out:
137 g_match_info_free (match);
138 g_regex_unref (regex);
139 g_free (contents);
140
141 g_debug ("Command-line parsed to %d", ret);
142
143 return ret;
144}
145#elif defined(__FreeBSD__)
146static int
147_parse_kcmdline (void)
148{
149 int ret = CMDLINE_UNSET-1;
150 char value[KENV_MVALLEN];
151
152 /* a compile time check to avoid unexpected stack overflow */
153 _Static_assert(KENV_MVALLEN < 1024 * 1024, "KENV_MVALLEN is too large");
154
155 if (kenv (KENV_GET, "mate.fallback", value, KENV_MVALLEN) == -1)
156 return ret;
157
158 if (*value != '0' && *value != '1')
159 fprintf (stderrstderr, "mate-session-is-accelerated: Invalid value '%s' for mate.fallback passed in kernel environment.\n", value);
160 else
161 ret = atoi (value);
162
163 g_debug ("Kernel environment parsed to %d", ret);
164
165 return ret;
166}
167#else
168static int
169_parse_kcmdline (void)
170{
171 return CMDLINE_UNSET-1;
172}
173#endif
174
175static gboolean
176_has_composite (Display *display)
177{
178 int dummy1, dummy2;
179
180 return XCompositeQueryExtension (display, &dummy1, &dummy2);
181}
182
183static gboolean
184_is_comment (const char *line)
185{
186 while (*line && isspace(*line)((*__ctype_b_loc ())[(int) ((*line))] & (unsigned short int
) _ISspace)
)
187 line++;
188
189 if (*line == '#' || *line == '\0')
190 return TRUE(!(0));
191 return FALSE(0);
192}
193
194static gboolean
195_is_gl_renderer_blacklisted (const char *renderer)
196{
197 FILE *blacklist;
198 char *line = NULL((void*)0);
199 size_t line_len = 0;
200 gboolean ret = TRUE(!(0));
201
202 blacklist = fopen(PKGDATADIR"/usr/local/share/mate-session-manager" "/hardware-compatibility", "r");
203 if (blacklist == NULL((void*)0))
204 goto out;
205
206 while (getline (&line, &line_len, blacklist) != -1) {
207 int whitelist = 0;
208 const char *re_str;
209 regex_t re;
210 int status;
211
212 if (line == NULL((void*)0))
213 break;
214
215 /* Drop trailing \n */
216 line[strlen(line) - 1] = '\0';
217
218 if (_is_comment (line)) {
219 free (line);
220 line = NULL((void*)0);
221 continue;
222 }
223
224 if (line[0] == '+')
225 whitelist = 1;
226 else if (line[0] == '-')
227 whitelist = 0;
228 else {
229 _print_error ("Invalid syntax in this line for hardware compatibility:");
230 _print_error (line);
231 free (line);
232 line = NULL((void*)0);
233 continue;
234 }
235
236 re_str = line + 1;
237
238 if (regcomp (&re, re_str, REG_EXTENDED1|REG_ICASE(1 << 1)|REG_NOSUB(1 << 3)) != 0) {
239 _print_error ("Cannot use this regular expression for hardware compatibility:");
240 _print_error (re_str);
241 } else {
242 status = regexec (&re, renderer, 0, NULL((void*)0), 0);
243 regfree(&re);
244
245 if (status == 0) {
246 if (whitelist)
247 ret = FALSE(0);
248 goto out;
249 }
250 }
251
252 free (line);
253 line = NULL((void*)0);
254 }
255
256 ret = FALSE(0);
257
258out:
259 if (line != NULL((void*)0))
260 free (line);
261
262 if (blacklist != NULL((void*)0))
263 fclose (blacklist);
264
265 return ret;
266}
267
268static char *
269_get_hardware_gl (Display *display)
270{
271 int screen;
272 Window root;
273 XVisualInfo *visual = NULL((void*)0);
274 GLXContext context = NULL((void*)0);
275 XSetWindowAttributes cwa = { 0 };
276 Window window = None0L;
277 char *renderer = NULL((void*)0);
278
279 int attrlist[] = {
280 GLX_RGBA4,
281 GLX_RED_SIZE8, 1,
282 GLX_GREEN_SIZE9, 1,
283 GLX_BLUE_SIZE10, 1,
284 GLX_DOUBLEBUFFER5,
285 None0L
286 };
287
288 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
289 root = RootWindow (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
;
290
291 visual = glXChooseVisual (display, screen, attrlist);
292 if (!visual)
293 goto out;
294
295 context = glXCreateContext (display, visual, NULL((void*)0), True1);
296 if (!context)
297 goto out;
298
299 cwa.colormap = XCreateColormap (display, root,
300 visual->visual, AllocNone0);
301 cwa.background_pixel = 0;
302 cwa.border_pixel = 0;
303 window = XCreateWindow (display, root,
304 0, 0, 1, 1, 0,
305 visual->depth, InputOutput1, visual->visual,
306 CWColormap(1L<<13) | CWBackPixel(1L<<1) | CWBorderPixel(1L<<3),
307 &cwa);
308
309 if (!glXMakeCurrent (display, window, context))
310 goto out;
311
312 renderer = g_strdup ((const char *) glGetString (GL_RENDERER))g_strdup_inline ((const char *) glGetString (0x1F01));
313 if (_is_gl_renderer_blacklisted (renderer)) {
314 g_clear_pointer (&renderer, g_free)do { _Static_assert (sizeof *(&renderer) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ ((&renderer
)) _pp = (&renderer); __typeof__ (*(&renderer)) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_free) (_ptr); } while (
0)
;
315 goto out;
316 }
317 if (renderer && strcasestr (renderer, "llvmpipe"))
318 has_llvmpipe = TRUE(!(0));
319
320 /* we need to get the max texture and renderbuffer sizes while we have
321 * a context, but we'll check their values later */
322
323 glGetIntegerv (GL_MAX_TEXTURE_SIZE0x0D33, &max_texture_size);
324 if (glGetError() != GL_NO_ERROR0)
325 max_texture_size = SIZE_ERROR-1;
326
327 glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE_EXT0x84E8, &max_renderbuffer_size);
328 if (glGetError() != GL_NO_ERROR0)
329 max_renderbuffer_size = SIZE_ERROR-1;
330
331out:
332 glXMakeCurrent (display, None0L, None0L);
333 if (context)
334 glXDestroyContext (display, context);
335 if (window)
336 XDestroyWindow (display, window);
337 if (cwa.colormap)
338 XFreeColormap (display, cwa.colormap);
339
340 return renderer;
341}
342
343static gboolean
344_has_extension (const char *extension_list,
345 const char *extension)
346{
347 char **extensions;
348 guint i;
349 gboolean ret;
350
351 g_return_val_if_fail (extension != NULL, TRUE)do { if ((extension != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "extension != NULL"
); return ((!(0))); } } while (0)
;
352
353 /* Extension_list is one big string, containing extensions
354 * separated by spaces. */
355 if (extension_list == NULL((void*)0))
356 return FALSE(0);
357
358 ret = FALSE(0);
359
360 extensions = g_strsplit (extension_list, " ", -1);
361 if (extensions == NULL((void*)0))
362 return FALSE(0);
363
364 for (i = 0; extensions[i] != NULL((void*)0); i++) {
365 if (g_str_equal (extensions[i], extension)(strcmp ((const char *) (extensions[i]), (const char *) (extension
)) == 0)
) {
366 ret = TRUE(!(0));
367 break;
368 }
369 }
370
371 g_strfreev (extensions);
372
373 return ret;
374}
375
376static gboolean
377_has_texture_from_pixmap (Display *display)
378{
379 int screen;
380 const char *server_extensions;
381 const char *client_extensions;
382 gboolean ret = FALSE(0);
383
384 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
385
386 server_extensions = glXQueryServerString (display, screen,
387 GLX_EXTENSIONS3);
388 if (!_has_extension (server_extensions,
389 "GLX_EXT_texture_from_pixmap"))
390 goto out;
391
392 client_extensions = glXGetClientString (display, GLX_EXTENSIONS3);
393 if (!_has_extension (client_extensions,
394 "GLX_EXT_texture_from_pixmap"))
395 goto out;
396
397 ret = TRUE(!(0));
398
399out:
400 return ret;
401}
402
403static void
404_set_max_screen_size_property (Display *display, int screen, int size)
405{
406 Atom max_screen_size_atom;
407
408 max_screen_size_atom = XInternAtom (display, "_GNOME_MAX_SCREEN_SIZE",
409 False0);
410
411 /* Will be read by gnome-settings-daemon and
412 * gnome-control-center to avoid display configurations where 3D
413 * is not available (and would break gnome-shell) */
414 XChangeProperty (display, RootWindow(display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
,
415 max_screen_size_atom,
416 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
417 (unsigned char *)&size, 1);
418
419 XSync(display, False0);
420}
421
422static gboolean
423_is_max_texture_size_big_enough (Display *display)
424{
425 int screen, size;
426
427 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
428 size = MIN(max_renderbuffer_size, max_texture_size)(((max_renderbuffer_size) < (max_texture_size)) ? (max_renderbuffer_size
) : (max_texture_size))
;
429 if (size < DisplayWidth (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->width
)
||
430 size < DisplayHeight (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->height
)
)
431 return FALSE(0);
432
433 _set_max_screen_size_property (display, screen, size);
434
435 return TRUE(!(0));
436}
437
438static gboolean print_renderer = FALSE(0);
439
440static const GOptionEntry entries[] = {
441 { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print GL renderer name", NULL((void*)0) },
442 { NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0) },
443};
444
445int
446main (int argc, char **argv)
447{
448 int kcmdline_parsed;
449 Display *display = NULL((void*)0);
450 int ret = HELPER_NO_ACCEL1;
451 GOptionContext *context;
452 GError *error = NULL((void*)0);
453 char *renderer = NULL((void*)0);
454
455 setlocale (LC_ALL6, "");
456
457 context = g_option_context_new (NULL((void*)0));
458 g_option_context_add_main_entries (context, entries, NULL((void*)0));
459
460 if (!g_option_context_parse (context, &argc, &argv, &error)) {
461 g_error ("Can't parse command line: %s\n", error->message);
462 g_error_free (error);
463 goto out;
464 }
465
466 kcmdline_parsed = _parse_kcmdline ();
467 if (kcmdline_parsed > CMDLINE_UNSET-1) {
468 if (kcmdline_parsed == CMDLINE_NON_FALLBACK_FORCED0) {
469 _print_error ("Non-fallback mode forced by kernel command line.");
470 ret = HELPER_ACCEL0;
471 goto out;
472 } else if (kcmdline_parsed == CMDLINE_FALLBACK_FORCED1) {
473 _print_error ("Fallback mode forced by kernel command line.");
474 goto out;
475 }
476 }
477
478 display = XOpenDisplay (NULL((void*)0));
479 if (!display) {
480 _print_error ("No X display.");
481 goto out;
482 }
483
484 if (!_has_composite (display)) {
485 _print_error ("No composite extension.");
486 goto out;
487 }
488
489 renderer = _get_hardware_gl (display);
490 if (!renderer) {
491 _print_error ("No hardware 3D support.");
492 goto out;
493 }
494
495 if (!_has_texture_from_pixmap (display)) {
496 _print_error ("No GLX_EXT_texture_from_pixmap support.");
497 goto out;
498 }
499
500 if (!_is_max_texture_size_big_enough (display)) {
501 _print_error ("GL_MAX_{TEXTURE,RENDERBUFFER}_SIZE is too small.");
502 goto out;
503 }
504
505 ret = has_llvmpipe ? HELPER_SOFTWARE_RENDERING2 : HELPER_ACCEL0;
This statement is never executed
506
507 if (print_renderer)
508 g_print ("%s", renderer);
509
510out:
511 if (display)
512 XCloseDisplay (display);
513 g_option_context_free (context);
514 g_free (renderer);
515
516 return ret;
517}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-a80670.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-a80670.html new file mode 100644 index 0000000..b11e160 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-a80670.html @@ -0,0 +1,4937 @@ + + + +gsm-manager.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/gsm-manager.c
Warning:line 2932, column 25
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-manager.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-manager.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
6 * Copyright (C) 2012-2021 MATE Developers
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <string.h>
31#include <signal.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34
35#include <glib.h>
36#include <glib/gi18n.h>
37#include <glib/gstdio.h>
38#include <glib-object.h>
39#include <dbus/dbus-glib.h>
40#include <dbus/dbus-glib-lowlevel.h>
41
42#include <gtk/gtk.h> /* for logout dialog */
43#include <gio/gio.h> /* for gsettings */
44#include <gdk/gdkx.h>
45
46#include "gsm-manager.h"
47#include "gsm-manager-glue.h"
48
49#include "gsm-store.h"
50#include "gsm-inhibitor.h"
51#include "gsm-presence.h"
52
53#include "gsm-xsmp-client.h"
54#include "gsm-dbus-client.h"
55
56#include "gsm-autostart-app.h"
57
58#include "gsm-util.h"
59#include "mdm.h"
60#include "gsm-logout-dialog.h"
61#include "gsm-inhibit-dialog.h"
62#include "gsm-consolekit.h"
63#ifdef HAVE_SYSTEMD1
64#include "gsm-systemd.h"
65#endif
66#include "gsm-session-save.h"
67
68#define GSM_MANAGER_GET_PRIVATE(o)(((GsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((gsm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
+)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate)((GsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((gsm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
+
)
69
70#define GSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager" "/org/gnome/SessionManager"
71#define GSM_MANAGER_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
72
73#define GSM_MANAGER_PHASE_TIMEOUT30 30 /* seconds */
74
75/* In the exit phase, all apps were already given the chance to inhibit the session end
76 * At that stage we don't want to wait much for apps to respond, we want to exit, and fast.
77 */
78#define GSM_MANAGER_EXIT_PHASE_TIMEOUT1 1 /* seconds */
79
80#define MDM_FLEXISERVER_COMMAND"mdmflexiserver" "mdmflexiserver"
81#define MDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
82
83#define GDM_FLEXISERVER_COMMAND"gdmflexiserver" "gdmflexiserver"
84#define GDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
85
86#define LOCKDOWN_SCHEMA"org.mate.lockdown" "org.mate.lockdown"
87#define KEY_LOCK_DISABLE"disable-lock-screen" "disable-lock-screen"
88#define KEY_LOG_OUT_DISABLE"disable-log-out" "disable-log-out"
89#define KEY_USER_SWITCH_DISABLE"disable-user-switching" "disable-user-switching"
90
91#define SESSION_SCHEMA"org.mate.session" "org.mate.session"
92#define KEY_IDLE_DELAY"idle-delay" "idle-delay"
93#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
94
95#define SCREENSAVER_SCHEMA"org.mate.screensaver" "org.mate.screensaver"
96#define KEY_SLEEP_LOCK"lock-enabled" "lock-enabled"
97
98#ifdef __GNUC__4
99#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
100#else
101#define UNUSED_VARIABLE__attribute__ ((unused))
102#endif
103
104typedef enum
105{
106 GSM_MANAGER_LOGOUT_NONE,
107 GSM_MANAGER_LOGOUT_LOGOUT,
108 GSM_MANAGER_LOGOUT_REBOOT,
109 GSM_MANAGER_LOGOUT_REBOOT_INTERACT,
110 GSM_MANAGER_LOGOUT_REBOOT_MDM,
111 GSM_MANAGER_LOGOUT_SHUTDOWN,
112 GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT,
113 GSM_MANAGER_LOGOUT_SHUTDOWN_MDM
114} GsmManagerLogoutType;
115
116typedef struct {
117 gboolean failsafe;
118 GsmStore *clients;
119 GsmStore *inhibitors;
120 GsmStore *apps;
121 GsmPresence *presence;
122
123 /* Current status */
124 GsmManagerPhase phase;
125 guint phase_timeout_id;
126 GSList *pending_apps;
127 GsmManagerLogoutMode logout_mode;
128 GSList *query_clients;
129 guint query_timeout_id;
130 /* This is used for GSM_MANAGER_PHASE_END_SESSION only at the moment,
131 * since it uses a sublist of all running client that replied in a
132 * specific way */
133 GSList *next_query_clients;
134 /* This is the action that will be done just before we exit */
135 GsmManagerLogoutType logout_type;
136
137 GtkWidget *inhibit_dialog;
138
139 /* List of clients which were disconnected due to disabled condition
140 * and shouldn't be automatically restarted */
141 GSList *condition_clients;
142
143 GSettings *settings_session;
144 GSettings *settings_lockdown;
145 GSettings *settings_screensaver;
146
147 char *renderer;
148
149 DBusGProxy *bus_proxy;
150 DBusGConnection *connection;
151 gboolean dbus_disconnected : 1;
152} GsmManagerPrivate;
153
154enum {
155 PROP_0,
156 PROP_CLIENT_STORE,
157 PROP_RENDERER,
158 PROP_FAILSAFE
159};
160
161enum {
162 PHASE_CHANGED,
163 CLIENT_ADDED,
164 CLIENT_REMOVED,
165 INHIBITOR_ADDED,
166 INHIBITOR_REMOVED,
167 SESSION_RUNNING,
168 SESSION_OVER,
169 LAST_SIGNAL
170};
171
172static guint signals [LAST_SIGNAL] = { 0 };
173
174static void gsm_manager_finalize (GObject *object);
175
176static gboolean _log_out_is_locked_down (GsmManager *manager);
177static gboolean _switch_user_is_locked_down (GsmManager *manager);
178
179static void _handle_client_end_session_response (GsmManager *manager,
180 GsmClient *client,
181 gboolean is_ok,
182 gboolean do_last,
183 gboolean cancel,
184 const char *reason);
185
186static gboolean auto_save_is_enabled (GsmManager *manager);
187static void maybe_save_session (GsmManager *manager);
188
189static gpointer manager_object = NULL((void*)0);
190
191G_DEFINE_TYPE_WITH_PRIVATE (GsmManager, gsm_manager, G_TYPE_OBJECT)static void gsm_manager_init (GsmManager *self); static void gsm_manager_class_init
(GsmManagerClass *klass); static GType gsm_manager_get_type_once
(void); static gpointer gsm_manager_parent_class = ((void*)0
); static gint GsmManager_private_offset; static void gsm_manager_class_intern_init
(gpointer klass) { gsm_manager_parent_class = g_type_class_peek_parent
(klass); if (GsmManager_private_offset != 0) g_type_class_adjust_private_offset
(klass, &GsmManager_private_offset); gsm_manager_class_init
((GsmManagerClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer gsm_manager_get_instance_private (GsmManager
*self) { return (((gpointer) ((guint8*) (self) + (glong) (GsmManager_private_offset
)))); } GType gsm_manager_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_manager_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_manager_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("GsmManager"
), sizeof (GsmManagerClass), (GClassInitFunc)(void (*)(void))
gsm_manager_class_intern_init, sizeof (GsmManager), (GInstanceInitFunc
)(void (*)(void)) gsm_manager_init, (GTypeFlags) 0); { {{ GsmManager_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (GsmManagerPrivate
)); };} } return g_define_type_id; }
192
193GQuark
194gsm_manager_error_quark (void)
195{
196 static GQuark ret = 0;
197 if (ret == 0) {
198 ret = g_quark_from_static_string ("gsm_manager_error");
199 }
200
201 return ret;
202}
203
204#define ENUM_ENTRY(NAME, DESC){ NAME, "" "NAME" "", DESC } { NAME, "" #NAME "", DESC }
205
206GType
207gsm_manager_error_get_type (void)
208{
209 static GType etype = 0;
210
211 if (etype == 0) {
212 static const GEnumValue values[] = {
213 ENUM_ENTRY (GSM_MANAGER_ERROR_GENERAL, "GeneralError"){ GSM_MANAGER_ERROR_GENERAL, "" "GSM_MANAGER_ERROR_GENERAL" ""
, "GeneralError" }
,
214 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "NotInInitialization"){ GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "" "GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION"
"", "NotInInitialization" }
,
215 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_RUNNING, "NotInRunning"){ GSM_MANAGER_ERROR_NOT_IN_RUNNING, "" "GSM_MANAGER_ERROR_NOT_IN_RUNNING"
"", "NotInRunning" }
,
216 ENUM_ENTRY (GSM_MANAGER_ERROR_ALREADY_REGISTERED, "AlreadyRegistered"){ GSM_MANAGER_ERROR_ALREADY_REGISTERED, "" "GSM_MANAGER_ERROR_ALREADY_REGISTERED"
"", "AlreadyRegistered" }
,
217 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"){ GSM_MANAGER_ERROR_NOT_REGISTERED, "" "GSM_MANAGER_ERROR_NOT_REGISTERED"
"", "NotRegistered" }
,
218 ENUM_ENTRY (GSM_MANAGER_ERROR_INVALID_OPTION, "InvalidOption"){ GSM_MANAGER_ERROR_INVALID_OPTION, "" "GSM_MANAGER_ERROR_INVALID_OPTION"
"", "InvalidOption" }
,
219 ENUM_ENTRY (GSM_MANAGER_ERROR_LOCKED_DOWN, "LockedDown"){ GSM_MANAGER_ERROR_LOCKED_DOWN, "" "GSM_MANAGER_ERROR_LOCKED_DOWN"
"", "LockedDown" }
,
220 { 0, 0, 0 }
221 };
222
223 g_assert (GSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1)do { if (GSM_MANAGER_NUM_ERRORS == (sizeof (values) / sizeof (
(values)[0])) - 1) ; else g_assertion_message_expr (((gchar*)
0), "gsm-manager.c", 223, ((const char*) (__func__)), "GSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1"
); } while (0)
;
224
225 etype = g_enum_register_static ("GsmManagerError", values);
226 }
227
228 return etype;
229}
230
231static gboolean
232_debug_client (const char *id,
233 GsmClient *client,
234 GsmManager *manager)
235{
236 g_debug ("GsmManager: Client %s", gsm_client_peek_id (client));
237 return FALSE(0);
238}
239
240static void
241debug_clients (GsmManager *manager)
242{
243 GsmManagerPrivate *priv;
244 priv = gsm_manager_get_instance_private (manager);
245 gsm_store_foreach (priv->clients,
246 (GsmStoreFunc)_debug_client,
247 manager);
248}
249
250static gboolean
251_debug_inhibitor (const char *id,
252 GsmInhibitor *inhibitor,
253 GsmManager *manager)
254{
255 g_debug ("GsmManager: Inhibitor app:%s client:%s bus-name:%s reason:%s",
256 gsm_inhibitor_peek_app_id (inhibitor),
257 gsm_inhibitor_peek_client_id (inhibitor),
258 gsm_inhibitor_peek_bus_name (inhibitor),
259 gsm_inhibitor_peek_reason (inhibitor));
260 return FALSE(0);
261}
262
263static void
264debug_inhibitors (GsmManager *manager)
265{
266 GsmManagerPrivate *priv;
267
268 priv = gsm_manager_get_instance_private (manager);
269 gsm_store_foreach (priv->inhibitors,
270 (GsmStoreFunc)_debug_inhibitor,
271 manager);
272}
273
274static gboolean
275_find_by_cookie (const char *id,
276 GsmInhibitor *inhibitor,
277 guint *cookie_ap)
278{
279 guint cookie_b;
280
281 cookie_b = gsm_inhibitor_peek_cookie (inhibitor);
282
283 return (*cookie_ap == cookie_b);
284}
285
286static gboolean
287_find_by_startup_id (const char *id,
288 GsmClient *client,
289 const char *startup_id_a)
290{
291 const char *startup_id_b;
292
293 startup_id_b = gsm_client_peek_startup_id (client);
294 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
295 return FALSE(0);
296 }
297
298 return (strcmp (startup_id_a, startup_id_b) == 0);
299}
300
301static void
302app_condition_changed (GsmApp *app,
303 gboolean condition,
304 GsmManager *manager)
305{
306 GsmClient *client;
307 GsmManagerPrivate *priv;
308
309 priv = gsm_manager_get_instance_private (manager);
310
311 g_debug ("GsmManager: app:%s condition changed condition:%d",
312 gsm_app_peek_id (app),
313 condition);
314
315 client = (GsmClient *)gsm_store_find (priv->clients,
316 (GsmStoreFunc)_find_by_startup_id,
317 (char *)gsm_app_peek_startup_id (app));
318
319 if (condition) {
320 if (!gsm_app_is_running (app) && client == NULL((void*)0)) {
321 GError *error = NULL((void*)0);
322 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
323
324 g_debug ("GsmManager: starting app '%s'", gsm_app_peek_id (app));
325
326 res = gsm_app_start (app, &error);
327 if (error != NULL((void*)0)) {
328 g_warning ("Not able to start app from its condition: %s",
329 error->message);
330 g_error_free (error);
331 }
332 } else {
333 g_debug ("GsmManager: not starting - app still running '%s'", gsm_app_peek_id (app));
334 }
335 } else {
336 GError *error;
337 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
338
339 if (client != NULL((void*)0)) {
340 /* Kill client in case condition if false and make sure it won't
341 * be automatically restarted by adding the client to
342 * condition_clients */
343 priv->condition_clients =
344 g_slist_prepend (priv->condition_clients, client);
345
346 g_debug ("GsmManager: stopping client %s for app", gsm_client_peek_id (client));
347
348 error = NULL((void*)0);
349 res = gsm_client_stop (client, &error);
350 if (error != NULL((void*)0)) {
351 g_warning ("Not able to stop app client from its condition: %s",
352 error->message);
353 g_error_free (error);
354 }
355 } else {
356 g_debug ("GsmManager: stopping app %s", gsm_app_peek_id (app));
357
358 /* If we don't have a client then we should try to kill the app,
359 * if it is running */
360 error = NULL((void*)0);
361 if (gsm_app_is_running (app)) {
362 res = gsm_app_stop (app, &error);
363 if (error != NULL((void*)0)) {
364 g_warning ("Not able to stop app from its condition: %s",
365 error->message);
366 g_error_free (error);
367 }
368 }
369 }
370 }
371}
372
373static const char *
374phase_num_to_name (guint phase)
375{
376 const char *name;
377
378 switch (phase) {
379 case GSM_MANAGER_PHASE_STARTUP:
380 name = "STARTUP";
381 break;
382 case GSM_MANAGER_PHASE_INITIALIZATION:
383 name = "INITIALIZATION";
384 break;
385 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
386 name = "WINDOW_MANAGER";
387 break;
388 case GSM_MANAGER_PHASE_PANEL:
389 name = "PANEL";
390 break;
391 case GSM_MANAGER_PHASE_DESKTOP:
392 name = "DESKTOP";
393 break;
394 case GSM_MANAGER_PHASE_APPLICATION:
395 name = "APPLICATION";
396 break;
397 case GSM_MANAGER_PHASE_RUNNING:
398 name = "RUNNING";
399 break;
400 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
401 name = "QUERY_END_SESSION";
402 break;
403 case GSM_MANAGER_PHASE_END_SESSION:
404 name = "END_SESSION";
405 break;
406 case GSM_MANAGER_PHASE_EXIT:
407 name = "EXIT";
408 break;
409 default:
410 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
410, ((const char*) (__func__)), ((void*)0)); } while (0)
;
411 break;
412 }
413
414 return name;
415}
416
417static void start_phase (GsmManager *manager);
418
419static void
420quit_request_completed_consolekit (GsmConsolekit *consolekit,
421 GError *error,
422 gpointer user_data)
423{
424 MdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
425
426 if (error != NULL((void*)0)) {
427 mdm_set_logout_action (fallback_action);
428 }
429
430 g_object_unref (consolekit);
431
432 gtk_main_quit ();
433}
434
435#ifdef HAVE_SYSTEMD1
436static void
437quit_request_completed_systemd (GsmSystemd *systemd,
438 GError *error,
439 gpointer user_data)
440{
441 MdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
442
443 if (error != NULL((void*)0)) {
444 mdm_set_logout_action (fallback_action);
445 }
446
447 g_object_unref (systemd);
448
449 gtk_main_quit ();
450}
451#endif
452
453static void
454gsm_manager_quit (GsmManager *manager)
455{
456 GsmConsolekit *consolekit;
457 GsmManagerPrivate *priv;
458#ifdef HAVE_SYSTEMD1
459 GsmSystemd *systemd;
460#endif
461
462 priv = gsm_manager_get_instance_private (manager);
463 /* See the comment in request_reboot() for some more details about how
464 * this works. */
465
466 switch (priv->logout_type) {
467 case GSM_MANAGER_LOGOUT_LOGOUT:
468 gtk_main_quit ();
469 break;
470 case GSM_MANAGER_LOGOUT_REBOOT:
471 case GSM_MANAGER_LOGOUT_REBOOT_INTERACT:
472 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
473
474#ifdef HAVE_SYSTEMD1
475 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
476 systemd = gsm_get_systemd ();
477 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
478 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
479 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
480 GINT_TO_POINTER (MDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
;
481 gsm_systemd_attempt_restart (systemd);
482 }
483 else {
484#endif
485 consolekit = gsm_get_consolekit ();
486 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
487 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
488 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
489 GINT_TO_POINTER (MDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
;
490 gsm_consolekit_attempt_restart (consolekit);
491#ifdef HAVE_SYSTEMD1
492 }
493#endif
494 break;
495 case GSM_MANAGER_LOGOUT_REBOOT_MDM:
496 mdm_set_logout_action (MDM_LOGOUT_ACTION_REBOOT);
497 gtk_main_quit ();
498 break;
499 case GSM_MANAGER_LOGOUT_SHUTDOWN:
500 case GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
501 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
502
503#ifdef HAVE_SYSTEMD1
504 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
505 systemd = gsm_get_systemd ();
506 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
507 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
508 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
509 GINT_TO_POINTER (MDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
;
510 gsm_systemd_attempt_stop (systemd);
511 }
512 else {
513#endif
514 consolekit = gsm_get_consolekit ();
515 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
516 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
517 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
518 GINT_TO_POINTER (MDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
;
519 gsm_consolekit_attempt_stop (consolekit);
520#ifdef HAVE_SYSTEMD1
521 }
522#endif
523 break;
524 case GSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
525 mdm_set_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
526 gtk_main_quit ();
527 break;
528 default:
529 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
529, ((const char*) (__func__)), ((void*)0)); } while (0)
;
530 break;
531 }
532}
533
534static void
535end_phase (GsmManager *manager)
536{
537 GsmManagerPrivate *priv;
538 gboolean start_next_phase = TRUE(!(0));
539
540 priv = gsm_manager_get_instance_private (manager);
541
542 g_debug ("GsmManager: ending phase %s\n",
543 phase_num_to_name (priv->phase));
544
545 g_slist_free (priv->pending_apps);
546 priv->pending_apps = NULL((void*)0);
547
548 g_slist_free (priv->query_clients);
549 priv->query_clients = NULL((void*)0);
550
551 g_slist_free (priv->next_query_clients);
552 priv->next_query_clients = NULL((void*)0);
553
554 if (priv->phase_timeout_id > 0) {
555 g_source_remove (priv->phase_timeout_id);
556 priv->phase_timeout_id = 0;
557 }
558
559 switch (priv->phase) {
560 case GSM_MANAGER_PHASE_STARTUP:
561 case GSM_MANAGER_PHASE_INITIALIZATION:
562 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
563 case GSM_MANAGER_PHASE_PANEL:
564 case GSM_MANAGER_PHASE_DESKTOP:
565 case GSM_MANAGER_PHASE_APPLICATION:
566 break;
567 case GSM_MANAGER_PHASE_RUNNING:
568 if (_log_out_is_locked_down (manager)) {
569 g_warning ("Unable to logout: Logout has been locked down");
570 start_next_phase = FALSE(0);
571 }
572 break;
573 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
574 break;
575 case GSM_MANAGER_PHASE_END_SESSION:
576 if (auto_save_is_enabled (manager))
577 maybe_save_session (manager);
578 break;
579 case GSM_MANAGER_PHASE_EXIT:
580 start_next_phase = FALSE(0);
581 gsm_manager_quit (manager);
582 break;
583 default:
584 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
584, ((const char*) (__func__)), ((void*)0)); } while (0)
;
585 break;
586 }
587
588 if (start_next_phase) {
589 priv->phase++;
590 start_phase (manager);
591 }
592}
593
594static void
595app_registered (GsmApp *app,
596 GsmManager *manager)
597{
598 GsmManagerPrivate *priv;
599
600 priv = gsm_manager_get_instance_private (manager);
601 priv->pending_apps = g_slist_remove (priv->pending_apps, app);
602 g_signal_handlers_disconnect_by_func (app, app_registered, manager)g_signal_handlers_disconnect_matched ((app), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
603
604 if (priv->pending_apps == NULL((void*)0)) {
605 if (priv->phase_timeout_id > 0) {
606 g_source_remove (priv->phase_timeout_id);
607 priv->phase_timeout_id = 0;
608 }
609
610 end_phase (manager);
611 }
612}
613
614static gboolean
615on_phase_timeout (GsmManager *manager)
616{
617 GSList *a;
618 GsmManagerPrivate *priv;
619
620 priv = gsm_manager_get_instance_private (manager);
621 priv->phase_timeout_id = 0;
622
623 switch (priv->phase) {
624 case GSM_MANAGER_PHASE_STARTUP:
625 case GSM_MANAGER_PHASE_INITIALIZATION:
626 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
627 case GSM_MANAGER_PHASE_PANEL:
628 case GSM_MANAGER_PHASE_DESKTOP:
629 case GSM_MANAGER_PHASE_APPLICATION:
630 for (a = priv->pending_apps; a; a = a->next) {
631 g_warning ("Application '%s' failed to register before timeout",
632 gsm_app_peek_app_id (a->data));
633 g_signal_handlers_disconnect_by_func (a->data, app_registered, manager)g_signal_handlers_disconnect_matched ((a->data), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
634 /* FIXME: what if the app was filling in a required slot? */
635 }
636 break;
637 case GSM_MANAGER_PHASE_RUNNING:
638 break;
639 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
640 case GSM_MANAGER_PHASE_END_SESSION:
641 break;
642 case GSM_MANAGER_PHASE_EXIT:
643 break;
644 default:
645 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
645, ((const char*) (__func__)), ((void*)0)); } while (0)
;
646 break;
647 }
648
649 end_phase (manager);
650
651 return FALSE(0);
652}
653
654static gboolean
655_autostart_delay_timeout (GsmApp *app)
656{
657 GError *error = NULL((void*)0);
658 gboolean res;
659
660 if (!gsm_app_peek_is_disabled (app)
661 && !gsm_app_peek_is_conditionally_disabled (app)) {
662 res = gsm_app_start (app, &error);
663 if (!res) {
664 if (error != NULL((void*)0)) {
665 g_warning ("Could not launch application '%s': %s",
666 gsm_app_peek_app_id (app),
667 error->message);
668 g_error_free (error);
669 }
670 }
671 }
672
673 g_object_unref (app);
674
675 return FALSE(0);
676}
677
678static gboolean
679_start_app (const char *id,
680 GsmApp *app,
681 GsmManager *manager)
682{
683 GError *error;
684 gboolean res;
685 int delay;
686 GsmManagerPrivate *priv;
687
688 priv = gsm_manager_get_instance_private (manager);
689
690 if (gsm_app_peek_phase (app) != priv->phase) {
691 goto out;
692 }
693
694 /* Keep track of app autostart condition in order to react
695 * accordingly in the future. */
696 g_signal_connect (app,g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
697 "condition-changed",g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
698 G_CALLBACK (app_condition_changed),g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
699 manager)g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
700
701 if (gsm_app_peek_is_disabled (app)
702 || gsm_app_peek_is_conditionally_disabled (app)) {
703 g_debug ("GsmManager: Skipping disabled app: %s", id);
704 goto out;
705 }
706
707 delay = gsm_app_peek_autostart_delay (app);
708 if (delay > 0) {
709 g_timeout_add_seconds (delay,
710 (GSourceFunc)_autostart_delay_timeout,
711 g_object_ref (app)((__typeof__ (app)) (g_object_ref) (app)));
712 g_debug ("GsmManager: %s is scheduled to start in %d seconds", id, delay);
713 goto out;
714 }
715
716 error = NULL((void*)0);
717 res = gsm_app_start (app, &error);
718 if (!res) {
719 if (error != NULL((void*)0)) {
720 g_warning ("Could not launch application '%s': %s",
721 gsm_app_peek_app_id (app),
722 error->message);
723 g_error_free (error);
724 error = NULL((void*)0);
725 }
726 goto out;
727 }
728
729 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
730 g_signal_connect (app,g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
731 "exited",g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
732 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
733 manager)g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
;
734 g_signal_connect (app,g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
735 "registered",g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
736 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
737 manager)g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
;
738 priv->pending_apps = g_slist_prepend (priv->pending_apps, app);
739 }
740 out:
741 return FALSE(0);
742}
743
744static void
745do_phase_startup (GsmManager *manager)
746{
747 GsmManagerPrivate *priv;
748
749 priv = gsm_manager_get_instance_private (manager);
750 gsm_store_foreach (priv->apps,
751 (GsmStoreFunc)_start_app,
752 manager);
753
754 if (priv->pending_apps != NULL((void*)0)) {
755 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
756 priv->phase_timeout_id = g_timeout_add_seconds (GSM_MANAGER_PHASE_TIMEOUT30,
757 (GSourceFunc)on_phase_timeout,
758 manager);
759 }
760 } else {
761 end_phase (manager);
762 }
763}
764
765typedef struct {
766 GsmManager *manager;
767 guint flags;
768} ClientEndSessionData;
769
770static gboolean
771_client_end_session (GsmClient *client,
772 ClientEndSessionData *data)
773{
774 gboolean ret;
775 GError *error;
776 GsmManagerPrivate *priv;
777
778 priv = gsm_manager_get_instance_private (data->manager);
779
780 error = NULL((void*)0);
781 ret = gsm_client_end_session (client, data->flags, &error);
782 if (! ret) {
783 g_warning ("Unable to query client: %s", error->message);
784 g_error_free (error);
785 /* FIXME: what should we do if we can't communicate with client? */
786 } else {
787 g_debug ("GsmManager: adding client to end-session clients: %s", gsm_client_peek_id (client));
788 priv->query_clients = g_slist_prepend (priv->query_clients,
789 client);
790 }
791
792 return FALSE(0);
793}
794
795static gboolean
796_client_end_session_helper (const char *id,
797 GsmClient *client,
798 ClientEndSessionData *data)
799{
800 return _client_end_session (client, data);
801}
802
803static void
804do_phase_end_session (GsmManager *manager)
805{
806 ClientEndSessionData data;
807 GsmManagerPrivate *priv;
808
809 data.manager = manager;
810 data.flags = 0;
811 priv = gsm_manager_get_instance_private (manager);
812
813 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
814 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
815 }
816 if (auto_save_is_enabled (manager)) {
817 data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
818 }
819
820 if (priv->phase_timeout_id > 0) {
821 g_source_remove (priv->phase_timeout_id);
822 priv->phase_timeout_id = 0;
823 }
824
825 if (gsm_store_size (priv->clients) > 0) {
826 priv->phase_timeout_id = g_timeout_add_seconds (GSM_MANAGER_PHASE_TIMEOUT30,
827 (GSourceFunc)on_phase_timeout,
828 manager);
829
830 gsm_store_foreach (priv->clients,
831 (GsmStoreFunc)_client_end_session_helper,
832 &data);
833 } else {
834 end_phase (manager);
835 }
836}
837
838static void
839do_phase_end_session_part_2 (GsmManager *manager)
840{
841 ClientEndSessionData data;
842 GsmManagerPrivate *priv;
843
844 data.manager = manager;
845 data.flags = 0;
846 priv = gsm_manager_get_instance_private (manager);
847
848 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
849 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
850 }
851 if (auto_save_is_enabled (manager)) {
852 data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
853 }
854 data.flags |= GSM_CLIENT_END_SESSION_FLAG_LAST;
855
856 /* keep the timeout that was started at the beginning of the
857 * GSM_MANAGER_PHASE_END_SESSION phase */
858
859 if (g_slist_length (priv->next_query_clients) > 0) {
860 g_slist_foreach (priv->next_query_clients,
861 (GFunc)_client_end_session,
862 &data);
863
864 g_slist_free (priv->next_query_clients);
865 priv->next_query_clients = NULL((void*)0);
866 } else {
867 end_phase (manager);
868 }
869}
870
871static gboolean
872_client_stop (const char *id,
873 GsmClient *client,
874 gpointer user_data)
875{
876 gboolean ret;
877 GError *error;
878
879 error = NULL((void*)0);
880 ret = gsm_client_stop (client, &error);
881 if (! ret) {
882 g_warning ("Unable to stop client: %s", error->message);
883 g_error_free (error);
884 /* FIXME: what should we do if we can't communicate with client? */
885 } else {
886 g_debug ("GsmManager: stopped client: %s", gsm_client_peek_id (client));
887 }
888
889 return FALSE(0);
890}
891
892#ifdef HAVE_SYSTEMD1
893static void
894maybe_restart_user_bus (GsmManager *manager)
895{
896 GsmSystemd *systemd;
897 GsmManagerPrivate *priv;
898 GDBusConnection *connection;
899
900 g_autoptr(GVariant)__attribute__((cleanup(glib_autoptr_cleanup_GVariant))) GVariant_autoptr reply = NULL((void*)0);
901 g_autoptr(GError)__attribute__((cleanup(glib_autoptr_cleanup_GError))) GError_autoptr error = NULL((void*)0);
902
903 priv = gsm_manager_get_instance_private (manager);
904 if (priv->dbus_disconnected)
905 return;
906
907 systemd = gsm_get_systemd ();
908
909 if (!gsm_systemd_is_last_session_for_user (systemd))
910 return;
911
912 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL((void*)0), &error);
913
914 if (error != NULL((void*)0)) {
915 g_debug ("GsmManager: failed to connect to session bus: %s", error->message);
916 return;
917 }
918
919 reply = g_dbus_connection_call_sync (connection,
920 "org.freedesktop.systemd1",
921 "/org/freedesktop/systemd1",
922 "org.freedesktop.systemd1.Manager",
923 "TryRestartUnit",
924 g_variant_new ("(ss)", "dbus.service", "replace"),
925 NULL((void*)0),
926 G_DBUS_CALL_FLAGS_NONE,
927 -1,
928 NULL((void*)0),
929 &error);
930
931 if (error != NULL((void*)0)) {
932 g_debug ("GsmManager: reloading user bus failed: %s", error->message);
933 }
934}
935#endif
936
937static void
938do_phase_exit (GsmManager *manager)
939{
940 GsmManagerPrivate *priv;
941
942 priv = gsm_manager_get_instance_private (manager);
943 if (gsm_store_size (priv->clients) > 0) {
944 gsm_store_foreach (priv->clients,
945 (GsmStoreFunc)_client_stop,
946 NULL((void*)0));
947 }
948
949#ifdef HAVE_SYSTEMD1
950 maybe_restart_user_bus (manager);
951#endif
952
953 end_phase (manager);
954}
955
956static gboolean
957_client_query_end_session (const char *id,
958 GsmClient *client,
959 ClientEndSessionData *data)
960{
961 gboolean ret;
962 GError *error;
963 GsmManagerPrivate *priv;
964
965 priv = gsm_manager_get_instance_private (data->manager);
966
967 error = NULL((void*)0);
968 ret = gsm_client_query_end_session (client, data->flags, &error);
969 if (! ret) {
970 g_warning ("Unable to query client: %s", error->message);
971 g_error_free (error);
972 /* FIXME: what should we do if we can't communicate with client? */
973 } else {
974 g_debug ("GsmManager: adding client to query clients: %s", gsm_client_peek_id (client));
975 priv->query_clients = g_slist_prepend (priv->query_clients, client);
976 }
977
978 return FALSE(0);
979}
980
981static gboolean
982inhibitor_has_flag (gpointer key,
983 GsmInhibitor *inhibitor,
984 gpointer data)
985{
986 guint flag;
987 guint flags;
988
989 flag = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
990
991 flags = gsm_inhibitor_peek_flags (inhibitor);
992
993 return (flags & flag);
994}
995
996static gboolean
997gsm_manager_is_logout_inhibited (GsmManager *manager)
998{
999 GsmInhibitor *inhibitor;
1000 GsmManagerPrivate *priv;
1001
1002 priv = gsm_manager_get_instance_private (manager);
1003
1004 if (priv->inhibitors == NULL((void*)0)) {
1005 return FALSE(0);
1006 }
1007
1008 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
1009 (GsmStoreFunc)inhibitor_has_flag,
1010 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_LOGOUT)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_LOGOUT)));
1011 if (inhibitor == NULL((void*)0)) {
1012 return FALSE(0);
1013 }
1014 return TRUE(!(0));
1015}
1016
1017static gboolean
1018gsm_manager_is_idle_inhibited (GsmManager *manager)
1019{
1020 GsmInhibitor *inhibitor;
1021 GsmManagerPrivate *priv;
1022
1023 priv = gsm_manager_get_instance_private (manager);
1024
1025 if (priv->inhibitors == NULL((void*)0)) {
1026 return FALSE(0);
1027 }
1028
1029 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
1030 (GsmStoreFunc)inhibitor_has_flag,
1031 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_IDLE)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_IDLE)));
1032 if (inhibitor == NULL((void*)0)) {
1033 return FALSE(0);
1034 }
1035 return TRUE(!(0));
1036}
1037
1038static gboolean
1039_client_cancel_end_session (const char *id,
1040 GsmClient *client,
1041 GsmManager *manager)
1042{
1043 gboolean res;
1044 GError *error;
1045
1046 error = NULL((void*)0);
1047 res = gsm_client_cancel_end_session (client, &error);
1048 if (! res) {
1049 g_warning ("Unable to cancel end session: %s", error->message);
1050 g_error_free (error);
1051 }
1052
1053 return FALSE(0);
1054}
1055
1056static gboolean
1057inhibitor_is_jit (gpointer key,
1058 GsmInhibitor *inhibitor,
1059 GsmManager *manager)
1060{
1061 gboolean matches;
1062 const char *id;
1063
1064 id = gsm_inhibitor_peek_client_id (inhibitor);
1065
1066 matches = (id != NULL((void*)0) && id[0] != '\0');
1067
1068 return matches;
1069}
1070
1071static void
1072cancel_end_session (GsmManager *manager)
1073{
1074 GsmManagerPrivate *priv;
1075
1076 priv = gsm_manager_get_instance_private (manager);
1077 /* just ignore if received outside of shutdown */
1078 if (priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1079 return;
1080 }
1081
1082 /* switch back to running phase */
1083 g_debug ("GsmManager: Cancelling the end of session");
1084
1085 /* remove the dialog before we remove the inhibitors, else the dialog
1086 * will activate itself automatically when the last inhibitor will be
1087 * removed */
1088 if (priv->inhibit_dialog)
1089 gtk_widget_destroy (GTK_WIDGET (priv->inhibit_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_widget_get_type ())))))
)
);
1090 priv->inhibit_dialog = NULL((void*)0);
1091
1092 /* clear all JIT inhibitors */
1093 gsm_store_foreach_remove (priv->inhibitors,
1094 (GsmStoreFunc)inhibitor_is_jit,
1095 (gpointer)manager);
1096
1097 gsm_store_foreach (priv->clients,
1098 (GsmStoreFunc)_client_cancel_end_session,
1099 NULL((void*)0));
1100
1101 gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_RUNNING);
1102 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
1103
1104 priv->logout_type = GSM_MANAGER_LOGOUT_NONE;
1105 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
1106
1107 start_phase (manager);
1108}
1109
1110static gboolean
1111process_is_running (const char * name)
1112{
1113 int num_processes;
1114 char * command = g_strdup_printf ("pidof %s | wc -l", name);
1115 FILE *fp = popen(command, "r");
1116
1117 if (fscanf(fp, "%d", &num_processes) != 1)
1118 num_processes = 0;
1119
1120 pclose(fp);
1121 g_free (command);
1122
1123 if (num_processes > 0) {
1124 return TRUE(!(0));
1125 }
1126 else {
1127 return FALSE(0);
1128 }
1129}
1130
1131static void
1132manager_switch_user (GsmManager *manager)
1133{
1134 GError *error;
1135 gboolean res;
1136 char *command;
1137 const gchar *xdg_seat_path = g_getenv ("XDG_SEAT_PATH");
1138
1139 /* We have to do this here and in request_switch_user() because this
1140 * function can be called at a later time, not just directly after
1141 * request_switch_user(). */
1142 if (_switch_user_is_locked_down (manager)) {
1143 g_warning ("Unable to switch user: User switching has been locked down");
1144 return;
1145 }
1146
1147 if (process_is_running("mdm")) {
1148 /* MDM */
1149 command = g_strdup_printf ("%s %s",
1150 MDM_FLEXISERVER_COMMAND"mdmflexiserver",
1151 MDM_FLEXISERVER_ARGS"--startnew Standard");
1152
1153 error = NULL((void*)0);
1154 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1155
1156 g_free (command);
1157
1158 if (! res) {
1159 g_debug ("GsmManager: Unable to start MDM greeter: %s", error->message);
1160 g_error_free (error);
1161 }
1162 }
1163 else if (process_is_running("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary")) {
1164 /* GDM */
1165 command = g_strdup_printf ("%s %s",
1166 GDM_FLEXISERVER_COMMAND"gdmflexiserver",
1167 GDM_FLEXISERVER_ARGS"--startnew Standard");
1168
1169 error = NULL((void*)0);
1170 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1171
1172 g_free (command);
1173
1174 if (! res) {
1175 g_debug ("GsmManager: Unable to start GDM greeter: %s", error->message);
1176 g_error_free (error);
1177 }
1178 }
1179 else if (xdg_seat_path != NULL((void*)0)) {
1180 /* LightDM */
1181 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
1182 GDBusProxy *proxy = NULL((void*)0);
1183 error = NULL((void*)0);
1184
1185 proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
1186 flags,
1187 NULL((void*)0),
1188 "org.freedesktop.DisplayManager",
1189 xdg_seat_path,
1190 "org.freedesktop.DisplayManager.Seat",
1191 NULL((void*)0),
1192 &error);
1193 if (proxy != NULL((void*)0)) {
1194 g_dbus_proxy_call_sync (proxy,
1195 "SwitchToGreeter",
1196 g_variant_new ("()"),
1197 G_DBUS_CALL_FLAGS_NONE,
1198 -1,
1199 NULL((void*)0),
1200 NULL((void*)0));
1201 g_object_unref (proxy);
1202 }
1203 else {
1204 g_debug ("GsmManager: Unable to start LightDM greeter: %s", error->message);
1205 g_error_free (error);
1206 }
1207 }
1208}
1209
1210static gboolean
1211sleep_lock_is_enabled (GsmManager *manager)
1212{
1213 GsmManagerPrivate *priv;
1214
1215 priv = gsm_manager_get_instance_private (manager);
1216 if (priv->settings_screensaver != NULL((void*)0))
1217 return g_settings_get_boolean (priv->settings_screensaver,
1218 KEY_SLEEP_LOCK"lock-enabled");
1219 else
1220 return FALSE(0);
1221}
1222
1223static void
1224manager_perhaps_lock (GsmManager *manager)
1225{
1226 gchar **screen_locker_command;
1227
1228 if ((screen_locker_command = gsm_get_screen_locker_command ()) != NULL((void*)0)) {
1229 GError *error = NULL((void*)0);
1230
1231 /* only lock if mate-screensaver is set to lock */
1232 if (!g_strcmp0 (screen_locker_command[0], "mate-screensaver-command") &&
1233 !sleep_lock_is_enabled (manager)) {
1234 goto clear_screen_locker_command;
1235 }
1236
1237 /* do this sync to ensure it's on the screen when we start suspending */
1238 g_spawn_sync (NULL((void*)0), screen_locker_command, NULL((void*)0),
1239 G_SPAWN_DEFAULT | G_SPAWN_SEARCH_PATH,
1240 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1241
1242 if (error) {
1243 g_warning ("Couldn't lock screen: %s", error->message);
1244 g_error_free (error);
1245 }
1246
1247 } else {
1248 g_warning ("Couldn't find any screen locker");
1249 }
1250
1251clear_screen_locker_command:
1252
1253 g_strfreev (screen_locker_command);
1254}
1255
1256static void
1257manager_attempt_hibernate (GsmManager *manager)
1258{
1259#ifdef HAVE_SYSTEMD1
1260 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1261
1262 GsmSystemd *systemd;
1263
1264 systemd = gsm_get_systemd ();
1265
1266 /* lock the screen before we suspend */
1267 manager_perhaps_lock (manager);
1268
1269 gsm_systemd_attempt_hibernate (systemd);
1270 }
1271 else {
1272#endif
1273 GsmConsolekit *consolekit;
1274 consolekit = gsm_get_consolekit ();
1275
1276 gboolean can_hibernate = gsm_consolekit_can_hibernate (consolekit);
1277 if (can_hibernate) {
1278 /* lock the screen before we suspend */
1279 manager_perhaps_lock (manager);
1280
1281 gsm_consolekit_attempt_hibernate (consolekit);
1282 }
1283#ifdef HAVE_SYSTEMD1
1284 }
1285#endif
1286}
1287
1288static void
1289manager_attempt_suspend (GsmManager *manager)
1290{
1291#ifdef HAVE_SYSTEMD1
1292 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1293
1294 GsmSystemd *systemd;
1295
1296 systemd = gsm_get_systemd ();
1297
1298 /* lock the screen before we suspend */
1299 manager_perhaps_lock (manager);
1300
1301 gsm_systemd_attempt_suspend (systemd);
1302 }
1303 else {
1304#endif
1305 GsmConsolekit *consolekit;
1306 consolekit = gsm_get_consolekit ();
1307
1308 gboolean can_suspend = gsm_consolekit_can_suspend (consolekit);
1309 if (can_suspend) {
1310 /* lock the screen before we suspend */
1311 manager_perhaps_lock (manager);
1312
1313 gsm_consolekit_attempt_suspend (consolekit);
1314 }
1315#ifdef HAVE_SYSTEMD1
1316 }
1317#endif
1318}
1319
1320static void
1321do_inhibit_dialog_action (GsmManager *manager,
1322 int action)
1323{
1324 GsmManagerPrivate *priv;
1325
1326 priv = gsm_manager_get_instance_private (manager);
1327 switch (action) {
1328 case GSM_LOGOUT_ACTION_SWITCH_USER:
1329 manager_switch_user (manager);
1330 break;
1331 case GSM_LOGOUT_ACTION_HIBERNATE:
1332 manager_attempt_hibernate (manager);
1333 break;
1334 case GSM_LOGOUT_ACTION_SLEEP:
1335 manager_attempt_suspend (manager);
1336 break;
1337 case GSM_LOGOUT_ACTION_SHUTDOWN:
1338 case GSM_LOGOUT_ACTION_REBOOT:
1339 case GSM_LOGOUT_ACTION_LOGOUT:
1340 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_FORCE;
1341 end_phase (manager);
1342 break;
1343 default:
1344 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1344, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1345 break;
1346 }
1347}
1348
1349static void
1350inhibit_dialog_response (GsmInhibitDialog *dialog,
1351 guint response_id,
1352 GsmManager *manager)
1353{
1354 int action;
1355 GsmManagerPrivate *priv;
1356
1357 g_debug ("GsmManager: Inhibit dialog response: %d", response_id);
1358
1359 priv = gsm_manager_get_instance_private (manager);
1360 /* must destroy dialog before cancelling since we'll
1361 remove JIT inhibitors and we don't want to trigger
1362 action. */
1363 g_object_get (dialog, "action", &action, NULL((void*)0));
1364 gtk_widget_destroy (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
);
1365 priv->inhibit_dialog = NULL((void*)0);
1366
1367 /* In case of dialog cancel, switch user, hibernate and
1368 * suspend, we just perform the respective action and return,
1369 * without shutting down the session. */
1370 switch (response_id) {
1371 case GTK_RESPONSE_CANCEL:
1372 case GTK_RESPONSE_NONE:
1373 case GTK_RESPONSE_DELETE_EVENT:
1374 if (action == GSM_LOGOUT_ACTION_LOGOUT
1375 || action == GSM_LOGOUT_ACTION_SHUTDOWN
1376 || action == GSM_LOGOUT_ACTION_REBOOT) {
1377 cancel_end_session (manager);
1378 }
1379 break;
1380 case GTK_RESPONSE_ACCEPT:
1381 g_debug ("GsmManager: doing action %d", action);
1382 do_inhibit_dialog_action (manager, action);
1383 break;
1384 default:
1385 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1385, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1386 break;
1387 }
1388}
1389
1390static void
1391query_end_session_complete (GsmManager *manager)
1392{
1393 GsmLogoutAction action;
1394 GsmManagerPrivate *priv;
1395
1396 priv = gsm_manager_get_instance_private (manager);
1397
1398 g_debug ("GsmManager: query end session complete");
1399
1400 /* Remove the timeout since this can be called from outside the timer
1401 * and we don't want to have it called twice */
1402 if (priv->query_timeout_id > 0) {
1403 g_source_remove (priv->query_timeout_id);
1404 priv->query_timeout_id = 0;
1405 }
1406
1407 if (! gsm_manager_is_logout_inhibited (manager)) {
1408 end_phase (manager);
1409 return;
1410 }
1411
1412 if (priv->inhibit_dialog != NULL((void*)0)) {
1413 g_debug ("GsmManager: inhibit dialog already up");
1414 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
1415 return;
1416 }
1417
1418 switch (priv->logout_type) {
1419 case GSM_MANAGER_LOGOUT_LOGOUT:
1420 action = GSM_LOGOUT_ACTION_LOGOUT;
1421 break;
1422 case GSM_MANAGER_LOGOUT_REBOOT:
1423 case GSM_MANAGER_LOGOUT_REBOOT_INTERACT:
1424 case GSM_MANAGER_LOGOUT_REBOOT_MDM:
1425 action = GSM_LOGOUT_ACTION_REBOOT;
1426 break;
1427 case GSM_MANAGER_LOGOUT_SHUTDOWN:
1428 case GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
1429 case GSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
1430 action = GSM_LOGOUT_ACTION_SHUTDOWN;
1431 break;
1432 default:
1433 g_warning ("Unexpected logout type %d when creating inhibit dialog",
1434 priv->logout_type);
1435 action = GSM_LOGOUT_ACTION_LOGOUT;
1436 break;
1437 }
1438
1439 /* Note: GSM_LOGOUT_ACTION_SHUTDOWN and GSM_LOGOUT_ACTION_REBOOT are
1440 * actually handled the same way as GSM_LOGOUT_ACTION_LOGOUT in the
1441 * inhibit dialog; the action, if the button is clicked, will be to
1442 * simply go to the next phase. */
1443 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
1444 priv->clients,
1445 action);
1446
1447 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1448 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1449 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1450 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
1451 gtk_widget_show (priv->inhibit_dialog);
1452
1453}
1454
1455static guint32
1456generate_cookie (void)
1457{
1458 guint32 cookie;
1459
1460 cookie = (guint32)g_random_int_range (1, G_MAXINT32((gint32) 0x7fffffff));
1461
1462 return cookie;
1463}
1464
1465static guint32
1466_generate_unique_cookie (GsmManager *manager)
1467{
1468 guint32 cookie;
1469 GsmManagerPrivate *priv;
1470
1471 priv = gsm_manager_get_instance_private (manager);
1472
1473 do {
1474 cookie = generate_cookie ();
1475 } while (gsm_store_find (priv->inhibitors, (GsmStoreFunc)_find_by_cookie, &cookie) != NULL((void*)0));
1476
1477 return cookie;
1478}
1479
1480static gboolean
1481_on_query_end_session_timeout (GsmManager *manager)
1482{
1483 GSList *l;
1484 GsmManagerPrivate *priv;
1485
1486 priv = gsm_manager_get_instance_private (manager);
1487
1488 priv->query_timeout_id = 0;
1489
1490 g_debug ("GsmManager: query end session timed out");
1491
1492 for (l = priv->query_clients; l != NULL((void*)0); l = l->next) {
1493 guint cookie;
1494 GsmInhibitor *inhibitor;
1495 const char *bus_name;
1496 char *app_id;
1497
1498 g_warning ("Client '%s' failed to reply before timeout",
1499 gsm_client_peek_id (l->data));
1500
1501 /* Don't add "not responding" inhibitors if logout is forced
1502 */
1503 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
1504 continue;
1505 }
1506
1507 /* Add JIT inhibit for unresponsive client */
1508 if (GSM_IS_DBUS_CLIENT (l->data)) {
1509 bus_name = gsm_dbus_client_get_bus_name (l->data);
1510 } else {
1511 bus_name = NULL((void*)0);
1512 }
1513
1514 app_id = g_strdup (gsm_client_peek_app_id (l->data))g_strdup_inline (gsm_client_peek_app_id (l->data));
1515 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1516 /* XSMP clients don't give us an app id unless we start them */
1517 g_free (app_id);
1518 app_id = gsm_client_get_app_name (l->data);
1519 }
1520
1521 cookie = _generate_unique_cookie (manager);
1522 inhibitor = gsm_inhibitor_new_for_client (gsm_client_peek_id (l->data),
1523 app_id,
1524 GSM_INHIBITOR_FLAG_LOGOUT,
1525 _("Not responding")gettext ("Not responding"),
1526 bus_name,
1527 cookie);
1528 g_free (app_id);
1529 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
1530 g_object_unref (inhibitor);
1531 }
1532
1533 g_slist_free (priv->query_clients);
1534 priv->query_clients = NULL((void*)0);
1535
1536 query_end_session_complete (manager);
1537
1538 return FALSE(0);
1539}
1540
1541static void
1542do_phase_query_end_session (GsmManager *manager)
1543{
1544 ClientEndSessionData data;
1545 GsmManagerPrivate *priv;
1546
1547 data.manager = manager;
1548 data.flags = 0;
1549 priv = gsm_manager_get_instance_private (manager);
1550
1551 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
1552 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
1553 }
1554 /* We only query if an app is ready to log out, so we don't use
1555 * GSM_CLIENT_END_SESSION_FLAG_SAVE here.
1556 */
1557
1558 debug_clients (manager);
1559 g_debug ("GsmManager: sending query-end-session to clients (logout mode: %s)",
1560 priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL? "normal" :
1561 priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE? "forceful":
1562 "no confirmation");
1563 gsm_store_foreach (priv->clients,
1564 (GsmStoreFunc)_client_query_end_session,
1565 &data);
1566
1567 /* This phase doesn't time out unless logout is forced. Typically, this
1568 * separate timer is only used to show UI. */
1569 priv->query_timeout_id = g_timeout_add_seconds (1, (GSourceFunc)_on_query_end_session_timeout, manager);
1570}
1571
1572static void
1573update_idle (GsmManager *manager)
1574{
1575 GsmManagerPrivate *priv;
1576
1577 priv = gsm_manager_get_instance_private (manager);
1578 if (gsm_manager_is_idle_inhibited (manager)) {
1579 gsm_presence_set_idle_enabled (priv->presence, FALSE(0));
1580 } else {
1581 gsm_presence_set_idle_enabled (priv->presence, TRUE(!(0)));
1582 }
1583}
1584
1585static void
1586start_phase (GsmManager *manager)
1587{
1588 GsmManagerPrivate *priv;
1589
1590 priv = gsm_manager_get_instance_private (manager);
1591
1592 g_debug ("GsmManager: starting phase %s\n",
1593 phase_num_to_name (priv->phase));
1594
1595 /* reset state */
1596 g_slist_free (priv->pending_apps);
1597 priv->pending_apps = NULL((void*)0);
1598 g_slist_free (priv->query_clients);
1599 priv->query_clients = NULL((void*)0);
1600 g_slist_free (priv->next_query_clients);
1601 priv->next_query_clients = NULL((void*)0);
1602
1603 if (priv->query_timeout_id > 0) {
1604 g_source_remove (priv->query_timeout_id);
1605 priv->query_timeout_id = 0;
1606 }
1607 if (priv->phase_timeout_id > 0) {
1608 g_source_remove (priv->phase_timeout_id);
1609 priv->phase_timeout_id = 0;
1610 }
1611
1612 switch (priv->phase) {
1613 case GSM_MANAGER_PHASE_STARTUP:
1614 case GSM_MANAGER_PHASE_INITIALIZATION:
1615 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
1616 case GSM_MANAGER_PHASE_PANEL:
1617 case GSM_MANAGER_PHASE_DESKTOP:
1618 case GSM_MANAGER_PHASE_APPLICATION:
1619 do_phase_startup (manager);
1620 break;
1621 case GSM_MANAGER_PHASE_RUNNING:
1622 g_signal_emit (manager, signals[SESSION_RUNNING], 0);
1623 update_idle (manager);
1624 break;
1625 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
1626 do_phase_query_end_session (manager);
1627 break;
1628 case GSM_MANAGER_PHASE_END_SESSION:
1629 do_phase_end_session (manager);
1630 break;
1631 case GSM_MANAGER_PHASE_EXIT:
1632 do_phase_exit (manager);
1633 break;
1634 default:
1635 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1635, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1636 break;
1637 }
1638}
1639
1640static gboolean
1641_debug_app_for_phase (const char *id,
1642 GsmApp *app,
1643 gpointer data)
1644{
1645 guint phase;
1646
1647 phase = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
1648
1649 if (gsm_app_peek_phase (app) != phase) {
1650 return FALSE(0);
1651 }
1652
1653 g_debug ("GsmManager:\tID: %s\tapp-id:%s\tis-disabled:%d\tis-conditionally-disabled:%d\tis-delayed:%d",
1654 gsm_app_peek_id (app),
1655 gsm_app_peek_app_id (app),
1656 gsm_app_peek_is_disabled (app),
1657 gsm_app_peek_is_conditionally_disabled (app),
1658 (gsm_app_peek_autostart_delay (app) > 0));
1659
1660 return FALSE(0);
1661}
1662
1663static void
1664debug_app_summary (GsmManager *manager)
1665{
1666 guint phase;
1667 GsmManagerPrivate *priv;
1668
1669 priv = gsm_manager_get_instance_private (manager);
1670
1671 g_debug ("GsmManager: App startup summary");
1672 for (phase = GSM_MANAGER_PHASE_INITIALIZATION; phase < GSM_MANAGER_PHASE_RUNNING; phase++) {
1673 g_debug ("GsmManager: Phase %s", phase_num_to_name (phase));
1674 gsm_store_foreach (priv->apps,
1675 (GsmStoreFunc)_debug_app_for_phase,
1676 GUINT_TO_POINTER (phase)((gpointer) (gulong) (phase)));
1677 }
1678}
1679
1680void
1681gsm_manager_start (GsmManager *manager)
1682{
1683 g_debug ("GsmManager: GSM starting to manage");
1684
1685 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
1686
1687 gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_INITIALIZATION);
1688 debug_app_summary (manager);
1689 start_phase (manager);
1690}
1691
1692void
1693_gsm_manager_set_renderer (GsmManager *manager,
1694 const char *renderer)
1695{
1696 GsmManagerPrivate *priv;
1697 priv = gsm_manager_get_instance_private (manager);
1698 g_free (priv->renderer);
1699 priv->renderer = g_strdup (renderer)g_strdup_inline (renderer);
1700}
1701
1702static gboolean
1703_app_has_app_id (const char *id,
1704 GsmApp *app,
1705 const char *app_id_a)
1706{
1707 const char *app_id_b;
1708
1709 app_id_b = gsm_app_peek_app_id (app);
1710 return (app_id_b != NULL((void*)0) && strcmp (app_id_a, app_id_b) == 0);
1711}
1712
1713static GsmApp *
1714find_app_for_app_id (GsmManager *manager,
1715 const char *app_id)
1716{
1717 GsmApp *app;
1718 GsmManagerPrivate *priv;
1719
1720 priv = gsm_manager_get_instance_private (manager);
1721 app = (GsmApp *)gsm_store_find (priv->apps,
1722 (GsmStoreFunc)_app_has_app_id,
1723 (char *)app_id);
1724 return app;
1725}
1726
1727static gboolean
1728inhibitor_has_client_id (gpointer key,
1729 GsmInhibitor *inhibitor,
1730 const char *client_id_a)
1731{
1732 gboolean matches;
1733 const char *client_id_b;
1734
1735 client_id_b = gsm_inhibitor_peek_client_id (inhibitor);
1736
1737 matches = FALSE(0);
1738 if (! IS_STRING_EMPTY (client_id_a)((client_id_a)==((void*)0)||(client_id_a)[0]=='\0') && ! IS_STRING_EMPTY (client_id_b)((client_id_b)==((void*)0)||(client_id_b)[0]=='\0')) {
1739 matches = (strcmp (client_id_a, client_id_b) == 0);
1740 if (matches) {
1741 g_debug ("GsmManager: removing JIT inhibitor for %s for reason '%s'",
1742 gsm_inhibitor_peek_client_id (inhibitor),
1743 gsm_inhibitor_peek_reason (inhibitor));
1744 }
1745 }
1746
1747 return matches;
1748}
1749
1750static gboolean
1751_app_has_startup_id (const char *id,
1752 GsmApp *app,
1753 const char *startup_id_a)
1754{
1755 const char *startup_id_b;
1756
1757 startup_id_b = gsm_app_peek_startup_id (app);
1758
1759 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
1760 return FALSE(0);
1761 }
1762
1763 return (strcmp (startup_id_a, startup_id_b) == 0);
1764}
1765
1766static GsmApp *
1767find_app_for_startup_id (GsmManager *manager,
1768 const char *startup_id)
1769{
1770 GsmApp *found_app;
1771 GSList *a;
1772 GsmManagerPrivate *priv;
1773
1774 found_app = NULL((void*)0);
1775 priv = gsm_manager_get_instance_private (manager);
1776
1777 /* If we're starting up the session, try to match the new client
1778 * with one pending apps for the current phase. If not, try to match
1779 * with any of the autostarted apps. */
1780 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
1781 for (a = priv->pending_apps; a != NULL((void*)0); a = a->next) {
1782 GsmApp *app = GSM_APP (a->data);
1783
1784 if (strcmp (startup_id, gsm_app_peek_startup_id (app)) == 0) {
1785 found_app = app;
1786 goto out;
1787 }
1788 }
1789 } else {
1790 GsmApp *app;
1791
1792 app = (GsmApp *)gsm_store_find (priv->apps,
1793 (GsmStoreFunc)_app_has_startup_id,
1794 (char *)startup_id);
1795 if (app != NULL((void*)0)) {
1796 found_app = app;
1797 goto out;
1798 }
1799 }
1800 out:
1801 return found_app;
1802}
1803
1804static void
1805_disconnect_client (GsmManager *manager,
1806 GsmClient *client)
1807{
1808 gboolean is_condition_client;
1809 GsmApp *app;
1810 GError *error;
1811 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
1812 const char *app_id;
1813 const char *startup_id;
1814 gboolean app_restart;
1815 GsmClientRestartStyle client_restart_hint;
1816 GsmManagerPrivate *priv;
1817
1818 g_debug ("GsmManager: disconnect client: %s", gsm_client_peek_id (client));
1819
1820 /* take a ref so it doesn't get finalized */
1821 g_object_ref (client)((__typeof__ (client)) (g_object_ref) (client));
1822
1823 gsm_client_set_status (client, GSM_CLIENT_FINISHED);
1824
1825 is_condition_client = FALSE(0);
1826 priv = gsm_manager_get_instance_private (manager);
1827 if (g_slist_find (priv->condition_clients, client)) {
1828 priv->condition_clients = g_slist_remove (priv->condition_clients, client);
1829
1830 is_condition_client = TRUE(!(0));
1831 }
1832
1833 /* remove any inhibitors for this client */
1834 gsm_store_foreach_remove (priv->inhibitors,
1835 (GsmStoreFunc)inhibitor_has_client_id,
1836 (gpointer)gsm_client_peek_id (client));
1837
1838 app = NULL((void*)0);
1839
1840 /* first try to match on startup ID */
1841 startup_id = gsm_client_peek_startup_id (client);
1842 if (! IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
1843 app = find_app_for_startup_id (manager, startup_id);
1844
1845 }
1846
1847 /* then try to find matching app-id */
1848 if (app == NULL((void*)0)) {
1849 app_id = gsm_client_peek_app_id (client);
1850 if (! IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1851 g_debug ("GsmManager: disconnect for app '%s'", app_id);
1852 app = find_app_for_app_id (manager, app_id);
1853 }
1854 }
1855
1856 if (priv->phase == GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1857 /* Instead of answering our end session query, the client just exited.
1858 * Treat that as an "okay, end the session" answer.
1859 *
1860 * This call implicitly removes any inhibitors for the client, along
1861 * with removing the client from the pending query list.
1862 */
1863 _handle_client_end_session_response (manager,
1864 client,
1865 TRUE(!(0)),
1866 FALSE(0),
1867 FALSE(0),
1868 "Client exited in "
1869 "query end session phase "
1870 "instead of end session "
1871 "phase");
1872 }
1873
1874 if (priv->dbus_disconnected && GSM_IS_DBUS_CLIENT (client)) {
1875 g_debug ("GsmManager: dbus disconnected, not restarting application");
1876 goto out;
1877 }
1878
1879 if (app == NULL((void*)0)) {
1880 g_debug ("GsmManager: unable to find application for client - not restarting");
1881 goto out;
1882 }
1883
1884 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1885 g_debug ("GsmManager: in shutdown, not restarting application");
1886 goto out;
1887 }
1888
1889 app_restart = gsm_app_peek_autorestart (app);
1890 client_restart_hint = gsm_client_peek_restart_style_hint (client);
1891
1892 /* allow legacy clients to override the app info */
1893 if (! app_restart
1894 && client_restart_hint != GSM_CLIENT_RESTART_IMMEDIATELY) {
1895 g_debug ("GsmManager: autorestart not set, not restarting application");
1896 goto out;
1897 }
1898
1899 if (is_condition_client) {
1900 g_debug ("GsmManager: app conditionally disabled, not restarting application");
1901 goto out;
1902 }
1903
1904 g_debug ("GsmManager: restarting app");
1905
1906 error = NULL((void*)0);
1907 res = gsm_app_restart (app, &error);
1908 if (error != NULL((void*)0)) {
1909 g_warning ("Error on restarting session managed app: %s", error->message);
1910 g_error_free (error);
1911 }
1912
1913 out:
1914 g_object_unref (client);
1915}
1916
1917typedef struct {
1918 const char *service_name;
1919 GsmManager *manager;
1920} RemoveClientData;
1921
1922static gboolean
1923_disconnect_dbus_client (const char *id,
1924 GsmClient *client,
1925 RemoveClientData *data)
1926{
1927 const char *name;
1928
1929 if (! GSM_IS_DBUS_CLIENT (client)) {
1930 return FALSE(0);
1931 }
1932
1933 /* If no service name, then we simply disconnect all clients */
1934 if (!data->service_name) {
1935 _disconnect_client (data->manager, client);
1936 return TRUE(!(0));
1937 }
1938
1939 name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
1940 if (IS_STRING_EMPTY (name)((name)==((void*)0)||(name)[0]=='\0')) {
1941 return FALSE(0);
1942 }
1943
1944 if (strcmp (data->service_name, name) == 0) {
1945 _disconnect_client (data->manager, client);
1946 return TRUE(!(0));
1947 }
1948
1949 return FALSE(0);
1950}
1951
1952/**
1953 * remove_clients_for_connection:
1954 * @manager: a #GsmManager
1955 * @service_name: a service name
1956 *
1957 * Disconnects clients that own @service_name.
1958 *
1959 * If @service_name is NULL, then disconnects all clients for the connection.
1960 */
1961static void
1962remove_clients_for_connection (GsmManager *manager,
1963 const char *service_name)
1964{
1965 RemoveClientData data;
1966 GsmManagerPrivate *priv;
1967
1968 data.service_name = service_name;
1969 data.manager = manager;
1970 priv = gsm_manager_get_instance_private (manager);
1971
1972 /* disconnect dbus clients for name */
1973 gsm_store_foreach_remove (priv->clients,
1974 (GsmStoreFunc)_disconnect_dbus_client,
1975 &data);
1976
1977 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION
1978 && gsm_store_size (priv->clients) == 0) {
1979 g_debug ("GsmManager: last client disconnected - exiting");
1980 end_phase (manager);
1981 }
1982}
1983
1984static gboolean
1985inhibitor_has_bus_name (gpointer key,
1986 GsmInhibitor *inhibitor,
1987 RemoveClientData *data)
1988{
1989 gboolean matches;
1990 const char *bus_name_b;
1991
1992 bus_name_b = gsm_inhibitor_peek_bus_name (inhibitor);
1993
1994 matches = FALSE(0);
1995 if (! IS_STRING_EMPTY (data->service_name)((data->service_name)==((void*)0)||(data->service_name)
[0]=='\0')
&& ! IS_STRING_EMPTY (bus_name_b)((bus_name_b)==((void*)0)||(bus_name_b)[0]=='\0')) {
1996 matches = (strcmp (data->service_name, bus_name_b) == 0);
1997 if (matches) {
1998 g_debug ("GsmManager: removing inhibitor from %s for reason '%s' on connection %s",
1999 gsm_inhibitor_peek_app_id (inhibitor),
2000 gsm_inhibitor_peek_reason (inhibitor),
2001 gsm_inhibitor_peek_bus_name (inhibitor));
2002 }
2003 }
2004
2005 return matches;
2006}
2007
2008static void
2009remove_inhibitors_for_connection (GsmManager *manager,
2010 const char *service_name)
2011{
2012 guint UNUSED_VARIABLE__attribute__ ((unused)) n_removed;
2013 RemoveClientData data;
2014 GsmManagerPrivate *priv;
2015
2016 data.service_name = service_name;
2017 data.manager = manager;
2018 priv = gsm_manager_get_instance_private (manager);
2019
2020 debug_inhibitors (manager);
2021
2022 n_removed = gsm_store_foreach_remove (priv->inhibitors,
2023 (GsmStoreFunc)inhibitor_has_bus_name,
2024 &data);
2025}
2026
2027static void
2028bus_name_owner_changed (DBusGProxy *bus_proxy,
2029 const char *service_name,
2030 const char *old_service_name,
2031 const char *new_service_name,
2032 GsmManager *manager)
2033{
2034 if (strlen (new_service_name) == 0
2035 && strlen (old_service_name) > 0) {
2036 /* service removed */
2037 remove_inhibitors_for_connection (manager, old_service_name);
2038 remove_clients_for_connection (manager, old_service_name);
2039 } else if (strlen (old_service_name) == 0
2040 && strlen (new_service_name) > 0) {
2041 /* service added */
2042
2043 /* use this if we support automatically registering
2044 * well known bus names */
2045 }
2046}
2047
2048static DBusHandlerResult
2049gsm_manager_bus_filter (DBusConnection *connection,
2050 DBusMessage *message,
2051 void *user_data)
2052{
2053 GsmManager *manager;
2054 GsmManagerPrivate *priv;
2055
2056 manager = GSM_MANAGER (user_data);
2057 priv = gsm_manager_get_instance_private (manager);
2058
2059 if (dbus_message_is_signal (message,
2060 DBUS_INTERFACE_LOCAL"org.freedesktop.DBus.Local", "Disconnected") &&
2061 strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL"/org/freedesktop/DBus/Local") == 0) {
2062 g_debug ("GsmManager: dbus disconnected; disconnecting dbus clients...");
2063 priv->dbus_disconnected = TRUE(!(0));
2064 remove_clients_for_connection (manager, NULL((void*)0));
2065 /* let other filters get this disconnected signal, so that they
2066 * can handle it too */
2067 }
2068
2069 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2070}
2071
2072static gboolean
2073register_manager (GsmManager *manager)
2074{
2075 GError *error = NULL((void*)0);
2076 GsmManagerPrivate *priv;
2077 DBusConnection *connection;
2078
2079 error = NULL((void*)0);
2080 priv = gsm_manager_get_instance_private (manager);
2081
2082 priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
2083 if (priv->connection == NULL((void*)0)) {
2084 if (error != NULL((void*)0)) {
2085 g_critical ("error getting session bus: %s", error->message);
2086 g_error_free (error);
2087 }
2088 exit (1);
2089 }
2090
2091 connection = dbus_g_connection_get_connection (priv->connection);
2092 dbus_connection_add_filter (connection,
2093 gsm_manager_bus_filter,
2094 manager, NULL((void*)0));
2095 priv->dbus_disconnected = FALSE(0);
2096
2097 priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
2098 DBUS_SERVICE_DBUS"org.freedesktop.DBus",
2099 DBUS_PATH_DBUS"/org/freedesktop/DBus",
2100 DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
2101 dbus_g_proxy_add_signal (priv->bus_proxy,
2102 "NameOwnerChanged",
2103 G_TYPE_STRING((GType) ((16) << (2))),
2104 G_TYPE_STRING((GType) ((16) << (2))),
2105 G_TYPE_STRING((GType) ((16) << (2))),
2106 G_TYPE_INVALID((GType) ((0) << (2))));
2107 dbus_g_proxy_connect_signal (priv->bus_proxy,
2108 "NameOwnerChanged",
2109 G_CALLBACK (bus_name_owner_changed)((GCallback) (bus_name_owner_changed)),
2110 manager,
2111 NULL((void*)0));
2112
2113 dbus_g_connection_register_g_object (priv->connection, GSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager", G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
);
2114
2115 return TRUE(!(0));
2116}
2117
2118static void
2119gsm_manager_set_failsafe (GsmManager *manager,
2120 gboolean enabled)
2121{
2122 GsmManagerPrivate *priv;
2123
2124 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2125
2126 priv = gsm_manager_get_instance_private (manager);
2127
2128 priv->failsafe = enabled;
2129}
2130
2131static gboolean
2132_client_has_startup_id (const char *id,
2133 GsmClient *client,
2134 const char *startup_id_a)
2135{
2136 const char *startup_id_b;
2137
2138 startup_id_b = gsm_client_peek_startup_id (client);
2139
2140 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
2141 return FALSE(0);
2142 }
2143
2144 return (strcmp (startup_id_a, startup_id_b) == 0);
2145}
2146
2147static void
2148on_client_disconnected (GsmClient *client,
2149 GsmManager *manager)
2150{
2151 GsmManagerPrivate *priv;
2152
2153 g_debug ("GsmManager: disconnect client");
2154
2155 priv = gsm_manager_get_instance_private (manager);
2156
2157 _disconnect_client (manager, client);
2158 gsm_store_remove (priv->clients, gsm_client_peek_id (client));
2159 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION
2160 && gsm_store_size (priv->clients) == 0) {
2161 g_debug ("GsmManager: last client disconnected - exiting");
2162 end_phase (manager);
2163 }
2164}
2165
2166static gboolean
2167on_xsmp_client_register_request (GsmXSMPClient *client,
2168 char **id,
2169 GsmManager *manager)
2170{
2171 gboolean handled;
2172 char *new_id;
2173 GsmApp *app;
2174 GsmManagerPrivate *priv;
2175
2176 handled = TRUE(!(0));
2177 new_id = NULL((void*)0);
2178 priv = gsm_manager_get_instance_private (manager);
2179
2180 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2181 goto out;
2182 }
2183
2184 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2185 new_id = gsm_util_generate_startup_id ();
2186 } else {
2187 GsmClient *sm_client;
2188
2189 sm_client = (GsmClient *)gsm_store_find (priv->clients,
2190 (GsmStoreFunc)_client_has_startup_id,
2191 *id);
2192 /* We can't have two clients with the same id. */
2193 if (sm_client != NULL((void*)0)) {
2194 goto out;
2195 }
2196
2197 new_id = g_strdup (*id)g_strdup_inline (*id);
2198 }
2199
2200 g_debug ("GsmManager: Adding new client %s to session", new_id);
2201
2202 g_signal_connect (client,g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2203 "disconnected",g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2204 G_CALLBACK (on_client_disconnected),g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2205 manager)g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2206
2207 /* If it's a brand new client id, we just accept the client*/
2208 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2209 goto out;
2210 }
2211
2212 app = find_app_for_startup_id (manager, new_id);
2213 if (app != NULL((void*)0)) {
2214 gsm_client_set_app_id (GSM_CLIENT (client), gsm_app_peek_app_id (app));
2215 gsm_app_registered (app);
2216 goto out;
2217 }
2218
2219 /* app not found */
2220 g_free (new_id);
2221 new_id = NULL((void*)0);
2222
2223 out:
2224 g_free (*id);
2225 *id = new_id;
2226
2227 return handled;
2228}
2229
2230static gboolean
2231auto_save_is_enabled (GsmManager *manager)
2232{
2233 GsmManagerPrivate *priv;
2234
2235 priv = gsm_manager_get_instance_private (manager);
2236 return g_settings_get_boolean (priv->settings_session,
2237 KEY_AUTOSAVE"auto-save-session");
2238}
2239
2240static void
2241maybe_save_session (GsmManager *manager)
2242{
2243 GsmConsolekit *consolekit = NULL((void*)0);
2244#ifdef HAVE_SYSTEMD1
2245 GsmSystemd *systemd = NULL((void*)0);
2246#endif
2247 char *session_type;
2248 GError *error;
2249 GsmManagerPrivate *priv;
2250
2251#ifdef HAVE_SYSTEMD1
2252 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2253 systemd = gsm_get_systemd ();
2254 session_type = gsm_systemd_get_current_session_type (systemd);
2255
2256 if (g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0) {
2257 goto out;
2258 }
2259 }
2260 else {
2261#endif
2262 consolekit = gsm_get_consolekit ();
2263 session_type = gsm_consolekit_get_current_session_type (consolekit);
2264
2265 if (g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0) {
2266 goto out;
2267 }
2268#ifdef HAVE_SYSTEMD1
2269 }
2270#endif
2271
2272 priv = gsm_manager_get_instance_private (manager);
2273 /* We only allow session saving when session is running or when
2274 * logging out */
2275 if (priv->phase != GSM_MANAGER_PHASE_RUNNING &&
2276 priv->phase != GSM_MANAGER_PHASE_END_SESSION) {
2277 goto out;
2278 }
2279
2280 error = NULL((void*)0);
2281 gsm_session_save (priv->clients, &error);
2282
2283 if (error) {
2284 g_warning ("Error saving session: %s", error->message);
2285 g_error_free (error);
2286 }
2287
2288out:
2289 if (consolekit != NULL((void*)0))
2290 g_object_unref (consolekit);
2291#ifdef HAVE_SYSTEMD1
2292 if (systemd != NULL((void*)0))
2293 g_object_unref (systemd);
2294#endif
2295 g_free (session_type);
2296}
2297
2298static void
2299_handle_client_end_session_response (GsmManager *manager,
2300 GsmClient *client,
2301 gboolean is_ok,
2302 gboolean do_last,
2303 gboolean cancel,
2304 const char *reason)
2305{
2306 GsmManagerPrivate *priv;
2307
2308 priv = gsm_manager_get_instance_private (manager);
2309 /* just ignore if received outside of shutdown */
2310 if (priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2311 return;
2312 }
2313
2314 g_debug ("GsmManager: Response from end session request: is-ok=%d do-last=%d cancel=%d reason=%s", is_ok, do_last, cancel, reason ? reason :"");
2315
2316 if (cancel) {
2317 cancel_end_session (manager);
2318 return;
2319 }
2320
2321 priv->query_clients = g_slist_remove (priv->query_clients, client);
2322
2323 if (! is_ok && priv->logout_mode != GSM_MANAGER_LOGOUT_MODE_FORCE) {
2324 guint cookie;
2325 GsmInhibitor *inhibitor;
2326 char *app_id;
2327 const char *bus_name;
2328
2329 /* FIXME: do we support updating the reason? */
2330
2331 /* Create JIT inhibit */
2332 if (GSM_IS_DBUS_CLIENT (client)) {
2333 bus_name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
2334 } else {
2335 bus_name = NULL((void*)0);
2336 }
2337
2338 app_id = g_strdup (gsm_client_peek_app_id (client))g_strdup_inline (gsm_client_peek_app_id (client));
2339 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
2340 /* XSMP clients don't give us an app id unless we start them */
2341 g_free (app_id);
2342 app_id = gsm_client_get_app_name (client);
2343 }
2344
2345 cookie = _generate_unique_cookie (manager);
2346 inhibitor = gsm_inhibitor_new_for_client (gsm_client_peek_id (client),
2347 app_id,
2348 GSM_INHIBITOR_FLAG_LOGOUT,
2349 reason != NULL((void*)0) ? reason : _("Not responding")gettext ("Not responding"),
2350 bus_name,
2351 cookie);
2352 g_free (app_id);
2353 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
2354 g_object_unref (inhibitor);
2355 } else {
2356 gsm_store_foreach_remove (priv->inhibitors,
2357 (GsmStoreFunc)inhibitor_has_client_id,
2358 (gpointer)gsm_client_peek_id (client));
2359 }
2360
2361 if (priv->phase == GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2362 if (priv->query_clients == NULL((void*)0)) {
2363 query_end_session_complete (manager);
2364 }
2365 } else if (priv->phase == GSM_MANAGER_PHASE_END_SESSION) {
2366 if (do_last) {
2367 /* This only makes sense if we're in part 1 of
2368 * GSM_MANAGER_PHASE_END_SESSION. Doing this in part 2
2369 * can only happen because of a buggy client that loops
2370 * wanting to be last again and again. The phase
2371 * timeout will take care of this issue. */
2372 priv->next_query_clients = g_slist_prepend (priv->next_query_clients,
2373 client);
2374 }
2375
2376 /* we can continue to the next step if all clients have replied
2377 * and if there's no inhibitor */
2378 if (priv->query_clients != NULL((void*)0)
2379 || gsm_manager_is_logout_inhibited (manager)) {
2380 return;
2381 }
2382
2383 if (priv->next_query_clients != NULL((void*)0)) {
2384 do_phase_end_session_part_2 (manager);
2385 } else {
2386 end_phase (manager);
2387 }
2388 }
2389}
2390
2391static void
2392on_client_end_session_response (GsmClient *client,
2393 gboolean is_ok,
2394 gboolean do_last,
2395 gboolean cancel,
2396 const char *reason,
2397 GsmManager *manager)
2398{
2399 _handle_client_end_session_response (manager,
2400 client,
2401 is_ok,
2402 do_last,
2403 cancel,
2404 reason);
2405}
2406
2407static void
2408on_xsmp_client_logout_request (GsmXSMPClient *client,
2409 gboolean show_dialog,
2410 GsmManager *manager)
2411{
2412 GError *error;
2413 int logout_mode;
2414
2415 if (show_dialog) {
2416 logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
2417 } else {
2418 logout_mode = GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION;
2419 }
2420
2421 error = NULL((void*)0);
2422 gsm_manager_logout (manager, logout_mode, &error);
2423 if (error != NULL((void*)0)) {
2424 g_warning ("Unable to logout: %s", error->message);
2425 g_error_free (error);
2426 }
2427}
2428
2429static void
2430on_store_client_added (GsmStore *store,
2431 const char *id,
2432 GsmManager *manager)
2433{
2434 GsmClient *client;
2435
2436 g_debug ("GsmManager: Client added: %s", id);
2437
2438 client = (GsmClient *)gsm_store_lookup (store, id);
2439
2440 /* a bit hacky */
2441 if (GSM_IS_XSMP_CLIENT (client)) {
2442 g_signal_connect (client,g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2443 "register-request",g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2444 G_CALLBACK (on_xsmp_client_register_request),g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2445 manager)g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
;
2446 g_signal_connect (client,g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2447 "logout-request",g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2448 G_CALLBACK (on_xsmp_client_logout_request),g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2449 manager)g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
;
2450 }
2451
2452 g_signal_connect (client,g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2453 "end-session-response",g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2454 G_CALLBACK (on_client_end_session_response),g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2455 manager)g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
;
2456
2457 g_signal_emit (manager, signals [CLIENT_ADDED], 0, id);
2458 /* FIXME: disconnect signal handler */
2459}
2460
2461static void
2462on_store_client_removed (GsmStore *store,
2463 const char *id,
2464 GsmManager *manager)
2465{
2466 g_debug ("GsmManager: Client removed: %s", id);
2467
2468 g_signal_emit (manager, signals [CLIENT_REMOVED], 0, id);
2469}
2470
2471static void
2472gsm_manager_set_client_store (GsmManager *manager,
2473 GsmStore *store)
2474{
2475 GsmManagerPrivate *priv;
2476
2477 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2478 priv = gsm_manager_get_instance_private (manager);
2479
2480 if (store != NULL((void*)0)) {
2481 g_object_ref (store)((__typeof__ (store)) (g_object_ref) (store));
2482 }
2483
2484 if (priv->clients != NULL((void*)0)) {
2485 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2486 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2487 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2488 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2489 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2490 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2491
2492 g_object_unref (priv->clients);
2493 }
2494
2495 g_debug ("GsmManager: setting client store %p", store);
2496
2497 priv->clients = store;
2498
2499 if (priv->clients != NULL((void*)0)) {
2500 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2501 "added",g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2502 G_CALLBACK (on_store_client_added),g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2503 manager)g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2504 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2505 "removed",g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2506 G_CALLBACK (on_store_client_removed),g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2507 manager)g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2508 }
2509}
2510
2511static void
2512gsm_manager_set_property (GObject *object,
2513 guint prop_id,
2514 const GValue *value,
2515 GParamSpec *pspec)
2516{
2517 GsmManager *self;
2518
2519 self = GSM_MANAGER (object);
2520
2521 switch (prop_id) {
2522 case PROP_FAILSAFE:
2523 gsm_manager_set_failsafe (self, g_value_get_boolean (value));
2524 break;
2525 case PROP_CLIENT_STORE:
2526 gsm_manager_set_client_store (self, g_value_get_object (value));
2527 break;
2528 default:
2529 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-manager.c", 2529, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2530 break;
2531 }
2532}
2533
2534static void
2535gsm_manager_get_property (GObject *object,
2536 guint prop_id,
2537 GValue *value,
2538 GParamSpec *pspec)
2539{
2540 GsmManager *self;
2541 GsmManagerPrivate *priv;
2542
2543 self = GSM_MANAGER (object);
2544 priv = gsm_manager_get_instance_private (self);
2545
2546 switch (prop_id) {
2547 case PROP_FAILSAFE:
2548 g_value_set_boolean (value, priv->failsafe);
2549 break;
2550 case PROP_CLIENT_STORE:
2551 g_value_set_object (value, priv->clients);
2552 break;
2553 case PROP_RENDERER:
2554 g_value_set_string (value, priv->renderer);
2555 break;
2556 default:
2557 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-manager.c", 2557, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2558 break;
2559 }
2560}
2561
2562static gboolean
2563_find_app_provides (const char *id,
2564 GsmApp *app,
2565 const char *service)
2566{
2567 return gsm_app_provides (app, service);
2568}
2569
2570static GObject *
2571gsm_manager_constructor (GType type,
2572 guint n_construct_properties,
2573 GObjectConstructParam *construct_properties)
2574{
2575 GsmManager *manager;
2576
2577 manager = GSM_MANAGER (G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->constructor (type,
2578 n_construct_properties,
2579 construct_properties));
2580 return G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
;
2581}
2582
2583static void
2584on_store_inhibitor_added (GsmStore *store,
2585 const char *id,
2586 GsmManager *manager)
2587{
2588 g_debug ("GsmManager: Inhibitor added: %s", id);
2589 g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
2590 update_idle (manager);
2591}
2592
2593static void
2594on_store_inhibitor_removed (GsmStore *store,
2595 const char *id,
2596 GsmManager *manager)
2597{
2598 g_debug ("GsmManager: Inhibitor removed: %s", id);
2599 g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
2600 update_idle (manager);
2601}
2602
2603static void
2604gsm_manager_dispose (GObject *object)
2605{
2606 GsmManagerPrivate *priv;
2607 GsmManager *manager = GSM_MANAGER (object);
2608
2609 g_debug ("GsmManager: disposing manager");
2610
2611 priv = gsm_manager_get_instance_private (manager);
2612
2613 if (priv->clients != NULL((void*)0)) {
2614 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2615 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2616 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2617 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2618 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2619 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2620 g_object_unref (priv->clients);
2621 priv->clients = NULL((void*)0);
2622 }
2623
2624 if (priv->apps != NULL((void*)0)) {
2625 g_object_unref (priv->apps);
2626 priv->apps = NULL((void*)0);
2627 }
2628
2629 if (priv->inhibitors != NULL((void*)0)) {
2630 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2631 on_store_inhibitor_added,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2632 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
;
2633 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2634 on_store_inhibitor_removed,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2635 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
;
2636
2637 g_object_unref (priv->inhibitors);
2638 priv->inhibitors = NULL((void*)0);
2639 }
2640
2641 if (priv->presence != NULL((void*)0)) {
2642 g_object_unref (priv->presence);
2643 priv->presence = NULL((void*)0);
2644 }
2645
2646 if (priv->settings_session) {
2647 g_object_unref (priv->settings_session);
2648 priv->settings_session = NULL((void*)0);
2649 }
2650
2651 if (priv->settings_lockdown) {
2652 g_object_unref (priv->settings_lockdown);
2653 priv->settings_lockdown = NULL((void*)0);
2654 }
2655
2656 if (priv->settings_screensaver) {
2657 g_object_unref (priv->settings_screensaver);
2658 priv->settings_screensaver = NULL((void*)0);
2659 }
2660
2661 g_clear_pointer (&priv->renderer, g_free)do { _Static_assert (sizeof *(&priv->renderer) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
priv->renderer)) _pp = (&priv->renderer); __typeof__
(*(&priv->renderer)) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_free) (_ptr); } while (0)
;
2662
2663 G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->dispose (object);
2664}
2665
2666static void
2667gsm_manager_class_init (GsmManagerClass *klass)
2668{
2669 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
2670
2671 object_class->get_property = gsm_manager_get_property;
2672 object_class->set_property = gsm_manager_set_property;
2673 object_class->constructor = gsm_manager_constructor;
2674 object_class->finalize = gsm_manager_finalize;
2675 object_class->dispose = gsm_manager_dispose;
2676
2677 signals [PHASE_CHANGED] =
2678 g_signal_new ("phase-changed",
2679 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2680 G_SIGNAL_RUN_LAST,
2681 G_STRUCT_OFFSET (GsmManagerClass, phase_changed)((glong) __builtin_offsetof(GsmManagerClass, phase_changed)),
2682 NULL((void*)0),
2683 NULL((void*)0),
2684 g_cclosure_marshal_VOID__STRING,
2685 G_TYPE_NONE((GType) ((1) << (2))),
2686 1, G_TYPE_STRING((GType) ((16) << (2))));
2687
2688 signals [SESSION_RUNNING] =
2689 g_signal_new ("session-running",
2690 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2691 G_SIGNAL_RUN_LAST,
2692 G_STRUCT_OFFSET (GsmManagerClass, session_running)((glong) __builtin_offsetof(GsmManagerClass, session_running)
)
,
2693 NULL((void*)0),
2694 NULL((void*)0),
2695 g_cclosure_marshal_VOID__VOID,
2696 G_TYPE_NONE((GType) ((1) << (2))),
2697 0);
2698
2699 signals [SESSION_OVER] =
2700 g_signal_new ("session-over",
2701 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2702 G_SIGNAL_RUN_LAST,
2703 G_STRUCT_OFFSET (GsmManagerClass, session_over)((glong) __builtin_offsetof(GsmManagerClass, session_over)),
2704 NULL((void*)0), NULL((void*)0),
2705 g_cclosure_marshal_VOID__VOID,
2706 G_TYPE_NONE((GType) ((1) << (2))),
2707 0);
2708 signals [CLIENT_ADDED] =
2709 g_signal_new ("client-added",
2710 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2711 G_SIGNAL_RUN_LAST,
2712 G_STRUCT_OFFSET (GsmManagerClass, client_added)((glong) __builtin_offsetof(GsmManagerClass, client_added)),
2713 NULL((void*)0),
2714 NULL((void*)0),
2715 g_cclosure_marshal_VOID__BOXED,
2716 G_TYPE_NONE((GType) ((1) << (2))),
2717 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2718 signals [CLIENT_REMOVED] =
2719 g_signal_new ("client-removed",
2720 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2721 G_SIGNAL_RUN_LAST,
2722 G_STRUCT_OFFSET (GsmManagerClass, client_removed)((glong) __builtin_offsetof(GsmManagerClass, client_removed)),
2723 NULL((void*)0),
2724 NULL((void*)0),
2725 g_cclosure_marshal_VOID__BOXED,
2726 G_TYPE_NONE((GType) ((1) << (2))),
2727 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2728 signals [INHIBITOR_ADDED] =
2729 g_signal_new ("inhibitor-added",
2730 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2731 G_SIGNAL_RUN_LAST,
2732 G_STRUCT_OFFSET (GsmManagerClass, inhibitor_added)((glong) __builtin_offsetof(GsmManagerClass, inhibitor_added)
)
,
2733 NULL((void*)0),
2734 NULL((void*)0),
2735 g_cclosure_marshal_VOID__BOXED,
2736 G_TYPE_NONE((GType) ((1) << (2))),
2737 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2738 signals [INHIBITOR_REMOVED] =
2739 g_signal_new ("inhibitor-removed",
2740 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2741 G_SIGNAL_RUN_LAST,
2742 G_STRUCT_OFFSET (GsmManagerClass, inhibitor_removed)((glong) __builtin_offsetof(GsmManagerClass, inhibitor_removed
))
,
2743 NULL((void*)0),
2744 NULL((void*)0),
2745 g_cclosure_marshal_VOID__BOXED,
2746 G_TYPE_NONE((GType) ((1) << (2))),
2747 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2748
2749 g_object_class_install_property (object_class,
2750 PROP_FAILSAFE,
2751 g_param_spec_boolean ("failsafe",
2752 NULL((void*)0),
2753 NULL((void*)0),
2754 FALSE(0),
2755 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2756 g_object_class_install_property (object_class,
2757 PROP_CLIENT_STORE,
2758 g_param_spec_object ("client-store",
2759 NULL((void*)0),
2760 NULL((void*)0),
2761 GSM_TYPE_STORE(gsm_store_get_type ()),
2762 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2763
2764 g_object_class_install_property (object_class,
2765 PROP_RENDERER,
2766 g_param_spec_string ("renderer",
2767 NULL((void*)0),
2768 NULL((void*)0),
2769 NULL((void*)0),
2770 G_PARAM_READABLE));
2771
2772 dbus_g_object_type_install_info (GSM_TYPE_MANAGER(gsm_manager_get_type ()), &dbus_glib_gsm_manager_object_info);
2773 dbus_g_error_domain_register (GSM_MANAGER_ERRORgsm_manager_error_quark (), NULL((void*)0), GSM_MANAGER_TYPE_ERROR(gsm_manager_error_get_type ()));
2774}
2775
2776static void
2777load_idle_delay_from_gsettings (GsmManager *manager)
2778{
2779 glong value;
2780 GsmManagerPrivate *priv;
2781
2782 priv = gsm_manager_get_instance_private (manager);
2783 value = g_settings_get_int (priv->settings_session,
2784 KEY_IDLE_DELAY"idle-delay");
2785 gsm_presence_set_idle_timeout (priv->presence, value * 60000);
2786}
2787
2788static void
2789on_gsettings_key_changed (GSettings *settings,
2790 gchar *key,
2791 GsmManager *manager)
2792{
2793 GsmManagerPrivate *priv;
2794
2795 priv = gsm_manager_get_instance_private (manager);
2796 if (g_strcmp0 (key, KEY_IDLE_DELAY"idle-delay") == 0) {
2797 int delay;
2798 delay = g_settings_get_int (settings, key);
2799 gsm_presence_set_idle_timeout (priv->presence, delay * 60000);
2800 } else if (g_strcmp0 (key, KEY_LOCK_DISABLE"disable-lock-screen") == 0) {
2801 /* ??? */
2802 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2803 disabled = g_settings_get_boolean (settings, key);
2804 } else if (g_strcmp0 (key, KEY_USER_SWITCH_DISABLE"disable-user-switching") == 0) {
2805 /* ??? */
2806 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2807 disabled = g_settings_get_boolean (settings, key);
2808 } else {
2809 g_debug ("Config key not handled: %s", key);
2810 }
2811}
2812
2813static void
2814on_presence_status_changed (GsmPresence *presence,
2815 guint status,
2816 GsmManager *manager)
2817{
2818#ifdef HAVE_SYSTEMD1
2819 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2820 GsmSystemd *systemd;
2821
2822 systemd = gsm_get_systemd ();
2823 gsm_systemd_set_session_idle (systemd,
2824 (status == GSM_PRESENCE_STATUS_IDLE));
2825 }
2826 else {
2827#endif
2828 GsmConsolekit *consolekit;
2829
2830 consolekit = gsm_get_consolekit ();
2831 gsm_consolekit_set_session_idle (consolekit,
2832 (status == GSM_PRESENCE_STATUS_IDLE));
2833#ifdef HAVE_SYSTEMD1
2834 }
2835#endif
2836}
2837
2838static void
2839gsm_manager_init (GsmManager *manager)
2840{
2841 gchar **schemas = NULL((void*)0);
2842 gboolean schema_exists;
2843 guint i;
2844 GsmManagerPrivate *priv;
2845
2846 priv = gsm_manager_get_instance_private (manager);
2847
2848 priv->settings_session = g_settings_new (SESSION_SCHEMA"org.mate.session");
2849 priv->settings_lockdown = g_settings_new (LOCKDOWN_SCHEMA"org.mate.lockdown");
2850
2851 /* check if mate-screensaver is installed */
2852 g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (), TRUE(!(0)), &schemas, NULL((void*)0));
2853 schema_exists = FALSE(0);
2854 for (i = 0; schemas[i] != NULL((void*)0); i++) {
2855 if (g_str_equal (schemas[i], SCREENSAVER_SCHEMA)(strcmp ((const char *) (schemas[i]), (const char *) ("org.mate.screensaver"
)) == 0)
) {
2856 schema_exists = TRUE(!(0));
2857 break;
2858 }
2859 }
2860
2861 g_strfreev (schemas);
2862
2863 if (schema_exists == TRUE(!(0)))
2864 priv->settings_screensaver = g_settings_new (SCREENSAVER_SCHEMA"org.mate.screensaver");
2865 else
2866 priv->settings_screensaver = NULL((void*)0);
2867
2868 priv->inhibitors = gsm_store_new ();
2869 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2870 "added",g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2871 G_CALLBACK (on_store_inhibitor_added),g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2872 manager)g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2873 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2874 "removed",g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2875 G_CALLBACK (on_store_inhibitor_removed),g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2876 manager)g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2877
2878 priv->apps = gsm_store_new ();
2879
2880 priv->presence = gsm_presence_new ();
2881 g_signal_connect (priv->presence,g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2882 "status-changed",g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2883 G_CALLBACK (on_presence_status_changed),g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2884 manager)g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
;
2885 g_signal_connect (priv->settings_session,g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2886 "changed",g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2887 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2888 manager)g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2889 g_signal_connect (priv->settings_lockdown,g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2890 "changed",g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2891 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2892 manager)g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2893
2894 load_idle_delay_from_gsettings (manager);
2895}
2896
2897static void
2898gsm_manager_finalize (GObject *object)
2899{
2900 GsmManager *manager;
2901 GsmManagerPrivate *priv;
2902
2903 g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
2904 g_return_if_fail (GSM_IS_MANAGER (object))do { if ((GSM_IS_MANAGER (object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (object)"
); return; } } while (0)
;
2905
2906 manager = GSM_MANAGER (object);
2907 priv = gsm_manager_get_instance_private (manager);
2908
2909 g_return_if_fail (priv != NULL)do { if ((priv != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "priv != NULL"); return
; } } while (0)
;
2910
2911 G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->finalize (object);
2912}
2913
2914GsmManager *
2915gsm_manager_new (GsmStore *client_store,
2916 gboolean failsafe)
2917{
2918 if (manager_object != NULL((void*)0)) {
2919 g_object_ref (manager_object)((__typeof__ (manager_object)) (g_object_ref) (manager_object
))
;
2920 } else {
2921 gboolean res;
2922
2923 manager_object = g_object_new (GSM_TYPE_MANAGER(gsm_manager_get_type ()),
2924 "client-store", client_store,
2925 "failsafe", failsafe,
2926 NULL((void*)0));
2927
2928 g_object_add_weak_pointer (manager_object,
2929 (gpointer *) &manager_object);
2930 res = register_manager (manager_object);
2931 if (! res) {
2932 g_object_unref (manager_object);
This statement is never executed
2933 return NULL((void*)0);
2934 }
2935 }
2936
2937 return GSM_MANAGER (manager_object);
2938}
2939
2940gboolean
2941gsm_manager_setenv (GsmManager *manager,
2942 const char *variable,
2943 const char *value,
2944 GError **error)
2945{
2946 GsmManagerPrivate *priv;
2947
2948 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2949
2950 priv = gsm_manager_get_instance_private (manager);
2951 if (priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
2952 g_set_error (error,
2953 GSM_MANAGER_ERRORgsm_manager_error_quark (),
2954 GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2955 "Setenv interface is only available during the Initialization phase");
2956 return FALSE(0);
2957 }
2958
2959 gsm_util_setenv (variable, value);
2960
2961 return TRUE(!(0));
2962}
2963
2964gboolean
2965gsm_manager_initialization_error (GsmManager *manager,
2966 const char *message,
2967 gboolean fatal,
2968 GError **error)
2969{
2970 GsmManagerPrivate *priv;
2971 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2972
2973 priv = gsm_manager_get_instance_private (manager);
2974
2975 if (priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
2976 g_set_error (error,
2977 GSM_MANAGER_ERRORgsm_manager_error_quark (),
2978 GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2979 "InitializationError interface is only available during the Initialization phase");
2980 return FALSE(0);
2981 }
2982
2983 gsm_util_init_error (fatal, "%s", message);
2984
2985 return TRUE(!(0));
2986}
2987
2988static gboolean
2989gsm_manager_is_switch_user_inhibited (GsmManager *manager)
2990{
2991 GsmInhibitor *inhibitor;
2992 GsmManagerPrivate *priv;
2993
2994 priv = gsm_manager_get_instance_private (manager);
2995
2996 if (priv->inhibitors == NULL((void*)0)) {
2997 return FALSE(0);
2998 }
2999
3000 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3001 (GsmStoreFunc)inhibitor_has_flag,
3002 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_SWITCH_USER)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_SWITCH_USER)));
3003 if (inhibitor == NULL((void*)0)) {
3004 return FALSE(0);
3005 }
3006 return TRUE(!(0));
3007}
3008
3009static gboolean
3010gsm_manager_is_suspend_inhibited (GsmManager *manager)
3011{
3012 GsmInhibitor *inhibitor;
3013 GsmManagerPrivate *priv;
3014
3015 priv = gsm_manager_get_instance_private (manager);
3016
3017 if (priv->inhibitors == NULL((void*)0)) {
3018 return FALSE(0);
3019 }
3020
3021 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3022 (GsmStoreFunc)inhibitor_has_flag,
3023 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_SUSPEND)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_SUSPEND)));
3024 if (inhibitor == NULL((void*)0)) {
3025 return FALSE(0);
3026 }
3027 return TRUE(!(0));
3028}
3029
3030static void
3031request_reboot_privileges_completed_consolekit (GsmConsolekit *consolekit,
3032 gboolean success,
3033 gboolean ask_later,
3034 GError *error,
3035 GsmManager *manager)
3036{
3037 GsmManagerPrivate *priv;
3038
3039 priv = gsm_manager_get_instance_private (manager);
3040 /* make sure we disconnect the signal handler so that it's not called
3041 * again next time the event is fired -- this can happen if the reboot
3042 * is cancelled. */
3043 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3044 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3045 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3046
3047 g_object_unref (consolekit);
3048
3049 if (success) {
3050 if (ask_later) {
3051 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3052 } else {
3053 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT;
3054 }
3055
3056 end_phase (manager);
3057 }
3058}
3059
3060#ifdef HAVE_SYSTEMD1
3061static void
3062request_reboot_privileges_completed_systemd (GsmSystemd *systemd,
3063 gboolean success,
3064 gboolean ask_later,
3065 GError *error,
3066 GsmManager *manager)
3067{
3068 GsmManagerPrivate *priv;
3069
3070 priv = gsm_manager_get_instance_private (manager);
3071 /* make sure we disconnect the signal handler so that it's not called
3072 * again next time the event is fired -- this can happen if the reboot
3073 * is cancelled. */
3074 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3075 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3076 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3077
3078 g_object_unref (systemd);
3079
3080 if (success) {
3081 if (ask_later) {
3082 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3083 } else {
3084 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT;
3085 }
3086
3087 end_phase (manager);
3088 }
3089}
3090#endif
3091
3092static void
3093request_reboot (GsmManager *manager)
3094{
3095 GsmConsolekit *consolekit;
3096#ifdef HAVE_SYSTEMD1
3097 GsmSystemd *systemd;
3098#endif
3099 gboolean success;
3100 GsmManagerPrivate *priv;
3101
3102 g_debug ("GsmManager: requesting reboot");
3103
3104 priv = gsm_manager_get_instance_private (manager);
3105
3106 /* We request the privileges before doing anything. There are a few
3107 * different cases here:
3108 *
3109 * - no systemd: we fallback on ConsoleKit
3110 * - no ConsoleKit: we fallback on MDM
3111 * - no password required: everything is fine
3112 * - password asked once: we ask for it now. If the user enters it
3113 * fine, then all is great. If the user doesn't enter it fine, we
3114 * don't do anything (so no logout).
3115 * - password asked each time: we don't ask it for now since we don't
3116 * want to ask for it twice. Instead we'll ask for it at the very
3117 * end. If the user will enter it fine, then all is great again. If
3118 * the user doesn't enter it fine, then we'll just fallback to MDM.
3119 *
3120 * The last case (password asked each time) is a bit broken, but
3121 * there's really nothing we can do about it. Generally speaking,
3122 * though, the password will only be asked once (unless the system is
3123 * configured in paranoid mode), and most probably only if there are
3124 * more than one user connected. So the general case is that it will
3125 * just work fine.
3126 */
3127
3128#ifdef HAVE_SYSTEMD1
3129 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3130 systemd = gsm_get_systemd ();
3131 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3132 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3133 G_CALLBACK (request_reboot_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3134 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
;
3135 success = gsm_systemd_get_restart_privileges (systemd);
3136
3137 if (!success) {
3138 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3139 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3140 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3141 g_object_unref (systemd);
3142
3143 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_MDM;
3144 end_phase (manager);
3145 }
3146 }
3147 else {
3148#endif
3149 consolekit = gsm_get_consolekit ();
3150 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3151 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3152 G_CALLBACK (request_reboot_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3153 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3154 success = gsm_consolekit_get_restart_privileges (consolekit);
3155
3156 if (!success) {
3157 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3158 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3159 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3160 g_object_unref (consolekit);
3161
3162 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_MDM;
3163 end_phase (manager);
3164 }
3165#ifdef HAVE_SYSTEMD1
3166 }
3167#endif
3168}
3169
3170static void
3171request_shutdown_privileges_completed_consolekit (GsmConsolekit *consolekit,
3172 gboolean success,
3173 gboolean ask_later,
3174 GError *error,
3175 GsmManager *manager)
3176{
3177 GsmManagerPrivate *priv;
3178
3179 priv = gsm_manager_get_instance_private (manager);
3180 /* make sure we disconnect the signal handler so that it's not called
3181 * again next time the event is fired -- this can happen if the reboot
3182 * is cancelled. */
3183 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3184 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3185 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3186
3187 g_object_unref (consolekit);
3188
3189 if (success) {
3190 if (ask_later) {
3191 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3192 } else {
3193 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN;
3194 }
3195
3196 end_phase (manager);
3197 }
3198}
3199
3200#ifdef HAVE_SYSTEMD1
3201static void
3202request_shutdown_privileges_completed_systemd (GsmSystemd *systemd,
3203 gboolean success,
3204 gboolean ask_later,
3205 GError *error,
3206 GsmManager *manager)
3207{
3208 GsmManagerPrivate *priv;
3209
3210 priv = gsm_manager_get_instance_private (manager);
3211 /* make sure we disconnect the signal handler so that it's not called
3212 * again next time the event is fired -- this can happen if the reboot
3213 * is cancelled. */
3214 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3215 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3216 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3217
3218 g_object_unref (systemd);
3219
3220 if (success) {
3221 if (ask_later) {
3222 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3223 } else {
3224 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN;
3225 }
3226
3227 end_phase (manager);
3228 }
3229}
3230#endif
3231
3232static void
3233request_shutdown (GsmManager *manager)
3234{
3235 GsmConsolekit *consolekit;
3236#ifdef HAVE_SYSTEMD1
3237 GsmSystemd *systemd;
3238#endif
3239 gboolean success;
3240 GsmManagerPrivate *priv;
3241
3242 g_debug ("GsmManager: requesting shutdown");
3243
3244 priv = gsm_manager_get_instance_private (manager);
3245
3246 /* See the comment in request_reboot() for some more details about how
3247 * this works. */
3248
3249#ifdef HAVE_SYSTEMD1
3250 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3251 systemd = gsm_get_systemd ();
3252 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3253 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3254 G_CALLBACK (request_shutdown_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3255 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
;
3256 success = gsm_systemd_get_stop_privileges (systemd);
3257
3258 if (!success) {
3259 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3260 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3261 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3262 g_object_unref (systemd);
3263
3264 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_MDM;
3265 end_phase (manager);
3266 }
3267 }
3268 else {
3269#endif
3270 consolekit = gsm_get_consolekit ();
3271 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3272 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3273 G_CALLBACK (request_shutdown_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3274 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3275 success = gsm_consolekit_get_stop_privileges (consolekit);
3276
3277 if (!success) {
3278 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3279 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3280 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3281 g_object_unref (consolekit);
3282
3283 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_MDM;
3284 end_phase (manager);
3285 }
3286#ifdef HAVE_SYSTEMD1
3287 }
3288#endif
3289}
3290
3291static void
3292request_suspend (GsmManager *manager)
3293{
3294 GsmManagerPrivate *priv;
3295
3296 g_debug ("GsmManager: requesting suspend");
3297
3298 if (! gsm_manager_is_suspend_inhibited (manager)) {
3299 manager_attempt_suspend (manager);
3300 return;
3301 }
3302
3303 priv = gsm_manager_get_instance_private (manager);
3304 if (priv->inhibit_dialog != NULL((void*)0)) {
3305 g_debug ("GsmManager: inhibit dialog already up");
3306 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3307 return;
3308 }
3309
3310 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3311 priv->clients,
3312 GSM_LOGOUT_ACTION_SLEEP);
3313
3314 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3315 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3316 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3317 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3318 gtk_widget_show (priv->inhibit_dialog);
3319}
3320
3321static void
3322request_hibernate (GsmManager *manager)
3323{
3324 GsmManagerPrivate *priv;
3325
3326 g_debug ("GsmManager: requesting hibernate");
3327
3328 /* hibernate uses suspend inhibit */
3329 if (! gsm_manager_is_suspend_inhibited (manager)) {
3330 manager_attempt_hibernate (manager);
3331 return;
3332 }
3333
3334 priv = gsm_manager_get_instance_private (manager);
3335 if (priv->inhibit_dialog != NULL((void*)0)) {
3336 g_debug ("GsmManager: inhibit dialog already up");
3337 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3338 return;
3339 }
3340
3341 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3342 priv->clients,
3343 GSM_LOGOUT_ACTION_HIBERNATE);
3344
3345 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3346 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3347 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3348 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3349 gtk_widget_show (priv->inhibit_dialog);
3350}
3351
3352static void
3353request_logout (GsmManager *manager,
3354 GsmManagerLogoutMode mode)
3355{
3356 GsmManagerPrivate *priv;
3357
3358 g_debug ("GsmManager: requesting logout");
3359
3360 priv = gsm_manager_get_instance_private (manager);
3361
3362 priv->logout_mode = mode;
3363 priv->logout_type = GSM_MANAGER_LOGOUT_LOGOUT;
3364
3365 end_phase (manager);
3366}
3367
3368static void
3369request_switch_user (GsmManager *manager)
3370{
3371 GsmManagerPrivate *priv;
3372
3373 g_debug ("GsmManager: requesting user switch");
3374
3375 /* See comment in manager_switch_user() to understand why we do this in
3376 * both functions. */
3377 if (_switch_user_is_locked_down (manager)) {
3378 g_warning ("Unable to switch user: User switching has been locked down");
3379 return;
3380 }
3381
3382 if (! gsm_manager_is_switch_user_inhibited (manager)) {
3383 manager_switch_user (manager);
3384 return;
3385 }
3386
3387 priv = gsm_manager_get_instance_private (manager);
3388 if (priv->inhibit_dialog != NULL((void*)0)) {
3389 g_debug ("GsmManager: inhibit dialog already up");
3390 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3391 return;
3392 }
3393
3394 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3395 priv->clients,
3396 GSM_LOGOUT_ACTION_SWITCH_USER);
3397
3398 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3399 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3400 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3401 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3402 gtk_widget_show (priv->inhibit_dialog);
3403}
3404
3405static void
3406logout_dialog_response (GsmLogoutDialog *logout_dialog,
3407 guint response_id,
3408 GsmManager *manager)
3409{
3410 GsmManagerPrivate *priv;
3411
3412 priv = gsm_manager_get_instance_private (manager);
3413 /* We should only be here if mode has already have been set from
3414 * show_fallback_shutdown/logout_dialog
3415 */
3416 g_assert (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL)do { if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL
) ; else g_assertion_message_expr (((gchar*) 0), "gsm-manager.c"
, 3416, ((const char*) (__func__)), "priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL"
); } while (0)
;
3417
3418 g_debug ("GsmManager: Logout dialog response: %d", response_id);
3419
3420 gtk_widget_destroy (GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
);
3421
3422 /* In case of dialog cancel, switch user, hibernate and
3423 * suspend, we just perform the respective action and return,
3424 * without shutting down the session. */
3425 switch (response_id) {
3426 case GTK_RESPONSE_CANCEL:
3427 case GTK_RESPONSE_NONE:
3428 case GTK_RESPONSE_DELETE_EVENT:
3429 break;
3430 case GSM_LOGOUT_RESPONSE_SWITCH_USER:
3431 request_switch_user (manager);
3432 break;
3433 case GSM_LOGOUT_RESPONSE_HIBERNATE:
3434 request_hibernate (manager);
3435 break;
3436 case GSM_LOGOUT_RESPONSE_SLEEP:
3437 request_suspend (manager);
3438 break;
3439 case GSM_LOGOUT_RESPONSE_SHUTDOWN:
3440 request_shutdown (manager);
3441 break;
3442 case GSM_LOGOUT_RESPONSE_REBOOT:
3443 request_reboot (manager);
3444 break;
3445 case GSM_LOGOUT_RESPONSE_LOGOUT:
3446 /* We've already gotten confirmation from the user so
3447 * initiate the logout in NO_CONFIRMATION mode.
3448 *
3449 * (it shouldn't matter whether we use NO_CONFIRMATION or stay
3450 * with NORMAL, unless the shell happens to start after the
3451 * user confirmed)
3452 */
3453 request_logout (manager, GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION);
3454 break;
3455 default:
3456 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
3456, ((const char*) (__func__)), ((void*)0)); } while (0)
;
3457 break;
3458 }
3459}
3460
3461static void
3462show_shutdown_dialog (GsmManager *manager)
3463{
3464 GtkWidget *dialog;
3465 GsmManagerPrivate *priv;
3466
3467 priv = gsm_manager_get_instance_private (manager);
3468 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3469 /* Already shutting down, nothing more to do */
3470 return;
3471 }
3472
3473 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
3474
3475 dialog = gsm_get_shutdown_dialog (gdk_screen_get_default (),
3476 gtk_get_current_event_time ());
3477
3478 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3479 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3480 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3481 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3482 gtk_widget_show (dialog);
3483 gtk_window_present_with_time (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
3484 gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
)));
3485}
3486
3487static void
3488show_logout_dialog (GsmManager *manager)
3489{
3490 GtkWidget *dialog;
3491 GsmManagerPrivate *priv;
3492
3493 priv = gsm_manager_get_instance_private (manager);
3494 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3495 /* Already shutting down, nothing more to do */
3496 return;
3497 }
3498
3499 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
3500
3501 dialog = gsm_get_logout_dialog (gdk_screen_get_default (),
3502 gtk_get_current_event_time ());
3503
3504 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3505 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3506 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3507 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3508 gtk_widget_show (dialog);
3509 gtk_window_present_with_time (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
3510 gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
)));
3511}
3512
3513static void
3514user_logout (GsmManager *manager,
3515 GsmManagerLogoutMode mode)
3516{
3517 gboolean logout_prompt;
3518 GsmManagerPrivate *priv;
3519
3520 priv = gsm_manager_get_instance_private (manager);
3521
3522 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3523 /* Already shutting down, nothing more to do */
3524 return;
3525 }
3526
3527 logout_prompt =
3528 g_settings_get_boolean (priv->settings_session,
3529 "logout-prompt");
3530
3531 /* If the shell isn't running, and this isn't a non-interative logout request,
3532 * and the user has their settings configured to show a confirmation dialog for
3533 * logout, then go ahead and show the confirmation dialog now.
3534 */
3535 if (mode == GSM_MANAGER_LOGOUT_MODE_NORMAL && logout_prompt) {
3536 show_logout_dialog (manager);
3537 } else {
3538 request_logout (manager, mode);
3539 }
3540}
3541
3542/*
3543 dbus-send --session --type=method_call --print-reply
3544 --dest=org.gnome.SessionManager
3545 /org/gnome/SessionManager
3546 org.freedesktop.DBus.Introspectable.Introspect
3547*/
3548
3549gboolean
3550gsm_manager_set_phase (GsmManager *manager,
3551 GsmManagerPhase phase)
3552{
3553 GsmManagerPrivate *priv;
3554
3555 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3556
3557 priv = gsm_manager_get_instance_private (manager);
3558 priv->phase = phase;
3559 return (TRUE(!(0)));
3560}
3561
3562gboolean
3563gsm_manager_request_shutdown (GsmManager *manager,
3564 GError **error)
3565{
3566 GsmManagerPrivate *priv;
3567 g_debug ("GsmManager: RequestShutdown called");
3568
3569 g_return_val_if_fail(GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3570
3571 priv = gsm_manager_get_instance_private (manager);
3572 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3573 g_set_error (error,
3574 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3575 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3576 "RequestShutdown interface is only available during the Running phase");
3577 return FALSE(0);
3578 }
3579
3580 request_shutdown (manager);
3581
3582 return TRUE(!(0));
3583}
3584
3585gboolean
3586gsm_manager_request_reboot (GsmManager *manager,
3587 GError **error)
3588{
3589 GsmManagerPrivate *priv;
3590
3591 g_debug ("GsmManager: RequestReboot called");
3592
3593 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3594
3595 priv = gsm_manager_get_instance_private (manager);
3596 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3597 g_set_error (error,
3598 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3599 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3600 "RequestReboot interface is only available during the running phase");
3601 return FALSE(0);
3602 }
3603
3604 request_reboot (manager);
3605
3606 return TRUE(!(0));
3607}
3608
3609static gboolean
3610_log_out_is_locked_down (GsmManager *manager)
3611{
3612 GsmManagerPrivate *priv;
3613
3614 priv = gsm_manager_get_instance_private (manager);
3615
3616 return g_settings_get_boolean (priv->settings_lockdown,
3617 KEY_LOG_OUT_DISABLE"disable-log-out");
3618}
3619
3620static gboolean
3621_switch_user_is_locked_down (GsmManager *manager)
3622{
3623 GsmManagerPrivate *priv;
3624
3625 priv = gsm_manager_get_instance_private (manager);
3626 return g_settings_get_boolean (priv->settings_lockdown,
3627 KEY_USER_SWITCH_DISABLE"disable-user-switching");
3628}
3629
3630gboolean
3631gsm_manager_shutdown (GsmManager *manager,
3632 GError **error)
3633{
3634 GsmManagerPrivate *priv;
3635 g_debug ("GsmManager: Shutdown called");
3636
3637 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3638
3639 priv = gsm_manager_get_instance_private (manager);
3640 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3641 g_set_error (error,
3642 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3643 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3644 "Shutdown interface is only available during the Running phase");
3645 return FALSE(0);
3646 }
3647
3648 if (_log_out_is_locked_down (manager)) {
3649 g_set_error (error,
3650 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3651 GSM_MANAGER_ERROR_LOCKED_DOWN,
3652 "Logout has been locked down");
3653 return FALSE(0);
3654 }
3655
3656 show_shutdown_dialog (manager);
3657
3658 return TRUE(!(0));
3659}
3660
3661gboolean
3662gsm_manager_can_shutdown (GsmManager *manager,
3663 gboolean *shutdown_available,
3664 GError **error)
3665{
3666 GsmConsolekit *consolekit;
3667#ifdef HAVE_SYSTEMD1
3668 GsmSystemd *systemd;
3669#endif
3670 g_debug ("GsmManager: CanShutdown called");
3671
3672 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3673
3674#ifdef HAVE_SYSTEMD1
3675 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3676 systemd = gsm_get_systemd ();
3677 *shutdown_available = gsm_systemd_can_stop (systemd)
3678 || gsm_systemd_can_restart (systemd)
3679 || gsm_systemd_can_suspend (systemd)
3680 || gsm_systemd_can_hibernate (systemd);
3681 g_object_unref (systemd);
3682 }
3683 else {
3684#endif
3685 consolekit = gsm_get_consolekit ();
3686 *shutdown_available = !_log_out_is_locked_down (manager) &&
3687 (gsm_consolekit_can_stop (consolekit)
3688 || gsm_consolekit_can_restart (consolekit)
3689 || gsm_consolekit_can_suspend (consolekit)
3690 || gsm_consolekit_can_hibernate (consolekit));
3691 g_object_unref (consolekit);
3692#ifdef HAVE_SYSTEMD1
3693 }
3694#endif
3695
3696 return TRUE(!(0));
3697}
3698
3699gboolean
3700gsm_manager_logout (GsmManager *manager,
3701 guint logout_mode,
3702 GError **error)
3703{
3704 GsmManagerPrivate *priv;
3705 g_debug ("GsmManager: Logout called");
3706
3707 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3708
3709 priv = gsm_manager_get_instance_private (manager);
3710 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3711 g_set_error (error,
3712 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3713 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3714 "Shutdown interface is only available during the Running phase");
3715 return FALSE(0);
3716 }
3717
3718 if (_log_out_is_locked_down (manager)) {
3719 g_set_error (error,
3720 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3721 GSM_MANAGER_ERROR_LOCKED_DOWN,
3722 "Logout has been locked down");
3723 return FALSE(0);
3724 }
3725
3726 switch (logout_mode) {
3727 case GSM_MANAGER_LOGOUT_MODE_NORMAL:
3728 case GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
3729 case GSM_MANAGER_LOGOUT_MODE_FORCE:
3730 user_logout (manager, logout_mode);
3731 break;
3732
3733 default:
3734 g_debug ("Unknown logout mode option");
3735
3736 g_set_error (error,
3737 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3738 GSM_MANAGER_ERROR_INVALID_OPTION,
3739 "Unknown logout mode flag");
3740 return FALSE(0);
3741 }
3742
3743 return TRUE(!(0));
3744}
3745
3746gboolean
3747gsm_manager_register_client (GsmManager *manager,
3748 const char *app_id,
3749 const char *startup_id,
3750 DBusGMethodInvocation *context)
3751{
3752 char *new_startup_id;
3753 char *sender;
3754 GsmClient *client;
3755 GsmApp *app;
3756 GsmManagerPrivate *priv;
3757
3758 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3759
3760 app = NULL((void*)0);
3761 client = NULL((void*)0);
3762
3763 g_debug ("GsmManager: RegisterClient %s", startup_id);
3764
3765 priv = gsm_manager_get_instance_private (manager);
3766 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3767 GError *new_error;
3768
3769 g_debug ("Unable to register client: shutting down");
3770
3771 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3772 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3773 "Unable to register client");
3774 dbus_g_method_return_error (context, new_error);
3775 g_error_free (new_error);
3776 return FALSE(0);
3777 }
3778
3779 if (IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3780 new_startup_id = gsm_util_generate_startup_id ();
3781 } else {
3782
3783 client = (GsmClient *)gsm_store_find (priv->clients,
3784 (GsmStoreFunc)_client_has_startup_id,
3785 (char *)startup_id);
3786 /* We can't have two clients with the same startup id. */
3787 if (client != NULL((void*)0)) {
3788 GError *new_error;
3789
3790 g_debug ("Unable to register client: already registered");
3791
3792 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3793 GSM_MANAGER_ERROR_ALREADY_REGISTERED,
3794 "Unable to register client");
3795 dbus_g_method_return_error (context, new_error);
3796 g_error_free (new_error);
3797 return FALSE(0);
3798 }
3799
3800 new_startup_id = g_strdup (startup_id)g_strdup_inline (startup_id);
3801 }
3802
3803 g_debug ("GsmManager: Adding new client %s to session", new_startup_id);
3804
3805 if (app == NULL((void*)0) && !IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3806 app = find_app_for_startup_id (manager, startup_id);
3807 }
3808 if (app == NULL((void*)0) && !IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3809 /* try to associate this app id with a known app */
3810 app = find_app_for_app_id (manager, app_id);
3811 }
3812
3813 sender = dbus_g_method_get_sender (context);
3814 client = gsm_dbus_client_new (new_startup_id, sender);
3815 g_free (sender);
3816 if (client == NULL((void*)0)) {
3817 GError *new_error;
3818
3819 g_debug ("Unable to create client");
3820
3821 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3822 GSM_MANAGER_ERROR_GENERAL,
3823 "Unable to register client");
3824 dbus_g_method_return_error (context, new_error);
3825 g_error_free (new_error);
3826 return FALSE(0);
3827 }
3828
3829 gsm_store_add (priv->clients, gsm_client_peek_id (client), G_OBJECT (client)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((client)), (((GType) ((20) << (2))))))))
);
3830 /* the store will own the ref */
3831 g_object_unref (client);
3832
3833 if (app != NULL((void*)0)) {
3834 gsm_client_set_app_id (client, gsm_app_peek_app_id (app));
3835 gsm_app_registered (app);
3836 } else {
3837 /* if an app id is specified store it in the client
3838 so we can save it later */
3839 gsm_client_set_app_id (client, app_id);
3840 }
3841
3842 gsm_client_set_status (client, GSM_CLIENT_REGISTERED);
3843
3844 g_assert (new_startup_id != NULL)do { if (new_startup_id != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "gsm-manager.c", 3844, ((const char*) (__func__
)), "new_startup_id != NULL"); } while (0)
;
3845 g_free (new_startup_id);
3846
3847 dbus_g_method_return (context, gsm_client_peek_id (client));
3848
3849 return TRUE(!(0));
3850}
3851
3852gboolean
3853gsm_manager_unregister_client (GsmManager *manager,
3854 const char *client_id,
3855 DBusGMethodInvocation *context)
3856{
3857 GsmClient *client;
3858 GsmManagerPrivate *priv;
3859
3860 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3861
3862 g_debug ("GsmManager: UnregisterClient %s", client_id);
3863
3864 priv = gsm_manager_get_instance_private (manager);
3865 client = (GsmClient *)gsm_store_lookup (priv->clients, client_id);
3866 if (client == NULL((void*)0)) {
3867 GError *new_error;
3868
3869 g_debug ("Unable to unregister client: not registered");
3870
3871 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3872 GSM_MANAGER_ERROR_NOT_REGISTERED,
3873 "Unable to unregister client");
3874 dbus_g_method_return_error (context, new_error);
3875 g_error_free (new_error);
3876 return FALSE(0);
3877 }
3878
3879 /* don't disconnect client here, only change the status.
3880 Wait until it leaves the bus before disconnecting it */
3881 gsm_client_set_status (client, GSM_CLIENT_UNREGISTERED);
3882
3883 dbus_g_method_return (context);
3884
3885 return TRUE(!(0));
3886}
3887
3888gboolean
3889gsm_manager_inhibit (GsmManager *manager,
3890 const char *app_id,
3891 guint toplevel_xid,
3892 const char *reason,
3893 guint flags,
3894 DBusGMethodInvocation *context)
3895{
3896 GsmInhibitor *inhibitor;
3897 guint cookie;
3898 GsmManagerPrivate *priv;
3899
3900 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3901
3902 g_debug ("GsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u",
3903 toplevel_xid,
3904 app_id,
3905 reason,
3906 flags);
3907
3908 priv = gsm_manager_get_instance_private (manager);
3909 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
3910 GError *new_error;
3911
3912 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3913 GSM_MANAGER_ERROR_GENERAL,
3914 "Forced logout cannot be inhibited");
3915 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3916 dbus_g_method_return_error (context, new_error);
3917 g_error_free (new_error);
3918 return FALSE(0);
3919 }
3920
3921 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3922 GError *new_error;
3923
3924 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3925 GSM_MANAGER_ERROR_GENERAL,
3926 "Application ID not specified");
3927 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3928 dbus_g_method_return_error (context, new_error);
3929 g_error_free (new_error);
3930 return FALSE(0);
3931 }
3932
3933 if (IS_STRING_EMPTY (reason)((reason)==((void*)0)||(reason)[0]=='\0')) {
3934 GError *new_error;
3935
3936 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3937 GSM_MANAGER_ERROR_GENERAL,
3938 "Reason not specified");
3939 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3940 dbus_g_method_return_error (context, new_error);
3941 g_error_free (new_error);
3942 return FALSE(0);
3943 }
3944
3945 if (flags == 0) {
3946 GError *new_error;
3947
3948 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3949 GSM_MANAGER_ERROR_GENERAL,
3950 "Invalid inhibit flags");
3951 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3952 dbus_g_method_return_error (context, new_error);
3953 g_error_free (new_error);
3954 return FALSE(0);
3955 }
3956
3957 cookie = _generate_unique_cookie (manager);
3958 inhibitor = gsm_inhibitor_new (app_id,
3959 toplevel_xid,
3960 flags,
3961 reason,
3962 dbus_g_method_get_sender (context),
3963 cookie);
3964 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
3965 g_object_unref (inhibitor);
3966
3967 dbus_g_method_return (context, cookie);
3968
3969 return TRUE(!(0));
3970}
3971
3972gboolean
3973gsm_manager_uninhibit (GsmManager *manager,
3974 guint cookie,
3975 DBusGMethodInvocation *context)
3976{
3977 GsmInhibitor *inhibitor;
3978 GsmManagerPrivate *priv;
3979
3980 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3981
3982 g_debug ("GsmManager: Uninhibit %u", cookie);
3983
3984 priv = gsm_manager_get_instance_private (manager);
3985 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3986 (GsmStoreFunc)_find_by_cookie,
3987 &cookie);
3988 if (inhibitor == NULL((void*)0)) {
3989 GError *new_error;
3990
3991 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3992 GSM_MANAGER_ERROR_GENERAL,
3993 "Unable to uninhibit: Invalid cookie");
3994 dbus_g_method_return_error (context, new_error);
3995 g_debug ("Unable to uninhibit: %s", new_error->message);
3996 g_error_free (new_error);
3997 return FALSE(0);
3998 }
3999
4000 g_debug ("GsmManager: removing inhibitor %s %u reason '%s' %u connection %s",
4001 gsm_inhibitor_peek_app_id (inhibitor),
4002 gsm_inhibitor_peek_toplevel_xid (inhibitor),
4003 gsm_inhibitor_peek_reason (inhibitor),
4004 gsm_inhibitor_peek_flags (inhibitor),
4005 gsm_inhibitor_peek_bus_name (inhibitor));
4006
4007 gsm_store_remove (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor));
4008
4009 dbus_g_method_return (context);
4010
4011 return TRUE(!(0));
4012}
4013
4014gboolean
4015gsm_manager_is_inhibited (GsmManager *manager,
4016 guint flags,
4017 gboolean *is_inhibited,
4018 GError *error)
4019{
4020 GsmInhibitor *inhibitor;
4021 GsmManagerPrivate *priv;
4022
4023 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4024
4025 priv = gsm_manager_get_instance_private (manager);
4026 if (priv->inhibitors == NULL((void*)0)
4027 || gsm_store_size (priv->inhibitors) == 0) {
4028 *is_inhibited = FALSE(0);
4029 return TRUE(!(0));
4030 }
4031
4032 inhibitor = (GsmInhibitor *) gsm_store_find (priv->inhibitors,
4033 (GsmStoreFunc)inhibitor_has_flag,
4034 GUINT_TO_POINTER (flags)((gpointer) (gulong) (flags)));
4035 if (inhibitor == NULL((void*)0)) {
4036 *is_inhibited = FALSE(0);
4037 } else {
4038 *is_inhibited = TRUE(!(0));
4039 }
4040
4041 return TRUE(!(0));
4042
4043}
4044
4045static gboolean
4046listify_store_ids (char *id,
4047 GObject *object,
4048 GPtrArray **array)
4049{
4050 g_ptr_array_add (*array, g_strdup (id)g_strdup_inline (id));
4051 return FALSE(0);
4052}
4053
4054gboolean
4055gsm_manager_get_clients (GsmManager *manager,
4056 GPtrArray **clients,
4057 GError **error)
4058{
4059 GsmManagerPrivate *priv;
4060 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4061
4062 if (clients == NULL((void*)0)) {
4063 return FALSE(0);
4064 }
4065
4066 *clients = g_ptr_array_new ();
4067 priv = gsm_manager_get_instance_private (manager);
4068 gsm_store_foreach (priv->clients, (GsmStoreFunc)listify_store_ids, clients);
4069
4070 return TRUE(!(0));
4071}
4072
4073gboolean
4074gsm_manager_get_inhibitors (GsmManager *manager,
4075 GPtrArray **inhibitors,
4076 GError **error)
4077{
4078 GsmManagerPrivate *priv;
4079
4080 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4081
4082 if (inhibitors == NULL((void*)0)) {
4083 return FALSE(0);
4084 }
4085
4086 *inhibitors = g_ptr_array_new ();
4087 priv = gsm_manager_get_instance_private (manager);
4088 gsm_store_foreach (priv->inhibitors,
4089 (GsmStoreFunc) listify_store_ids,
4090 inhibitors);
4091
4092 return TRUE(!(0));
4093}
4094
4095static gboolean
4096_app_has_autostart_condition (const char *id,
4097 GsmApp *app,
4098 const char *condition)
4099{
4100 gboolean has;
4101 gboolean disabled;
4102
4103 has = gsm_app_has_autostart_condition (app, condition);
4104 disabled = gsm_app_peek_is_disabled (app);
4105
4106 return has && !disabled;
4107}
4108
4109gboolean
4110gsm_manager_is_autostart_condition_handled (GsmManager *manager,
4111 const char *condition,
4112 gboolean *handled,
4113 GError **error)
4114{
4115 GsmApp *app;
4116 GsmManagerPrivate *priv;
4117
4118 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4119
4120 priv = gsm_manager_get_instance_private (manager);
4121 app = (GsmApp *) gsm_store_find (priv->apps,(
4122 GsmStoreFunc) _app_has_autostart_condition,
4123 (char *)condition);
4124
4125 if (app != NULL((void*)0)) {
4126 *handled = TRUE(!(0));
4127 } else {
4128 *handled = FALSE(0);
4129 }
4130
4131 return TRUE(!(0));
4132}
4133
4134static void
4135append_app (GsmManager *manager,
4136 GsmApp *app)
4137{
4138 const char *id;
4139 const char *app_id;
4140 GsmApp *dup;
4141 GsmManagerPrivate *priv;
4142
4143 id = gsm_app_peek_id (app);
4144 if (IS_STRING_EMPTY (id)((id)==((void*)0)||(id)[0]=='\0')) {
4145 g_debug ("GsmManager: not adding app: no id");
4146 return;
4147 }
4148
4149 priv = gsm_manager_get_instance_private (manager);
4150 dup = (GsmApp *)gsm_store_lookup (priv->apps, id);
4151 if (dup != NULL((void*)0)) {
4152 g_debug ("GsmManager: not adding app: already added");
4153 return;
4154 }
4155
4156 app_id = gsm_app_peek_app_id (app);
4157 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
4158 g_debug ("GsmManager: not adding app: no app-id");
4159 return;
4160 }
4161
4162 dup = find_app_for_app_id (manager, app_id);
4163 if (dup != NULL((void*)0)) {
4164 g_debug ("GsmManager: not adding app: app-id already exists");
4165 return;
4166 }
4167
4168 gsm_store_add (priv->apps, id, G_OBJECT (app)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), (((GType) ((20) << (2))))))))
);
4169}
4170
4171gboolean
4172gsm_manager_add_autostart_app (GsmManager *manager,
4173 const char *path,
4174 const char *provides)
4175{
4176 GsmApp *app;
4177 GsmManagerPrivate *priv;
4178
4179 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4180 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4181
4182 priv = gsm_manager_get_instance_private (manager);
4183 /* first check to see if service is already provided */
4184 if (provides != NULL((void*)0)) {
4185 GsmApp *dup;
4186
4187 dup = (GsmApp *)gsm_store_find (priv->apps,
4188 (GsmStoreFunc)_find_app_provides,
4189 (char *)provides);
4190 if (dup != NULL((void*)0)) {
4191 g_debug ("GsmManager: service '%s' is already provided", provides);
4192 return FALSE(0);
4193 }
4194 }
4195
4196 app = gsm_autostart_app_new (path);
4197 if (app == NULL((void*)0)) {
4198 g_warning ("could not read %s", path);
4199 return FALSE(0);
4200 }
4201
4202 g_debug ("GsmManager: read %s", path);
4203 append_app (manager, app);
4204 g_object_unref (app);
4205
4206 return TRUE(!(0));
4207}
4208
4209gboolean
4210gsm_manager_add_autostart_apps_from_dir (GsmManager *manager,
4211 const char *path)
4212{
4213 GDir *dir;
4214 const char *name;
4215
4216 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4217 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4218
4219 g_debug ("GsmManager: *** Adding autostart apps for %s", path);
4220
4221 dir = g_dir_open (path, 0, NULL((void*)0));
4222 if (dir == NULL((void*)0)) {
4223 return FALSE(0);
4224 }
4225
4226 while ((name = g_dir_read_name (dir))) {
4227 char *desktop_file;
4228
4229 if (!g_str_has_suffix (name, ".desktop")(__builtin_constant_p (".desktop")? __extension__ ({ const char
* const __str = (name); const char * const __suffix = (".desktop"
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (name, ".desktop"
) )
) {
4230 continue;
4231 }
4232
4233 desktop_file = g_build_filename (path, name, NULL((void*)0));
4234 gsm_manager_add_autostart_app (manager, desktop_file, NULL((void*)0));
4235 g_free (desktop_file);
4236 }
4237
4238 g_dir_close (dir);
4239
4240 return TRUE(!(0));
4241}
4242
4243gboolean
4244gsm_manager_is_session_running (GsmManager *manager,
4245 gboolean *running,
4246 GError **error)
4247{
4248 GsmManagerPrivate *priv;
4249
4250 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4251
4252 priv = gsm_manager_get_instance_private (manager);
4253 *running = (priv->phase == GSM_MANAGER_PHASE_RUNNING);
4254 return TRUE(!(0));
4255}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-abdc03.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-abdc03.html new file mode 100644 index 0000000..6c6eda2 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-abdc03.html @@ -0,0 +1,1486 @@ + + + +main.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/main.c
Warning:line 631, column 16
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c main.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23#include <config.h>
24
25#include <signal.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <errno(*__errno_location ()).h>
30#include <time.h>
31
32#include <glib/gi18n.h>
33#include <glib.h>
34#include <gtk/gtk.h>
35#include <gio/gio.h>
36
37#include <dbus/dbus.h>
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-bindings.h>
40#include <dbus/dbus-glib-lowlevel.h>
41
42#include "mdm-signal-handler.h"
43#include "mdm-log.h"
44
45#include "gsm-consolekit.h"
46#ifdef HAVE_SYSTEMD1
47#include "gsm-systemd.h"
48#endif
49#include "gsm-util.h"
50#include "gsm-manager.h"
51#include "gsm-xsmp-server.h"
52#include "gsm-store.h"
53
54#include "msm-gnome.h"
55
56#define GSM_SCHEMA"org.mate.session" "org.mate.session"
57#define GSM_DEFAULT_SESSION_KEY"default-session" "default-session"
58#define GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components" GSM_SCHEMA"org.mate.session" ".required-components"
59#define GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list" "required-components-list"
60
61#define ACCESSIBILITY_KEY"accessibility" "accessibility"
62#define ACCESSIBILITY_SCHEMA"org.mate.interface" "org.mate.interface"
63
64#define DEBUG_SCHEMA"org.mate.debug" "org.mate.debug"
65#define DEBUG_KEY"mate-session" "mate-session"
66
67#define VISUAL_SCHEMA"org.mate.applications-at-visual" "org.mate.applications-at-visual"
68#define VISUAL_KEY"exec" "exec"
69#define VISUAL_STARTUP_KEY"startup" "startup"
70
71#define MOBILITY_SCHEMA"org.mate.applications-at-mobility" "org.mate.applications-at-mobility"
72#define MOBILITY_KEY"exec" "exec"
73#define MOBILITY_STARTUP_KEY"startup" "startup"
74
75#define MATE_INTERFACE_SCHEMA"org.mate.interface" "org.mate.interface"
76#define GTK_OVERLAY_SCROLL"gtk-overlay-scrolling" "gtk-overlay-scrolling"
77
78#define GSM_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
79
80#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
81
82static gboolean failsafe = FALSE(0);
83static gboolean show_version = FALSE(0);
84static gboolean debug = FALSE(0);
85static gboolean disable_acceleration_check = FALSE(0);
86
87static gboolean
88initialize_gsettings (void)
89{
90 GSettings* settings;
91 time_t now = time (0);
92 gboolean ret;
93
94 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
95
96 if (!settings)
97 return FALSE(0);
98
99 ret = g_settings_set_int (settings, "session-start", now);
100
101 g_settings_sync ();
102
103 g_object_unref (settings);
104
105 return ret;
106}
107
108static void on_bus_name_lost(DBusGProxy* bus_proxy, const char* name, gpointer data)
109{
110 g_warning("Lost name on bus: %s, exiting", name);
111 exit(1);
112}
113
114static gboolean acquire_name_on_proxy(DBusGProxy* bus_proxy, const char* name)
115{
116 GError* error;
117 guint result;
118 gboolean res;
119 gboolean ret;
120
121 ret = FALSE(0);
122
123 if (bus_proxy == NULL((void*)0))
124 {
125 goto out;
126 }
127
128 error = NULL((void*)0);
129 res = dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING((GType) ((16) << (2))), name, G_TYPE_UINT((GType) ((7) << (2))), 0, G_TYPE_INVALID((GType) ((0) << (2))), G_TYPE_UINT((GType) ((7) << (2))), &result, G_TYPE_INVALID((GType) ((0) << (2))));
130
131 if (! res)
132 {
133 if (error != NULL((void*)0))
134 {
135 g_warning("Failed to acquire %s: %s", name, error->message);
136 g_error_free(error);
137 }
138 else
139 {
140 g_warning ("Failed to acquire %s", name);
141 }
142
143 goto out;
144 }
145
146 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER1)
147 {
148 if (error != NULL((void*)0))
149 {
150 g_warning("Failed to acquire %s: %s", name, error->message);
151 g_error_free(error);
152 }
153 else
154 {
155 g_warning("Failed to acquire %s", name);
156 }
157
158 goto out;
159 }
160
161 /* register for name lost */
162 dbus_g_proxy_add_signal(bus_proxy, "NameLost", G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_INVALID((GType) ((0) << (2))));
163 dbus_g_proxy_connect_signal(bus_proxy, "NameLost", G_CALLBACK(on_bus_name_lost)((GCallback) (on_bus_name_lost)), NULL((void*)0), NULL((void*)0));
164
165 ret = TRUE(!(0));
166
167 out:
168
169 return ret;
170}
171
172static gboolean acquire_name(void)
173{
174 DBusGProxy* bus_proxy;
175 GError* error;
176 DBusGConnection* connection;
177
178 error = NULL((void*)0);
179 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
180
181 if (connection == NULL((void*)0))
182 {
183 gsm_util_init_error(TRUE(!(0)), "Could not connect to session bus: %s", error->message);
184 /* not reached */
185 }
186
187 bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS"org.freedesktop.DBus", DBUS_PATH_DBUS"/org/freedesktop/DBus", DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
188
189 if (!acquire_name_on_proxy(bus_proxy, GSM_DBUS_NAME"org.gnome.SessionManager"))
190 {
191 gsm_util_init_error(TRUE(!(0)), "%s", "Could not acquire name on session bus");
192 /* not reached */
193 }
194
195 g_object_unref(bus_proxy);
196
197 return TRUE(!(0));
198}
199
200/* This doesn't contain the required components, so we need to always
201 * call append_required_apps() after a call to append_default_apps(). */
202static void append_default_apps(GsmManager* manager, const char* default_session_key, char** autostart_dirs)
203{
204 gint i;
205 gchar** default_apps;
206 GSettings* settings;
207
208 g_debug("main: *** Adding default apps");
209
210 g_assert(default_session_key != NULL)do { if (default_session_key != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 210, ((const char*) (__func__)), "default_session_key != NULL"
); } while (0)
;
211 g_assert(autostart_dirs != NULL)do { if (autostart_dirs != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 211, ((const char*) (__func__)), "autostart_dirs != NULL"
); } while (0)
;
212
213 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
214 default_apps = g_settings_get_strv (settings, default_session_key);
215 g_object_unref(settings);
216
217 for (i = 0; default_apps[i]; i++)
218 {
219 char* app_path;
220
221 if (IS_STRING_EMPTY((char*) default_apps[i])(((char*) default_apps[i])==((void*)0)||((char*) default_apps
[i])[0]=='\0')
)
222 {
223 continue;
224 }
225
226 app_path = gsm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs);
227
228 if (app_path != NULL((void*)0))
229 {
230 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
231 g_free(app_path);
232 }
233 }
234
235 g_strfreev (default_apps);
236}
237
238static void append_required_apps(GsmManager* manager)
239{
240 gchar** required_components;
241 gint i;
242 GSettings* settings;
243 GSettings* settings_required_components;
244
245 g_debug("main: *** Adding required apps");
246
247 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
248 settings_required_components = g_settings_new (GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components");
249
250 required_components = g_settings_get_strv(settings, GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list");
251
252 if (required_components == NULL((void*)0))
253 {
254 g_warning("No required applications specified");
255 }
256 else
257 {
258 for (i = 0; required_components[i]; i++)
259 {
260 char* default_provider;
261 const char* component;
262
263 if (IS_STRING_EMPTY((char*) required_components[i])(((char*) required_components[i])==((void*)0)||((char*) required_components
[i])[0]=='\0')
)
264 {
265 continue;
266 }
267
268 component = required_components[i];
269
270 default_provider = g_settings_get_string (settings_required_components, component);
271
272 g_debug ("main: %s looking for component: '%s'", component, default_provider);
273
274 if (default_provider != NULL((void*)0))
275 {
276 char* app_path;
277
278 app_path = gsm_util_find_desktop_file_for_app_name(default_provider, NULL((void*)0));
279
280 if (app_path != NULL((void*)0))
281 {
282 gsm_manager_add_autostart_app(manager, app_path, component);
283 }
284 else
285 {
286 g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component);
287 }
288
289 g_free(app_path);
290 }
291
292 g_free(default_provider);
293 }
294 }
295
296 g_debug("main: *** Done adding required apps");
297
298 g_strfreev(required_components);
299
300 g_object_unref(settings);
301 g_object_unref(settings_required_components);
302}
303
304static void append_accessibility_apps(GsmManager* manager)
305{
306 GSettings* mobility_settings;
307 GSettings* visual_settings;
308
309 g_debug("main: *** Adding accesibility apps");
310
311 mobility_settings = g_settings_new (MOBILITY_SCHEMA"org.mate.applications-at-mobility");
312 visual_settings = g_settings_new (VISUAL_SCHEMA"org.mate.applications-at-visual");
313
314 if (g_settings_get_boolean (mobility_settings, MOBILITY_STARTUP_KEY"startup"))
315 {
316 gchar *mobility_exec;
317 mobility_exec = g_settings_get_string (mobility_settings, MOBILITY_KEY"exec");
318 if (mobility_exec != NULL((void*)0) && mobility_exec[0] != 0)
319 {
320 char* app_path;
321 app_path = gsm_util_find_desktop_file_for_app_name(mobility_exec, NULL((void*)0));
322 if (app_path != NULL((void*)0))
323 {
324 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
325 g_free (app_path);
326 }
327 g_free (mobility_exec);
328 }
329 }
330
331 if (g_settings_get_boolean (visual_settings, VISUAL_STARTUP_KEY"startup"))
332 {
333 gchar *visual_exec;
334 visual_exec = g_settings_get_string (visual_settings, VISUAL_KEY"exec");
335 if (visual_exec != NULL((void*)0) && visual_exec[0] != 0)
336 {
337 char* app_path;
338 app_path = gsm_util_find_desktop_file_for_app_name(visual_exec, NULL((void*)0));
339 if (app_path != NULL((void*)0))
340 {
341 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
342 g_free (app_path);
343 }
344 g_free (visual_exec);
345 }
346 }
347
348 g_object_unref (mobility_settings);
349 g_object_unref (visual_settings);
350}
351
352static void maybe_load_saved_session_apps(GsmManager* manager)
353{
354 GsmConsolekit* consolekit = NULL((void*)0);
355#ifdef HAVE_SYSTEMD1
356 GsmSystemd* systemd = NULL((void*)0);
357#endif
358 char* session_type;
359 gboolean is_login;
360
361#ifdef HAVE_SYSTEMD1
362 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
363 systemd = gsm_get_systemd();
364 session_type = gsm_systemd_get_current_session_type(systemd);
365 is_login = g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0;
366 }
367 else {
368#endif
369 consolekit = gsm_get_consolekit();
370 session_type = gsm_consolekit_get_current_session_type(consolekit);
371 is_login = g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0;
372#ifdef HAVE_SYSTEMD1
373 }
374#endif
375
376 if (!is_login)
377 {
378 GSettings* settings;
379 gboolean autostart;
380
381 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
382 autostart = g_settings_get_boolean (settings, KEY_AUTOSAVE"auto-save-session");
383 g_object_unref (settings);
384
385 if (autostart == TRUE(!(0)))
386 gsm_manager_add_autostart_apps_from_dir(manager, gsm_util_get_saved_session_dir());
387 }
388
389 if (consolekit != NULL((void*)0))
390 g_object_unref(consolekit);
391#ifdef HAVE_SYSTEMD1
392 if (systemd != NULL((void*)0))
393 g_object_unref(systemd);
394#endif
395 g_free(session_type);
396}
397
398static void load_standard_apps (GsmManager* manager, const char* default_session_key)
399{
400 char** autostart_dirs;
401 int i;
402
403 autostart_dirs = gsm_util_get_autostart_dirs();
404
405 if (!failsafe)
406 {
407 maybe_load_saved_session_apps(manager);
408
409 for (i = 0; autostart_dirs[i]; i++)
410 {
411 gsm_manager_add_autostart_apps_from_dir(manager, autostart_dirs[i]);
412 }
413 }
414
415 /* We do this at the end in case a saved session contains an
416 * application that already provides one of the components. */
417 append_default_apps(manager, default_session_key, autostart_dirs);
418 append_required_apps(manager);
419 append_accessibility_apps(manager);
420
421 g_strfreev(autostart_dirs);
422}
423
424static void load_override_apps(GsmManager* manager, char** override_autostart_dirs)
425{
426 int i;
427
428 for (i = 0; override_autostart_dirs[i]; i++)
429 {
430 gsm_manager_add_autostart_apps_from_dir(manager, override_autostart_dirs[i]);
431 }
432}
433
434static gboolean signal_cb(int signo, gpointer data)
435{
436 int ret;
437 GsmManager* manager;
438
439 g_debug("Got callback for signal %d", signo);
440
441 ret = TRUE(!(0));
442
443 switch (signo)
444 {
445 case SIGFPE8:
446 case SIGPIPE13:
447 /* let the fatal signals interrupt us */
448 g_debug ("Caught signal %d, shutting down abnormally.", signo);
449 ret = FALSE(0);
450 break;
451 case SIGINT2:
452 case SIGTERM15:
453 manager = (GsmManager*) data;
454 gsm_manager_logout(manager, GSM_MANAGER_LOGOUT_MODE_FORCE, NULL((void*)0));
455
456 /* let the fatal signals interrupt us */
457 g_debug("Caught signal %d, shutting down normally.", signo);
458 ret = TRUE(!(0));
459 break;
460 case SIGHUP1:
461 g_debug("Got HUP signal");
462 ret = TRUE(!(0));
463 break;
464 case SIGUSR110:
465 g_debug("Got USR1 signal");
466 ret = TRUE(!(0));
467 mdm_log_toggle_debug();
468 break;
469 default:
470 g_debug("Caught unhandled signal %d", signo);
471 ret = TRUE(!(0));
472
473 break;
474 }
475
476 return ret;
477}
478
479static void shutdown_cb(gpointer data)
480{
481 GsmManager* manager = (GsmManager*) data;
482 g_debug("Calling shutdown callback function");
483
484 /*
485 * When the signal handler gets a shutdown signal, it calls
486 * this function to inform GsmManager to not restart
487 * applications in the off chance a handler is already queued
488 * to dispatch following the below call to gtk_main_quit.
489 */
490 gsm_manager_set_phase(manager, GSM_MANAGER_PHASE_EXIT);
491
492 gtk_main_quit();
493}
494
495static gboolean require_dbus_session(int argc, char** argv, GError** error)
496{
497 char** new_argv;
498 int i;
499
500 if (g_getenv("DBUS_SESSION_BUS_ADDRESS"))
501 {
502 return TRUE(!(0));
503 }
504
505 /* Just a sanity check to prevent infinite recursion if
506 * dbus-launch fails to set DBUS_SESSION_BUS_ADDRESS
507 */
508 g_return_val_if_fail(!g_str_has_prefix(argv[0], "dbus-launch"), TRUE)do { if ((!(__builtin_constant_p ("dbus-launch")? __extension__
({ const char * const __str = (argv[0]); const char * const __prefix
= ("dbus-launch"); gboolean __result = (0); if (__str == ((void
*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix)
(__str, __prefix); else { const size_t __str_len = strlen ((
(__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (argv[0], "dbus-launch"
) ))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const
char*) (__func__)), "!g_str_has_prefix(argv[0], \"dbus-launch\")"
); return ((!(0))); } } while (0)
;
509
510 /* +2 for our new arguments, +1 for NULL */
511 new_argv = g_malloc(argc + 3 * sizeof (*argv));
512
513 new_argv[0] = "dbus-launch";
514 new_argv[1] = "--exit-with-session";
515
516 for (i = 0; i < argc; i++)
517 {
518 new_argv[i + 2] = argv[i];
519 }
520
521 new_argv[i + 2] = NULL((void*)0);
522
523 if (!execvp("dbus-launch", new_argv))
524 {
525 g_set_error(error, G_SPAWN_ERRORg_spawn_error_quark (), G_SPAWN_ERROR_FAILED, "No session bus and could not exec dbus-launch: %s", g_strerror(errno(*__errno_location ())));
526 g_free (new_argv);
527 return FALSE(0);
528 }
529
530 g_free (new_argv);
531
532 /* Should not be reached */
533 return TRUE(!(0));
534}
535
536static void
537debug_changed (GSettings *settings, gchar *key, gpointer user_data)
538{
539 debug = g_settings_get_boolean (settings, DEBUG_KEY"mate-session");
540 mdm_log_set_debug (debug);
541}
542
543static gboolean
544schema_exists (const gchar* schema_name)
545{
546 GSettingsSchemaSource *source;
547 GSettingsSchema *schema;
548 gboolean exists;
549
550 source = g_settings_schema_source_get_default();
551 schema = g_settings_schema_source_lookup (source, schema_name, FALSE(0));
552 exists = (schema != NULL((void*)0));
553 if (schema)
554 g_settings_schema_unref (schema);
555
556 return exists;
557}
558
559static void set_overlay_scroll (void)
560{
561 GSettings *settings;
562 gboolean enabled;
563
564 settings = g_settings_new (MATE_INTERFACE_SCHEMA"org.mate.interface");
565 enabled = g_settings_get_boolean (settings, GTK_OVERLAY_SCROLL"gtk-overlay-scrolling");
566
567 if (enabled) {
568 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "1");
569 } else {
570 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "0");
571 }
572
573 g_object_unref (settings);
574}
575
576static gboolean
577check_gl (gchar **gl_renderer, GError **error)
578{
579 int status;
580 char *argv[] = { LIBEXECDIR"/usr/local/libexec" "/mate-session-check-accelerated", NULL((void*)0) };
581
582 if (getenv ("DISPLAY") == NULL((void*)0)) {
583 /* Not connected to X11, someone else will take care of checking GL */
584 return TRUE(!(0));
585 }
586
587 if (!g_spawn_sync (NULL((void*)0), (char **) argv, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), gl_renderer, NULL((void*)0),
588 &status, error)) {
589 return FALSE(0);
590 }
591
592 return g_spawn_check_exit_status (status, error);
593}
594
595int main(int argc, char** argv)
596{
597 struct sigaction sa;
598 GError* error;
599 const char* display_str;
600 GsmManager* manager;
601 GsmStore* client_store;
602 GsmXsmpServer* xsmp_server;
603 GSettings* debug_settings = NULL((void*)0);
604 GSettings* accessibility_settings;
605 MdmSignalHandler* signal_handler;
606 static char** override_autostart_dirs = NULL((void*)0);
607 char* gl_renderer = NULL((void*)0);
608 gboolean gl_failed = FALSE(0);
609
610 static GOptionEntry entries[] = {
611 {"autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories")("Override standard autostart directories"), NULL((void*)0)},
612 {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code")("Enable debugging code"), NULL((void*)0)},
613 {"failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications")("Do not load user-specified applications"), NULL((void*)0)},
614 {"version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application")("Version of this application"), NULL((void*)0)},
615 { "disable-acceleration-check", 0, 0, G_OPTION_ARG_NONE, &disable_acceleration_check, N_("Disable hardware acceleration check")("Disable hardware acceleration check"), NULL((void*)0) },
616 {NULL((void*)0), 0, 0, 0, NULL((void*)0), NULL((void*)0), NULL((void*)0) }
617 };
618
619 /* Make sure that we have a session bus */
620 if (!require_dbus_session(argc, argv, &error))
1
Assuming the condition is false
2
Taking false branch
621 {
622 gsm_util_init_error(TRUE(!(0)), "%s", error->message);
623 }
624
625#ifdef ENABLE_NLS1
626 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
627 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
628 textdomain(GETTEXT_PACKAGE"mate-session-manager");
629#endif /* ENABLE_NLS */
630
631 sa.sa_handler__sigaction_handler.sa_handler = SIG_IGN((__sighandler_t) 1);
3
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms
632 sa.sa_flags = 0;
633 sigemptyset(&sa.sa_mask);
634 sigaction(SIGPIPE13, &sa, 0);
635
636 error = NULL((void*)0);
637 gtk_init_with_args(&argc, &argv, (char*) _(" - the MATE session manager")gettext (" - the MATE session manager"), entries, GETTEXT_PACKAGE"mate-session-manager", &error);
638
639 if (error != NULL((void*)0))
640 {
641 g_warning("%s", error->message);
642 exit(1);
643 }
644
645 if (show_version)
646 {
647 g_print("%s %s\n", g_get_application_name(), VERSION"1.27.0");
648 exit(1);
649 }
650
651 gsm_util_export_activation_environment (NULL((void*)0));
652
653#ifdef HAVE_SYSTEMD1
654 gsm_util_export_user_environment (NULL((void*)0));
655#endif
656
657 mdm_log_init();
658
659 /* Allows to enable/disable debug from GSettings only if it is not set from argument */
660 if (!debug && schema_exists(DEBUG_SCHEMA"org.mate.debug"))
661 {
662 debug_settings = g_settings_new (DEBUG_SCHEMA"org.mate.debug");
663 g_signal_connect (debug_settings, "changed::" DEBUG_KEY, G_CALLBACK (debug_changed), NULL)g_signal_connect_data ((debug_settings), ("changed::" "mate-session"
), (((GCallback) (debug_changed))), (((void*)0)), ((void*)0),
(GConnectFlags) 0)
;
664 debug = g_settings_get_boolean (debug_settings, DEBUG_KEY"mate-session");
665 }
666
667 mdm_log_set_debug(debug);
668
669 if (disable_acceleration_check) {
670 g_debug ("hardware acceleration check is disabled");
671 } else {
672 /* Check GL, if it doesn't work out then force software fallback */
673 if (!check_gl (&gl_renderer, &error)) {
674 gl_failed = TRUE(!(0));
675
676 g_debug ("hardware acceleration check failed: %s",
677 error? error->message : "");
678 g_clear_error (&error);
679 if (g_getenv ("LIBGL_ALWAYS_SOFTWARE") == NULL((void*)0)) {
680 g_setenv ("LIBGL_ALWAYS_SOFTWARE", "1", TRUE(!(0)));
681 if (!check_gl (&gl_renderer, &error)) {
682 g_warning ("software acceleration check failed: %s",
683 error? error->message : "");
684 g_clear_error (&error);
685 } else {
686 gl_failed = FALSE(0);
687 }
688 }
689 }
690 }
691
692 if (gl_failed) {
693 g_warning ("gl_failed!");
694 }
695
696 if (g_getenv ("XDG_CURRENT_DESKTOP") == NULL((void*)0))
697 gsm_util_setenv ("XDG_CURRENT_DESKTOP", "MATE");
698
699 /* Set DISPLAY explicitly for all our children, in case --display
700 * was specified on the command line.
701 */
702 display_str = gdk_display_get_name (gdk_display_get_default());
703 gsm_util_setenv("DISPLAY", display_str);
704
705 /* Some third-party programs rely on MATE_DESKTOP_SESSION_ID to
706 * detect if MATE is running. We keep this for compatibility reasons.
707 */
708 gsm_util_setenv("MATE_DESKTOP_SESSION_ID", "this-is-deprecated");
709
710 /*
711 * Make sure gsettings is set up correctly. If not, then bail.
712 */
713
714 if (initialize_gsettings () != TRUE(!(0)))
715 exit (1);
716
717 /* Look if accessibility is enabled */
718 accessibility_settings = g_settings_new (ACCESSIBILITY_SCHEMA"org.mate.interface");
719 if (g_settings_get_boolean (accessibility_settings, ACCESSIBILITY_KEY"accessibility"))
720 {
721 gsm_util_setenv("GTK_MODULES", "gail:atk-bridge");
722 }
723 g_object_unref (accessibility_settings);
724
725 client_store = gsm_store_new();
726
727 xsmp_server = gsm_xsmp_server_new(client_store);
728
729 /* Now make sure they succeeded. (They'll call
730 * gsm_util_init_error() if they failed.)
731 */
732 acquire_name();
733
734 /* Starts gnome compat mode */
735 msm_gnome_start();
736
737 /* Set to use Gtk3 overlay scroll */
738 set_overlay_scroll ();
739
740 manager = gsm_manager_new(client_store, failsafe);
741
742 signal_handler = mdm_signal_handler_new();
743 mdm_signal_handler_add_fatal(signal_handler);
744 mdm_signal_handler_add(signal_handler, SIGFPE8, signal_cb, NULL((void*)0));
745 mdm_signal_handler_add(signal_handler, SIGHUP1, signal_cb, NULL((void*)0));
746 mdm_signal_handler_add(signal_handler, SIGUSR110, signal_cb, NULL((void*)0));
747 mdm_signal_handler_add(signal_handler, SIGTERM15, signal_cb, manager);
748 mdm_signal_handler_add(signal_handler, SIGINT2, signal_cb, manager);
749 mdm_signal_handler_set_fatal_func(signal_handler, shutdown_cb, manager);
750
751 if (override_autostart_dirs != NULL((void*)0))
752 {
753 load_override_apps(manager, override_autostart_dirs);
754 }
755 else
756 {
757 load_standard_apps(manager, GSM_DEFAULT_SESSION_KEY"default-session");
758 }
759
760 gsm_xsmp_server_start(xsmp_server);
761 _gsm_manager_set_renderer (manager, gl_renderer);
762 gsm_manager_start(manager);
763
764 gtk_main();
765
766 if (xsmp_server != NULL((void*)0))
767 {
768 g_object_unref(xsmp_server);
769 }
770
771 if (manager != NULL((void*)0))
772 {
773 g_debug("Unreffing manager");
774 g_object_unref(manager);
775 }
776
777 if (gl_renderer != NULL((void*)0))
778 {
779 g_free (gl_renderer);
780 }
781
782 if (client_store != NULL((void*)0))
783 {
784 g_object_unref(client_store);
785 }
786
787 if (debug_settings != NULL((void*)0))
788 {
789 g_object_unref(debug_settings);
790 }
791
792 msm_gnome_stop();
793 mdm_log_shutdown();
794
795 return 0;
796}
797
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-b8f564.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-b8f564.html new file mode 100644 index 0000000..38a0903 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-b8f564.html @@ -0,0 +1,2089 @@ + + + +eggsmclient-xsmp.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-submodules/libegg/eggsmclient-xsmp.c
Warning:line 1199, column 18
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggsmclient-xsmp.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-submodules/libegg -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D EGG_SM_CLIENT_BACKEND_XSMP -D G_LOG_DOMAIN="EggSMClient" -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D PIC -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-submodules/libegg -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c eggsmclient-xsmp.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2007 Novell, Inc.
3 *
4 * Inspired by various other pieces of code including GsmClient (C)
5 * 2001 Havoc Pennington, MateClient (C) 1998 Carsten Schaar, and twm
6 * session code (C) 1998 The Open Group.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "config.h"
25
26#include "eggsmclient.h"
27#include "eggsmclient-private.h"
28
29#include "eggdesktopfile.h"
30
31#include <errno(*__errno_location ()).h>
32#include <fcntl.h>
33#include <stdlib.h>
34#include <string.h>
35#include <unistd.h>
36#include <X11/SM/SMlib.h>
37
38#include <gtk/gtk.h>
39#include <gdk/gdk.h>
40
41#ifdef GDK_WINDOWING_X11
42#include <gdk/gdkx.h>
43#endif
44
45#define EGG_TYPE_SM_CLIENT_XSMP(egg_sm_client_xsmp_get_type ()) (egg_sm_client_xsmp_get_type ())
46#define EGG_SM_CLIENT_XSMP(obj)((((EggSMClientXSMP*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((egg_sm_client_xsmp_get_type ()))))))
(G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP)(((EggSMClientXSMP*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((egg_sm_client_xsmp_get_type ())))))
)
47#define EGG_SM_CLIENT_XSMP_CLASS(klass)((((EggSMClientXSMPClass*) (void *) g_type_check_class_cast (
(GTypeClass*) ((klass)), ((egg_sm_client_xsmp_get_type ()))))
))
(G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)(((EggSMClientXSMPClass*) (void *) g_type_check_class_cast ((
GTypeClass*) ((klass)), ((egg_sm_client_xsmp_get_type ())))))
)
48#define EGG_IS_SM_CLIENT_XSMP(obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(obj)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(obj)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))
)
49#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean __r
; if (!__class) __r = (0); else if (__class->g_type == __t
) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; }))))
(G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean __r
; if (!__class) __r = (0); else if (__class->g_type == __t
) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; })))
)
50#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj)((((EggSMClientXSMPClass*) (((GTypeInstance*) ((obj)))->g_class
))))
(G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)(((EggSMClientXSMPClass*) (((GTypeInstance*) ((obj)))->g_class
)))
)
51
52typedef struct _EggSMClientXSMP EggSMClientXSMP;
53typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass;
54
55/* These mostly correspond to the similarly-named states in section
56 * 9.1 of the XSMP spec. Some of the states there aren't represented
57 * here, because we don't need them. SHUTDOWN_CANCELLED is slightly
58 * different from the spec; we use it when the client is IDLE after a
59 * ShutdownCancelled message, but the application is still interacting
60 * and doesn't know the shutdown has been cancelled yet.
61 */
62typedef enum
63{
64 XSMP_STATE_IDLE,
65 XSMP_STATE_SAVE_YOURSELF,
66 XSMP_STATE_INTERACT_REQUEST,
67 XSMP_STATE_INTERACT,
68 XSMP_STATE_SAVE_YOURSELF_DONE,
69 XSMP_STATE_SHUTDOWN_CANCELLED,
70 XSMP_STATE_CONNECTION_CLOSED
71} EggSMClientXSMPState;
72
73static const char *state_names[] =
74{
75 "idle",
76 "save-yourself",
77 "interact-request",
78 "interact",
79 "save-yourself-done",
80 "shutdown-cancelled",
81 "connection-closed"
82};
83
84#define EGG_SM_CLIENT_XSMP_STATE(xsmp)(state_names[(xsmp)->state]) (state_names[(xsmp)->state])
85
86struct _EggSMClientXSMP
87{
88 EggSMClient parent;
89
90 SmcConn connection;
91 char *client_id;
92
93 EggSMClientXSMPState state;
94 char **restart_command;
95 gboolean set_restart_command;
96 int restart_style;
97 char **discard_command;
98 gboolean set_discard_command;
99
100 guint idle;
101
102 /* Current SaveYourself state */
103 guint expecting_initial_save_yourself : 1;
104 guint need_save_state : 1;
105 guint need_quit_requested : 1;
106 guint interact_errors : 1;
107 guint shutting_down : 1;
108
109 /* Todo list */
110 guint waiting_to_set_initial_properties : 1;
111 guint waiting_to_emit_quit : 1;
112 guint waiting_to_emit_quit_cancelled : 1;
113 guint waiting_to_save_myself : 1;
114
115};
116
117struct _EggSMClientXSMPClass
118{
119 EggSMClientClass parent_class;
120
121};
122
123static void sm_client_xsmp_startup (EggSMClient *client,
124 const char *client_id);
125static void sm_client_xsmp_set_restart_command (EggSMClient *client,
126 int argc,
127 const char **argv);
128static void sm_client_xsmp_set_discard_command (EggSMClient *client,
129 int argc,
130 const char **argv);
131static void sm_client_xsmp_will_quit (EggSMClient *client,
132 gboolean will_quit);
133static gboolean sm_client_xsmp_end_session (EggSMClient *client,
134 EggSMClientEndStyle style,
135 gboolean request_confirmation);
136
137static void xsmp_save_yourself (SmcConn smc_conn,
138 SmPointer client_data,
139 int save_style,
140 Boolint shutdown,
141 int interact_style,
142 Boolint fast);
143static void xsmp_die (SmcConn smc_conn,
144 SmPointer client_data);
145static void xsmp_save_complete (SmcConn smc_conn,
146 SmPointer client_data);
147static void xsmp_shutdown_cancelled (SmcConn smc_conn,
148 SmPointer client_data);
149static void xsmp_interact (SmcConn smc_conn,
150 SmPointer client_data);
151
152static SmProp *array_prop (const char *name,
153 ...);
154static SmProp *ptrarray_prop (const char *name,
155 GPtrArray *values);
156static SmProp *string_prop (const char *name,
157 const char *value);
158static SmProp *card8_prop (const char *name,
159 unsigned char value);
160
161static void set_properties (EggSMClientXSMP *xsmp, ...);
162static void delete_properties (EggSMClientXSMP *xsmp, ...);
163
164static GPtrArray *generate_command (char **restart_command,
165 const char *client_id,
166 const char *state_file);
167
168static void save_state (EggSMClientXSMP *xsmp);
169static void do_save_yourself (EggSMClientXSMP *xsmp);
170static void update_pending_events (EggSMClientXSMP *xsmp);
171
172static void ice_init (void);
173static gboolean process_ice_messages (IceConn ice_conn);
174static void smc_error_handler (SmcConn smc_conn,
175 Boolint swap,
176 int offending_minor_opcode,
177 unsigned long offending_sequence,
178 int error_class,
179 int severity,
180 SmPointer values);
181
182G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT)static void egg_sm_client_xsmp_init (EggSMClientXSMP *self); static
void egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass
); static GType egg_sm_client_xsmp_get_type_once (void); static
gpointer egg_sm_client_xsmp_parent_class = ((void*)0); static
gint EggSMClientXSMP_private_offset; static void egg_sm_client_xsmp_class_intern_init
(gpointer klass) { egg_sm_client_xsmp_parent_class = g_type_class_peek_parent
(klass); if (EggSMClientXSMP_private_offset != 0) g_type_class_adjust_private_offset
(klass, &EggSMClientXSMP_private_offset); egg_sm_client_xsmp_class_init
((EggSMClientXSMPClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer egg_sm_client_xsmp_get_instance_private
(EggSMClientXSMP *self) { return (((gpointer) ((guint8*) (self
) + (glong) (EggSMClientXSMP_private_offset)))); } GType egg_sm_client_xsmp_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = egg_sm_client_xsmp_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType egg_sm_client_xsmp_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((egg_sm_client_get_type ()), g_intern_static_string ("EggSMClientXSMP"
), sizeof (EggSMClientXSMPClass), (GClassInitFunc)(void (*)(void
)) egg_sm_client_xsmp_class_intern_init, sizeof (EggSMClientXSMP
), (GInstanceInitFunc)(void (*)(void)) egg_sm_client_xsmp_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
183
184static void
185egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp)
186{
187 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
188 xsmp->connection = NULL((void*)0);
189 xsmp->restart_style = SmRestartIfRunning0;
190}
191
192static void
193egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass)
194{
195 EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
196
197 sm_client_class->startup = sm_client_xsmp_startup;
198 sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
199 sm_client_class->set_discard_command = sm_client_xsmp_set_discard_command;
200 sm_client_class->will_quit = sm_client_xsmp_will_quit;
201 sm_client_class->end_session = sm_client_xsmp_end_session;
202}
203
204EggSMClient *
205egg_sm_client_xsmp_new (void)
206{
207 if (!g_getenv ("SESSION_MANAGER"))
208 return NULL((void*)0);
209
210 return g_object_new (EGG_TYPE_SM_CLIENT_XSMP(egg_sm_client_xsmp_get_type ()), NULL((void*)0));
211}
212
213static gboolean
214sm_client_xsmp_set_initial_properties (gpointer user_data)
215{
216 EggSMClientXSMP *xsmp = user_data;
217 EggDesktopFile *desktop_file;
218 GPtrArray *clone, *restart;
219 char pid_str[64];
220
221 if (xsmp->idle)
222 {
223 g_source_remove (xsmp->idle);
224 xsmp->idle = 0;
225 }
226 xsmp->waiting_to_set_initial_properties = FALSE(0);
227
228 if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
229 xsmp->restart_style = SmRestartNever3;
230
231 /* Parse info out of desktop file */
232 desktop_file = egg_get_desktop_file ();
233 if (desktop_file)
234 {
235 GError *err = NULL((void*)0);
236 char **argv;
237 int argc;
238
239 if (xsmp->restart_style == SmRestartIfRunning0)
240 {
241 if (egg_desktop_file_get_boolean (desktop_file,
242 "X-MATE-AutoRestart", NULL((void*)0)))
243 xsmp->restart_style = SmRestartImmediately2;
244 }
245
246 if (!xsmp->set_restart_command)
247 {
248 char *cmdline;
249
250 cmdline = egg_desktop_file_parse_exec (desktop_file, NULL((void*)0), &err);
251 if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
252 {
253 egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
254 argc, (const char **)argv);
255 g_strfreev (argv);
256 }
257 else
258 {
259 g_warning ("Could not parse Exec line in desktop file: %s",
260 err->message);
261 g_error_free (err);
262 }
263 g_free (cmdline);
264 }
265 }
266
267 if (!xsmp->set_restart_command)
268 xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
269
270 clone = generate_command (xsmp->restart_command, NULL((void*)0), NULL((void*)0));
271 restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL((void*)0));
272
273 g_debug ("Setting initial properties");
274
275 /* Program, CloneCommand, RestartCommand, and UserID are required.
276 * ProcessID isn't required, but the SM may be able to do something
277 * useful with it.
278 */
279 g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
280 set_properties (xsmp,
281 string_prop (SmProgram"Program", g_get_prgname ()),
282 ptrarray_prop (SmCloneCommand"CloneCommand", clone),
283 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
284 string_prop (SmUserID"UserID", g_get_user_name ()),
285 string_prop (SmProcessID"ProcessID", pid_str),
286 card8_prop (SmRestartStyleHint"RestartStyleHint", xsmp->restart_style),
287 NULL((void*)0));
288 g_ptr_array_free (clone, TRUE(!(0)));
289 g_ptr_array_free (restart, TRUE(!(0)));
290
291 if (desktop_file)
292 {
293 set_properties (xsmp,
294 string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
295 NULL((void*)0));
296 }
297
298 update_pending_events (xsmp);
299 return FALSE(0);
300}
301
302/* This gets called from two different places: xsmp_die() (when the
303 * server asks us to disconnect) and process_ice_messages() (when the
304 * server disconnects unexpectedly).
305 */
306static void
307sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp)
308{
309 SmcConn connection;
310
311 if (!xsmp->connection)
312 return;
313
314 g_debug ("Disconnecting");
315
316 connection = xsmp->connection;
317 xsmp->connection = NULL((void*)0);
318 SmcCloseConnection (connection, 0, NULL((void*)0));
319 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
320
321 xsmp->waiting_to_save_myself = FALSE(0);
322 update_pending_events (xsmp);
323}
324
325static void
326sm_client_xsmp_startup (EggSMClient *client,
327 const char *client_id)
328{
329 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
330 SmcCallbacks callbacks;
331 char *ret_client_id;
332 char error_string_ret[256];
333
334 xsmp->client_id = g_strdup (client_id)g_strdup_inline (client_id);
335
336 ice_init ();
337 SmcSetErrorHandler (smc_error_handler);
338
339 callbacks.save_yourself.callback = xsmp_save_yourself;
340 callbacks.die.callback = xsmp_die;
341 callbacks.save_complete.callback = xsmp_save_complete;
342 callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
343
344 callbacks.save_yourself.client_data = xsmp;
345 callbacks.die.client_data = xsmp;
346 callbacks.save_complete.client_data = xsmp;
347 callbacks.shutdown_cancelled.client_data = xsmp;
348
349 client_id = NULL((void*)0);
350 error_string_ret[0] = '\0';
351 xsmp->connection =
352 SmcOpenConnection (NULL((void*)0), xsmp, SmProtoMajor1, SmProtoMinor0,
353 SmcSaveYourselfProcMask(1L << 0) | SmcDieProcMask(1L << 1) |
354 SmcSaveCompleteProcMask(1L << 2) |
355 SmcShutdownCancelledProcMask(1L << 3),
356 &callbacks,
357 xsmp->client_id, &ret_client_id,
358 sizeof (error_string_ret), error_string_ret);
359
360 if (!xsmp->connection)
361 {
362 g_warning ("Failed to connect to the session manager: %s\n",
363 error_string_ret[0] ?
364 error_string_ret : "no error message given");
365 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
366 return;
367 }
368
369 /* We expect a pointless initial SaveYourself if either (a) we
370 * didn't have an initial client ID, or (b) we DID have an initial
371 * client ID, but the server rejected it and gave us a new one.
372 */
373 if (!xsmp->client_id ||
374 (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
375 xsmp->expecting_initial_save_yourself = TRUE(!(0));
376
377 if (ret_client_id)
378 {
379 g_free (xsmp->client_id);
380 xsmp->client_id = g_strdup (ret_client_id)g_strdup_inline (ret_client_id);
381 free (ret_client_id);
382
383#ifdef GDK_WINDOWING_X11
384 if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(gdk_display_get_default ())); GType __t = ((gdk_x11_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
385 gdk_x11_set_sm_client_id (xsmp->client_id);
386#endif
387
388 g_debug ("Got client ID \"%s\"", xsmp->client_id);
389 }
390
391 xsmp->state = XSMP_STATE_IDLE;
392
393 /* Do not set the initial properties until we reach the main loop,
394 * so that the application has a chance to call
395 * egg_set_desktop_file(). (This may also help the session manager
396 * have a better idea of when the application is fully up and
397 * running.)
398 */
399 xsmp->waiting_to_set_initial_properties = TRUE(!(0));
400 xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
401}
402
403static void
404sm_client_xsmp_set_restart_command (EggSMClient *client,
405 int argc,
406 const char **argv)
407{
408 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
409 int i;
410
411 g_strfreev (xsmp->restart_command);
412
413 xsmp->restart_command = g_new (char *, argc + 1)((char * *) g_malloc_n ((argc + 1), sizeof (char *)));
414 for (i = 0; i < argc; i++)
415 xsmp->restart_command[i] = g_strdup (argv[i])g_strdup_inline (argv[i]);
416 xsmp->restart_command[i] = NULL((void*)0);
417
418 xsmp->set_restart_command = TRUE(!(0));
419}
420
421static void
422sm_client_xsmp_set_discard_command (EggSMClient *client,
423 int argc,
424 const char **argv)
425{
426 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
427 int i;
428
429 g_strfreev (xsmp->discard_command);
430
431 xsmp->discard_command = g_new (char *, argc + 1)((char * *) g_malloc_n ((argc + 1), sizeof (char *)));
432 for (i = 0; i < argc; i++)
433 xsmp->discard_command[i] = g_strdup (argv[i])g_strdup_inline (argv[i]);
434 xsmp->discard_command[i] = NULL((void*)0);
435
436 xsmp->set_discard_command = TRUE(!(0));
437}
438
439static void
440sm_client_xsmp_will_quit (EggSMClient *client,
441 gboolean will_quit)
442{
443 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
444
445 if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
446 {
447 /* The session manager has already exited! Schedule a quit
448 * signal.
449 */
450 xsmp->waiting_to_emit_quit = TRUE(!(0));
451 update_pending_events (xsmp);
452 return;
453 }
454 else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
455 {
456 /* We received a ShutdownCancelled message while the application
457 * was interacting; Schedule a quit_cancelled signal.
458 */
459 xsmp->waiting_to_emit_quit_cancelled = TRUE(!(0));
460 update_pending_events (xsmp);
461 return;
462 }
463
464 g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT)do { if ((xsmp->state == XSMP_STATE_INTERACT)) { } else { g_return_if_fail_warning
("EggSMClient", ((const char*) (__func__)), "xsmp->state == XSMP_STATE_INTERACT"
); return; } } while (0)
;
465
466 g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
467 SmcInteractDone (xsmp->connection, !will_quit);
468
469 if (will_quit && xsmp->need_save_state)
470 save_state (xsmp);
471
472 g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
473 SmcSaveYourselfDone (xsmp->connection, will_quit);
474 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
475}
476
477static gboolean
478sm_client_xsmp_end_session (EggSMClient *client,
479 EggSMClientEndStyle style,
480 gboolean request_confirmation)
481{
482 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
483 int save_type;
484
485 /* To end the session via XSMP, we have to send a
486 * SaveYourselfRequest. We aren't allowed to do that if anything
487 * else is going on, but we don't want to expose this fact to the
488 * application. So we do our best to patch things up here...
489 *
490 * In the worst case, this method might block for some length of
491 * time in process_ice_messages, but the only time that code path is
492 * honestly likely to get hit is if the application tries to end the
493 * session as the very first thing it does, in which case it
494 * probably won't actually block anyway. It's not worth gunking up
495 * the API to try to deal nicely with the other 0.01% of cases where
496 * this happens.
497 */
498
499 while (xsmp->state != XSMP_STATE_IDLE ||
500 xsmp->expecting_initial_save_yourself)
501 {
502 /* If we're already shutting down, we don't need to do anything. */
503 if (xsmp->shutting_down)
504 return TRUE(!(0));
505
506 switch (xsmp->state)
507 {
508 case XSMP_STATE_CONNECTION_CLOSED:
509 return FALSE(0);
510
511 case XSMP_STATE_SAVE_YOURSELF:
512 /* Trying to log out from the save_state callback? Whatever.
513 * Abort the save_state.
514 */
515 SmcSaveYourselfDone (xsmp->connection, FALSE(0));
516 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
517 break;
518
519 case XSMP_STATE_INTERACT_REQUEST:
520 case XSMP_STATE_INTERACT:
521 case XSMP_STATE_SHUTDOWN_CANCELLED:
522 /* Already in a shutdown-related state, just ignore
523 * the new shutdown request...
524 */
525 return TRUE(!(0));
526
527 case XSMP_STATE_IDLE:
528 if (xsmp->waiting_to_set_initial_properties)
529 sm_client_xsmp_set_initial_properties (xsmp);
530
531 if (!xsmp->expecting_initial_save_yourself)
532 break;
533 /* else fall through */
534
535 case XSMP_STATE_SAVE_YOURSELF_DONE:
536 /* We need to wait for some response from the server.*/
537 process_ice_messages (SmcGetIceConnection (xsmp->connection));
538 break;
539
540 default:
541 /* Hm... shouldn't happen */
542 return FALSE(0);
543 }
544 }
545
546 /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
547 * the user chooses to save the session. But mate-session will do
548 * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
549 * save the session... Sigh.
550 */
551 if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
552 save_type = SmSaveBoth2;
553 else
554 save_type = SmSaveGlobal0;
555
556 g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
557 SmcRequestSaveYourself (xsmp->connection,
558 save_type,
559 True1, /* shutdown */
560 SmInteractStyleAny2,
561 !request_confirmation, /* fast */
562 True1 /* global */);
563 return TRUE(!(0));
564}
565
566static gboolean
567idle_do_pending_events (gpointer data)
568{
569 EggSMClientXSMP *xsmp = data;
570 EggSMClient *client = data;
571
572 xsmp->idle = 0;
573
574 if (xsmp->waiting_to_emit_quit)
575 {
576 xsmp->waiting_to_emit_quit = FALSE(0);
577 egg_sm_client_quit (client);
578 goto out;
579 }
580
581 if (xsmp->waiting_to_emit_quit_cancelled)
582 {
583 xsmp->waiting_to_emit_quit_cancelled = FALSE(0);
584 egg_sm_client_quit_cancelled (client);
585 xsmp->state = XSMP_STATE_IDLE;
586 }
587
588 if (xsmp->waiting_to_save_myself)
589 {
590 xsmp->waiting_to_save_myself = FALSE(0);
591 do_save_yourself (xsmp);
592 }
593
594out:
595 return FALSE(0);
596}
597
598static void
599update_pending_events (EggSMClientXSMP *xsmp)
600{
601 gboolean want_idle =
602 xsmp->waiting_to_emit_quit ||
603 xsmp->waiting_to_emit_quit_cancelled ||
604 xsmp->waiting_to_save_myself;
605
606 if (want_idle)
607 {
608 if (xsmp->idle == 0)
609 xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
610 }
611 else
612 {
613 if (xsmp->idle != 0)
614 g_source_remove (xsmp->idle);
615 xsmp->idle = 0;
616 }
617}
618
619static void
620fix_broken_state (EggSMClientXSMP *xsmp, const char *message,
621 gboolean send_interact_done,
622 gboolean send_save_yourself_done)
623{
624 g_warning ("Received XSMP %s message in state %s: client or server error",
625 message, EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
626
627 /* Forget any pending SaveYourself plans we had */
628 xsmp->waiting_to_save_myself = FALSE(0);
629 update_pending_events (xsmp);
630
631 if (send_interact_done)
632 SmcInteractDone (xsmp->connection, False0);
633 if (send_save_yourself_done)
634 SmcSaveYourselfDone (xsmp->connection, True1);
635
636 xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
637}
638
639/* SM callbacks */
640
641static void
642xsmp_save_yourself (SmcConn smc_conn,
643 SmPointer client_data,
644 int save_type,
645 Boolint shutdown,
646 int interact_style,
647 Boolint fast)
648{
649 EggSMClientXSMP *xsmp = client_data;
650 gboolean wants_quit_requested;
651
652 g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
653 save_type == SmSaveLocal1 ? "SmSaveLocal" :
654 save_type == SmSaveGlobal0 ? "SmSaveGlobal" : "SmSaveBoth",
655 shutdown ? "Shutdown" : "!Shutdown",
656 interact_style == SmInteractStyleAny2 ? "SmInteractStyleAny" :
657 interact_style == SmInteractStyleErrors1 ? "SmInteractStyleErrors" :
658 "SmInteractStyleNone", fast ? "Fast" : "!Fast",
659 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
660
661 if (xsmp->state != XSMP_STATE_IDLE &&
662 xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
663 {
664 fix_broken_state (xsmp, "SaveYourself", FALSE(0), TRUE(!(0)));
665 return;
666 }
667
668 if (xsmp->waiting_to_set_initial_properties)
669 sm_client_xsmp_set_initial_properties (xsmp);
670
671 /* If this is the initial SaveYourself, ignore it; we've already set
672 * properties and there's no reason to actually save state too.
673 */
674 if (xsmp->expecting_initial_save_yourself)
675 {
676 xsmp->expecting_initial_save_yourself = FALSE(0);
677
678 if (save_type == SmSaveLocal1 &&
679 interact_style == SmInteractStyleNone0 &&
680 !shutdown && !fast)
681 {
682 g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
683 SmcSaveYourselfDone (xsmp->connection, True1);
684 /* As explained in the comment at the end of
685 * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
686 * state here, not IDLE.
687 */
688 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
689 return;
690 }
691 else
692 g_warning ("First SaveYourself was not the expected one!");
693 }
694
695 /* Even ignoring the "fast" flag completely, there are still 18
696 * different combinations of save_type, shutdown and interact_style.
697 * We interpret them as follows:
698 *
699 * Type Shutdown Interact Interpretation
700 * G F A/E/N do nothing (1)
701 * G T N do nothing (1)*
702 * G T A/E quit_requested (2)
703 * L/B F A/E/N save_state (3)
704 * L/B T N save_state (3)*
705 * L/B T A/E quit_requested, then save_state (4)
706 *
707 * 1. Do nothing, because the SM asked us to do something
708 * uninteresting (save open files, but then don't quit
709 * afterward) or rude (save open files without asking the user
710 * for confirmation).
711 *
712 * 2. Request interaction and then emit ::quit_requested. This
713 * perhaps isn't quite correct for the SmInteractStyleErrors
714 * case, but we don't care.
715 *
716 * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
717 * rows essentially get demoted to SmSaveLocal, because their
718 * Global halves correspond to "do nothing".
719 *
720 * 4. Request interaction, emit ::quit_requested, and then emit
721 * ::save_state after interacting. This is the SmSaveBoth
722 * equivalent of #2, but we also promote SmSaveLocal shutdown
723 * SaveYourselfs to SmSaveBoth here, because we want to give
724 * the user a chance to save open files before quitting.
725 *
726 * (* It would be nice if we could do something useful when the
727 * session manager sends a SaveYourself with shutdown True and
728 * SmInteractStyleNone. But we can't, so we just pretend it didn't
729 * even tell us it was shutting down. The docs for ::quit mention
730 * that it might not always be preceded by ::quit_requested.)
731 */
732
733 /* As an optimization, we don't actually request interaction and
734 * emit ::quit_requested if the application isn't listening to the
735 * signal.
736 */
737 wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT(egg_sm_client_get_type ())), 0, FALSE(0));
738
739 xsmp->need_save_state = (save_type != SmSaveGlobal0);
740 xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
741 interact_style != SmInteractStyleNone0);
742 xsmp->interact_errors = (interact_style == SmInteractStyleErrors1);
743
744 xsmp->shutting_down = shutdown;
745
746 do_save_yourself (xsmp);
747}
748
749static void
750do_save_yourself (EggSMClientXSMP *xsmp)
751{
752 if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
753 {
754 /* The SM cancelled a previous SaveYourself, but we haven't yet
755 * had a chance to tell the application, so we can't start
756 * processing this SaveYourself yet.
757 */
758 xsmp->waiting_to_save_myself = TRUE(!(0));
759 update_pending_events (xsmp);
760 return;
761 }
762
763 if (xsmp->need_quit_requested)
764 {
765 xsmp->state = XSMP_STATE_INTERACT_REQUEST;
766
767 g_debug ("Sending InteractRequest(%s)",
768 xsmp->interact_errors ? "Error" : "Normal");
769 SmcInteractRequest (xsmp->connection,
770 xsmp->interact_errors ? SmDialogError0 : SmDialogNormal1,
771 xsmp_interact,
772 xsmp);
773 return;
774 }
775
776 if (xsmp->need_save_state)
777 {
778 save_state (xsmp);
779
780 /* Though unlikely, the client could have been disconnected
781 * while the application was saving its state.
782 */
783 if (!xsmp->connection)
784 return;
785 }
786
787 g_debug ("Sending SaveYourselfDone(True)");
788 SmcSaveYourselfDone (xsmp->connection, True1);
789
790 /* The client state diagram in the XSMP spec says that after a
791 * non-shutdown SaveYourself, we go directly back to "idle". But
792 * everything else in both the XSMP spec and the libSM docs
793 * disagrees.
794 */
795 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
796}
797
798static void
799save_state (EggSMClientXSMP *xsmp)
800{
801 GKeyFile *state_file;
802 char *state_file_path, *data;
803 EggDesktopFile *desktop_file;
804 GPtrArray *restart, *discard;
805 int offset, fd;
806
807 /* We set xsmp->state before emitting save_state, but our caller is
808 * responsible for setting it back afterward.
809 */
810 xsmp->state = XSMP_STATE_SAVE_YOURSELF;
811
812 state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
813 if (!state_file)
814 {
815 restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL((void*)0));
816 set_properties (xsmp,
817 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
818 NULL((void*)0));
819 g_ptr_array_free (restart, TRUE(!(0)));
820
821 if (xsmp->set_discard_command)
822 {
823 discard = generate_command (xsmp->discard_command, NULL((void*)0), NULL((void*)0));
824 set_properties (xsmp,
825 ptrarray_prop (SmDiscardCommand"DiscardCommand", discard),
826 NULL((void*)0));
827 g_ptr_array_free (discard, TRUE(!(0)));
828 }
829 else
830 delete_properties (xsmp, SmDiscardCommand"DiscardCommand", NULL((void*)0));
831
832 return;
833 }
834
835 desktop_file = egg_get_desktop_file ();
836 if (desktop_file)
837 {
838 GKeyFile *merged_file;
839 char *desktop_file_path;
840
841 merged_file = g_key_file_new ();
842 desktop_file_path =
843 g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
844 NULL((void*)0), NULL((void*)0));
845 if (desktop_file_path &&
846 g_key_file_load_from_file (merged_file, desktop_file_path,
847 G_KEY_FILE_KEEP_COMMENTS |
848 G_KEY_FILE_KEEP_TRANSLATIONS, NULL((void*)0)))
849 {
850 guint g, k, i;
851 char **groups, **keys, *value, *exec;
852
853 groups = g_key_file_get_groups (state_file, NULL((void*)0));
854 for (g = 0; groups[g]; g++)
855 {
856 keys = g_key_file_get_keys (state_file, groups[g], NULL((void*)0), NULL((void*)0));
857 for (k = 0; keys[k]; k++)
858 {
859 value = g_key_file_get_value (state_file, groups[g],
860 keys[k], NULL((void*)0));
861 if (value)
862 {
863 g_key_file_set_value (merged_file, groups[g],
864 keys[k], value);
865 g_free (value);
866 }
867 }
868 g_strfreev (keys);
869 }
870 g_strfreev (groups);
871
872 g_key_file_free (state_file);
873 state_file = merged_file;
874
875 /* Update Exec key using "--sm-client-state-file %k" */
876 restart = generate_command (xsmp->restart_command,
877 NULL((void*)0), "%k");
878 for (i = 0; i < restart->len; i++)
879 restart->pdata[i] = g_shell_quote (restart->pdata[i]);
880 g_ptr_array_add (restart, NULL((void*)0));
881 exec = g_strjoinv (" ", (char **)restart->pdata);
882 g_strfreev ((char **)restart->pdata);
883 g_ptr_array_free (restart, FALSE(0));
884
885 g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP"Desktop Entry",
886 EGG_DESKTOP_FILE_KEY_EXEC"Exec",
887 exec);
888 g_free (exec);
889 }
890 else
891 desktop_file = NULL((void*)0);
892
893 g_free (desktop_file_path);
894 }
895
896 /* Now write state_file to disk. (We can't use mktemp(), because
897 * that requires the filename to end with "XXXXXX", and we want
898 * it to end with ".desktop".)
899 */
900
901 data = g_key_file_to_data (state_file, NULL((void*)0), NULL((void*)0));
902 g_key_file_free (state_file);
903
904 offset = 0;
905 while (1)
906 {
907 state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
908 g_get_user_config_dir (),
909 G_DIR_SEPARATOR'/', G_DIR_SEPARATOR'/',
910 g_get_prgname (),
911 (long)time (NULL((void*)0)) + offset,
912 desktop_file ? "desktop" : "state");
913
914 fd = open (state_file_path, O_WRONLY01 | O_CREAT0100 | O_EXCL0200, 0644);
915 if (fd == -1)
916 {
917 if (errno(*__errno_location ()) == EEXIST17)
918 {
919 offset++;
920 g_free (state_file_path);
921 continue;
922 }
923 else if (errno(*__errno_location ()) == ENOTDIR20 || errno(*__errno_location ()) == ENOENT2)
924 {
925 char *sep = strrchr (state_file_path, G_DIR_SEPARATOR'/');
926
927 *sep = '\0';
928 if (g_mkdir_with_parents (state_file_path, 0755) != 0)
929 {
930 g_warning ("Could not create directory '%s'",
931 state_file_path);
932 g_free (state_file_path);
933 state_file_path = NULL((void*)0);
934 break;
935 }
936
937 continue;
938 }
939
940 g_warning ("Could not create file '%s': %s",
941 state_file_path, g_strerror (errno(*__errno_location ())));
942 g_free (state_file_path);
943 state_file_path = NULL((void*)0);
944 break;
945 }
946
947 close (fd);
948 g_file_set_contents (state_file_path, data, -1, NULL((void*)0));
949 break;
950 }
951 g_free (data);
952
953 restart = generate_command (xsmp->restart_command, xsmp->client_id,
954 state_file_path);
955 set_properties (xsmp,
956 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
957 NULL((void*)0));
958 g_ptr_array_free (restart, TRUE(!(0)));
959
960 if (state_file_path)
961 {
962 set_properties (xsmp,
963 array_prop (SmDiscardCommand"DiscardCommand",
964 "/bin/rm", "-rf", state_file_path,
965 NULL((void*)0)),
966 NULL((void*)0));
967 g_free (state_file_path);
968 }
969}
970
971static void
972xsmp_interact (SmcConn smc_conn,
973 SmPointer client_data)
974{
975 EggSMClientXSMP *xsmp = client_data;
976 EggSMClient *client = client_data;
977
978 g_debug ("Received Interact message in state %s",
979 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
980
981 if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
982 {
983 fix_broken_state (xsmp, "Interact", TRUE(!(0)), TRUE(!(0)));
984 return;
985 }
986
987 xsmp->state = XSMP_STATE_INTERACT;
988 egg_sm_client_quit_requested (client);
989}
990
991static void
992xsmp_die (SmcConn smc_conn,
993 SmPointer client_data)
994{
995 EggSMClientXSMP *xsmp = client_data;
996 EggSMClient *client = client_data;
997
998 g_debug ("Received Die message in state %s",
999 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1000
1001 sm_client_xsmp_disconnect (xsmp);
1002 egg_sm_client_quit (client);
1003}
1004
1005static void
1006xsmp_save_complete (SmcConn smc_conn,
1007 SmPointer client_data)
1008{
1009 EggSMClientXSMP *xsmp = client_data;
1010
1011 g_debug ("Received SaveComplete message in state %s",
1012 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1013
1014 if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
1015 xsmp->state = XSMP_STATE_IDLE;
1016 else
1017 fix_broken_state (xsmp, "SaveComplete", FALSE(0), FALSE(0));
1018}
1019
1020static void
1021xsmp_shutdown_cancelled (SmcConn smc_conn,
1022 SmPointer client_data)
1023{
1024 EggSMClientXSMP *xsmp = client_data;
1025 EggSMClient *client = client_data;
1026
1027 g_debug ("Received ShutdownCancelled message in state %s",
1028 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1029
1030 xsmp->shutting_down = FALSE(0);
1031
1032 if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
1033 {
1034 /* We've finished interacting and now the SM has agreed to
1035 * cancel the shutdown.
1036 */
1037 xsmp->state = XSMP_STATE_IDLE;
1038 egg_sm_client_quit_cancelled (client);
1039 }
1040 else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
1041 {
1042 /* Hm... ok, so we got a shutdown SaveYourself, which got
1043 * cancelled, but the application was still interacting, so we
1044 * didn't tell it yet, and then *another* SaveYourself arrived,
1045 * which we must still be waiting to tell the app about, except
1046 * that now that SaveYourself has been cancelled too! Dizzy yet?
1047 */
1048 xsmp->waiting_to_save_myself = FALSE(0);
1049 update_pending_events (xsmp);
1050 }
1051 else
1052 {
1053 g_debug ("Sending SaveYourselfDone(False)");
1054 SmcSaveYourselfDone (xsmp->connection, False0);
1055
1056 if (xsmp->state == XSMP_STATE_INTERACT)
1057 {
1058 /* The application is currently interacting, so we can't
1059 * tell it about the cancellation yet; we will wait until
1060 * after it calls egg_sm_client_will_quit().
1061 */
1062 xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
1063 }
1064 else
1065 {
1066 /* The shutdown was cancelled before the application got a
1067 * chance to interact.
1068 */
1069 xsmp->state = XSMP_STATE_IDLE;
1070 }
1071 }
1072}
1073
1074/* Utilities */
1075
1076/* Create a restart/clone/Exec command based on @restart_command.
1077 * If @client_id is non-%NULL, add "--sm-client-id @client_id".
1078 * If @state_file is non-%NULL, add "--sm-client-state-file @state_file".
1079 *
1080 * None of the input strings are g_strdup()ed; the caller must keep
1081 * them around until it is done with the returned GPtrArray, and must
1082 * then free the array, but not its contents.
1083 */
1084static GPtrArray *
1085generate_command (char **restart_command, const char *client_id,
1086 const char *state_file)
1087{
1088 GPtrArray *cmd;
1089 int i;
1090
1091 cmd = g_ptr_array_new ();
1092 g_ptr_array_add (cmd, restart_command[0]);
1093
1094 if (client_id)
1095 {
1096 g_ptr_array_add (cmd, (char *)"--sm-client-id");
1097 g_ptr_array_add (cmd, (char *)client_id);
1098 }
1099
1100 if (state_file)
1101 {
1102 g_ptr_array_add (cmd, (char *)"--sm-client-state-file");
1103 g_ptr_array_add (cmd, (char *)state_file);
1104 }
1105
1106 for (i = 1; restart_command[i]; i++)
1107 g_ptr_array_add (cmd, restart_command[i]);
1108
1109 return cmd;
1110}
1111
1112/* Takes a NULL-terminated list of SmProp * values, created by
1113 * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and
1114 * frees them.
1115 */
1116static void
1117set_properties (EggSMClientXSMP *xsmp, ...)
1118{
1119 GPtrArray *props;
1120 SmProp *prop;
1121 va_list ap;
1122 guint i;
1123
1124 props = g_ptr_array_new ();
1125
1126 va_start (ap, xsmp)__builtin_va_start(ap, xsmp);
1127 while ((prop = va_arg (ap, SmProp *)__builtin_va_arg(ap, SmProp *)))
1128 g_ptr_array_add (props, prop);
1129 va_end (ap)__builtin_va_end(ap);
1130
1131 if (xsmp->connection)
1132 {
1133 SmcSetProperties (xsmp->connection, props->len,
1134 (SmProp **)props->pdata);
1135 }
1136
1137 for (i = 0; i < props->len; i++)
1138 {
1139 prop = props->pdata[i];
1140 g_free (prop->vals);
1141 g_free (prop);
1142 }
1143 g_ptr_array_free (props, TRUE(!(0)));
1144}
1145
1146/* Takes a NULL-terminated list of property names and deletes them. */
1147static void
1148delete_properties (EggSMClientXSMP *xsmp, ...)
1149{
1150 GPtrArray *props;
1151 char *prop;
1152 va_list ap;
1153
1154 if (!xsmp->connection)
1155 return;
1156
1157 props = g_ptr_array_new ();
1158
1159 va_start (ap, xsmp)__builtin_va_start(ap, xsmp);
1160 while ((prop = va_arg (ap, char *)__builtin_va_arg(ap, char *)))
1161 g_ptr_array_add (props, prop);
1162 va_end (ap)__builtin_va_end(ap);
1163
1164 SmcDeleteProperties (xsmp->connection, props->len,
1165 (char **)props->pdata);
1166
1167 g_ptr_array_free (props, TRUE(!(0)));
1168}
1169
1170/* Takes an array of strings and creates a LISTofARRAY8 property. The
1171 * strings are neither dupped nor freed; they need to remain valid
1172 * until you're done with the SmProp.
1173 */
1174static SmProp *
1175array_prop (const char *name, ...)
1176{
1177 SmProp *prop;
1178 SmPropValue pv;
1179 GArray *vals;
1180 char *value;
1181 va_list ap;
1182
1183 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1184 prop->name = (char *)name;
1185 prop->type = (char *)SmLISTofARRAY8"LISTofARRAY8";
1186
1187 vals = g_array_new (FALSE(0), FALSE(0), sizeof (SmPropValue));
1188
1189 va_start (ap, name)__builtin_va_start(ap, name);
1190 while ((value = va_arg (ap, char *)__builtin_va_arg(ap, char *)))
1191 {
1192 pv.length = strlen (value);
1193 pv.value = value;
1194 g_array_append_val (vals, pv)g_array_append_vals (vals, &(pv), 1);
1195 }
1196 va_end (ap)__builtin_va_end(ap);
1197
1198 prop->num_vals = vals->len;
1199 prop->vals = (SmPropValue *)vals->data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
1200
1201 g_array_free (vals, FALSE(0));
1202
1203 return prop;
1204}
1205
1206/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property.
1207 * The array contents are neither dupped nor freed; they need to
1208 * remain valid until you're done with the SmProp.
1209 */
1210static SmProp *
1211ptrarray_prop (const char *name, GPtrArray *values)
1212{
1213 SmProp *prop;
1214 SmPropValue pv;
1215 GArray *vals;
1216 guint i;
1217
1218 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1219 prop->name = (char *)name;
1220 prop->type = (char *)SmLISTofARRAY8"LISTofARRAY8";
1221
1222 vals = g_array_new (FALSE(0), FALSE(0), sizeof (SmPropValue));
1223
1224 for (i = 0; i < values->len; i++)
1225 {
1226 pv.length = strlen (values->pdata[i]);
1227 pv.value = values->pdata[i];
1228 g_array_append_val (vals, pv)g_array_append_vals (vals, &(pv), 1);
1229 }
1230
1231 prop->num_vals = vals->len;
1232 prop->vals = (SmPropValue *)vals->data;
1233
1234 g_array_free (vals, FALSE(0));
1235
1236 return prop;
1237}
1238
1239/* Takes a string and creates an ARRAY8 property. The string is
1240 * neither dupped nor freed; it needs to remain valid until you're
1241 * done with the SmProp.
1242 */
1243static SmProp *
1244string_prop (const char *name, const char *value)
1245{
1246 SmProp *prop;
1247
1248 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1249 prop->name = (char *)name;
1250 prop->type = (char *)SmARRAY8"ARRAY8";
1251
1252 prop->num_vals = 1;
1253 prop->vals = g_new (SmPropValue, 1)((SmPropValue *) g_malloc_n ((1), sizeof (SmPropValue)));
1254
1255 prop->vals[0].length = strlen (value);
1256 prop->vals[0].value = (char *)value;
1257
1258 return prop;
1259}
1260
1261/* Takes a char and creates a CARD8 property. */
1262static SmProp *
1263card8_prop (const char *name, unsigned char value)
1264{
1265 SmProp *prop;
1266 char *card8val;
1267
1268 /* To avoid having to allocate and free prop->vals[0], we cheat and
1269 * make vals a 2-element-long array and then use the second element
1270 * to store value.
1271 */
1272
1273 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1274 prop->name = (char *)name;
1275 prop->type = (char *)SmCARD8"CARD8";
1276
1277 prop->num_vals = 1;
1278 prop->vals = g_new (SmPropValue, 2)((SmPropValue *) g_malloc_n ((2), sizeof (SmPropValue)));
1279 card8val = (char *)(&prop->vals[1]);
1280 card8val[0] = value;
1281
1282 prop->vals[0].length = 1;
1283 prop->vals[0].value = card8val;
1284
1285 return prop;
1286}
1287
1288/* ICE code. This makes no effort to play nice with anyone else trying
1289 * to use libICE. Fortunately, no one uses libICE for anything other
1290 * than SM. (DCOP uses ICE, but it has its own private copy of
1291 * libICE.)
1292 *
1293 * When this moves to gtk, it will need to be cleverer, to avoid
1294 * tripping over old apps that use MateClient or that use libSM
1295 * directly.
1296 */
1297
1298#include <X11/ICE/ICElib.h>
1299#include <fcntl.h>
1300
1301static void ice_error_handler (IceConn ice_conn,
1302 Boolint swap,
1303 int offending_minor_opcode,
1304 unsigned long offending_sequence,
1305 int error_class,
1306 int severity,
1307 IcePointer values);
1308static void ice_io_error_handler (IceConn ice_conn);
1309static void ice_connection_watch (IceConn ice_conn,
1310 IcePointer client_data,
1311 Boolint opening,
1312 IcePointer *watch_data);
1313
1314static void
1315ice_init (void)
1316{
1317 IceSetIOErrorHandler (ice_io_error_handler);
1318 IceSetErrorHandler (ice_error_handler);
1319 IceAddConnectionWatch (ice_connection_watch, NULL((void*)0));
1320}
1321
1322static gboolean
1323process_ice_messages (IceConn ice_conn)
1324{
1325 IceProcessMessagesStatus status;
1326 status = IceProcessMessages (ice_conn, NULL((void*)0), NULL((void*)0));
1327
1328 switch (status)
1329 {
1330 case IceProcessMessagesSuccess:
1331 return TRUE(!(0));
1332
1333 case IceProcessMessagesIOError:
1334 sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
1335 return FALSE(0);
1336
1337 case IceProcessMessagesConnectionClosed:
1338 return FALSE(0);
1339
1340 default:
1341 g_assert_not_reached ()do { g_assertion_message_expr ("EggSMClient", "eggsmclient-xsmp.c"
, 1341, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1342 }
1343}
1344
1345static gboolean
1346ice_iochannel_watch (GIOChannel *channel,
1347 GIOCondition condition,
1348 gpointer client_data)
1349{
1350 return process_ice_messages (client_data);
1351}
1352
1353static void
1354ice_connection_watch (IceConn ice_conn,
1355 IcePointer client_data,
1356 Boolint opening,
1357 IcePointer *watch_data)
1358{
1359 guint watch_id;
1360
1361 if (opening)
1362 {
1363 GIOChannel *channel;
1364 int fd = IceConnectionNumber (ice_conn);
1365
1366 fcntl (fd, F_SETFD2, fcntl (fd, F_GETFD1, 0) | FD_CLOEXEC1);
1367 channel = g_io_channel_unix_new (fd);
1368 watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
1369 ice_iochannel_watch, ice_conn);
1370 g_io_channel_unref (channel);
1371
1372 *watch_data = GUINT_TO_POINTER (watch_id)((gpointer) (gulong) (watch_id));
1373 }
1374 else
1375 {
1376 watch_id = GPOINTER_TO_UINT (*watch_data)((guint) (gulong) (*watch_data));
1377 g_source_remove (watch_id);
1378 }
1379}
1380
1381static void
1382ice_error_handler (IceConn ice_conn,
1383 Boolint swap,
1384 int offending_minor_opcode,
1385 unsigned long offending_sequence,
1386 int error_class,
1387 int severity,
1388 IcePointer values)
1389{
1390 /* Do nothing */
1391}
1392
1393static void
1394ice_io_error_handler (IceConn ice_conn)
1395{
1396 /* Do nothing */
1397}
1398
1399static void
1400smc_error_handler (SmcConn smc_conn,
1401 Boolint swap,
1402 int offending_minor_opcode,
1403 unsigned long offending_sequence,
1404 int error_class,
1405 int severity,
1406 SmPointer values)
1407{
1408 /* Do nothing */
1409}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-bd4e55.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-bd4e55.html new file mode 100644 index 0000000..0cbe4e0 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-bd4e55.html @@ -0,0 +1,1197 @@ + + + +mate-session-check-accelerated-gl-helper.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-check-accelerated-gl-helper.c
Warning:line 462, column 17
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-check-accelerated-gl-helper.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -D PKGDATADIR="/usr/local/share/mate-session-manager" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-check-accelerated-gl-helper.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2010 Novell, Inc.
3 * Copyright (C) 2006-2009 Red Hat, Inc.
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Author:
21 * Vincent Untz <vuntz@gnome.org>
22 *
23 * Most of the code comes from desktop-effects [1], released under GPLv2+.
24 * desktop-effects was written by:
25 * Soren Sandmann <sandmann@redhat.com>
26 *
27 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
28 */
29
30/*
31 * Here's the rationale behind this helper, quoting Owen, in his mail to the
32 * release team:
33 * (http://mail.gnome.org/archives/release-team/2010-June/msg00079.html)
34 *
35 * """
36 * There are some limits to what we can do here automatically without
37 * knowing anything about the driver situation on the system. The basic
38 * problem is that there are all sorts of suck:
39 *
40 * * No GL at all. This typically only happens if a system is
41 * misconfigured.
42 *
43 * * Only software GL. This one is easy to detect. We have code in
44 * the Fedora desktop-effects tool, etc.
45 *
46 * * GL that isn't featureful enough. (Tiny texture size limits, no
47 * texture-from-pixmap, etc.) Possible to detect with more work, but
48 * largely a fringe case.
49 *
50 * * Buggy GL. This isn't possible to detect. Except for the case where
51 * all GL programs crash. For that reason, we probably don't want
52 * gnome-session to directly try and do any GL detection; better to
53 * use a helper binary.
54 *
55 * * Horribly slow hardware GL. We could theoretically develop some sort
56 * of benchmark, but it's a tricky area. And how slow is too slow?
57 * """
58 *
59 * Some other tools are doing similar checks:
60 * - desktop-effects (Fedora Config Tool) [1]
61 * - drak3d (Mandriva Config Tool) [2]
62 * - compiz-manager (Compiz wrapper) [3]
63 *
64 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
65 * [2] http://svn.mandriva.com/cgi-bin/viewvc.cgi/soft/drak3d/trunk/lib/Xconfig/glx.pm?view=markup
66 * [3] http://git.compiz.org/fusion/misc/compiz-manager/tree/compiz-manager
67 */
68
69/* for strcasestr */
70#define _GNU_SOURCE
71
72#include <ctype.h>
73#include <locale.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <glib.h>
78
79#include <regex.h>
80
81#ifdef __FreeBSD__
82#include <kenv.h>
83#endif
84
85#include <X11/Xlib.h>
86#include <X11/Xatom.h>
87#include <X11/extensions/Xcomposite.h>
88#include <GL/gl.h>
89#include <GL/glx.h>
90
91#include "mate-session-check-accelerated-common.h"
92
93#define SIZE_UNSET0 0
94#define SIZE_ERROR-1 -1
95static int max_texture_size = SIZE_UNSET0;
96static int max_renderbuffer_size = SIZE_UNSET0;
97static gboolean has_llvmpipe = FALSE(0);
98
99static inline void
100_print_error (const char *str)
101{
102 fprintf (stderrstderr, "mate-session-is-accelerated: %s\n", str);
103}
104
105#define CMDLINE_UNSET-1 -1
106#define CMDLINE_NON_FALLBACK_FORCED0 0
107#define CMDLINE_FALLBACK_FORCED1 1
108
109#if defined(__linux__1)
110static int
111_parse_kcmdline (void)
112{
113 int ret = CMDLINE_UNSET-1;
114 GRegex *regex;
115 GMatchInfo *match;
116 char *contents;
117 char *word;
118 const char *arg;
119
120 if (!g_file_get_contents ("/proc/cmdline", &contents, NULL((void*)0), NULL((void*)0)))
121 return ret;
122
123 regex = g_regex_new ("mate.fallback=(\\S+)", 0, G_REGEX_MATCH_NOTEMPTY, NULL((void*)0));
124 if (!g_regex_match (regex, contents, G_REGEX_MATCH_NOTEMPTY, &match))
125 goto out;
126
127 word = g_match_info_fetch (match, 0);
128 g_debug ("Found command-line match '%s'", word);
129 arg = word + strlen ("mate.fallback=");
130 if (*arg != '0' && *arg != '1')
131 fprintf (stderrstderr, "mate-session-check-accelerated: Invalid value '%s' for mate.fallback passed in kernel command line.\n", arg);
132 else
133 ret = atoi (arg);
134 g_free (word);
135
136out:
137 g_match_info_free (match);
138 g_regex_unref (regex);
139 g_free (contents);
140
141 g_debug ("Command-line parsed to %d", ret);
142
143 return ret;
144}
145#elif defined(__FreeBSD__)
146static int
147_parse_kcmdline (void)
148{
149 int ret = CMDLINE_UNSET-1;
150 char value[KENV_MVALLEN];
151
152 /* a compile time check to avoid unexpected stack overflow */
153 _Static_assert(KENV_MVALLEN < 1024 * 1024, "KENV_MVALLEN is too large");
154
155 if (kenv (KENV_GET, "mate.fallback", value, KENV_MVALLEN) == -1)
156 return ret;
157
158 if (*value != '0' && *value != '1')
159 fprintf (stderrstderr, "mate-session-is-accelerated: Invalid value '%s' for mate.fallback passed in kernel environment.\n", value);
160 else
161 ret = atoi (value);
162
163 g_debug ("Kernel environment parsed to %d", ret);
164
165 return ret;
166}
167#else
168static int
169_parse_kcmdline (void)
170{
171 return CMDLINE_UNSET-1;
172}
173#endif
174
175static gboolean
176_has_composite (Display *display)
177{
178 int dummy1, dummy2;
179
180 return XCompositeQueryExtension (display, &dummy1, &dummy2);
181}
182
183static gboolean
184_is_comment (const char *line)
185{
186 while (*line && isspace(*line)((*__ctype_b_loc ())[(int) ((*line))] & (unsigned short int
) _ISspace)
)
187 line++;
188
189 if (*line == '#' || *line == '\0')
190 return TRUE(!(0));
191 return FALSE(0);
192}
193
194static gboolean
195_is_gl_renderer_blacklisted (const char *renderer)
196{
197 FILE *blacklist;
198 char *line = NULL((void*)0);
199 size_t line_len = 0;
200 gboolean ret = TRUE(!(0));
201
202 blacklist = fopen(PKGDATADIR"/usr/local/share/mate-session-manager" "/hardware-compatibility", "r");
203 if (blacklist == NULL((void*)0))
204 goto out;
205
206 while (getline (&line, &line_len, blacklist) != -1) {
207 int whitelist = 0;
208 const char *re_str;
209 regex_t re;
210 int status;
211
212 if (line == NULL((void*)0))
213 break;
214
215 /* Drop trailing \n */
216 line[strlen(line) - 1] = '\0';
217
218 if (_is_comment (line)) {
219 free (line);
220 line = NULL((void*)0);
221 continue;
222 }
223
224 if (line[0] == '+')
225 whitelist = 1;
226 else if (line[0] == '-')
227 whitelist = 0;
228 else {
229 _print_error ("Invalid syntax in this line for hardware compatibility:");
230 _print_error (line);
231 free (line);
232 line = NULL((void*)0);
233 continue;
234 }
235
236 re_str = line + 1;
237
238 if (regcomp (&re, re_str, REG_EXTENDED1|REG_ICASE(1 << 1)|REG_NOSUB(1 << 3)) != 0) {
239 _print_error ("Cannot use this regular expression for hardware compatibility:");
240 _print_error (re_str);
241 } else {
242 status = regexec (&re, renderer, 0, NULL((void*)0), 0);
243 regfree(&re);
244
245 if (status == 0) {
246 if (whitelist)
247 ret = FALSE(0);
248 goto out;
249 }
250 }
251
252 free (line);
253 line = NULL((void*)0);
254 }
255
256 ret = FALSE(0);
257
258out:
259 if (line != NULL((void*)0))
260 free (line);
261
262 if (blacklist != NULL((void*)0))
263 fclose (blacklist);
264
265 return ret;
266}
267
268static char *
269_get_hardware_gl (Display *display)
270{
271 int screen;
272 Window root;
273 XVisualInfo *visual = NULL((void*)0);
274 GLXContext context = NULL((void*)0);
275 XSetWindowAttributes cwa = { 0 };
276 Window window = None0L;
277 char *renderer = NULL((void*)0);
278
279 int attrlist[] = {
280 GLX_RGBA4,
281 GLX_RED_SIZE8, 1,
282 GLX_GREEN_SIZE9, 1,
283 GLX_BLUE_SIZE10, 1,
284 GLX_DOUBLEBUFFER5,
285 None0L
286 };
287
288 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
289 root = RootWindow (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
;
290
291 visual = glXChooseVisual (display, screen, attrlist);
292 if (!visual)
293 goto out;
294
295 context = glXCreateContext (display, visual, NULL((void*)0), True1);
296 if (!context)
297 goto out;
298
299 cwa.colormap = XCreateColormap (display, root,
300 visual->visual, AllocNone0);
301 cwa.background_pixel = 0;
302 cwa.border_pixel = 0;
303 window = XCreateWindow (display, root,
304 0, 0, 1, 1, 0,
305 visual->depth, InputOutput1, visual->visual,
306 CWColormap(1L<<13) | CWBackPixel(1L<<1) | CWBorderPixel(1L<<3),
307 &cwa);
308
309 if (!glXMakeCurrent (display, window, context))
310 goto out;
311
312 renderer = g_strdup ((const char *) glGetString (GL_RENDERER))g_strdup_inline ((const char *) glGetString (0x1F01));
313 if (_is_gl_renderer_blacklisted (renderer)) {
314 g_clear_pointer (&renderer, g_free)do { _Static_assert (sizeof *(&renderer) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ ((&renderer
)) _pp = (&renderer); __typeof__ (*(&renderer)) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_free) (_ptr); } while (
0)
;
315 goto out;
316 }
317 if (renderer && strcasestr (renderer, "llvmpipe"))
318 has_llvmpipe = TRUE(!(0));
319
320 /* we need to get the max texture and renderbuffer sizes while we have
321 * a context, but we'll check their values later */
322
323 glGetIntegerv (GL_MAX_TEXTURE_SIZE0x0D33, &max_texture_size);
324 if (glGetError() != GL_NO_ERROR0)
325 max_texture_size = SIZE_ERROR-1;
326
327 glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE_EXT0x84E8, &max_renderbuffer_size);
328 if (glGetError() != GL_NO_ERROR0)
329 max_renderbuffer_size = SIZE_ERROR-1;
330
331out:
332 glXMakeCurrent (display, None0L, None0L);
333 if (context)
334 glXDestroyContext (display, context);
335 if (window)
336 XDestroyWindow (display, window);
337 if (cwa.colormap)
338 XFreeColormap (display, cwa.colormap);
339
340 return renderer;
341}
342
343static gboolean
344_has_extension (const char *extension_list,
345 const char *extension)
346{
347 char **extensions;
348 guint i;
349 gboolean ret;
350
351 g_return_val_if_fail (extension != NULL, TRUE)do { if ((extension != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "extension != NULL"
); return ((!(0))); } } while (0)
;
352
353 /* Extension_list is one big string, containing extensions
354 * separated by spaces. */
355 if (extension_list == NULL((void*)0))
356 return FALSE(0);
357
358 ret = FALSE(0);
359
360 extensions = g_strsplit (extension_list, " ", -1);
361 if (extensions == NULL((void*)0))
362 return FALSE(0);
363
364 for (i = 0; extensions[i] != NULL((void*)0); i++) {
365 if (g_str_equal (extensions[i], extension)(strcmp ((const char *) (extensions[i]), (const char *) (extension
)) == 0)
) {
366 ret = TRUE(!(0));
367 break;
368 }
369 }
370
371 g_strfreev (extensions);
372
373 return ret;
374}
375
376static gboolean
377_has_texture_from_pixmap (Display *display)
378{
379 int screen;
380 const char *server_extensions;
381 const char *client_extensions;
382 gboolean ret = FALSE(0);
383
384 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
385
386 server_extensions = glXQueryServerString (display, screen,
387 GLX_EXTENSIONS3);
388 if (!_has_extension (server_extensions,
389 "GLX_EXT_texture_from_pixmap"))
390 goto out;
391
392 client_extensions = glXGetClientString (display, GLX_EXTENSIONS3);
393 if (!_has_extension (client_extensions,
394 "GLX_EXT_texture_from_pixmap"))
395 goto out;
396
397 ret = TRUE(!(0));
398
399out:
400 return ret;
401}
402
403static void
404_set_max_screen_size_property (Display *display, int screen, int size)
405{
406 Atom max_screen_size_atom;
407
408 max_screen_size_atom = XInternAtom (display, "_GNOME_MAX_SCREEN_SIZE",
409 False0);
410
411 /* Will be read by gnome-settings-daemon and
412 * gnome-control-center to avoid display configurations where 3D
413 * is not available (and would break gnome-shell) */
414 XChangeProperty (display, RootWindow(display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
,
415 max_screen_size_atom,
416 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
417 (unsigned char *)&size, 1);
418
419 XSync(display, False0);
420}
421
422static gboolean
423_is_max_texture_size_big_enough (Display *display)
424{
425 int screen, size;
426
427 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
428 size = MIN(max_renderbuffer_size, max_texture_size)(((max_renderbuffer_size) < (max_texture_size)) ? (max_renderbuffer_size
) : (max_texture_size))
;
429 if (size < DisplayWidth (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->width
)
||
430 size < DisplayHeight (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->height
)
)
431 return FALSE(0);
432
433 _set_max_screen_size_property (display, screen, size);
434
435 return TRUE(!(0));
436}
437
438static gboolean print_renderer = FALSE(0);
439
440static const GOptionEntry entries[] = {
441 { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print GL renderer name", NULL((void*)0) },
442 { NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0) },
443};
444
445int
446main (int argc, char **argv)
447{
448 int kcmdline_parsed;
449 Display *display = NULL((void*)0);
450 int ret = HELPER_NO_ACCEL1;
451 GOptionContext *context;
452 GError *error = NULL((void*)0);
453 char *renderer = NULL((void*)0);
454
455 setlocale (LC_ALL6, "");
456
457 context = g_option_context_new (NULL((void*)0));
458 g_option_context_add_main_entries (context, entries, NULL((void*)0));
459
460 if (!g_option_context_parse (context, &argc, &argv, &error)) {
461 g_error ("Can't parse command line: %s\n", error->message);
462 g_error_free (error);
This statement is never executed
463 goto out;
464 }
465
466 kcmdline_parsed = _parse_kcmdline ();
467 if (kcmdline_parsed > CMDLINE_UNSET-1) {
468 if (kcmdline_parsed == CMDLINE_NON_FALLBACK_FORCED0) {
469 _print_error ("Non-fallback mode forced by kernel command line.");
470 ret = HELPER_ACCEL0;
471 goto out;
472 } else if (kcmdline_parsed == CMDLINE_FALLBACK_FORCED1) {
473 _print_error ("Fallback mode forced by kernel command line.");
474 goto out;
475 }
476 }
477
478 display = XOpenDisplay (NULL((void*)0));
479 if (!display) {
480 _print_error ("No X display.");
481 goto out;
482 }
483
484 if (!_has_composite (display)) {
485 _print_error ("No composite extension.");
486 goto out;
487 }
488
489 renderer = _get_hardware_gl (display);
490 if (!renderer) {
491 _print_error ("No hardware 3D support.");
492 goto out;
493 }
494
495 if (!_has_texture_from_pixmap (display)) {
496 _print_error ("No GLX_EXT_texture_from_pixmap support.");
497 goto out;
498 }
499
500 if (!_is_max_texture_size_big_enough (display)) {
501 _print_error ("GL_MAX_{TEXTURE,RENDERBUFFER}_SIZE is too small.");
502 goto out;
503 }
504
505 ret = has_llvmpipe ? HELPER_SOFTWARE_RENDERING2 : HELPER_ACCEL0;
506
507 if (print_renderer)
508 g_print ("%s", renderer);
509
510out:
511 if (display)
512 XCloseDisplay (display);
513 g_option_context_free (context);
514 g_free (renderer);
515
516 return ret;
517}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cd0613.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cd0613.html new file mode 100644 index 0000000..4093616 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cd0613.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 283, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
This statement is never executed
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cf3974.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cf3974.html new file mode 100644 index 0000000..df7411a --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-cf3974.html @@ -0,0 +1,2089 @@ + + + +eggsmclient-xsmp.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-submodules/libegg/eggsmclient-xsmp.c
Warning:line 1232, column 18
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name eggsmclient-xsmp.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-submodules/libegg -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D EGG_SM_CLIENT_BACKEND_XSMP -D G_LOG_DOMAIN="EggSMClient" -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D PIC -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-submodules/libegg -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c eggsmclient-xsmp.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2007 Novell, Inc.
3 *
4 * Inspired by various other pieces of code including GsmClient (C)
5 * 2001 Havoc Pennington, MateClient (C) 1998 Carsten Schaar, and twm
6 * session code (C) 1998 The Open Group.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "config.h"
25
26#include "eggsmclient.h"
27#include "eggsmclient-private.h"
28
29#include "eggdesktopfile.h"
30
31#include <errno(*__errno_location ()).h>
32#include <fcntl.h>
33#include <stdlib.h>
34#include <string.h>
35#include <unistd.h>
36#include <X11/SM/SMlib.h>
37
38#include <gtk/gtk.h>
39#include <gdk/gdk.h>
40
41#ifdef GDK_WINDOWING_X11
42#include <gdk/gdkx.h>
43#endif
44
45#define EGG_TYPE_SM_CLIENT_XSMP(egg_sm_client_xsmp_get_type ()) (egg_sm_client_xsmp_get_type ())
46#define EGG_SM_CLIENT_XSMP(obj)((((EggSMClientXSMP*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((egg_sm_client_xsmp_get_type ()))))))
(G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP)(((EggSMClientXSMP*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((obj)), ((egg_sm_client_xsmp_get_type ())))))
)
47#define EGG_SM_CLIENT_XSMP_CLASS(klass)((((EggSMClientXSMPClass*) (void *) g_type_check_class_cast (
(GTypeClass*) ((klass)), ((egg_sm_client_xsmp_get_type ()))))
))
(G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)(((EggSMClientXSMPClass*) (void *) g_type_check_class_cast ((
GTypeClass*) ((klass)), ((egg_sm_client_xsmp_get_type ())))))
)
48#define EGG_IS_SM_CLIENT_XSMP(obj)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(obj)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(obj)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))
)
49#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean __r
; if (!__class) __r = (0); else if (__class->g_type == __t
) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; }))))
(G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((egg_sm_client_xsmp_get_type ())); gboolean __r
; if (!__class) __r = (0); else if (__class->g_type == __t
) __r = (!(0)); else __r = g_type_check_class_is_a (__class, __t
); __r; })))
)
50#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj)((((EggSMClientXSMPClass*) (((GTypeInstance*) ((obj)))->g_class
))))
(G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)(((EggSMClientXSMPClass*) (((GTypeInstance*) ((obj)))->g_class
)))
)
51
52typedef struct _EggSMClientXSMP EggSMClientXSMP;
53typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass;
54
55/* These mostly correspond to the similarly-named states in section
56 * 9.1 of the XSMP spec. Some of the states there aren't represented
57 * here, because we don't need them. SHUTDOWN_CANCELLED is slightly
58 * different from the spec; we use it when the client is IDLE after a
59 * ShutdownCancelled message, but the application is still interacting
60 * and doesn't know the shutdown has been cancelled yet.
61 */
62typedef enum
63{
64 XSMP_STATE_IDLE,
65 XSMP_STATE_SAVE_YOURSELF,
66 XSMP_STATE_INTERACT_REQUEST,
67 XSMP_STATE_INTERACT,
68 XSMP_STATE_SAVE_YOURSELF_DONE,
69 XSMP_STATE_SHUTDOWN_CANCELLED,
70 XSMP_STATE_CONNECTION_CLOSED
71} EggSMClientXSMPState;
72
73static const char *state_names[] =
74{
75 "idle",
76 "save-yourself",
77 "interact-request",
78 "interact",
79 "save-yourself-done",
80 "shutdown-cancelled",
81 "connection-closed"
82};
83
84#define EGG_SM_CLIENT_XSMP_STATE(xsmp)(state_names[(xsmp)->state]) (state_names[(xsmp)->state])
85
86struct _EggSMClientXSMP
87{
88 EggSMClient parent;
89
90 SmcConn connection;
91 char *client_id;
92
93 EggSMClientXSMPState state;
94 char **restart_command;
95 gboolean set_restart_command;
96 int restart_style;
97 char **discard_command;
98 gboolean set_discard_command;
99
100 guint idle;
101
102 /* Current SaveYourself state */
103 guint expecting_initial_save_yourself : 1;
104 guint need_save_state : 1;
105 guint need_quit_requested : 1;
106 guint interact_errors : 1;
107 guint shutting_down : 1;
108
109 /* Todo list */
110 guint waiting_to_set_initial_properties : 1;
111 guint waiting_to_emit_quit : 1;
112 guint waiting_to_emit_quit_cancelled : 1;
113 guint waiting_to_save_myself : 1;
114
115};
116
117struct _EggSMClientXSMPClass
118{
119 EggSMClientClass parent_class;
120
121};
122
123static void sm_client_xsmp_startup (EggSMClient *client,
124 const char *client_id);
125static void sm_client_xsmp_set_restart_command (EggSMClient *client,
126 int argc,
127 const char **argv);
128static void sm_client_xsmp_set_discard_command (EggSMClient *client,
129 int argc,
130 const char **argv);
131static void sm_client_xsmp_will_quit (EggSMClient *client,
132 gboolean will_quit);
133static gboolean sm_client_xsmp_end_session (EggSMClient *client,
134 EggSMClientEndStyle style,
135 gboolean request_confirmation);
136
137static void xsmp_save_yourself (SmcConn smc_conn,
138 SmPointer client_data,
139 int save_style,
140 Boolint shutdown,
141 int interact_style,
142 Boolint fast);
143static void xsmp_die (SmcConn smc_conn,
144 SmPointer client_data);
145static void xsmp_save_complete (SmcConn smc_conn,
146 SmPointer client_data);
147static void xsmp_shutdown_cancelled (SmcConn smc_conn,
148 SmPointer client_data);
149static void xsmp_interact (SmcConn smc_conn,
150 SmPointer client_data);
151
152static SmProp *array_prop (const char *name,
153 ...);
154static SmProp *ptrarray_prop (const char *name,
155 GPtrArray *values);
156static SmProp *string_prop (const char *name,
157 const char *value);
158static SmProp *card8_prop (const char *name,
159 unsigned char value);
160
161static void set_properties (EggSMClientXSMP *xsmp, ...);
162static void delete_properties (EggSMClientXSMP *xsmp, ...);
163
164static GPtrArray *generate_command (char **restart_command,
165 const char *client_id,
166 const char *state_file);
167
168static void save_state (EggSMClientXSMP *xsmp);
169static void do_save_yourself (EggSMClientXSMP *xsmp);
170static void update_pending_events (EggSMClientXSMP *xsmp);
171
172static void ice_init (void);
173static gboolean process_ice_messages (IceConn ice_conn);
174static void smc_error_handler (SmcConn smc_conn,
175 Boolint swap,
176 int offending_minor_opcode,
177 unsigned long offending_sequence,
178 int error_class,
179 int severity,
180 SmPointer values);
181
182G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT)static void egg_sm_client_xsmp_init (EggSMClientXSMP *self); static
void egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass
); static GType egg_sm_client_xsmp_get_type_once (void); static
gpointer egg_sm_client_xsmp_parent_class = ((void*)0); static
gint EggSMClientXSMP_private_offset; static void egg_sm_client_xsmp_class_intern_init
(gpointer klass) { egg_sm_client_xsmp_parent_class = g_type_class_peek_parent
(klass); if (EggSMClientXSMP_private_offset != 0) g_type_class_adjust_private_offset
(klass, &EggSMClientXSMP_private_offset); egg_sm_client_xsmp_class_init
((EggSMClientXSMPClass*) klass); } __attribute__ ((__unused__
)) static inline gpointer egg_sm_client_xsmp_get_instance_private
(EggSMClientXSMP *self) { return (((gpointer) ((guint8*) (self
) + (glong) (EggSMClientXSMP_private_offset)))); } GType egg_sm_client_xsmp_get_type
(void) { static gsize static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0));
(!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = egg_sm_client_xsmp_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType egg_sm_client_xsmp_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((egg_sm_client_get_type ()), g_intern_static_string ("EggSMClientXSMP"
), sizeof (EggSMClientXSMPClass), (GClassInitFunc)(void (*)(void
)) egg_sm_client_xsmp_class_intern_init, sizeof (EggSMClientXSMP
), (GInstanceInitFunc)(void (*)(void)) egg_sm_client_xsmp_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
183
184static void
185egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp)
186{
187 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
188 xsmp->connection = NULL((void*)0);
189 xsmp->restart_style = SmRestartIfRunning0;
190}
191
192static void
193egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass)
194{
195 EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass);
196
197 sm_client_class->startup = sm_client_xsmp_startup;
198 sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command;
199 sm_client_class->set_discard_command = sm_client_xsmp_set_discard_command;
200 sm_client_class->will_quit = sm_client_xsmp_will_quit;
201 sm_client_class->end_session = sm_client_xsmp_end_session;
202}
203
204EggSMClient *
205egg_sm_client_xsmp_new (void)
206{
207 if (!g_getenv ("SESSION_MANAGER"))
208 return NULL((void*)0);
209
210 return g_object_new (EGG_TYPE_SM_CLIENT_XSMP(egg_sm_client_xsmp_get_type ()), NULL((void*)0));
211}
212
213static gboolean
214sm_client_xsmp_set_initial_properties (gpointer user_data)
215{
216 EggSMClientXSMP *xsmp = user_data;
217 EggDesktopFile *desktop_file;
218 GPtrArray *clone, *restart;
219 char pid_str[64];
220
221 if (xsmp->idle)
222 {
223 g_source_remove (xsmp->idle);
224 xsmp->idle = 0;
225 }
226 xsmp->waiting_to_set_initial_properties = FALSE(0);
227
228 if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
229 xsmp->restart_style = SmRestartNever3;
230
231 /* Parse info out of desktop file */
232 desktop_file = egg_get_desktop_file ();
233 if (desktop_file)
234 {
235 GError *err = NULL((void*)0);
236 char **argv;
237 int argc;
238
239 if (xsmp->restart_style == SmRestartIfRunning0)
240 {
241 if (egg_desktop_file_get_boolean (desktop_file,
242 "X-MATE-AutoRestart", NULL((void*)0)))
243 xsmp->restart_style = SmRestartImmediately2;
244 }
245
246 if (!xsmp->set_restart_command)
247 {
248 char *cmdline;
249
250 cmdline = egg_desktop_file_parse_exec (desktop_file, NULL((void*)0), &err);
251 if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err))
252 {
253 egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp),
254 argc, (const char **)argv);
255 g_strfreev (argv);
256 }
257 else
258 {
259 g_warning ("Could not parse Exec line in desktop file: %s",
260 err->message);
261 g_error_free (err);
262 }
263 g_free (cmdline);
264 }
265 }
266
267 if (!xsmp->set_restart_command)
268 xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1);
269
270 clone = generate_command (xsmp->restart_command, NULL((void*)0), NULL((void*)0));
271 restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL((void*)0));
272
273 g_debug ("Setting initial properties");
274
275 /* Program, CloneCommand, RestartCommand, and UserID are required.
276 * ProcessID isn't required, but the SM may be able to do something
277 * useful with it.
278 */
279 g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ());
280 set_properties (xsmp,
281 string_prop (SmProgram"Program", g_get_prgname ()),
282 ptrarray_prop (SmCloneCommand"CloneCommand", clone),
283 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
284 string_prop (SmUserID"UserID", g_get_user_name ()),
285 string_prop (SmProcessID"ProcessID", pid_str),
286 card8_prop (SmRestartStyleHint"RestartStyleHint", xsmp->restart_style),
287 NULL((void*)0));
288 g_ptr_array_free (clone, TRUE(!(0)));
289 g_ptr_array_free (restart, TRUE(!(0)));
290
291 if (desktop_file)
292 {
293 set_properties (xsmp,
294 string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)),
295 NULL((void*)0));
296 }
297
298 update_pending_events (xsmp);
299 return FALSE(0);
300}
301
302/* This gets called from two different places: xsmp_die() (when the
303 * server asks us to disconnect) and process_ice_messages() (when the
304 * server disconnects unexpectedly).
305 */
306static void
307sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp)
308{
309 SmcConn connection;
310
311 if (!xsmp->connection)
312 return;
313
314 g_debug ("Disconnecting");
315
316 connection = xsmp->connection;
317 xsmp->connection = NULL((void*)0);
318 SmcCloseConnection (connection, 0, NULL((void*)0));
319 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
320
321 xsmp->waiting_to_save_myself = FALSE(0);
322 update_pending_events (xsmp);
323}
324
325static void
326sm_client_xsmp_startup (EggSMClient *client,
327 const char *client_id)
328{
329 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
330 SmcCallbacks callbacks;
331 char *ret_client_id;
332 char error_string_ret[256];
333
334 xsmp->client_id = g_strdup (client_id)g_strdup_inline (client_id);
335
336 ice_init ();
337 SmcSetErrorHandler (smc_error_handler);
338
339 callbacks.save_yourself.callback = xsmp_save_yourself;
340 callbacks.die.callback = xsmp_die;
341 callbacks.save_complete.callback = xsmp_save_complete;
342 callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
343
344 callbacks.save_yourself.client_data = xsmp;
345 callbacks.die.client_data = xsmp;
346 callbacks.save_complete.client_data = xsmp;
347 callbacks.shutdown_cancelled.client_data = xsmp;
348
349 client_id = NULL((void*)0);
350 error_string_ret[0] = '\0';
351 xsmp->connection =
352 SmcOpenConnection (NULL((void*)0), xsmp, SmProtoMajor1, SmProtoMinor0,
353 SmcSaveYourselfProcMask(1L << 0) | SmcDieProcMask(1L << 1) |
354 SmcSaveCompleteProcMask(1L << 2) |
355 SmcShutdownCancelledProcMask(1L << 3),
356 &callbacks,
357 xsmp->client_id, &ret_client_id,
358 sizeof (error_string_ret), error_string_ret);
359
360 if (!xsmp->connection)
361 {
362 g_warning ("Failed to connect to the session manager: %s\n",
363 error_string_ret[0] ?
364 error_string_ret : "no error message given");
365 xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
366 return;
367 }
368
369 /* We expect a pointless initial SaveYourself if either (a) we
370 * didn't have an initial client ID, or (b) we DID have an initial
371 * client ID, but the server rejected it and gave us a new one.
372 */
373 if (!xsmp->client_id ||
374 (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
375 xsmp->expecting_initial_save_yourself = TRUE(!(0));
376
377 if (ret_client_id)
378 {
379 g_free (xsmp->client_id);
380 xsmp->client_id = g_strdup (ret_client_id)g_strdup_inline (ret_client_id);
381 free (ret_client_id);
382
383#ifdef GDK_WINDOWING_X11
384 if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(gdk_display_get_default ())); GType __t = ((gdk_x11_display_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; }))))
)
385 gdk_x11_set_sm_client_id (xsmp->client_id);
386#endif
387
388 g_debug ("Got client ID \"%s\"", xsmp->client_id);
389 }
390
391 xsmp->state = XSMP_STATE_IDLE;
392
393 /* Do not set the initial properties until we reach the main loop,
394 * so that the application has a chance to call
395 * egg_set_desktop_file(). (This may also help the session manager
396 * have a better idea of when the application is fully up and
397 * running.)
398 */
399 xsmp->waiting_to_set_initial_properties = TRUE(!(0));
400 xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
401}
402
403static void
404sm_client_xsmp_set_restart_command (EggSMClient *client,
405 int argc,
406 const char **argv)
407{
408 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
409 int i;
410
411 g_strfreev (xsmp->restart_command);
412
413 xsmp->restart_command = g_new (char *, argc + 1)((char * *) g_malloc_n ((argc + 1), sizeof (char *)));
414 for (i = 0; i < argc; i++)
415 xsmp->restart_command[i] = g_strdup (argv[i])g_strdup_inline (argv[i]);
416 xsmp->restart_command[i] = NULL((void*)0);
417
418 xsmp->set_restart_command = TRUE(!(0));
419}
420
421static void
422sm_client_xsmp_set_discard_command (EggSMClient *client,
423 int argc,
424 const char **argv)
425{
426 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
427 int i;
428
429 g_strfreev (xsmp->discard_command);
430
431 xsmp->discard_command = g_new (char *, argc + 1)((char * *) g_malloc_n ((argc + 1), sizeof (char *)));
432 for (i = 0; i < argc; i++)
433 xsmp->discard_command[i] = g_strdup (argv[i])g_strdup_inline (argv[i]);
434 xsmp->discard_command[i] = NULL((void*)0);
435
436 xsmp->set_discard_command = TRUE(!(0));
437}
438
439static void
440sm_client_xsmp_will_quit (EggSMClient *client,
441 gboolean will_quit)
442{
443 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
444
445 if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED)
446 {
447 /* The session manager has already exited! Schedule a quit
448 * signal.
449 */
450 xsmp->waiting_to_emit_quit = TRUE(!(0));
451 update_pending_events (xsmp);
452 return;
453 }
454 else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
455 {
456 /* We received a ShutdownCancelled message while the application
457 * was interacting; Schedule a quit_cancelled signal.
458 */
459 xsmp->waiting_to_emit_quit_cancelled = TRUE(!(0));
460 update_pending_events (xsmp);
461 return;
462 }
463
464 g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT)do { if ((xsmp->state == XSMP_STATE_INTERACT)) { } else { g_return_if_fail_warning
("EggSMClient", ((const char*) (__func__)), "xsmp->state == XSMP_STATE_INTERACT"
); return; } } while (0)
;
465
466 g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True");
467 SmcInteractDone (xsmp->connection, !will_quit);
468
469 if (will_quit && xsmp->need_save_state)
470 save_state (xsmp);
471
472 g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False");
473 SmcSaveYourselfDone (xsmp->connection, will_quit);
474 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
475}
476
477static gboolean
478sm_client_xsmp_end_session (EggSMClient *client,
479 EggSMClientEndStyle style,
480 gboolean request_confirmation)
481{
482 EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
483 int save_type;
484
485 /* To end the session via XSMP, we have to send a
486 * SaveYourselfRequest. We aren't allowed to do that if anything
487 * else is going on, but we don't want to expose this fact to the
488 * application. So we do our best to patch things up here...
489 *
490 * In the worst case, this method might block for some length of
491 * time in process_ice_messages, but the only time that code path is
492 * honestly likely to get hit is if the application tries to end the
493 * session as the very first thing it does, in which case it
494 * probably won't actually block anyway. It's not worth gunking up
495 * the API to try to deal nicely with the other 0.01% of cases where
496 * this happens.
497 */
498
499 while (xsmp->state != XSMP_STATE_IDLE ||
500 xsmp->expecting_initial_save_yourself)
501 {
502 /* If we're already shutting down, we don't need to do anything. */
503 if (xsmp->shutting_down)
504 return TRUE(!(0));
505
506 switch (xsmp->state)
507 {
508 case XSMP_STATE_CONNECTION_CLOSED:
509 return FALSE(0);
510
511 case XSMP_STATE_SAVE_YOURSELF:
512 /* Trying to log out from the save_state callback? Whatever.
513 * Abort the save_state.
514 */
515 SmcSaveYourselfDone (xsmp->connection, FALSE(0));
516 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
517 break;
518
519 case XSMP_STATE_INTERACT_REQUEST:
520 case XSMP_STATE_INTERACT:
521 case XSMP_STATE_SHUTDOWN_CANCELLED:
522 /* Already in a shutdown-related state, just ignore
523 * the new shutdown request...
524 */
525 return TRUE(!(0));
526
527 case XSMP_STATE_IDLE:
528 if (xsmp->waiting_to_set_initial_properties)
529 sm_client_xsmp_set_initial_properties (xsmp);
530
531 if (!xsmp->expecting_initial_save_yourself)
532 break;
533 /* else fall through */
534
535 case XSMP_STATE_SAVE_YOURSELF_DONE:
536 /* We need to wait for some response from the server.*/
537 process_ice_messages (SmcGetIceConnection (xsmp->connection));
538 break;
539
540 default:
541 /* Hm... shouldn't happen */
542 return FALSE(0);
543 }
544 }
545
546 /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and
547 * the user chooses to save the session. But mate-session will do
548 * the wrong thing if we pass SmSaveBoth and the user chooses NOT to
549 * save the session... Sigh.
550 */
551 if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session"))
552 save_type = SmSaveBoth2;
553 else
554 save_type = SmSaveGlobal0;
555
556 g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : "");
557 SmcRequestSaveYourself (xsmp->connection,
558 save_type,
559 True1, /* shutdown */
560 SmInteractStyleAny2,
561 !request_confirmation, /* fast */
562 True1 /* global */);
563 return TRUE(!(0));
564}
565
566static gboolean
567idle_do_pending_events (gpointer data)
568{
569 EggSMClientXSMP *xsmp = data;
570 EggSMClient *client = data;
571
572 xsmp->idle = 0;
573
574 if (xsmp->waiting_to_emit_quit)
575 {
576 xsmp->waiting_to_emit_quit = FALSE(0);
577 egg_sm_client_quit (client);
578 goto out;
579 }
580
581 if (xsmp->waiting_to_emit_quit_cancelled)
582 {
583 xsmp->waiting_to_emit_quit_cancelled = FALSE(0);
584 egg_sm_client_quit_cancelled (client);
585 xsmp->state = XSMP_STATE_IDLE;
586 }
587
588 if (xsmp->waiting_to_save_myself)
589 {
590 xsmp->waiting_to_save_myself = FALSE(0);
591 do_save_yourself (xsmp);
592 }
593
594out:
595 return FALSE(0);
596}
597
598static void
599update_pending_events (EggSMClientXSMP *xsmp)
600{
601 gboolean want_idle =
602 xsmp->waiting_to_emit_quit ||
603 xsmp->waiting_to_emit_quit_cancelled ||
604 xsmp->waiting_to_save_myself;
605
606 if (want_idle)
607 {
608 if (xsmp->idle == 0)
609 xsmp->idle = g_idle_add (idle_do_pending_events, xsmp);
610 }
611 else
612 {
613 if (xsmp->idle != 0)
614 g_source_remove (xsmp->idle);
615 xsmp->idle = 0;
616 }
617}
618
619static void
620fix_broken_state (EggSMClientXSMP *xsmp, const char *message,
621 gboolean send_interact_done,
622 gboolean send_save_yourself_done)
623{
624 g_warning ("Received XSMP %s message in state %s: client or server error",
625 message, EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
626
627 /* Forget any pending SaveYourself plans we had */
628 xsmp->waiting_to_save_myself = FALSE(0);
629 update_pending_events (xsmp);
630
631 if (send_interact_done)
632 SmcInteractDone (xsmp->connection, False0);
633 if (send_save_yourself_done)
634 SmcSaveYourselfDone (xsmp->connection, True1);
635
636 xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE;
637}
638
639/* SM callbacks */
640
641static void
642xsmp_save_yourself (SmcConn smc_conn,
643 SmPointer client_data,
644 int save_type,
645 Boolint shutdown,
646 int interact_style,
647 Boolint fast)
648{
649 EggSMClientXSMP *xsmp = client_data;
650 gboolean wants_quit_requested;
651
652 g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s",
653 save_type == SmSaveLocal1 ? "SmSaveLocal" :
654 save_type == SmSaveGlobal0 ? "SmSaveGlobal" : "SmSaveBoth",
655 shutdown ? "Shutdown" : "!Shutdown",
656 interact_style == SmInteractStyleAny2 ? "SmInteractStyleAny" :
657 interact_style == SmInteractStyleErrors1 ? "SmInteractStyleErrors" :
658 "SmInteractStyleNone", fast ? "Fast" : "!Fast",
659 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
660
661 if (xsmp->state != XSMP_STATE_IDLE &&
662 xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED)
663 {
664 fix_broken_state (xsmp, "SaveYourself", FALSE(0), TRUE(!(0)));
665 return;
666 }
667
668 if (xsmp->waiting_to_set_initial_properties)
669 sm_client_xsmp_set_initial_properties (xsmp);
670
671 /* If this is the initial SaveYourself, ignore it; we've already set
672 * properties and there's no reason to actually save state too.
673 */
674 if (xsmp->expecting_initial_save_yourself)
675 {
676 xsmp->expecting_initial_save_yourself = FALSE(0);
677
678 if (save_type == SmSaveLocal1 &&
679 interact_style == SmInteractStyleNone0 &&
680 !shutdown && !fast)
681 {
682 g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself");
683 SmcSaveYourselfDone (xsmp->connection, True1);
684 /* As explained in the comment at the end of
685 * do_save_yourself(), SAVE_YOURSELF_DONE is the correct
686 * state here, not IDLE.
687 */
688 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
689 return;
690 }
691 else
692 g_warning ("First SaveYourself was not the expected one!");
693 }
694
695 /* Even ignoring the "fast" flag completely, there are still 18
696 * different combinations of save_type, shutdown and interact_style.
697 * We interpret them as follows:
698 *
699 * Type Shutdown Interact Interpretation
700 * G F A/E/N do nothing (1)
701 * G T N do nothing (1)*
702 * G T A/E quit_requested (2)
703 * L/B F A/E/N save_state (3)
704 * L/B T N save_state (3)*
705 * L/B T A/E quit_requested, then save_state (4)
706 *
707 * 1. Do nothing, because the SM asked us to do something
708 * uninteresting (save open files, but then don't quit
709 * afterward) or rude (save open files without asking the user
710 * for confirmation).
711 *
712 * 2. Request interaction and then emit ::quit_requested. This
713 * perhaps isn't quite correct for the SmInteractStyleErrors
714 * case, but we don't care.
715 *
716 * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these
717 * rows essentially get demoted to SmSaveLocal, because their
718 * Global halves correspond to "do nothing".
719 *
720 * 4. Request interaction, emit ::quit_requested, and then emit
721 * ::save_state after interacting. This is the SmSaveBoth
722 * equivalent of #2, but we also promote SmSaveLocal shutdown
723 * SaveYourselfs to SmSaveBoth here, because we want to give
724 * the user a chance to save open files before quitting.
725 *
726 * (* It would be nice if we could do something useful when the
727 * session manager sends a SaveYourself with shutdown True and
728 * SmInteractStyleNone. But we can't, so we just pretend it didn't
729 * even tell us it was shutting down. The docs for ::quit mention
730 * that it might not always be preceded by ::quit_requested.)
731 */
732
733 /* As an optimization, we don't actually request interaction and
734 * emit ::quit_requested if the application isn't listening to the
735 * signal.
736 */
737 wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT(egg_sm_client_get_type ())), 0, FALSE(0));
738
739 xsmp->need_save_state = (save_type != SmSaveGlobal0);
740 xsmp->need_quit_requested = (shutdown && wants_quit_requested &&
741 interact_style != SmInteractStyleNone0);
742 xsmp->interact_errors = (interact_style == SmInteractStyleErrors1);
743
744 xsmp->shutting_down = shutdown;
745
746 do_save_yourself (xsmp);
747}
748
749static void
750do_save_yourself (EggSMClientXSMP *xsmp)
751{
752 if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
753 {
754 /* The SM cancelled a previous SaveYourself, but we haven't yet
755 * had a chance to tell the application, so we can't start
756 * processing this SaveYourself yet.
757 */
758 xsmp->waiting_to_save_myself = TRUE(!(0));
759 update_pending_events (xsmp);
760 return;
761 }
762
763 if (xsmp->need_quit_requested)
764 {
765 xsmp->state = XSMP_STATE_INTERACT_REQUEST;
766
767 g_debug ("Sending InteractRequest(%s)",
768 xsmp->interact_errors ? "Error" : "Normal");
769 SmcInteractRequest (xsmp->connection,
770 xsmp->interact_errors ? SmDialogError0 : SmDialogNormal1,
771 xsmp_interact,
772 xsmp);
773 return;
774 }
775
776 if (xsmp->need_save_state)
777 {
778 save_state (xsmp);
779
780 /* Though unlikely, the client could have been disconnected
781 * while the application was saving its state.
782 */
783 if (!xsmp->connection)
784 return;
785 }
786
787 g_debug ("Sending SaveYourselfDone(True)");
788 SmcSaveYourselfDone (xsmp->connection, True1);
789
790 /* The client state diagram in the XSMP spec says that after a
791 * non-shutdown SaveYourself, we go directly back to "idle". But
792 * everything else in both the XSMP spec and the libSM docs
793 * disagrees.
794 */
795 xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
796}
797
798static void
799save_state (EggSMClientXSMP *xsmp)
800{
801 GKeyFile *state_file;
802 char *state_file_path, *data;
803 EggDesktopFile *desktop_file;
804 GPtrArray *restart, *discard;
805 int offset, fd;
806
807 /* We set xsmp->state before emitting save_state, but our caller is
808 * responsible for setting it back afterward.
809 */
810 xsmp->state = XSMP_STATE_SAVE_YOURSELF;
811
812 state_file = egg_sm_client_save_state ((EggSMClient *)xsmp);
813 if (!state_file)
814 {
815 restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL((void*)0));
816 set_properties (xsmp,
817 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
818 NULL((void*)0));
819 g_ptr_array_free (restart, TRUE(!(0)));
820
821 if (xsmp->set_discard_command)
822 {
823 discard = generate_command (xsmp->discard_command, NULL((void*)0), NULL((void*)0));
824 set_properties (xsmp,
825 ptrarray_prop (SmDiscardCommand"DiscardCommand", discard),
826 NULL((void*)0));
827 g_ptr_array_free (discard, TRUE(!(0)));
828 }
829 else
830 delete_properties (xsmp, SmDiscardCommand"DiscardCommand", NULL((void*)0));
831
832 return;
833 }
834
835 desktop_file = egg_get_desktop_file ();
836 if (desktop_file)
837 {
838 GKeyFile *merged_file;
839 char *desktop_file_path;
840
841 merged_file = g_key_file_new ();
842 desktop_file_path =
843 g_filename_from_uri (egg_desktop_file_get_source (desktop_file),
844 NULL((void*)0), NULL((void*)0));
845 if (desktop_file_path &&
846 g_key_file_load_from_file (merged_file, desktop_file_path,
847 G_KEY_FILE_KEEP_COMMENTS |
848 G_KEY_FILE_KEEP_TRANSLATIONS, NULL((void*)0)))
849 {
850 guint g, k, i;
851 char **groups, **keys, *value, *exec;
852
853 groups = g_key_file_get_groups (state_file, NULL((void*)0));
854 for (g = 0; groups[g]; g++)
855 {
856 keys = g_key_file_get_keys (state_file, groups[g], NULL((void*)0), NULL((void*)0));
857 for (k = 0; keys[k]; k++)
858 {
859 value = g_key_file_get_value (state_file, groups[g],
860 keys[k], NULL((void*)0));
861 if (value)
862 {
863 g_key_file_set_value (merged_file, groups[g],
864 keys[k], value);
865 g_free (value);
866 }
867 }
868 g_strfreev (keys);
869 }
870 g_strfreev (groups);
871
872 g_key_file_free (state_file);
873 state_file = merged_file;
874
875 /* Update Exec key using "--sm-client-state-file %k" */
876 restart = generate_command (xsmp->restart_command,
877 NULL((void*)0), "%k");
878 for (i = 0; i < restart->len; i++)
879 restart->pdata[i] = g_shell_quote (restart->pdata[i]);
880 g_ptr_array_add (restart, NULL((void*)0));
881 exec = g_strjoinv (" ", (char **)restart->pdata);
882 g_strfreev ((char **)restart->pdata);
883 g_ptr_array_free (restart, FALSE(0));
884
885 g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP"Desktop Entry",
886 EGG_DESKTOP_FILE_KEY_EXEC"Exec",
887 exec);
888 g_free (exec);
889 }
890 else
891 desktop_file = NULL((void*)0);
892
893 g_free (desktop_file_path);
894 }
895
896 /* Now write state_file to disk. (We can't use mktemp(), because
897 * that requires the filename to end with "XXXXXX", and we want
898 * it to end with ".desktop".)
899 */
900
901 data = g_key_file_to_data (state_file, NULL((void*)0), NULL((void*)0));
902 g_key_file_free (state_file);
903
904 offset = 0;
905 while (1)
906 {
907 state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s",
908 g_get_user_config_dir (),
909 G_DIR_SEPARATOR'/', G_DIR_SEPARATOR'/',
910 g_get_prgname (),
911 (long)time (NULL((void*)0)) + offset,
912 desktop_file ? "desktop" : "state");
913
914 fd = open (state_file_path, O_WRONLY01 | O_CREAT0100 | O_EXCL0200, 0644);
915 if (fd == -1)
916 {
917 if (errno(*__errno_location ()) == EEXIST17)
918 {
919 offset++;
920 g_free (state_file_path);
921 continue;
922 }
923 else if (errno(*__errno_location ()) == ENOTDIR20 || errno(*__errno_location ()) == ENOENT2)
924 {
925 char *sep = strrchr (state_file_path, G_DIR_SEPARATOR'/');
926
927 *sep = '\0';
928 if (g_mkdir_with_parents (state_file_path, 0755) != 0)
929 {
930 g_warning ("Could not create directory '%s'",
931 state_file_path);
932 g_free (state_file_path);
933 state_file_path = NULL((void*)0);
934 break;
935 }
936
937 continue;
938 }
939
940 g_warning ("Could not create file '%s': %s",
941 state_file_path, g_strerror (errno(*__errno_location ())));
942 g_free (state_file_path);
943 state_file_path = NULL((void*)0);
944 break;
945 }
946
947 close (fd);
948 g_file_set_contents (state_file_path, data, -1, NULL((void*)0));
949 break;
950 }
951 g_free (data);
952
953 restart = generate_command (xsmp->restart_command, xsmp->client_id,
954 state_file_path);
955 set_properties (xsmp,
956 ptrarray_prop (SmRestartCommand"RestartCommand", restart),
957 NULL((void*)0));
958 g_ptr_array_free (restart, TRUE(!(0)));
959
960 if (state_file_path)
961 {
962 set_properties (xsmp,
963 array_prop (SmDiscardCommand"DiscardCommand",
964 "/bin/rm", "-rf", state_file_path,
965 NULL((void*)0)),
966 NULL((void*)0));
967 g_free (state_file_path);
968 }
969}
970
971static void
972xsmp_interact (SmcConn smc_conn,
973 SmPointer client_data)
974{
975 EggSMClientXSMP *xsmp = client_data;
976 EggSMClient *client = client_data;
977
978 g_debug ("Received Interact message in state %s",
979 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
980
981 if (xsmp->state != XSMP_STATE_INTERACT_REQUEST)
982 {
983 fix_broken_state (xsmp, "Interact", TRUE(!(0)), TRUE(!(0)));
984 return;
985 }
986
987 xsmp->state = XSMP_STATE_INTERACT;
988 egg_sm_client_quit_requested (client);
989}
990
991static void
992xsmp_die (SmcConn smc_conn,
993 SmPointer client_data)
994{
995 EggSMClientXSMP *xsmp = client_data;
996 EggSMClient *client = client_data;
997
998 g_debug ("Received Die message in state %s",
999 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1000
1001 sm_client_xsmp_disconnect (xsmp);
1002 egg_sm_client_quit (client);
1003}
1004
1005static void
1006xsmp_save_complete (SmcConn smc_conn,
1007 SmPointer client_data)
1008{
1009 EggSMClientXSMP *xsmp = client_data;
1010
1011 g_debug ("Received SaveComplete message in state %s",
1012 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1013
1014 if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
1015 xsmp->state = XSMP_STATE_IDLE;
1016 else
1017 fix_broken_state (xsmp, "SaveComplete", FALSE(0), FALSE(0));
1018}
1019
1020static void
1021xsmp_shutdown_cancelled (SmcConn smc_conn,
1022 SmPointer client_data)
1023{
1024 EggSMClientXSMP *xsmp = client_data;
1025 EggSMClient *client = client_data;
1026
1027 g_debug ("Received ShutdownCancelled message in state %s",
1028 EGG_SM_CLIENT_XSMP_STATE (xsmp)(state_names[(xsmp)->state]));
1029
1030 xsmp->shutting_down = FALSE(0);
1031
1032 if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE)
1033 {
1034 /* We've finished interacting and now the SM has agreed to
1035 * cancel the shutdown.
1036 */
1037 xsmp->state = XSMP_STATE_IDLE;
1038 egg_sm_client_quit_cancelled (client);
1039 }
1040 else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED)
1041 {
1042 /* Hm... ok, so we got a shutdown SaveYourself, which got
1043 * cancelled, but the application was still interacting, so we
1044 * didn't tell it yet, and then *another* SaveYourself arrived,
1045 * which we must still be waiting to tell the app about, except
1046 * that now that SaveYourself has been cancelled too! Dizzy yet?
1047 */
1048 xsmp->waiting_to_save_myself = FALSE(0);
1049 update_pending_events (xsmp);
1050 }
1051 else
1052 {
1053 g_debug ("Sending SaveYourselfDone(False)");
1054 SmcSaveYourselfDone (xsmp->connection, False0);
1055
1056 if (xsmp->state == XSMP_STATE_INTERACT)
1057 {
1058 /* The application is currently interacting, so we can't
1059 * tell it about the cancellation yet; we will wait until
1060 * after it calls egg_sm_client_will_quit().
1061 */
1062 xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED;
1063 }
1064 else
1065 {
1066 /* The shutdown was cancelled before the application got a
1067 * chance to interact.
1068 */
1069 xsmp->state = XSMP_STATE_IDLE;
1070 }
1071 }
1072}
1073
1074/* Utilities */
1075
1076/* Create a restart/clone/Exec command based on @restart_command.
1077 * If @client_id is non-%NULL, add "--sm-client-id @client_id".
1078 * If @state_file is non-%NULL, add "--sm-client-state-file @state_file".
1079 *
1080 * None of the input strings are g_strdup()ed; the caller must keep
1081 * them around until it is done with the returned GPtrArray, and must
1082 * then free the array, but not its contents.
1083 */
1084static GPtrArray *
1085generate_command (char **restart_command, const char *client_id,
1086 const char *state_file)
1087{
1088 GPtrArray *cmd;
1089 int i;
1090
1091 cmd = g_ptr_array_new ();
1092 g_ptr_array_add (cmd, restart_command[0]);
1093
1094 if (client_id)
1095 {
1096 g_ptr_array_add (cmd, (char *)"--sm-client-id");
1097 g_ptr_array_add (cmd, (char *)client_id);
1098 }
1099
1100 if (state_file)
1101 {
1102 g_ptr_array_add (cmd, (char *)"--sm-client-state-file");
1103 g_ptr_array_add (cmd, (char *)state_file);
1104 }
1105
1106 for (i = 1; restart_command[i]; i++)
1107 g_ptr_array_add (cmd, restart_command[i]);
1108
1109 return cmd;
1110}
1111
1112/* Takes a NULL-terminated list of SmProp * values, created by
1113 * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and
1114 * frees them.
1115 */
1116static void
1117set_properties (EggSMClientXSMP *xsmp, ...)
1118{
1119 GPtrArray *props;
1120 SmProp *prop;
1121 va_list ap;
1122 guint i;
1123
1124 props = g_ptr_array_new ();
1125
1126 va_start (ap, xsmp)__builtin_va_start(ap, xsmp);
1127 while ((prop = va_arg (ap, SmProp *)__builtin_va_arg(ap, SmProp *)))
1128 g_ptr_array_add (props, prop);
1129 va_end (ap)__builtin_va_end(ap);
1130
1131 if (xsmp->connection)
1132 {
1133 SmcSetProperties (xsmp->connection, props->len,
1134 (SmProp **)props->pdata);
1135 }
1136
1137 for (i = 0; i < props->len; i++)
1138 {
1139 prop = props->pdata[i];
1140 g_free (prop->vals);
1141 g_free (prop);
1142 }
1143 g_ptr_array_free (props, TRUE(!(0)));
1144}
1145
1146/* Takes a NULL-terminated list of property names and deletes them. */
1147static void
1148delete_properties (EggSMClientXSMP *xsmp, ...)
1149{
1150 GPtrArray *props;
1151 char *prop;
1152 va_list ap;
1153
1154 if (!xsmp->connection)
1155 return;
1156
1157 props = g_ptr_array_new ();
1158
1159 va_start (ap, xsmp)__builtin_va_start(ap, xsmp);
1160 while ((prop = va_arg (ap, char *)__builtin_va_arg(ap, char *)))
1161 g_ptr_array_add (props, prop);
1162 va_end (ap)__builtin_va_end(ap);
1163
1164 SmcDeleteProperties (xsmp->connection, props->len,
1165 (char **)props->pdata);
1166
1167 g_ptr_array_free (props, TRUE(!(0)));
1168}
1169
1170/* Takes an array of strings and creates a LISTofARRAY8 property. The
1171 * strings are neither dupped nor freed; they need to remain valid
1172 * until you're done with the SmProp.
1173 */
1174static SmProp *
1175array_prop (const char *name, ...)
1176{
1177 SmProp *prop;
1178 SmPropValue pv;
1179 GArray *vals;
1180 char *value;
1181 va_list ap;
1182
1183 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1184 prop->name = (char *)name;
1185 prop->type = (char *)SmLISTofARRAY8"LISTofARRAY8";
1186
1187 vals = g_array_new (FALSE(0), FALSE(0), sizeof (SmPropValue));
1188
1189 va_start (ap, name)__builtin_va_start(ap, name);
1190 while ((value = va_arg (ap, char *)__builtin_va_arg(ap, char *)))
1191 {
1192 pv.length = strlen (value);
1193 pv.value = value;
1194 g_array_append_val (vals, pv)g_array_append_vals (vals, &(pv), 1);
1195 }
1196 va_end (ap)__builtin_va_end(ap);
1197
1198 prop->num_vals = vals->len;
1199 prop->vals = (SmPropValue *)vals->data;
1200
1201 g_array_free (vals, FALSE(0));
1202
1203 return prop;
1204}
1205
1206/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property.
1207 * The array contents are neither dupped nor freed; they need to
1208 * remain valid until you're done with the SmProp.
1209 */
1210static SmProp *
1211ptrarray_prop (const char *name, GPtrArray *values)
1212{
1213 SmProp *prop;
1214 SmPropValue pv;
1215 GArray *vals;
1216 guint i;
1217
1218 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1219 prop->name = (char *)name;
1220 prop->type = (char *)SmLISTofARRAY8"LISTofARRAY8";
1221
1222 vals = g_array_new (FALSE(0), FALSE(0), sizeof (SmPropValue));
1223
1224 for (i = 0; i < values->len; i++)
1225 {
1226 pv.length = strlen (values->pdata[i]);
1227 pv.value = values->pdata[i];
1228 g_array_append_val (vals, pv)g_array_append_vals (vals, &(pv), 1);
1229 }
1230
1231 prop->num_vals = vals->len;
1232 prop->vals = (SmPropValue *)vals->data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
1233
1234 g_array_free (vals, FALSE(0));
1235
1236 return prop;
1237}
1238
1239/* Takes a string and creates an ARRAY8 property. The string is
1240 * neither dupped nor freed; it needs to remain valid until you're
1241 * done with the SmProp.
1242 */
1243static SmProp *
1244string_prop (const char *name, const char *value)
1245{
1246 SmProp *prop;
1247
1248 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1249 prop->name = (char *)name;
1250 prop->type = (char *)SmARRAY8"ARRAY8";
1251
1252 prop->num_vals = 1;
1253 prop->vals = g_new (SmPropValue, 1)((SmPropValue *) g_malloc_n ((1), sizeof (SmPropValue)));
1254
1255 prop->vals[0].length = strlen (value);
1256 prop->vals[0].value = (char *)value;
1257
1258 return prop;
1259}
1260
1261/* Takes a char and creates a CARD8 property. */
1262static SmProp *
1263card8_prop (const char *name, unsigned char value)
1264{
1265 SmProp *prop;
1266 char *card8val;
1267
1268 /* To avoid having to allocate and free prop->vals[0], we cheat and
1269 * make vals a 2-element-long array and then use the second element
1270 * to store value.
1271 */
1272
1273 prop = g_new (SmProp, 1)((SmProp *) g_malloc_n ((1), sizeof (SmProp)));
1274 prop->name = (char *)name;
1275 prop->type = (char *)SmCARD8"CARD8";
1276
1277 prop->num_vals = 1;
1278 prop->vals = g_new (SmPropValue, 2)((SmPropValue *) g_malloc_n ((2), sizeof (SmPropValue)));
1279 card8val = (char *)(&prop->vals[1]);
1280 card8val[0] = value;
1281
1282 prop->vals[0].length = 1;
1283 prop->vals[0].value = card8val;
1284
1285 return prop;
1286}
1287
1288/* ICE code. This makes no effort to play nice with anyone else trying
1289 * to use libICE. Fortunately, no one uses libICE for anything other
1290 * than SM. (DCOP uses ICE, but it has its own private copy of
1291 * libICE.)
1292 *
1293 * When this moves to gtk, it will need to be cleverer, to avoid
1294 * tripping over old apps that use MateClient or that use libSM
1295 * directly.
1296 */
1297
1298#include <X11/ICE/ICElib.h>
1299#include <fcntl.h>
1300
1301static void ice_error_handler (IceConn ice_conn,
1302 Boolint swap,
1303 int offending_minor_opcode,
1304 unsigned long offending_sequence,
1305 int error_class,
1306 int severity,
1307 IcePointer values);
1308static void ice_io_error_handler (IceConn ice_conn);
1309static void ice_connection_watch (IceConn ice_conn,
1310 IcePointer client_data,
1311 Boolint opening,
1312 IcePointer *watch_data);
1313
1314static void
1315ice_init (void)
1316{
1317 IceSetIOErrorHandler (ice_io_error_handler);
1318 IceSetErrorHandler (ice_error_handler);
1319 IceAddConnectionWatch (ice_connection_watch, NULL((void*)0));
1320}
1321
1322static gboolean
1323process_ice_messages (IceConn ice_conn)
1324{
1325 IceProcessMessagesStatus status;
1326 status = IceProcessMessages (ice_conn, NULL((void*)0), NULL((void*)0));
1327
1328 switch (status)
1329 {
1330 case IceProcessMessagesSuccess:
1331 return TRUE(!(0));
1332
1333 case IceProcessMessagesIOError:
1334 sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn));
1335 return FALSE(0);
1336
1337 case IceProcessMessagesConnectionClosed:
1338 return FALSE(0);
1339
1340 default:
1341 g_assert_not_reached ()do { g_assertion_message_expr ("EggSMClient", "eggsmclient-xsmp.c"
, 1341, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1342 }
1343}
1344
1345static gboolean
1346ice_iochannel_watch (GIOChannel *channel,
1347 GIOCondition condition,
1348 gpointer client_data)
1349{
1350 return process_ice_messages (client_data);
1351}
1352
1353static void
1354ice_connection_watch (IceConn ice_conn,
1355 IcePointer client_data,
1356 Boolint opening,
1357 IcePointer *watch_data)
1358{
1359 guint watch_id;
1360
1361 if (opening)
1362 {
1363 GIOChannel *channel;
1364 int fd = IceConnectionNumber (ice_conn);
1365
1366 fcntl (fd, F_SETFD2, fcntl (fd, F_GETFD1, 0) | FD_CLOEXEC1);
1367 channel = g_io_channel_unix_new (fd);
1368 watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR,
1369 ice_iochannel_watch, ice_conn);
1370 g_io_channel_unref (channel);
1371
1372 *watch_data = GUINT_TO_POINTER (watch_id)((gpointer) (gulong) (watch_id));
1373 }
1374 else
1375 {
1376 watch_id = GPOINTER_TO_UINT (*watch_data)((guint) (gulong) (*watch_data));
1377 g_source_remove (watch_id);
1378 }
1379}
1380
1381static void
1382ice_error_handler (IceConn ice_conn,
1383 Boolint swap,
1384 int offending_minor_opcode,
1385 unsigned long offending_sequence,
1386 int error_class,
1387 int severity,
1388 IcePointer values)
1389{
1390 /* Do nothing */
1391}
1392
1393static void
1394ice_io_error_handler (IceConn ice_conn)
1395{
1396 /* Do nothing */
1397}
1398
1399static void
1400smc_error_handler (SmcConn smc_conn,
1401 Boolint swap,
1402 int offending_minor_opcode,
1403 unsigned long offending_sequence,
1404 int error_class,
1405 int severity,
1406 SmPointer values)
1407{
1408 /* Do nothing */
1409}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-d9bc25.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-d9bc25.html new file mode 100644 index 0000000..30e1c0d --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-d9bc25.html @@ -0,0 +1,967 @@ + + + +mate-session-save.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-save.c
Warning:line 271, column 3
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-save.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-save.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 * save-session.c - Small program to talk to session manager.
3
4 Copyright (C) 1998 Tom Tromey
5 Copyright (C) 2008 Red Hat, Inc.
6 * Copyright (C) 2012-2021 MATE Developers
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301, USA.
22*/
23
24#include <config.h>
25
26#include <unistd.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30
31#include <glib/gi18n.h>
32#include <gtk/gtk.h>
33
34#define GSM_SERVICE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
35#define GSM_PATH_DBUS"/org/gnome/SessionManager" "/org/gnome/SessionManager"
36#define GSM_INTERFACE_DBUS"org.gnome.SessionManager" "org.gnome.SessionManager"
37
38#define GSM_SERVICE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
39#define GSM_PATH_DBUS_OLD"/org/mate/SessionManager" "/org/mate/SessionManager"
40#define GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager" "org.mate.SessionManager"
41
42enum {
43 GSM_LOGOUT_MODE_NORMAL = 0,
44 GSM_LOGOUT_MODE_NO_CONFIRMATION,
45 GSM_LOGOUT_MODE_FORCE
46};
47
48/* True if killing. This is deprecated, but we keep it for compatibility
49 * reasons. */
50static gboolean kill_session = FALSE(0);
51
52/* The real options that should be used now. They are not ambiguous. */
53static gboolean logout = FALSE(0);
54static gboolean force_logout = FALSE(0);
55static gboolean logout_dialog = FALSE(0);
56static gboolean shutdown_dialog = FALSE(0);
57
58/* True if we should use dialog boxes */
59static gboolean show_error_dialogs = FALSE(0);
60
61/* True if we should do the requested action without confirmation */
62static gboolean no_interaction = FALSE(0);
63
64static char* session_name = NULL((void*)0);
65
66static GOptionEntry options[] = {
67 {"logout", '\0', 0, G_OPTION_ARG_NONE, &logout, N_("Log out")("Log out"), NULL((void*)0)},
68 {"force-logout", '\0', 0, G_OPTION_ARG_NONE, &force_logout, N_("Log out, ignoring any existing inhibitors")("Log out, ignoring any existing inhibitors"), NULL((void*)0)},
69 {"logout-dialog", '\0', 0, G_OPTION_ARG_NONE, &logout_dialog, N_("Show logout dialog")("Show logout dialog"), NULL((void*)0)},
70 {"shutdown-dialog", '\0', 0, G_OPTION_ARG_NONE, &shutdown_dialog, N_("Show shutdown dialog")("Show shutdown dialog"), NULL((void*)0)},
71 {"gui", '\0', 0, G_OPTION_ARG_NONE, &show_error_dialogs, N_("Use dialog boxes for errors")("Use dialog boxes for errors"), NULL((void*)0)},
72 /* deprecated options */
73 {"session-name", 's', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &session_name, N_("Set the current session name")("Set the current session name"), N_("NAME")("NAME")},
74 {"kill", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &kill_session, N_("Kill session")("Kill session"), NULL((void*)0)},
75 {"silent", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &no_interaction, N_("Do not require confirmation")("Do not require confirmation"), NULL((void*)0)},
76 {NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0)}
77};
78
79static void display_error(const char* message)
80{
81 if (show_error_dialogs && !no_interaction)
82 {
83 GtkWidget* dialog = gtk_message_dialog_new(NULL((void*)0), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
84
85 gtk_window_set_default_icon_name ("dialog-error");
86
87 gtk_dialog_run(GTK_DIALOG(dialog)((((GtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_dialog_get_type ()))))))
);
88 gtk_widget_destroy(dialog);
89 }
90 else
91 {
92 g_printerr("%s\n", message);
93 }
94}
95
96static GDBusProxy* get_sm_proxy(void)
97{
98 GError *error = NULL((void*)0);
99 GDBusProxy *sm_proxy = NULL((void*)0);
100
101 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
102 G_DBUS_PROXY_FLAGS_NONE,
103 NULL((void*)0),
104 GSM_SERVICE_DBUS"org.gnome.SessionManager",
105 GSM_PATH_DBUS"/org/gnome/SessionManager",
106 GSM_INTERFACE_DBUS"org.gnome.SessionManager",
107 NULL((void*)0),
108 &error);
109 if (sm_proxy == NULL((void*)0))
110 {
111 g_warning ("Couldn't create DBus proxy: %s", error->message);
112 g_error_free (error);
113
114 /* Try the old name - for the case when we've just upgraded from 1.10
115 * so the old m-s-m is currently running */
116 sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
117 G_DBUS_PROXY_FLAGS_NONE,
118 NULL((void*)0),
119 GSM_SERVICE_DBUS_OLD"org.mate.SessionManager",
120 GSM_PATH_DBUS_OLD"/org/mate/SessionManager",
121 GSM_INTERFACE_DBUS_OLD"org.mate.SessionManager",
122 NULL((void*)0),
123 NULL((void*)0));
124 if (sm_proxy == NULL((void*)0))
125 {
126 /* Okay, it wasn't the upgrade case, so now we can give up. */
127 display_error (_("Could not connect to the session manager")gettext ("Could not connect to the session manager"));
128 return NULL((void*)0);
129 }
130 }
131
132 return sm_proxy;
133}
134
135static void do_logout(unsigned int mode)
136{
137 GDBusProxy* sm_proxy;
138 GError* error;
139 GVariant *ret;
140
141 sm_proxy = get_sm_proxy ();
142
143 if (sm_proxy == NULL((void*)0))
144 {
145 return;
146 }
147
148 error = NULL((void*)0);
149 ret = g_dbus_proxy_call_sync (sm_proxy, "Logout",
150 g_variant_new ("(u)", mode),
151 G_DBUS_CALL_FLAGS_NONE,
152 -1,
153 NULL((void*)0),
154 &error);
155
156 if (ret == NULL((void*)0))
157 {
158 g_warning ("Failed to call logout: %s", error->message);
159 g_error_free (error);
160 } else {
161 g_variant_unref (ret);
162 }
163
164 if (sm_proxy != NULL((void*)0))
165 {
166 g_object_unref (sm_proxy);
167 }
168}
169
170static void do_shutdown_dialog(void)
171{
172 GDBusProxy* sm_proxy;
173 GError* error;
174 GVariant *ret;
175
176 sm_proxy = get_sm_proxy ();
177
178 if (sm_proxy == NULL((void*)0))
179 {
180 return;
181 }
182
183 error = NULL((void*)0);
184 ret = g_dbus_proxy_call_sync (sm_proxy, "Shutdown",
185 g_variant_new ("()"),
186 G_DBUS_CALL_FLAGS_NONE,
187 -1,
188 NULL((void*)0),
189 &error);
190 if (ret == NULL((void*)0))
191 {
192 g_warning ("Failed to call shutdown: %s", error->message);
193 g_error_free (error);
194 } else {
195 g_variant_unref (ret);
196 }
197
198 if (sm_proxy != NULL((void*)0))
199 {
200 g_object_unref (sm_proxy);
201 }
202}
203
204int main(int argc, char* argv[])
205{
206 GError* error;
207 int conflicting_options;
208
209 /* Initialize the i18n stuff */
210#ifdef ENABLE_NLS1
211 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
212 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
213 textdomain(GETTEXT_PACKAGE"mate-session-manager");
214#endif /* ENABLE_NLS */
215
216 error = NULL((void*)0);
217
218 if (!gtk_init_with_args(&argc, &argv, NULL((void*)0), options, NULL((void*)0), &error))
219 {
220 g_warning("Unable to start: %s", error->message);
221 g_error_free(error);
222 exit(1);
223 }
224
225 conflicting_options = 0;
226
227 if (kill_session)
228 {
229 conflicting_options++;
230 }
231
232 if (logout)
233 {
234 conflicting_options++;
235 }
236
237 if (force_logout)
238 {
239 conflicting_options++;
240 }
241
242 if (logout_dialog)
243 {
244 conflicting_options++;
245 }
246
247 if (shutdown_dialog)
248 {
249 conflicting_options++;
250 }
251
252 if (conflicting_options > 1)
253 {
254 display_error(_("Program called with conflicting options")gettext ("Program called with conflicting options"));
255 }
256
257 if (kill_session)
258 {
259 if (no_interaction)
260 {
261 force_logout = TRUE(!(0));
262 }
263 else
264 {
265 logout_dialog = TRUE(!(0));
266 }
267 }
268
269 if (logout)
270 {
271 do_logout(GSM_LOGOUT_MODE_NO_CONFIRMATION);
This statement is never executed
272 }
273 else if (force_logout)
274 {
275 do_logout(GSM_LOGOUT_MODE_FORCE);
276 }
277 else if (logout_dialog)
278 {
279 do_logout(GSM_LOGOUT_MODE_NORMAL);
280 }
281 else if (shutdown_dialog)
282 {
283 do_shutdown_dialog();
284 }
285
286 return 0;
287}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-e4efad.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-e4efad.html new file mode 100644 index 0000000..e45599a --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-e4efad.html @@ -0,0 +1,1197 @@ + + + +mate-session-check-accelerated-gl-helper.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-check-accelerated-gl-helper.c
Warning:line 508, column 17
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-check-accelerated-gl-helper.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -D PKGDATADIR="/usr/local/share/mate-session-manager" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-check-accelerated-gl-helper.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2010 Novell, Inc.
3 * Copyright (C) 2006-2009 Red Hat, Inc.
4 * Copyright (C) 2012-2021 MATE Developers
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * Author:
21 * Vincent Untz <vuntz@gnome.org>
22 *
23 * Most of the code comes from desktop-effects [1], released under GPLv2+.
24 * desktop-effects was written by:
25 * Soren Sandmann <sandmann@redhat.com>
26 *
27 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
28 */
29
30/*
31 * Here's the rationale behind this helper, quoting Owen, in his mail to the
32 * release team:
33 * (http://mail.gnome.org/archives/release-team/2010-June/msg00079.html)
34 *
35 * """
36 * There are some limits to what we can do here automatically without
37 * knowing anything about the driver situation on the system. The basic
38 * problem is that there are all sorts of suck:
39 *
40 * * No GL at all. This typically only happens if a system is
41 * misconfigured.
42 *
43 * * Only software GL. This one is easy to detect. We have code in
44 * the Fedora desktop-effects tool, etc.
45 *
46 * * GL that isn't featureful enough. (Tiny texture size limits, no
47 * texture-from-pixmap, etc.) Possible to detect with more work, but
48 * largely a fringe case.
49 *
50 * * Buggy GL. This isn't possible to detect. Except for the case where
51 * all GL programs crash. For that reason, we probably don't want
52 * gnome-session to directly try and do any GL detection; better to
53 * use a helper binary.
54 *
55 * * Horribly slow hardware GL. We could theoretically develop some sort
56 * of benchmark, but it's a tricky area. And how slow is too slow?
57 * """
58 *
59 * Some other tools are doing similar checks:
60 * - desktop-effects (Fedora Config Tool) [1]
61 * - drak3d (Mandriva Config Tool) [2]
62 * - compiz-manager (Compiz wrapper) [3]
63 *
64 * [1] http://git.fedorahosted.org/git/?p=desktop-effects.git;a=blob_plain;f=desktop-effects.c;hb=HEAD
65 * [2] http://svn.mandriva.com/cgi-bin/viewvc.cgi/soft/drak3d/trunk/lib/Xconfig/glx.pm?view=markup
66 * [3] http://git.compiz.org/fusion/misc/compiz-manager/tree/compiz-manager
67 */
68
69/* for strcasestr */
70#define _GNU_SOURCE
71
72#include <ctype.h>
73#include <locale.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <glib.h>
78
79#include <regex.h>
80
81#ifdef __FreeBSD__
82#include <kenv.h>
83#endif
84
85#include <X11/Xlib.h>
86#include <X11/Xatom.h>
87#include <X11/extensions/Xcomposite.h>
88#include <GL/gl.h>
89#include <GL/glx.h>
90
91#include "mate-session-check-accelerated-common.h"
92
93#define SIZE_UNSET0 0
94#define SIZE_ERROR-1 -1
95static int max_texture_size = SIZE_UNSET0;
96static int max_renderbuffer_size = SIZE_UNSET0;
97static gboolean has_llvmpipe = FALSE(0);
98
99static inline void
100_print_error (const char *str)
101{
102 fprintf (stderrstderr, "mate-session-is-accelerated: %s\n", str);
103}
104
105#define CMDLINE_UNSET-1 -1
106#define CMDLINE_NON_FALLBACK_FORCED0 0
107#define CMDLINE_FALLBACK_FORCED1 1
108
109#if defined(__linux__1)
110static int
111_parse_kcmdline (void)
112{
113 int ret = CMDLINE_UNSET-1;
114 GRegex *regex;
115 GMatchInfo *match;
116 char *contents;
117 char *word;
118 const char *arg;
119
120 if (!g_file_get_contents ("/proc/cmdline", &contents, NULL((void*)0), NULL((void*)0)))
121 return ret;
122
123 regex = g_regex_new ("mate.fallback=(\\S+)", 0, G_REGEX_MATCH_NOTEMPTY, NULL((void*)0));
124 if (!g_regex_match (regex, contents, G_REGEX_MATCH_NOTEMPTY, &match))
125 goto out;
126
127 word = g_match_info_fetch (match, 0);
128 g_debug ("Found command-line match '%s'", word);
129 arg = word + strlen ("mate.fallback=");
130 if (*arg != '0' && *arg != '1')
131 fprintf (stderrstderr, "mate-session-check-accelerated: Invalid value '%s' for mate.fallback passed in kernel command line.\n", arg);
132 else
133 ret = atoi (arg);
134 g_free (word);
135
136out:
137 g_match_info_free (match);
138 g_regex_unref (regex);
139 g_free (contents);
140
141 g_debug ("Command-line parsed to %d", ret);
142
143 return ret;
144}
145#elif defined(__FreeBSD__)
146static int
147_parse_kcmdline (void)
148{
149 int ret = CMDLINE_UNSET-1;
150 char value[KENV_MVALLEN];
151
152 /* a compile time check to avoid unexpected stack overflow */
153 _Static_assert(KENV_MVALLEN < 1024 * 1024, "KENV_MVALLEN is too large");
154
155 if (kenv (KENV_GET, "mate.fallback", value, KENV_MVALLEN) == -1)
156 return ret;
157
158 if (*value != '0' && *value != '1')
159 fprintf (stderrstderr, "mate-session-is-accelerated: Invalid value '%s' for mate.fallback passed in kernel environment.\n", value);
160 else
161 ret = atoi (value);
162
163 g_debug ("Kernel environment parsed to %d", ret);
164
165 return ret;
166}
167#else
168static int
169_parse_kcmdline (void)
170{
171 return CMDLINE_UNSET-1;
172}
173#endif
174
175static gboolean
176_has_composite (Display *display)
177{
178 int dummy1, dummy2;
179
180 return XCompositeQueryExtension (display, &dummy1, &dummy2);
181}
182
183static gboolean
184_is_comment (const char *line)
185{
186 while (*line && isspace(*line)((*__ctype_b_loc ())[(int) ((*line))] & (unsigned short int
) _ISspace)
)
187 line++;
188
189 if (*line == '#' || *line == '\0')
190 return TRUE(!(0));
191 return FALSE(0);
192}
193
194static gboolean
195_is_gl_renderer_blacklisted (const char *renderer)
196{
197 FILE *blacklist;
198 char *line = NULL((void*)0);
199 size_t line_len = 0;
200 gboolean ret = TRUE(!(0));
201
202 blacklist = fopen(PKGDATADIR"/usr/local/share/mate-session-manager" "/hardware-compatibility", "r");
203 if (blacklist == NULL((void*)0))
204 goto out;
205
206 while (getline (&line, &line_len, blacklist) != -1) {
207 int whitelist = 0;
208 const char *re_str;
209 regex_t re;
210 int status;
211
212 if (line == NULL((void*)0))
213 break;
214
215 /* Drop trailing \n */
216 line[strlen(line) - 1] = '\0';
217
218 if (_is_comment (line)) {
219 free (line);
220 line = NULL((void*)0);
221 continue;
222 }
223
224 if (line[0] == '+')
225 whitelist = 1;
226 else if (line[0] == '-')
227 whitelist = 0;
228 else {
229 _print_error ("Invalid syntax in this line for hardware compatibility:");
230 _print_error (line);
231 free (line);
232 line = NULL((void*)0);
233 continue;
234 }
235
236 re_str = line + 1;
237
238 if (regcomp (&re, re_str, REG_EXTENDED1|REG_ICASE(1 << 1)|REG_NOSUB(1 << 3)) != 0) {
239 _print_error ("Cannot use this regular expression for hardware compatibility:");
240 _print_error (re_str);
241 } else {
242 status = regexec (&re, renderer, 0, NULL((void*)0), 0);
243 regfree(&re);
244
245 if (status == 0) {
246 if (whitelist)
247 ret = FALSE(0);
248 goto out;
249 }
250 }
251
252 free (line);
253 line = NULL((void*)0);
254 }
255
256 ret = FALSE(0);
257
258out:
259 if (line != NULL((void*)0))
260 free (line);
261
262 if (blacklist != NULL((void*)0))
263 fclose (blacklist);
264
265 return ret;
266}
267
268static char *
269_get_hardware_gl (Display *display)
270{
271 int screen;
272 Window root;
273 XVisualInfo *visual = NULL((void*)0);
274 GLXContext context = NULL((void*)0);
275 XSetWindowAttributes cwa = { 0 };
276 Window window = None0L;
277 char *renderer = NULL((void*)0);
278
279 int attrlist[] = {
280 GLX_RGBA4,
281 GLX_RED_SIZE8, 1,
282 GLX_GREEN_SIZE9, 1,
283 GLX_BLUE_SIZE10, 1,
284 GLX_DOUBLEBUFFER5,
285 None0L
286 };
287
288 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
289 root = RootWindow (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
;
290
291 visual = glXChooseVisual (display, screen, attrlist);
292 if (!visual)
293 goto out;
294
295 context = glXCreateContext (display, visual, NULL((void*)0), True1);
296 if (!context)
297 goto out;
298
299 cwa.colormap = XCreateColormap (display, root,
300 visual->visual, AllocNone0);
301 cwa.background_pixel = 0;
302 cwa.border_pixel = 0;
303 window = XCreateWindow (display, root,
304 0, 0, 1, 1, 0,
305 visual->depth, InputOutput1, visual->visual,
306 CWColormap(1L<<13) | CWBackPixel(1L<<1) | CWBorderPixel(1L<<3),
307 &cwa);
308
309 if (!glXMakeCurrent (display, window, context))
310 goto out;
311
312 renderer = g_strdup ((const char *) glGetString (GL_RENDERER))g_strdup_inline ((const char *) glGetString (0x1F01));
313 if (_is_gl_renderer_blacklisted (renderer)) {
314 g_clear_pointer (&renderer, g_free)do { _Static_assert (sizeof *(&renderer) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ ((&renderer
)) _pp = (&renderer); __typeof__ (*(&renderer)) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_free) (_ptr); } while (
0)
;
315 goto out;
316 }
317 if (renderer && strcasestr (renderer, "llvmpipe"))
318 has_llvmpipe = TRUE(!(0));
319
320 /* we need to get the max texture and renderbuffer sizes while we have
321 * a context, but we'll check their values later */
322
323 glGetIntegerv (GL_MAX_TEXTURE_SIZE0x0D33, &max_texture_size);
324 if (glGetError() != GL_NO_ERROR0)
325 max_texture_size = SIZE_ERROR-1;
326
327 glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE_EXT0x84E8, &max_renderbuffer_size);
328 if (glGetError() != GL_NO_ERROR0)
329 max_renderbuffer_size = SIZE_ERROR-1;
330
331out:
332 glXMakeCurrent (display, None0L, None0L);
333 if (context)
334 glXDestroyContext (display, context);
335 if (window)
336 XDestroyWindow (display, window);
337 if (cwa.colormap)
338 XFreeColormap (display, cwa.colormap);
339
340 return renderer;
341}
342
343static gboolean
344_has_extension (const char *extension_list,
345 const char *extension)
346{
347 char **extensions;
348 guint i;
349 gboolean ret;
350
351 g_return_val_if_fail (extension != NULL, TRUE)do { if ((extension != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "extension != NULL"
); return ((!(0))); } } while (0)
;
352
353 /* Extension_list is one big string, containing extensions
354 * separated by spaces. */
355 if (extension_list == NULL((void*)0))
356 return FALSE(0);
357
358 ret = FALSE(0);
359
360 extensions = g_strsplit (extension_list, " ", -1);
361 if (extensions == NULL((void*)0))
362 return FALSE(0);
363
364 for (i = 0; extensions[i] != NULL((void*)0); i++) {
365 if (g_str_equal (extensions[i], extension)(strcmp ((const char *) (extensions[i]), (const char *) (extension
)) == 0)
) {
366 ret = TRUE(!(0));
367 break;
368 }
369 }
370
371 g_strfreev (extensions);
372
373 return ret;
374}
375
376static gboolean
377_has_texture_from_pixmap (Display *display)
378{
379 int screen;
380 const char *server_extensions;
381 const char *client_extensions;
382 gboolean ret = FALSE(0);
383
384 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
385
386 server_extensions = glXQueryServerString (display, screen,
387 GLX_EXTENSIONS3);
388 if (!_has_extension (server_extensions,
389 "GLX_EXT_texture_from_pixmap"))
390 goto out;
391
392 client_extensions = glXGetClientString (display, GLX_EXTENSIONS3);
393 if (!_has_extension (client_extensions,
394 "GLX_EXT_texture_from_pixmap"))
395 goto out;
396
397 ret = TRUE(!(0));
398
399out:
400 return ret;
401}
402
403static void
404_set_max_screen_size_property (Display *display, int screen, int size)
405{
406 Atom max_screen_size_atom;
407
408 max_screen_size_atom = XInternAtom (display, "_GNOME_MAX_SCREEN_SIZE",
409 False0);
410
411 /* Will be read by gnome-settings-daemon and
412 * gnome-control-center to avoid display configurations where 3D
413 * is not available (and would break gnome-shell) */
414 XChangeProperty (display, RootWindow(display, screen)((&((_XPrivDisplay)(display))->screens[screen])->root
)
,
415 max_screen_size_atom,
416 XA_CARDINAL((Atom) 6), 32, PropModeReplace0,
417 (unsigned char *)&size, 1);
418
419 XSync(display, False0);
420}
421
422static gboolean
423_is_max_texture_size_big_enough (Display *display)
424{
425 int screen, size;
426
427 screen = DefaultScreen (display)(((_XPrivDisplay)(display))->default_screen);
428 size = MIN(max_renderbuffer_size, max_texture_size)(((max_renderbuffer_size) < (max_texture_size)) ? (max_renderbuffer_size
) : (max_texture_size))
;
429 if (size < DisplayWidth (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->width
)
||
430 size < DisplayHeight (display, screen)((&((_XPrivDisplay)(display))->screens[screen])->height
)
)
431 return FALSE(0);
432
433 _set_max_screen_size_property (display, screen, size);
434
435 return TRUE(!(0));
436}
437
438static gboolean print_renderer = FALSE(0);
439
440static const GOptionEntry entries[] = {
441 { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print GL renderer name", NULL((void*)0) },
442 { NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0) },
443};
444
445int
446main (int argc, char **argv)
447{
448 int kcmdline_parsed;
449 Display *display = NULL((void*)0);
450 int ret = HELPER_NO_ACCEL1;
451 GOptionContext *context;
452 GError *error = NULL((void*)0);
453 char *renderer = NULL((void*)0);
454
455 setlocale (LC_ALL6, "");
456
457 context = g_option_context_new (NULL((void*)0));
458 g_option_context_add_main_entries (context, entries, NULL((void*)0));
459
460 if (!g_option_context_parse (context, &argc, &argv, &error)) {
461 g_error ("Can't parse command line: %s\n", error->message);
462 g_error_free (error);
463 goto out;
464 }
465
466 kcmdline_parsed = _parse_kcmdline ();
467 if (kcmdline_parsed > CMDLINE_UNSET-1) {
468 if (kcmdline_parsed == CMDLINE_NON_FALLBACK_FORCED0) {
469 _print_error ("Non-fallback mode forced by kernel command line.");
470 ret = HELPER_ACCEL0;
471 goto out;
472 } else if (kcmdline_parsed == CMDLINE_FALLBACK_FORCED1) {
473 _print_error ("Fallback mode forced by kernel command line.");
474 goto out;
475 }
476 }
477
478 display = XOpenDisplay (NULL((void*)0));
479 if (!display) {
480 _print_error ("No X display.");
481 goto out;
482 }
483
484 if (!_has_composite (display)) {
485 _print_error ("No composite extension.");
486 goto out;
487 }
488
489 renderer = _get_hardware_gl (display);
490 if (!renderer) {
491 _print_error ("No hardware 3D support.");
492 goto out;
493 }
494
495 if (!_has_texture_from_pixmap (display)) {
496 _print_error ("No GLX_EXT_texture_from_pixmap support.");
497 goto out;
498 }
499
500 if (!_is_max_texture_size_big_enough (display)) {
501 _print_error ("GL_MAX_{TEXTURE,RENDERBUFFER}_SIZE is too small.");
502 goto out;
503 }
504
505 ret = has_llvmpipe ? HELPER_SOFTWARE_RENDERING2 : HELPER_ACCEL0;
506
507 if (print_renderer)
508 g_print ("%s", renderer);
This statement is never executed
509
510out:
511 if (display)
512 XCloseDisplay (display);
513 g_option_context_free (context);
514 g_free (renderer);
515
516 return ret;
517}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f05804.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f05804.html new file mode 100644 index 0000000..5b8edf0 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f05804.html @@ -0,0 +1,915 @@ + + + +mate-session-check-accelerated-gles-helper.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:tools/mate-session-check-accelerated-gles-helper.c
Warning:line 223, column 25
This statement is never executed
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mate-session-check-accelerated-gles-helper.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/tools -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -D PKGDATADIR="/usr/local/share/mate-session-manager" -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -D LOCALE_DIR="/usr/local/share/locale" -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/tools -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c mate-session-check-accelerated-gles-helper.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- mode:c; c-basic-offset: 8; indent-tabs-mode: nil; -*- */
2/*
3 *
4 * Copyright (C) 2016 Endless Mobile, Inc
5 * Copyright (C) 2016-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * Author:
22 * Cosimo Cecchi <cosimo@endlessm.com>
23 */
24
25/* for strcasestr */
26#define _GNU_SOURCE
27
28#include <config.h>
29
30#include <gtk/gtk.h>
31#include <locale.h>
32#include <stdlib.h>
33#include <string.h>
34
35#ifdef GDK_WINDOWING_X11
36#define GL_GLEXT_PROTOTYPES
37
38#include <gdk/gdkx.h>
39#include <GLES2/gl2.h>
40#include <GLES2/gl2ext.h>
41#include <EGL/egl.h>
42#include <EGL/eglext.h>
43#endif
44
45#include "mate-session-check-accelerated-common.h"
46
47#ifdef GDK_WINDOWING_X11
48static EGLDisplay
49get_display (void *native)
50{
51 EGLDisplay dpy = NULL((void*)0);
52 const char *client_exts = eglQueryString (NULL((void*)0), EGL_EXTENSIONS0x3055);
53
54 if (g_strstr_len (client_exts, -1, "EGL_KHR_platform_base")) {
55 PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display =
56 (void *) eglGetProcAddress ("eglGetPlatformDisplay");
57
58 if (get_platform_display)
59 dpy = get_platform_display (EGL_PLATFORM_X11_KHR0x31D5, native, NULL((void*)0));
60
61 if (dpy)
62 return dpy;
63 }
64
65 if (g_strstr_len (client_exts, -1, "EGL_EXT_platform_base")) {
66 PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display =
67 (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT");
68
69 if (get_platform_display)
70 dpy = get_platform_display (EGL_PLATFORM_X11_KHR0x31D5, native, NULL((void*)0));
71
72 if (dpy)
73 return dpy;
74 }
75
76 return eglGetDisplay ((EGLNativeDisplayType) native);
77}
78
79static char *
80get_gles_renderer (void)
81{
82 /* Select GLESv2 config */
83 EGLint attribs[] = {
84 EGL_RENDERABLE_TYPE0x3040, EGL_OPENGL_ES2_BIT0x0004,
85 EGL_RED_SIZE0x3024, 1,
86 EGL_GREEN_SIZE0x3023, 1,
87 EGL_BLUE_SIZE0x3022, 1,
88 EGL_NONE0x3038
89 };
90
91 EGLint ctx_attribs[] = {
92 EGL_CONTEXT_CLIENT_VERSION0x3098, 2,
93 EGL_NONE0x3038
94 };
95
96 gboolean egl_inited = FALSE(0);
97 GdkDisplay *gdk_dpy;
98 Display *display;
99 Window win = None0L;
100 EGLContext egl_ctx = NULL((void*)0);
101 EGLDisplay egl_dpy = NULL((void*)0);
102 EGLSurface egl_surf = NULL((void*)0);
103 char *renderer = NULL((void*)0);
104
105 gdk_dpy = gdk_display_get_default ();
106 gdk_x11_display_error_trap_push (gdk_dpy);
107 display = GDK_DISPLAY_XDISPLAY (gdk_dpy)(gdk_x11_display_get_xdisplay (gdk_dpy));
108 egl_dpy = get_display (display);
109 if (!egl_dpy) {
110 g_warning ("eglGetDisplay() failed");
111 goto out;
112 }
113
114 EGLint egl_major, egl_minor;
115 if (!eglInitialize (egl_dpy, &egl_major, &egl_minor)) {
116 g_warning ("eglInitialize() failed");
117 goto out;
118 }
119
120 egl_inited = TRUE(!(0));
121
122 EGLint num_configs;
123 EGLConfig config;
124 if (!eglChooseConfig (egl_dpy, attribs, &config, 1, &num_configs)) {
125 g_warning ("Failed to get EGL configuration");
126 goto out;
127 }
128
129 EGLint vid;
130 if (!eglGetConfigAttrib (egl_dpy, config, EGL_NATIVE_VISUAL_ID0x302E, &vid)) {
131 g_warning ("Failed to get EGL visual");
132 goto out;
133 }
134
135 /* The X window visual must match the EGL config */
136 XVisualInfo *vis_info, vis_template;
137 int num_visuals;
138 vis_template.visualid = vid;
139 vis_info = XGetVisualInfo (display, VisualIDMask0x1, &vis_template, &num_visuals);
140 if (!vis_info) {
141 g_warning ("Failed to get X visual");
142 goto out;
143 }
144
145 XSetWindowAttributes attr;
146 attr.colormap = XCreateColormap (display, DefaultRootWindow (display)((&((_XPrivDisplay)(display))->screens[(((_XPrivDisplay
)(display))->default_screen)])->root)
,
147 vis_info->visual, AllocNone0);
148 win = XCreateWindow (display, DefaultRootWindow (display)((&((_XPrivDisplay)(display))->screens[(((_XPrivDisplay
)(display))->default_screen)])->root)
,
149 0, 0, /* x, y */
150 1, 1, /* width, height */
151 0, /* border_width */
152 vis_info->depth, InputOutput1,
153 vis_info->visual, CWColormap(1L<<13), &attr);
154 XFree (vis_info);
155
156 eglBindAPI (EGL_OPENGL_ES_API0x30A0);
157
158 egl_ctx = eglCreateContext (egl_dpy, config, EGL_NO_CONTEXT((EGLContext) (0)), ctx_attribs);
159 if (!egl_ctx) {
160 g_warning ("Failed to create EGL context");
161 goto out;
162 }
163
164 egl_surf = eglCreateWindowSurface (egl_dpy, config, win, NULL((void*)0));
165 if (!egl_surf) {
166 g_warning ("Failed to create EGL surface");
167 goto out;
168 }
169
170 if (!eglMakeCurrent (egl_dpy, egl_surf, egl_surf, egl_ctx)) {
171 g_warning ("eglMakeCurrent() failed");
172 goto out;
173 }
174
175 renderer = g_strdup ((const char *) glGetString (GL_RENDERER))g_strdup_inline ((const char *) glGetString (0x1F01));
176
177 out:
178 if (egl_ctx)
179 eglDestroyContext (egl_dpy, egl_ctx);
180 if (egl_surf)
181 eglDestroySurface (egl_dpy, egl_surf);
182 if (egl_inited)
183 eglTerminate (egl_dpy);
184 if (win != None0L)
185 XDestroyWindow (display, win);
186
187 gdk_x11_display_error_trap_pop_ignored (gdk_dpy);
188 return renderer;
189}
190#endif
191
192static gboolean print_renderer = FALSE(0);
193
194static const GOptionEntry entries[] = {
195 { "print-renderer", 'p', 0, G_OPTION_ARG_NONE, &print_renderer, "Print EGL renderer name", NULL((void*)0) },
196 { NULL((void*)0), 0, 0, G_OPTION_ARG_NONE, NULL((void*)0), NULL((void*)0), NULL((void*)0) },
197};
198
199int
200main (int argc,
201 char **argv)
202{
203 GOptionContext *context;
204 int ret = HELPER_NO_ACCEL1;
205 GError *error = NULL((void*)0);
206
207 setlocale (LC_ALL6, "");
208
209 context = g_option_context_new (NULL((void*)0));
210 g_option_context_add_group (context, gtk_get_option_group (TRUE(!(0))));
211 g_option_context_add_main_entries (context, entries, NULL((void*)0));
212
213 if (!g_option_context_parse (context, &argc, &argv, &error)) {
214 g_error ("Can't parse command line: %s\n", error->message);
215 g_error_free (error);
216 goto out;
217 }
218
219#ifdef GDK_WINDOWING_X11
220 char *renderer = get_gles_renderer ();
221 if (renderer != NULL((void*)0)) {
222 if (print_renderer)
223 g_print ("%s", renderer);
This statement is never executed
224 if (strcasestr (renderer, "llvmpipe"))
225 ret = HELPER_SOFTWARE_RENDERING2;
226 else
227 ret = HELPER_ACCEL0;
228 }
229 g_free (renderer);
230#endif
231
232out:
233 g_option_context_free (context);
234 return ret;
235}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f291f4.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f291f4.html new file mode 100644 index 0000000..3ac069a --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-f291f4.html @@ -0,0 +1,1477 @@ + + + +main.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/main.c
Warning:line 441, column 2
Value stored to 'ret' is never read
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c main.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2006 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2012-2021 MATE Developers
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23#include <config.h>
24
25#include <signal.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <errno(*__errno_location ()).h>
30#include <time.h>
31
32#include <glib/gi18n.h>
33#include <glib.h>
34#include <gtk/gtk.h>
35#include <gio/gio.h>
36
37#include <dbus/dbus.h>
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-bindings.h>
40#include <dbus/dbus-glib-lowlevel.h>
41
42#include "mdm-signal-handler.h"
43#include "mdm-log.h"
44
45#include "gsm-consolekit.h"
46#ifdef HAVE_SYSTEMD1
47#include "gsm-systemd.h"
48#endif
49#include "gsm-util.h"
50#include "gsm-manager.h"
51#include "gsm-xsmp-server.h"
52#include "gsm-store.h"
53
54#include "msm-gnome.h"
55
56#define GSM_SCHEMA"org.mate.session" "org.mate.session"
57#define GSM_DEFAULT_SESSION_KEY"default-session" "default-session"
58#define GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components" GSM_SCHEMA"org.mate.session" ".required-components"
59#define GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list" "required-components-list"
60
61#define ACCESSIBILITY_KEY"accessibility" "accessibility"
62#define ACCESSIBILITY_SCHEMA"org.mate.interface" "org.mate.interface"
63
64#define DEBUG_SCHEMA"org.mate.debug" "org.mate.debug"
65#define DEBUG_KEY"mate-session" "mate-session"
66
67#define VISUAL_SCHEMA"org.mate.applications-at-visual" "org.mate.applications-at-visual"
68#define VISUAL_KEY"exec" "exec"
69#define VISUAL_STARTUP_KEY"startup" "startup"
70
71#define MOBILITY_SCHEMA"org.mate.applications-at-mobility" "org.mate.applications-at-mobility"
72#define MOBILITY_KEY"exec" "exec"
73#define MOBILITY_STARTUP_KEY"startup" "startup"
74
75#define MATE_INTERFACE_SCHEMA"org.mate.interface" "org.mate.interface"
76#define GTK_OVERLAY_SCROLL"gtk-overlay-scrolling" "gtk-overlay-scrolling"
77
78#define GSM_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
79
80#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
81
82static gboolean failsafe = FALSE(0);
83static gboolean show_version = FALSE(0);
84static gboolean debug = FALSE(0);
85static gboolean disable_acceleration_check = FALSE(0);
86
87static gboolean
88initialize_gsettings (void)
89{
90 GSettings* settings;
91 time_t now = time (0);
92 gboolean ret;
93
94 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
95
96 if (!settings)
97 return FALSE(0);
98
99 ret = g_settings_set_int (settings, "session-start", now);
100
101 g_settings_sync ();
102
103 g_object_unref (settings);
104
105 return ret;
106}
107
108static void on_bus_name_lost(DBusGProxy* bus_proxy, const char* name, gpointer data)
109{
110 g_warning("Lost name on bus: %s, exiting", name);
111 exit(1);
112}
113
114static gboolean acquire_name_on_proxy(DBusGProxy* bus_proxy, const char* name)
115{
116 GError* error;
117 guint result;
118 gboolean res;
119 gboolean ret;
120
121 ret = FALSE(0);
122
123 if (bus_proxy == NULL((void*)0))
124 {
125 goto out;
126 }
127
128 error = NULL((void*)0);
129 res = dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING((GType) ((16) << (2))), name, G_TYPE_UINT((GType) ((7) << (2))), 0, G_TYPE_INVALID((GType) ((0) << (2))), G_TYPE_UINT((GType) ((7) << (2))), &result, G_TYPE_INVALID((GType) ((0) << (2))));
130
131 if (! res)
132 {
133 if (error != NULL((void*)0))
134 {
135 g_warning("Failed to acquire %s: %s", name, error->message);
136 g_error_free(error);
137 }
138 else
139 {
140 g_warning ("Failed to acquire %s", name);
141 }
142
143 goto out;
144 }
145
146 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER1)
147 {
148 if (error != NULL((void*)0))
149 {
150 g_warning("Failed to acquire %s: %s", name, error->message);
151 g_error_free(error);
152 }
153 else
154 {
155 g_warning("Failed to acquire %s", name);
156 }
157
158 goto out;
159 }
160
161 /* register for name lost */
162 dbus_g_proxy_add_signal(bus_proxy, "NameLost", G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_INVALID((GType) ((0) << (2))));
163 dbus_g_proxy_connect_signal(bus_proxy, "NameLost", G_CALLBACK(on_bus_name_lost)((GCallback) (on_bus_name_lost)), NULL((void*)0), NULL((void*)0));
164
165 ret = TRUE(!(0));
166
167 out:
168
169 return ret;
170}
171
172static gboolean acquire_name(void)
173{
174 DBusGProxy* bus_proxy;
175 GError* error;
176 DBusGConnection* connection;
177
178 error = NULL((void*)0);
179 connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
180
181 if (connection == NULL((void*)0))
182 {
183 gsm_util_init_error(TRUE(!(0)), "Could not connect to session bus: %s", error->message);
184 /* not reached */
185 }
186
187 bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS"org.freedesktop.DBus", DBUS_PATH_DBUS"/org/freedesktop/DBus", DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
188
189 if (!acquire_name_on_proxy(bus_proxy, GSM_DBUS_NAME"org.gnome.SessionManager"))
190 {
191 gsm_util_init_error(TRUE(!(0)), "%s", "Could not acquire name on session bus");
192 /* not reached */
193 }
194
195 g_object_unref(bus_proxy);
196
197 return TRUE(!(0));
198}
199
200/* This doesn't contain the required components, so we need to always
201 * call append_required_apps() after a call to append_default_apps(). */
202static void append_default_apps(GsmManager* manager, const char* default_session_key, char** autostart_dirs)
203{
204 gint i;
205 gchar** default_apps;
206 GSettings* settings;
207
208 g_debug("main: *** Adding default apps");
209
210 g_assert(default_session_key != NULL)do { if (default_session_key != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 210, ((const char*) (__func__)), "default_session_key != NULL"
); } while (0)
;
211 g_assert(autostart_dirs != NULL)do { if (autostart_dirs != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 211, ((const char*) (__func__)), "autostart_dirs != NULL"
); } while (0)
;
212
213 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
214 default_apps = g_settings_get_strv (settings, default_session_key);
215 g_object_unref(settings);
216
217 for (i = 0; default_apps[i]; i++)
218 {
219 char* app_path;
220
221 if (IS_STRING_EMPTY((char*) default_apps[i])(((char*) default_apps[i])==((void*)0)||((char*) default_apps
[i])[0]=='\0')
)
222 {
223 continue;
224 }
225
226 app_path = gsm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs);
227
228 if (app_path != NULL((void*)0))
229 {
230 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
231 g_free(app_path);
232 }
233 }
234
235 g_strfreev (default_apps);
236}
237
238static void append_required_apps(GsmManager* manager)
239{
240 gchar** required_components;
241 gint i;
242 GSettings* settings;
243 GSettings* settings_required_components;
244
245 g_debug("main: *** Adding required apps");
246
247 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
248 settings_required_components = g_settings_new (GSM_REQUIRED_COMPONENTS_SCHEMA"org.mate.session" ".required-components");
249
250 required_components = g_settings_get_strv(settings, GSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list");
251
252 if (required_components == NULL((void*)0))
253 {
254 g_warning("No required applications specified");
255 }
256 else
257 {
258 for (i = 0; required_components[i]; i++)
259 {
260 char* default_provider;
261 const char* component;
262
263 if (IS_STRING_EMPTY((char*) required_components[i])(((char*) required_components[i])==((void*)0)||((char*) required_components
[i])[0]=='\0')
)
264 {
265 continue;
266 }
267
268 component = required_components[i];
269
270 default_provider = g_settings_get_string (settings_required_components, component);
271
272 g_debug ("main: %s looking for component: '%s'", component, default_provider);
273
274 if (default_provider != NULL((void*)0))
275 {
276 char* app_path;
277
278 app_path = gsm_util_find_desktop_file_for_app_name(default_provider, NULL((void*)0));
279
280 if (app_path != NULL((void*)0))
281 {
282 gsm_manager_add_autostart_app(manager, app_path, component);
283 }
284 else
285 {
286 g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component);
287 }
288
289 g_free(app_path);
290 }
291
292 g_free(default_provider);
293 }
294 }
295
296 g_debug("main: *** Done adding required apps");
297
298 g_strfreev(required_components);
299
300 g_object_unref(settings);
301 g_object_unref(settings_required_components);
302}
303
304static void append_accessibility_apps(GsmManager* manager)
305{
306 GSettings* mobility_settings;
307 GSettings* visual_settings;
308
309 g_debug("main: *** Adding accesibility apps");
310
311 mobility_settings = g_settings_new (MOBILITY_SCHEMA"org.mate.applications-at-mobility");
312 visual_settings = g_settings_new (VISUAL_SCHEMA"org.mate.applications-at-visual");
313
314 if (g_settings_get_boolean (mobility_settings, MOBILITY_STARTUP_KEY"startup"))
315 {
316 gchar *mobility_exec;
317 mobility_exec = g_settings_get_string (mobility_settings, MOBILITY_KEY"exec");
318 if (mobility_exec != NULL((void*)0) && mobility_exec[0] != 0)
319 {
320 char* app_path;
321 app_path = gsm_util_find_desktop_file_for_app_name(mobility_exec, NULL((void*)0));
322 if (app_path != NULL((void*)0))
323 {
324 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
325 g_free (app_path);
326 }
327 g_free (mobility_exec);
328 }
329 }
330
331 if (g_settings_get_boolean (visual_settings, VISUAL_STARTUP_KEY"startup"))
332 {
333 gchar *visual_exec;
334 visual_exec = g_settings_get_string (visual_settings, VISUAL_KEY"exec");
335 if (visual_exec != NULL((void*)0) && visual_exec[0] != 0)
336 {
337 char* app_path;
338 app_path = gsm_util_find_desktop_file_for_app_name(visual_exec, NULL((void*)0));
339 if (app_path != NULL((void*)0))
340 {
341 gsm_manager_add_autostart_app(manager, app_path, NULL((void*)0));
342 g_free (app_path);
343 }
344 g_free (visual_exec);
345 }
346 }
347
348 g_object_unref (mobility_settings);
349 g_object_unref (visual_settings);
350}
351
352static void maybe_load_saved_session_apps(GsmManager* manager)
353{
354 GsmConsolekit* consolekit = NULL((void*)0);
355#ifdef HAVE_SYSTEMD1
356 GsmSystemd* systemd = NULL((void*)0);
357#endif
358 char* session_type;
359 gboolean is_login;
360
361#ifdef HAVE_SYSTEMD1
362 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
363 systemd = gsm_get_systemd();
364 session_type = gsm_systemd_get_current_session_type(systemd);
365 is_login = g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0;
366 }
367 else {
368#endif
369 consolekit = gsm_get_consolekit();
370 session_type = gsm_consolekit_get_current_session_type(consolekit);
371 is_login = g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0;
372#ifdef HAVE_SYSTEMD1
373 }
374#endif
375
376 if (!is_login)
377 {
378 GSettings* settings;
379 gboolean autostart;
380
381 settings = g_settings_new (GSM_SCHEMA"org.mate.session");
382 autostart = g_settings_get_boolean (settings, KEY_AUTOSAVE"auto-save-session");
383 g_object_unref (settings);
384
385 if (autostart == TRUE(!(0)))
386 gsm_manager_add_autostart_apps_from_dir(manager, gsm_util_get_saved_session_dir());
387 }
388
389 if (consolekit != NULL((void*)0))
390 g_object_unref(consolekit);
391#ifdef HAVE_SYSTEMD1
392 if (systemd != NULL((void*)0))
393 g_object_unref(systemd);
394#endif
395 g_free(session_type);
396}
397
398static void load_standard_apps (GsmManager* manager, const char* default_session_key)
399{
400 char** autostart_dirs;
401 int i;
402
403 autostart_dirs = gsm_util_get_autostart_dirs();
404
405 if (!failsafe)
406 {
407 maybe_load_saved_session_apps(manager);
408
409 for (i = 0; autostart_dirs[i]; i++)
410 {
411 gsm_manager_add_autostart_apps_from_dir(manager, autostart_dirs[i]);
412 }
413 }
414
415 /* We do this at the end in case a saved session contains an
416 * application that already provides one of the components. */
417 append_default_apps(manager, default_session_key, autostart_dirs);
418 append_required_apps(manager);
419 append_accessibility_apps(manager);
420
421 g_strfreev(autostart_dirs);
422}
423
424static void load_override_apps(GsmManager* manager, char** override_autostart_dirs)
425{
426 int i;
427
428 for (i = 0; override_autostart_dirs[i]; i++)
429 {
430 gsm_manager_add_autostart_apps_from_dir(manager, override_autostart_dirs[i]);
431 }
432}
433
434static gboolean signal_cb(int signo, gpointer data)
435{
436 int ret;
437 GsmManager* manager;
438
439 g_debug("Got callback for signal %d", signo);
440
441 ret = TRUE(!(0));
Value stored to 'ret' is never read
442
443 switch (signo)
444 {
445 case SIGFPE8:
446 case SIGPIPE13:
447 /* let the fatal signals interrupt us */
448 g_debug ("Caught signal %d, shutting down abnormally.", signo);
449 ret = FALSE(0);
450 break;
451 case SIGINT2:
452 case SIGTERM15:
453 manager = (GsmManager*) data;
454 gsm_manager_logout(manager, GSM_MANAGER_LOGOUT_MODE_FORCE, NULL((void*)0));
455
456 /* let the fatal signals interrupt us */
457 g_debug("Caught signal %d, shutting down normally.", signo);
458 ret = TRUE(!(0));
459 break;
460 case SIGHUP1:
461 g_debug("Got HUP signal");
462 ret = TRUE(!(0));
463 break;
464 case SIGUSR110:
465 g_debug("Got USR1 signal");
466 ret = TRUE(!(0));
467 mdm_log_toggle_debug();
468 break;
469 default:
470 g_debug("Caught unhandled signal %d", signo);
471 ret = TRUE(!(0));
472
473 break;
474 }
475
476 return ret;
477}
478
479static void shutdown_cb(gpointer data)
480{
481 GsmManager* manager = (GsmManager*) data;
482 g_debug("Calling shutdown callback function");
483
484 /*
485 * When the signal handler gets a shutdown signal, it calls
486 * this function to inform GsmManager to not restart
487 * applications in the off chance a handler is already queued
488 * to dispatch following the below call to gtk_main_quit.
489 */
490 gsm_manager_set_phase(manager, GSM_MANAGER_PHASE_EXIT);
491
492 gtk_main_quit();
493}
494
495static gboolean require_dbus_session(int argc, char** argv, GError** error)
496{
497 char** new_argv;
498 int i;
499
500 if (g_getenv("DBUS_SESSION_BUS_ADDRESS"))
501 {
502 return TRUE(!(0));
503 }
504
505 /* Just a sanity check to prevent infinite recursion if
506 * dbus-launch fails to set DBUS_SESSION_BUS_ADDRESS
507 */
508 g_return_val_if_fail(!g_str_has_prefix(argv[0], "dbus-launch"), TRUE)do { if ((!(__builtin_constant_p ("dbus-launch")? __extension__
({ const char * const __str = (argv[0]); const char * const __prefix
= ("dbus-launch"); gboolean __result = (0); if (__str == ((void
*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix)
(__str, __prefix); else { const size_t __str_len = strlen ((
(__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (argv[0], "dbus-launch"
) ))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const
char*) (__func__)), "!g_str_has_prefix(argv[0], \"dbus-launch\")"
); return ((!(0))); } } while (0)
;
509
510 /* +2 for our new arguments, +1 for NULL */
511 new_argv = g_malloc(argc + 3 * sizeof (*argv));
512
513 new_argv[0] = "dbus-launch";
514 new_argv[1] = "--exit-with-session";
515
516 for (i = 0; i < argc; i++)
517 {
518 new_argv[i + 2] = argv[i];
519 }
520
521 new_argv[i + 2] = NULL((void*)0);
522
523 if (!execvp("dbus-launch", new_argv))
524 {
525 g_set_error(error, G_SPAWN_ERRORg_spawn_error_quark (), G_SPAWN_ERROR_FAILED, "No session bus and could not exec dbus-launch: %s", g_strerror(errno(*__errno_location ())));
526 g_free (new_argv);
527 return FALSE(0);
528 }
529
530 g_free (new_argv);
531
532 /* Should not be reached */
533 return TRUE(!(0));
534}
535
536static void
537debug_changed (GSettings *settings, gchar *key, gpointer user_data)
538{
539 debug = g_settings_get_boolean (settings, DEBUG_KEY"mate-session");
540 mdm_log_set_debug (debug);
541}
542
543static gboolean
544schema_exists (const gchar* schema_name)
545{
546 GSettingsSchemaSource *source;
547 GSettingsSchema *schema;
548 gboolean exists;
549
550 source = g_settings_schema_source_get_default();
551 schema = g_settings_schema_source_lookup (source, schema_name, FALSE(0));
552 exists = (schema != NULL((void*)0));
553 if (schema)
554 g_settings_schema_unref (schema);
555
556 return exists;
557}
558
559static void set_overlay_scroll (void)
560{
561 GSettings *settings;
562 gboolean enabled;
563
564 settings = g_settings_new (MATE_INTERFACE_SCHEMA"org.mate.interface");
565 enabled = g_settings_get_boolean (settings, GTK_OVERLAY_SCROLL"gtk-overlay-scrolling");
566
567 if (enabled) {
568 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "1");
569 } else {
570 gsm_util_setenv ("GTK_OVERLAY_SCROLLING", "0");
571 }
572
573 g_object_unref (settings);
574}
575
576static gboolean
577check_gl (gchar **gl_renderer, GError **error)
578{
579 int status;
580 char *argv[] = { LIBEXECDIR"/usr/local/libexec" "/mate-session-check-accelerated", NULL((void*)0) };
581
582 if (getenv ("DISPLAY") == NULL((void*)0)) {
583 /* Not connected to X11, someone else will take care of checking GL */
584 return TRUE(!(0));
585 }
586
587 if (!g_spawn_sync (NULL((void*)0), (char **) argv, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), gl_renderer, NULL((void*)0),
588 &status, error)) {
589 return FALSE(0);
590 }
591
592 return g_spawn_check_exit_status (status, error);
593}
594
595int main(int argc, char** argv)
596{
597 struct sigaction sa;
598 GError* error;
599 const char* display_str;
600 GsmManager* manager;
601 GsmStore* client_store;
602 GsmXsmpServer* xsmp_server;
603 GSettings* debug_settings = NULL((void*)0);
604 GSettings* accessibility_settings;
605 MdmSignalHandler* signal_handler;
606 static char** override_autostart_dirs = NULL((void*)0);
607 char* gl_renderer = NULL((void*)0);
608 gboolean gl_failed = FALSE(0);
609
610 static GOptionEntry entries[] = {
611 {"autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories")("Override standard autostart directories"), NULL((void*)0)},
612 {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code")("Enable debugging code"), NULL((void*)0)},
613 {"failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications")("Do not load user-specified applications"), NULL((void*)0)},
614 {"version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application")("Version of this application"), NULL((void*)0)},
615 { "disable-acceleration-check", 0, 0, G_OPTION_ARG_NONE, &disable_acceleration_check, N_("Disable hardware acceleration check")("Disable hardware acceleration check"), NULL((void*)0) },
616 {NULL((void*)0), 0, 0, 0, NULL((void*)0), NULL((void*)0), NULL((void*)0) }
617 };
618
619 /* Make sure that we have a session bus */
620 if (!require_dbus_session(argc, argv, &error))
621 {
622 gsm_util_init_error(TRUE(!(0)), "%s", error->message);
623 }
624
625#ifdef ENABLE_NLS1
626 bindtextdomain(GETTEXT_PACKAGE"mate-session-manager", LOCALE_DIR"/usr/local/share/locale");
627 bind_textdomain_codeset(GETTEXT_PACKAGE"mate-session-manager", "UTF-8");
628 textdomain(GETTEXT_PACKAGE"mate-session-manager");
629#endif /* ENABLE_NLS */
630
631 sa.sa_handler__sigaction_handler.sa_handler = SIG_IGN((__sighandler_t) 1);
632 sa.sa_flags = 0;
633 sigemptyset(&sa.sa_mask);
634 sigaction(SIGPIPE13, &sa, 0);
635
636 error = NULL((void*)0);
637 gtk_init_with_args(&argc, &argv, (char*) _(" - the MATE session manager")gettext (" - the MATE session manager"), entries, GETTEXT_PACKAGE"mate-session-manager", &error);
638
639 if (error != NULL((void*)0))
640 {
641 g_warning("%s", error->message);
642 exit(1);
643 }
644
645 if (show_version)
646 {
647 g_print("%s %s\n", g_get_application_name(), VERSION"1.27.0");
648 exit(1);
649 }
650
651 gsm_util_export_activation_environment (NULL((void*)0));
652
653#ifdef HAVE_SYSTEMD1
654 gsm_util_export_user_environment (NULL((void*)0));
655#endif
656
657 mdm_log_init();
658
659 /* Allows to enable/disable debug from GSettings only if it is not set from argument */
660 if (!debug && schema_exists(DEBUG_SCHEMA"org.mate.debug"))
661 {
662 debug_settings = g_settings_new (DEBUG_SCHEMA"org.mate.debug");
663 g_signal_connect (debug_settings, "changed::" DEBUG_KEY, G_CALLBACK (debug_changed), NULL)g_signal_connect_data ((debug_settings), ("changed::" "mate-session"
), (((GCallback) (debug_changed))), (((void*)0)), ((void*)0),
(GConnectFlags) 0)
;
664 debug = g_settings_get_boolean (debug_settings, DEBUG_KEY"mate-session");
665 }
666
667 mdm_log_set_debug(debug);
668
669 if (disable_acceleration_check) {
670 g_debug ("hardware acceleration check is disabled");
671 } else {
672 /* Check GL, if it doesn't work out then force software fallback */
673 if (!check_gl (&gl_renderer, &error)) {
674 gl_failed = TRUE(!(0));
675
676 g_debug ("hardware acceleration check failed: %s",
677 error? error->message : "");
678 g_clear_error (&error);
679 if (g_getenv ("LIBGL_ALWAYS_SOFTWARE") == NULL((void*)0)) {
680 g_setenv ("LIBGL_ALWAYS_SOFTWARE", "1", TRUE(!(0)));
681 if (!check_gl (&gl_renderer, &error)) {
682 g_warning ("software acceleration check failed: %s",
683 error? error->message : "");
684 g_clear_error (&error);
685 } else {
686 gl_failed = FALSE(0);
687 }
688 }
689 }
690 }
691
692 if (gl_failed) {
693 g_warning ("gl_failed!");
694 }
695
696 if (g_getenv ("XDG_CURRENT_DESKTOP") == NULL((void*)0))
697 gsm_util_setenv ("XDG_CURRENT_DESKTOP", "MATE");
698
699 /* Set DISPLAY explicitly for all our children, in case --display
700 * was specified on the command line.
701 */
702 display_str = gdk_display_get_name (gdk_display_get_default());
703 gsm_util_setenv("DISPLAY", display_str);
704
705 /* Some third-party programs rely on MATE_DESKTOP_SESSION_ID to
706 * detect if MATE is running. We keep this for compatibility reasons.
707 */
708 gsm_util_setenv("MATE_DESKTOP_SESSION_ID", "this-is-deprecated");
709
710 /*
711 * Make sure gsettings is set up correctly. If not, then bail.
712 */
713
714 if (initialize_gsettings () != TRUE(!(0)))
715 exit (1);
716
717 /* Look if accessibility is enabled */
718 accessibility_settings = g_settings_new (ACCESSIBILITY_SCHEMA"org.mate.interface");
719 if (g_settings_get_boolean (accessibility_settings, ACCESSIBILITY_KEY"accessibility"))
720 {
721 gsm_util_setenv("GTK_MODULES", "gail:atk-bridge");
722 }
723 g_object_unref (accessibility_settings);
724
725 client_store = gsm_store_new();
726
727 xsmp_server = gsm_xsmp_server_new(client_store);
728
729 /* Now make sure they succeeded. (They'll call
730 * gsm_util_init_error() if they failed.)
731 */
732 acquire_name();
733
734 /* Starts gnome compat mode */
735 msm_gnome_start();
736
737 /* Set to use Gtk3 overlay scroll */
738 set_overlay_scroll ();
739
740 manager = gsm_manager_new(client_store, failsafe);
741
742 signal_handler = mdm_signal_handler_new();
743 mdm_signal_handler_add_fatal(signal_handler);
744 mdm_signal_handler_add(signal_handler, SIGFPE8, signal_cb, NULL((void*)0));
745 mdm_signal_handler_add(signal_handler, SIGHUP1, signal_cb, NULL((void*)0));
746 mdm_signal_handler_add(signal_handler, SIGUSR110, signal_cb, NULL((void*)0));
747 mdm_signal_handler_add(signal_handler, SIGTERM15, signal_cb, manager);
748 mdm_signal_handler_add(signal_handler, SIGINT2, signal_cb, manager);
749 mdm_signal_handler_set_fatal_func(signal_handler, shutdown_cb, manager);
750
751 if (override_autostart_dirs != NULL((void*)0))
752 {
753 load_override_apps(manager, override_autostart_dirs);
754 }
755 else
756 {
757 load_standard_apps(manager, GSM_DEFAULT_SESSION_KEY"default-session");
758 }
759
760 gsm_xsmp_server_start(xsmp_server);
761 _gsm_manager_set_renderer (manager, gl_renderer);
762 gsm_manager_start(manager);
763
764 gtk_main();
765
766 if (xsmp_server != NULL((void*)0))
767 {
768 g_object_unref(xsmp_server);
769 }
770
771 if (manager != NULL((void*)0))
772 {
773 g_debug("Unreffing manager");
774 g_object_unref(manager);
775 }
776
777 if (gl_renderer != NULL((void*)0))
778 {
779 g_free (gl_renderer);
780 }
781
782 if (client_store != NULL((void*)0))
783 {
784 g_object_unref(client_store);
785 }
786
787 if (debug_settings != NULL((void*)0))
788 {
789 g_object_unref(debug_settings);
790 }
791
792 msm_gnome_stop();
793 mdm_log_shutdown();
794
795 return 0;
796}
797
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/report-fc5e64.html b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-fc5e64.html new file mode 100644 index 0000000..37aba37 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/report-fc5e64.html @@ -0,0 +1,4937 @@ + + + +gsm-manager.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:mate-session/gsm-manager.c
Warning:line 919, column 9
Value stored to 'reply' is never read
+ +

Annotated Source Code

+

Press '?' + to see keyboard shortcuts

+ + +
clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gsm-manager.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/mate-session -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/libxml2 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib64/dbus-1.0/include -I ../mate-submodules/libegg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/mate-session" -D LIBEXECDIR="/usr/local/libexec" -D GTKBUILDER_DIR="/usr/local/share/mate-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib64/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/mate-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-checker security.insecureAPI.strcpy -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-09-04-022211-5825-1 -x c gsm-manager.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
6 * Copyright (C) 2012-2021 MATE Developers
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <string.h>
31#include <signal.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34
35#include <glib.h>
36#include <glib/gi18n.h>
37#include <glib/gstdio.h>
38#include <glib-object.h>
39#include <dbus/dbus-glib.h>
40#include <dbus/dbus-glib-lowlevel.h>
41
42#include <gtk/gtk.h> /* for logout dialog */
43#include <gio/gio.h> /* for gsettings */
44#include <gdk/gdkx.h>
45
46#include "gsm-manager.h"
47#include "gsm-manager-glue.h"
48
49#include "gsm-store.h"
50#include "gsm-inhibitor.h"
51#include "gsm-presence.h"
52
53#include "gsm-xsmp-client.h"
54#include "gsm-dbus-client.h"
55
56#include "gsm-autostart-app.h"
57
58#include "gsm-util.h"
59#include "mdm.h"
60#include "gsm-logout-dialog.h"
61#include "gsm-inhibit-dialog.h"
62#include "gsm-consolekit.h"
63#ifdef HAVE_SYSTEMD1
64#include "gsm-systemd.h"
65#endif
66#include "gsm-session-save.h"
67
68#define GSM_MANAGER_GET_PRIVATE(o)(((GsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((gsm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
+)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate)((GsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((gsm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
+
)
69
70#define GSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager" "/org/gnome/SessionManager"
71#define GSM_MANAGER_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
72
73#define GSM_MANAGER_PHASE_TIMEOUT30 30 /* seconds */
74
75/* In the exit phase, all apps were already given the chance to inhibit the session end
76 * At that stage we don't want to wait much for apps to respond, we want to exit, and fast.
77 */
78#define GSM_MANAGER_EXIT_PHASE_TIMEOUT1 1 /* seconds */
79
80#define MDM_FLEXISERVER_COMMAND"mdmflexiserver" "mdmflexiserver"
81#define MDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
82
83#define GDM_FLEXISERVER_COMMAND"gdmflexiserver" "gdmflexiserver"
84#define GDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
85
86#define LOCKDOWN_SCHEMA"org.mate.lockdown" "org.mate.lockdown"
87#define KEY_LOCK_DISABLE"disable-lock-screen" "disable-lock-screen"
88#define KEY_LOG_OUT_DISABLE"disable-log-out" "disable-log-out"
89#define KEY_USER_SWITCH_DISABLE"disable-user-switching" "disable-user-switching"
90
91#define SESSION_SCHEMA"org.mate.session" "org.mate.session"
92#define KEY_IDLE_DELAY"idle-delay" "idle-delay"
93#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
94
95#define SCREENSAVER_SCHEMA"org.mate.screensaver" "org.mate.screensaver"
96#define KEY_SLEEP_LOCK"lock-enabled" "lock-enabled"
97
98#ifdef __GNUC__4
99#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
100#else
101#define UNUSED_VARIABLE__attribute__ ((unused))
102#endif
103
104typedef enum
105{
106 GSM_MANAGER_LOGOUT_NONE,
107 GSM_MANAGER_LOGOUT_LOGOUT,
108 GSM_MANAGER_LOGOUT_REBOOT,
109 GSM_MANAGER_LOGOUT_REBOOT_INTERACT,
110 GSM_MANAGER_LOGOUT_REBOOT_MDM,
111 GSM_MANAGER_LOGOUT_SHUTDOWN,
112 GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT,
113 GSM_MANAGER_LOGOUT_SHUTDOWN_MDM
114} GsmManagerLogoutType;
115
116typedef struct {
117 gboolean failsafe;
118 GsmStore *clients;
119 GsmStore *inhibitors;
120 GsmStore *apps;
121 GsmPresence *presence;
122
123 /* Current status */
124 GsmManagerPhase phase;
125 guint phase_timeout_id;
126 GSList *pending_apps;
127 GsmManagerLogoutMode logout_mode;
128 GSList *query_clients;
129 guint query_timeout_id;
130 /* This is used for GSM_MANAGER_PHASE_END_SESSION only at the moment,
131 * since it uses a sublist of all running client that replied in a
132 * specific way */
133 GSList *next_query_clients;
134 /* This is the action that will be done just before we exit */
135 GsmManagerLogoutType logout_type;
136
137 GtkWidget *inhibit_dialog;
138
139 /* List of clients which were disconnected due to disabled condition
140 * and shouldn't be automatically restarted */
141 GSList *condition_clients;
142
143 GSettings *settings_session;
144 GSettings *settings_lockdown;
145 GSettings *settings_screensaver;
146
147 char *renderer;
148
149 DBusGProxy *bus_proxy;
150 DBusGConnection *connection;
151 gboolean dbus_disconnected : 1;
152} GsmManagerPrivate;
153
154enum {
155 PROP_0,
156 PROP_CLIENT_STORE,
157 PROP_RENDERER,
158 PROP_FAILSAFE
159};
160
161enum {
162 PHASE_CHANGED,
163 CLIENT_ADDED,
164 CLIENT_REMOVED,
165 INHIBITOR_ADDED,
166 INHIBITOR_REMOVED,
167 SESSION_RUNNING,
168 SESSION_OVER,
169 LAST_SIGNAL
170};
171
172static guint signals [LAST_SIGNAL] = { 0 };
173
174static void gsm_manager_finalize (GObject *object);
175
176static gboolean _log_out_is_locked_down (GsmManager *manager);
177static gboolean _switch_user_is_locked_down (GsmManager *manager);
178
179static void _handle_client_end_session_response (GsmManager *manager,
180 GsmClient *client,
181 gboolean is_ok,
182 gboolean do_last,
183 gboolean cancel,
184 const char *reason);
185
186static gboolean auto_save_is_enabled (GsmManager *manager);
187static void maybe_save_session (GsmManager *manager);
188
189static gpointer manager_object = NULL((void*)0);
190
191G_DEFINE_TYPE_WITH_PRIVATE (GsmManager, gsm_manager, G_TYPE_OBJECT)static void gsm_manager_init (GsmManager *self); static void gsm_manager_class_init
(GsmManagerClass *klass); static GType gsm_manager_get_type_once
(void); static gpointer gsm_manager_parent_class = ((void*)0
); static gint GsmManager_private_offset; static void gsm_manager_class_intern_init
(gpointer klass) { gsm_manager_parent_class = g_type_class_peek_parent
(klass); if (GsmManager_private_offset != 0) g_type_class_adjust_private_offset
(klass, &GsmManager_private_offset); gsm_manager_class_init
((GsmManagerClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer gsm_manager_get_instance_private (GsmManager
*self) { return (((gpointer) ((guint8*) (self) + (glong) (GsmManager_private_offset
)))); } GType gsm_manager_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = gsm_manager_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType gsm_manager_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("GsmManager"
), sizeof (GsmManagerClass), (GClassInitFunc)(void (*)(void))
gsm_manager_class_intern_init, sizeof (GsmManager), (GInstanceInitFunc
)(void (*)(void)) gsm_manager_init, (GTypeFlags) 0); { {{ GsmManager_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (GsmManagerPrivate
)); };} } return g_define_type_id; }
192
193GQuark
194gsm_manager_error_quark (void)
195{
196 static GQuark ret = 0;
197 if (ret == 0) {
198 ret = g_quark_from_static_string ("gsm_manager_error");
199 }
200
201 return ret;
202}
203
204#define ENUM_ENTRY(NAME, DESC){ NAME, "" "NAME" "", DESC } { NAME, "" #NAME "", DESC }
205
206GType
207gsm_manager_error_get_type (void)
208{
209 static GType etype = 0;
210
211 if (etype == 0) {
212 static const GEnumValue values[] = {
213 ENUM_ENTRY (GSM_MANAGER_ERROR_GENERAL, "GeneralError"){ GSM_MANAGER_ERROR_GENERAL, "" "GSM_MANAGER_ERROR_GENERAL" ""
, "GeneralError" }
,
214 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "NotInInitialization"){ GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "" "GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION"
"", "NotInInitialization" }
,
215 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_RUNNING, "NotInRunning"){ GSM_MANAGER_ERROR_NOT_IN_RUNNING, "" "GSM_MANAGER_ERROR_NOT_IN_RUNNING"
"", "NotInRunning" }
,
216 ENUM_ENTRY (GSM_MANAGER_ERROR_ALREADY_REGISTERED, "AlreadyRegistered"){ GSM_MANAGER_ERROR_ALREADY_REGISTERED, "" "GSM_MANAGER_ERROR_ALREADY_REGISTERED"
"", "AlreadyRegistered" }
,
217 ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"){ GSM_MANAGER_ERROR_NOT_REGISTERED, "" "GSM_MANAGER_ERROR_NOT_REGISTERED"
"", "NotRegistered" }
,
218 ENUM_ENTRY (GSM_MANAGER_ERROR_INVALID_OPTION, "InvalidOption"){ GSM_MANAGER_ERROR_INVALID_OPTION, "" "GSM_MANAGER_ERROR_INVALID_OPTION"
"", "InvalidOption" }
,
219 ENUM_ENTRY (GSM_MANAGER_ERROR_LOCKED_DOWN, "LockedDown"){ GSM_MANAGER_ERROR_LOCKED_DOWN, "" "GSM_MANAGER_ERROR_LOCKED_DOWN"
"", "LockedDown" }
,
220 { 0, 0, 0 }
221 };
222
223 g_assert (GSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1)do { if (GSM_MANAGER_NUM_ERRORS == (sizeof (values) / sizeof (
(values)[0])) - 1) ; else g_assertion_message_expr (((gchar*)
0), "gsm-manager.c", 223, ((const char*) (__func__)), "GSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1"
); } while (0)
;
224
225 etype = g_enum_register_static ("GsmManagerError", values);
226 }
227
228 return etype;
229}
230
231static gboolean
232_debug_client (const char *id,
233 GsmClient *client,
234 GsmManager *manager)
235{
236 g_debug ("GsmManager: Client %s", gsm_client_peek_id (client));
237 return FALSE(0);
238}
239
240static void
241debug_clients (GsmManager *manager)
242{
243 GsmManagerPrivate *priv;
244 priv = gsm_manager_get_instance_private (manager);
245 gsm_store_foreach (priv->clients,
246 (GsmStoreFunc)_debug_client,
247 manager);
248}
249
250static gboolean
251_debug_inhibitor (const char *id,
252 GsmInhibitor *inhibitor,
253 GsmManager *manager)
254{
255 g_debug ("GsmManager: Inhibitor app:%s client:%s bus-name:%s reason:%s",
256 gsm_inhibitor_peek_app_id (inhibitor),
257 gsm_inhibitor_peek_client_id (inhibitor),
258 gsm_inhibitor_peek_bus_name (inhibitor),
259 gsm_inhibitor_peek_reason (inhibitor));
260 return FALSE(0);
261}
262
263static void
264debug_inhibitors (GsmManager *manager)
265{
266 GsmManagerPrivate *priv;
267
268 priv = gsm_manager_get_instance_private (manager);
269 gsm_store_foreach (priv->inhibitors,
270 (GsmStoreFunc)_debug_inhibitor,
271 manager);
272}
273
274static gboolean
275_find_by_cookie (const char *id,
276 GsmInhibitor *inhibitor,
277 guint *cookie_ap)
278{
279 guint cookie_b;
280
281 cookie_b = gsm_inhibitor_peek_cookie (inhibitor);
282
283 return (*cookie_ap == cookie_b);
284}
285
286static gboolean
287_find_by_startup_id (const char *id,
288 GsmClient *client,
289 const char *startup_id_a)
290{
291 const char *startup_id_b;
292
293 startup_id_b = gsm_client_peek_startup_id (client);
294 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
295 return FALSE(0);
296 }
297
298 return (strcmp (startup_id_a, startup_id_b) == 0);
299}
300
301static void
302app_condition_changed (GsmApp *app,
303 gboolean condition,
304 GsmManager *manager)
305{
306 GsmClient *client;
307 GsmManagerPrivate *priv;
308
309 priv = gsm_manager_get_instance_private (manager);
310
311 g_debug ("GsmManager: app:%s condition changed condition:%d",
312 gsm_app_peek_id (app),
313 condition);
314
315 client = (GsmClient *)gsm_store_find (priv->clients,
316 (GsmStoreFunc)_find_by_startup_id,
317 (char *)gsm_app_peek_startup_id (app));
318
319 if (condition) {
320 if (!gsm_app_is_running (app) && client == NULL((void*)0)) {
321 GError *error = NULL((void*)0);
322 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
323
324 g_debug ("GsmManager: starting app '%s'", gsm_app_peek_id (app));
325
326 res = gsm_app_start (app, &error);
327 if (error != NULL((void*)0)) {
328 g_warning ("Not able to start app from its condition: %s",
329 error->message);
330 g_error_free (error);
331 }
332 } else {
333 g_debug ("GsmManager: not starting - app still running '%s'", gsm_app_peek_id (app));
334 }
335 } else {
336 GError *error;
337 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
338
339 if (client != NULL((void*)0)) {
340 /* Kill client in case condition if false and make sure it won't
341 * be automatically restarted by adding the client to
342 * condition_clients */
343 priv->condition_clients =
344 g_slist_prepend (priv->condition_clients, client);
345
346 g_debug ("GsmManager: stopping client %s for app", gsm_client_peek_id (client));
347
348 error = NULL((void*)0);
349 res = gsm_client_stop (client, &error);
350 if (error != NULL((void*)0)) {
351 g_warning ("Not able to stop app client from its condition: %s",
352 error->message);
353 g_error_free (error);
354 }
355 } else {
356 g_debug ("GsmManager: stopping app %s", gsm_app_peek_id (app));
357
358 /* If we don't have a client then we should try to kill the app,
359 * if it is running */
360 error = NULL((void*)0);
361 if (gsm_app_is_running (app)) {
362 res = gsm_app_stop (app, &error);
363 if (error != NULL((void*)0)) {
364 g_warning ("Not able to stop app from its condition: %s",
365 error->message);
366 g_error_free (error);
367 }
368 }
369 }
370 }
371}
372
373static const char *
374phase_num_to_name (guint phase)
375{
376 const char *name;
377
378 switch (phase) {
379 case GSM_MANAGER_PHASE_STARTUP:
380 name = "STARTUP";
381 break;
382 case GSM_MANAGER_PHASE_INITIALIZATION:
383 name = "INITIALIZATION";
384 break;
385 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
386 name = "WINDOW_MANAGER";
387 break;
388 case GSM_MANAGER_PHASE_PANEL:
389 name = "PANEL";
390 break;
391 case GSM_MANAGER_PHASE_DESKTOP:
392 name = "DESKTOP";
393 break;
394 case GSM_MANAGER_PHASE_APPLICATION:
395 name = "APPLICATION";
396 break;
397 case GSM_MANAGER_PHASE_RUNNING:
398 name = "RUNNING";
399 break;
400 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
401 name = "QUERY_END_SESSION";
402 break;
403 case GSM_MANAGER_PHASE_END_SESSION:
404 name = "END_SESSION";
405 break;
406 case GSM_MANAGER_PHASE_EXIT:
407 name = "EXIT";
408 break;
409 default:
410 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
410, ((const char*) (__func__)), ((void*)0)); } while (0)
;
411 break;
412 }
413
414 return name;
415}
416
417static void start_phase (GsmManager *manager);
418
419static void
420quit_request_completed_consolekit (GsmConsolekit *consolekit,
421 GError *error,
422 gpointer user_data)
423{
424 MdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
425
426 if (error != NULL((void*)0)) {
427 mdm_set_logout_action (fallback_action);
428 }
429
430 g_object_unref (consolekit);
431
432 gtk_main_quit ();
433}
434
435#ifdef HAVE_SYSTEMD1
436static void
437quit_request_completed_systemd (GsmSystemd *systemd,
438 GError *error,
439 gpointer user_data)
440{
441 MdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
442
443 if (error != NULL((void*)0)) {
444 mdm_set_logout_action (fallback_action);
445 }
446
447 g_object_unref (systemd);
448
449 gtk_main_quit ();
450}
451#endif
452
453static void
454gsm_manager_quit (GsmManager *manager)
455{
456 GsmConsolekit *consolekit;
457 GsmManagerPrivate *priv;
458#ifdef HAVE_SYSTEMD1
459 GsmSystemd *systemd;
460#endif
461
462 priv = gsm_manager_get_instance_private (manager);
463 /* See the comment in request_reboot() for some more details about how
464 * this works. */
465
466 switch (priv->logout_type) {
467 case GSM_MANAGER_LOGOUT_LOGOUT:
468 gtk_main_quit ();
469 break;
470 case GSM_MANAGER_LOGOUT_REBOOT:
471 case GSM_MANAGER_LOGOUT_REBOOT_INTERACT:
472 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
473
474#ifdef HAVE_SYSTEMD1
475 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
476 systemd = gsm_get_systemd ();
477 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
478 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
479 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
480 GINT_TO_POINTER (MDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
;
481 gsm_systemd_attempt_restart (systemd);
482 }
483 else {
484#endif
485 consolekit = gsm_get_consolekit ();
486 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
487 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
488 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
489 GINT_TO_POINTER (MDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
;
490 gsm_consolekit_attempt_restart (consolekit);
491#ifdef HAVE_SYSTEMD1
492 }
493#endif
494 break;
495 case GSM_MANAGER_LOGOUT_REBOOT_MDM:
496 mdm_set_logout_action (MDM_LOGOUT_ACTION_REBOOT);
497 gtk_main_quit ();
498 break;
499 case GSM_MANAGER_LOGOUT_SHUTDOWN:
500 case GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
501 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
502
503#ifdef HAVE_SYSTEMD1
504 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
505 systemd = gsm_get_systemd ();
506 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
507 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
508 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
509 GINT_TO_POINTER (MDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
;
510 gsm_systemd_attempt_stop (systemd);
511 }
512 else {
513#endif
514 consolekit = gsm_get_consolekit ();
515 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
516 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
517 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
518 GINT_TO_POINTER (MDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (MDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
;
519 gsm_consolekit_attempt_stop (consolekit);
520#ifdef HAVE_SYSTEMD1
521 }
522#endif
523 break;
524 case GSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
525 mdm_set_logout_action (MDM_LOGOUT_ACTION_SHUTDOWN);
526 gtk_main_quit ();
527 break;
528 default:
529 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
529, ((const char*) (__func__)), ((void*)0)); } while (0)
;
530 break;
531 }
532}
533
534static void
535end_phase (GsmManager *manager)
536{
537 GsmManagerPrivate *priv;
538 gboolean start_next_phase = TRUE(!(0));
539
540 priv = gsm_manager_get_instance_private (manager);
541
542 g_debug ("GsmManager: ending phase %s\n",
543 phase_num_to_name (priv->phase));
544
545 g_slist_free (priv->pending_apps);
546 priv->pending_apps = NULL((void*)0);
547
548 g_slist_free (priv->query_clients);
549 priv->query_clients = NULL((void*)0);
550
551 g_slist_free (priv->next_query_clients);
552 priv->next_query_clients = NULL((void*)0);
553
554 if (priv->phase_timeout_id > 0) {
555 g_source_remove (priv->phase_timeout_id);
556 priv->phase_timeout_id = 0;
557 }
558
559 switch (priv->phase) {
560 case GSM_MANAGER_PHASE_STARTUP:
561 case GSM_MANAGER_PHASE_INITIALIZATION:
562 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
563 case GSM_MANAGER_PHASE_PANEL:
564 case GSM_MANAGER_PHASE_DESKTOP:
565 case GSM_MANAGER_PHASE_APPLICATION:
566 break;
567 case GSM_MANAGER_PHASE_RUNNING:
568 if (_log_out_is_locked_down (manager)) {
569 g_warning ("Unable to logout: Logout has been locked down");
570 start_next_phase = FALSE(0);
571 }
572 break;
573 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
574 break;
575 case GSM_MANAGER_PHASE_END_SESSION:
576 if (auto_save_is_enabled (manager))
577 maybe_save_session (manager);
578 break;
579 case GSM_MANAGER_PHASE_EXIT:
580 start_next_phase = FALSE(0);
581 gsm_manager_quit (manager);
582 break;
583 default:
584 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
584, ((const char*) (__func__)), ((void*)0)); } while (0)
;
585 break;
586 }
587
588 if (start_next_phase) {
589 priv->phase++;
590 start_phase (manager);
591 }
592}
593
594static void
595app_registered (GsmApp *app,
596 GsmManager *manager)
597{
598 GsmManagerPrivate *priv;
599
600 priv = gsm_manager_get_instance_private (manager);
601 priv->pending_apps = g_slist_remove (priv->pending_apps, app);
602 g_signal_handlers_disconnect_by_func (app, app_registered, manager)g_signal_handlers_disconnect_matched ((app), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
603
604 if (priv->pending_apps == NULL((void*)0)) {
605 if (priv->phase_timeout_id > 0) {
606 g_source_remove (priv->phase_timeout_id);
607 priv->phase_timeout_id = 0;
608 }
609
610 end_phase (manager);
611 }
612}
613
614static gboolean
615on_phase_timeout (GsmManager *manager)
616{
617 GSList *a;
618 GsmManagerPrivate *priv;
619
620 priv = gsm_manager_get_instance_private (manager);
621 priv->phase_timeout_id = 0;
622
623 switch (priv->phase) {
624 case GSM_MANAGER_PHASE_STARTUP:
625 case GSM_MANAGER_PHASE_INITIALIZATION:
626 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
627 case GSM_MANAGER_PHASE_PANEL:
628 case GSM_MANAGER_PHASE_DESKTOP:
629 case GSM_MANAGER_PHASE_APPLICATION:
630 for (a = priv->pending_apps; a; a = a->next) {
631 g_warning ("Application '%s' failed to register before timeout",
632 gsm_app_peek_app_id (a->data));
633 g_signal_handlers_disconnect_by_func (a->data, app_registered, manager)g_signal_handlers_disconnect_matched ((a->data), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
634 /* FIXME: what if the app was filling in a required slot? */
635 }
636 break;
637 case GSM_MANAGER_PHASE_RUNNING:
638 break;
639 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
640 case GSM_MANAGER_PHASE_END_SESSION:
641 break;
642 case GSM_MANAGER_PHASE_EXIT:
643 break;
644 default:
645 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
645, ((const char*) (__func__)), ((void*)0)); } while (0)
;
646 break;
647 }
648
649 end_phase (manager);
650
651 return FALSE(0);
652}
653
654static gboolean
655_autostart_delay_timeout (GsmApp *app)
656{
657 GError *error = NULL((void*)0);
658 gboolean res;
659
660 if (!gsm_app_peek_is_disabled (app)
661 && !gsm_app_peek_is_conditionally_disabled (app)) {
662 res = gsm_app_start (app, &error);
663 if (!res) {
664 if (error != NULL((void*)0)) {
665 g_warning ("Could not launch application '%s': %s",
666 gsm_app_peek_app_id (app),
667 error->message);
668 g_error_free (error);
669 }
670 }
671 }
672
673 g_object_unref (app);
674
675 return FALSE(0);
676}
677
678static gboolean
679_start_app (const char *id,
680 GsmApp *app,
681 GsmManager *manager)
682{
683 GError *error;
684 gboolean res;
685 int delay;
686 GsmManagerPrivate *priv;
687
688 priv = gsm_manager_get_instance_private (manager);
689
690 if (gsm_app_peek_phase (app) != priv->phase) {
691 goto out;
692 }
693
694 /* Keep track of app autostart condition in order to react
695 * accordingly in the future. */
696 g_signal_connect (app,g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
697 "condition-changed",g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
698 G_CALLBACK (app_condition_changed),g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
699 manager)g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
700
701 if (gsm_app_peek_is_disabled (app)
702 || gsm_app_peek_is_conditionally_disabled (app)) {
703 g_debug ("GsmManager: Skipping disabled app: %s", id);
704 goto out;
705 }
706
707 delay = gsm_app_peek_autostart_delay (app);
708 if (delay > 0) {
709 g_timeout_add_seconds (delay,
710 (GSourceFunc)_autostart_delay_timeout,
711 g_object_ref (app)((__typeof__ (app)) (g_object_ref) (app)));
712 g_debug ("GsmManager: %s is scheduled to start in %d seconds", id, delay);
713 goto out;
714 }
715
716 error = NULL((void*)0);
717 res = gsm_app_start (app, &error);
718 if (!res) {
719 if (error != NULL((void*)0)) {
720 g_warning ("Could not launch application '%s': %s",
721 gsm_app_peek_app_id (app),
722 error->message);
723 g_error_free (error);
724 error = NULL((void*)0);
725 }
726 goto out;
727 }
728
729 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
730 g_signal_connect (app,g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
731 "exited",g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
732 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
733 manager)g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
;
734 g_signal_connect (app,g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
735 "registered",g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
736 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
737 manager)g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
;
738 priv->pending_apps = g_slist_prepend (priv->pending_apps, app);
739 }
740 out:
741 return FALSE(0);
742}
743
744static void
745do_phase_startup (GsmManager *manager)
746{
747 GsmManagerPrivate *priv;
748
749 priv = gsm_manager_get_instance_private (manager);
750 gsm_store_foreach (priv->apps,
751 (GsmStoreFunc)_start_app,
752 manager);
753
754 if (priv->pending_apps != NULL((void*)0)) {
755 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
756 priv->phase_timeout_id = g_timeout_add_seconds (GSM_MANAGER_PHASE_TIMEOUT30,
757 (GSourceFunc)on_phase_timeout,
758 manager);
759 }
760 } else {
761 end_phase (manager);
762 }
763}
764
765typedef struct {
766 GsmManager *manager;
767 guint flags;
768} ClientEndSessionData;
769
770static gboolean
771_client_end_session (GsmClient *client,
772 ClientEndSessionData *data)
773{
774 gboolean ret;
775 GError *error;
776 GsmManagerPrivate *priv;
777
778 priv = gsm_manager_get_instance_private (data->manager);
779
780 error = NULL((void*)0);
781 ret = gsm_client_end_session (client, data->flags, &error);
782 if (! ret) {
783 g_warning ("Unable to query client: %s", error->message);
784 g_error_free (error);
785 /* FIXME: what should we do if we can't communicate with client? */
786 } else {
787 g_debug ("GsmManager: adding client to end-session clients: %s", gsm_client_peek_id (client));
788 priv->query_clients = g_slist_prepend (priv->query_clients,
789 client);
790 }
791
792 return FALSE(0);
793}
794
795static gboolean
796_client_end_session_helper (const char *id,
797 GsmClient *client,
798 ClientEndSessionData *data)
799{
800 return _client_end_session (client, data);
801}
802
803static void
804do_phase_end_session (GsmManager *manager)
805{
806 ClientEndSessionData data;
807 GsmManagerPrivate *priv;
808
809 data.manager = manager;
810 data.flags = 0;
811 priv = gsm_manager_get_instance_private (manager);
812
813 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
814 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
815 }
816 if (auto_save_is_enabled (manager)) {
817 data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
818 }
819
820 if (priv->phase_timeout_id > 0) {
821 g_source_remove (priv->phase_timeout_id);
822 priv->phase_timeout_id = 0;
823 }
824
825 if (gsm_store_size (priv->clients) > 0) {
826 priv->phase_timeout_id = g_timeout_add_seconds (GSM_MANAGER_PHASE_TIMEOUT30,
827 (GSourceFunc)on_phase_timeout,
828 manager);
829
830 gsm_store_foreach (priv->clients,
831 (GsmStoreFunc)_client_end_session_helper,
832 &data);
833 } else {
834 end_phase (manager);
835 }
836}
837
838static void
839do_phase_end_session_part_2 (GsmManager *manager)
840{
841 ClientEndSessionData data;
842 GsmManagerPrivate *priv;
843
844 data.manager = manager;
845 data.flags = 0;
846 priv = gsm_manager_get_instance_private (manager);
847
848 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
849 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
850 }
851 if (auto_save_is_enabled (manager)) {
852 data.flags |= GSM_CLIENT_END_SESSION_FLAG_SAVE;
853 }
854 data.flags |= GSM_CLIENT_END_SESSION_FLAG_LAST;
855
856 /* keep the timeout that was started at the beginning of the
857 * GSM_MANAGER_PHASE_END_SESSION phase */
858
859 if (g_slist_length (priv->next_query_clients) > 0) {
860 g_slist_foreach (priv->next_query_clients,
861 (GFunc)_client_end_session,
862 &data);
863
864 g_slist_free (priv->next_query_clients);
865 priv->next_query_clients = NULL((void*)0);
866 } else {
867 end_phase (manager);
868 }
869}
870
871static gboolean
872_client_stop (const char *id,
873 GsmClient *client,
874 gpointer user_data)
875{
876 gboolean ret;
877 GError *error;
878
879 error = NULL((void*)0);
880 ret = gsm_client_stop (client, &error);
881 if (! ret) {
882 g_warning ("Unable to stop client: %s", error->message);
883 g_error_free (error);
884 /* FIXME: what should we do if we can't communicate with client? */
885 } else {
886 g_debug ("GsmManager: stopped client: %s", gsm_client_peek_id (client));
887 }
888
889 return FALSE(0);
890}
891
892#ifdef HAVE_SYSTEMD1
893static void
894maybe_restart_user_bus (GsmManager *manager)
895{
896 GsmSystemd *systemd;
897 GsmManagerPrivate *priv;
898 GDBusConnection *connection;
899
900 g_autoptr(GVariant)__attribute__((cleanup(glib_autoptr_cleanup_GVariant))) GVariant_autoptr reply = NULL((void*)0);
901 g_autoptr(GError)__attribute__((cleanup(glib_autoptr_cleanup_GError))) GError_autoptr error = NULL((void*)0);
902
903 priv = gsm_manager_get_instance_private (manager);
904 if (priv->dbus_disconnected)
905 return;
906
907 systemd = gsm_get_systemd ();
908
909 if (!gsm_systemd_is_last_session_for_user (systemd))
910 return;
911
912 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL((void*)0), &error);
913
914 if (error != NULL((void*)0)) {
915 g_debug ("GsmManager: failed to connect to session bus: %s", error->message);
916 return;
917 }
918
919 reply = g_dbus_connection_call_sync (connection,
Value stored to 'reply' is never read
920 "org.freedesktop.systemd1",
921 "/org/freedesktop/systemd1",
922 "org.freedesktop.systemd1.Manager",
923 "TryRestartUnit",
924 g_variant_new ("(ss)", "dbus.service", "replace"),
925 NULL((void*)0),
926 G_DBUS_CALL_FLAGS_NONE,
927 -1,
928 NULL((void*)0),
929 &error);
930
931 if (error != NULL((void*)0)) {
932 g_debug ("GsmManager: reloading user bus failed: %s", error->message);
933 }
934}
935#endif
936
937static void
938do_phase_exit (GsmManager *manager)
939{
940 GsmManagerPrivate *priv;
941
942 priv = gsm_manager_get_instance_private (manager);
943 if (gsm_store_size (priv->clients) > 0) {
944 gsm_store_foreach (priv->clients,
945 (GsmStoreFunc)_client_stop,
946 NULL((void*)0));
947 }
948
949#ifdef HAVE_SYSTEMD1
950 maybe_restart_user_bus (manager);
951#endif
952
953 end_phase (manager);
954}
955
956static gboolean
957_client_query_end_session (const char *id,
958 GsmClient *client,
959 ClientEndSessionData *data)
960{
961 gboolean ret;
962 GError *error;
963 GsmManagerPrivate *priv;
964
965 priv = gsm_manager_get_instance_private (data->manager);
966
967 error = NULL((void*)0);
968 ret = gsm_client_query_end_session (client, data->flags, &error);
969 if (! ret) {
970 g_warning ("Unable to query client: %s", error->message);
971 g_error_free (error);
972 /* FIXME: what should we do if we can't communicate with client? */
973 } else {
974 g_debug ("GsmManager: adding client to query clients: %s", gsm_client_peek_id (client));
975 priv->query_clients = g_slist_prepend (priv->query_clients, client);
976 }
977
978 return FALSE(0);
979}
980
981static gboolean
982inhibitor_has_flag (gpointer key,
983 GsmInhibitor *inhibitor,
984 gpointer data)
985{
986 guint flag;
987 guint flags;
988
989 flag = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
990
991 flags = gsm_inhibitor_peek_flags (inhibitor);
992
993 return (flags & flag);
994}
995
996static gboolean
997gsm_manager_is_logout_inhibited (GsmManager *manager)
998{
999 GsmInhibitor *inhibitor;
1000 GsmManagerPrivate *priv;
1001
1002 priv = gsm_manager_get_instance_private (manager);
1003
1004 if (priv->inhibitors == NULL((void*)0)) {
1005 return FALSE(0);
1006 }
1007
1008 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
1009 (GsmStoreFunc)inhibitor_has_flag,
1010 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_LOGOUT)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_LOGOUT)));
1011 if (inhibitor == NULL((void*)0)) {
1012 return FALSE(0);
1013 }
1014 return TRUE(!(0));
1015}
1016
1017static gboolean
1018gsm_manager_is_idle_inhibited (GsmManager *manager)
1019{
1020 GsmInhibitor *inhibitor;
1021 GsmManagerPrivate *priv;
1022
1023 priv = gsm_manager_get_instance_private (manager);
1024
1025 if (priv->inhibitors == NULL((void*)0)) {
1026 return FALSE(0);
1027 }
1028
1029 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
1030 (GsmStoreFunc)inhibitor_has_flag,
1031 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_IDLE)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_IDLE)));
1032 if (inhibitor == NULL((void*)0)) {
1033 return FALSE(0);
1034 }
1035 return TRUE(!(0));
1036}
1037
1038static gboolean
1039_client_cancel_end_session (const char *id,
1040 GsmClient *client,
1041 GsmManager *manager)
1042{
1043 gboolean res;
1044 GError *error;
1045
1046 error = NULL((void*)0);
1047 res = gsm_client_cancel_end_session (client, &error);
1048 if (! res) {
1049 g_warning ("Unable to cancel end session: %s", error->message);
1050 g_error_free (error);
1051 }
1052
1053 return FALSE(0);
1054}
1055
1056static gboolean
1057inhibitor_is_jit (gpointer key,
1058 GsmInhibitor *inhibitor,
1059 GsmManager *manager)
1060{
1061 gboolean matches;
1062 const char *id;
1063
1064 id = gsm_inhibitor_peek_client_id (inhibitor);
1065
1066 matches = (id != NULL((void*)0) && id[0] != '\0');
1067
1068 return matches;
1069}
1070
1071static void
1072cancel_end_session (GsmManager *manager)
1073{
1074 GsmManagerPrivate *priv;
1075
1076 priv = gsm_manager_get_instance_private (manager);
1077 /* just ignore if received outside of shutdown */
1078 if (priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1079 return;
1080 }
1081
1082 /* switch back to running phase */
1083 g_debug ("GsmManager: Cancelling the end of session");
1084
1085 /* remove the dialog before we remove the inhibitors, else the dialog
1086 * will activate itself automatically when the last inhibitor will be
1087 * removed */
1088 if (priv->inhibit_dialog)
1089 gtk_widget_destroy (GTK_WIDGET (priv->inhibit_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_widget_get_type ())))))
)
);
1090 priv->inhibit_dialog = NULL((void*)0);
1091
1092 /* clear all JIT inhibitors */
1093 gsm_store_foreach_remove (priv->inhibitors,
1094 (GsmStoreFunc)inhibitor_is_jit,
1095 (gpointer)manager);
1096
1097 gsm_store_foreach (priv->clients,
1098 (GsmStoreFunc)_client_cancel_end_session,
1099 NULL((void*)0));
1100
1101 gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_RUNNING);
1102 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
1103
1104 priv->logout_type = GSM_MANAGER_LOGOUT_NONE;
1105 mdm_set_logout_action (MDM_LOGOUT_ACTION_NONE);
1106
1107 start_phase (manager);
1108}
1109
1110static gboolean
1111process_is_running (const char * name)
1112{
1113 int num_processes;
1114 char * command = g_strdup_printf ("pidof %s | wc -l", name);
1115 FILE *fp = popen(command, "r");
1116
1117 if (fscanf(fp, "%d", &num_processes) != 1)
1118 num_processes = 0;
1119
1120 pclose(fp);
1121 g_free (command);
1122
1123 if (num_processes > 0) {
1124 return TRUE(!(0));
1125 }
1126 else {
1127 return FALSE(0);
1128 }
1129}
1130
1131static void
1132manager_switch_user (GsmManager *manager)
1133{
1134 GError *error;
1135 gboolean res;
1136 char *command;
1137 const gchar *xdg_seat_path = g_getenv ("XDG_SEAT_PATH");
1138
1139 /* We have to do this here and in request_switch_user() because this
1140 * function can be called at a later time, not just directly after
1141 * request_switch_user(). */
1142 if (_switch_user_is_locked_down (manager)) {
1143 g_warning ("Unable to switch user: User switching has been locked down");
1144 return;
1145 }
1146
1147 if (process_is_running("mdm")) {
1148 /* MDM */
1149 command = g_strdup_printf ("%s %s",
1150 MDM_FLEXISERVER_COMMAND"mdmflexiserver",
1151 MDM_FLEXISERVER_ARGS"--startnew Standard");
1152
1153 error = NULL((void*)0);
1154 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1155
1156 g_free (command);
1157
1158 if (! res) {
1159 g_debug ("GsmManager: Unable to start MDM greeter: %s", error->message);
1160 g_error_free (error);
1161 }
1162 }
1163 else if (process_is_running("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary")) {
1164 /* GDM */
1165 command = g_strdup_printf ("%s %s",
1166 GDM_FLEXISERVER_COMMAND"gdmflexiserver",
1167 GDM_FLEXISERVER_ARGS"--startnew Standard");
1168
1169 error = NULL((void*)0);
1170 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1171
1172 g_free (command);
1173
1174 if (! res) {
1175 g_debug ("GsmManager: Unable to start GDM greeter: %s", error->message);
1176 g_error_free (error);
1177 }
1178 }
1179 else if (xdg_seat_path != NULL((void*)0)) {
1180 /* LightDM */
1181 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
1182 GDBusProxy *proxy = NULL((void*)0);
1183 error = NULL((void*)0);
1184
1185 proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
1186 flags,
1187 NULL((void*)0),
1188 "org.freedesktop.DisplayManager",
1189 xdg_seat_path,
1190 "org.freedesktop.DisplayManager.Seat",
1191 NULL((void*)0),
1192 &error);
1193 if (proxy != NULL((void*)0)) {
1194 g_dbus_proxy_call_sync (proxy,
1195 "SwitchToGreeter",
1196 g_variant_new ("()"),
1197 G_DBUS_CALL_FLAGS_NONE,
1198 -1,
1199 NULL((void*)0),
1200 NULL((void*)0));
1201 g_object_unref (proxy);
1202 }
1203 else {
1204 g_debug ("GsmManager: Unable to start LightDM greeter: %s", error->message);
1205 g_error_free (error);
1206 }
1207 }
1208}
1209
1210static gboolean
1211sleep_lock_is_enabled (GsmManager *manager)
1212{
1213 GsmManagerPrivate *priv;
1214
1215 priv = gsm_manager_get_instance_private (manager);
1216 if (priv->settings_screensaver != NULL((void*)0))
1217 return g_settings_get_boolean (priv->settings_screensaver,
1218 KEY_SLEEP_LOCK"lock-enabled");
1219 else
1220 return FALSE(0);
1221}
1222
1223static void
1224manager_perhaps_lock (GsmManager *manager)
1225{
1226 gchar **screen_locker_command;
1227
1228 if ((screen_locker_command = gsm_get_screen_locker_command ()) != NULL((void*)0)) {
1229 GError *error = NULL((void*)0);
1230
1231 /* only lock if mate-screensaver is set to lock */
1232 if (!g_strcmp0 (screen_locker_command[0], "mate-screensaver-command") &&
1233 !sleep_lock_is_enabled (manager)) {
1234 goto clear_screen_locker_command;
1235 }
1236
1237 /* do this sync to ensure it's on the screen when we start suspending */
1238 g_spawn_sync (NULL((void*)0), screen_locker_command, NULL((void*)0),
1239 G_SPAWN_DEFAULT | G_SPAWN_SEARCH_PATH,
1240 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1241
1242 if (error) {
1243 g_warning ("Couldn't lock screen: %s", error->message);
1244 g_error_free (error);
1245 }
1246
1247 } else {
1248 g_warning ("Couldn't find any screen locker");
1249 }
1250
1251clear_screen_locker_command:
1252
1253 g_strfreev (screen_locker_command);
1254}
1255
1256static void
1257manager_attempt_hibernate (GsmManager *manager)
1258{
1259#ifdef HAVE_SYSTEMD1
1260 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1261
1262 GsmSystemd *systemd;
1263
1264 systemd = gsm_get_systemd ();
1265
1266 /* lock the screen before we suspend */
1267 manager_perhaps_lock (manager);
1268
1269 gsm_systemd_attempt_hibernate (systemd);
1270 }
1271 else {
1272#endif
1273 GsmConsolekit *consolekit;
1274 consolekit = gsm_get_consolekit ();
1275
1276 gboolean can_hibernate = gsm_consolekit_can_hibernate (consolekit);
1277 if (can_hibernate) {
1278 /* lock the screen before we suspend */
1279 manager_perhaps_lock (manager);
1280
1281 gsm_consolekit_attempt_hibernate (consolekit);
1282 }
1283#ifdef HAVE_SYSTEMD1
1284 }
1285#endif
1286}
1287
1288static void
1289manager_attempt_suspend (GsmManager *manager)
1290{
1291#ifdef HAVE_SYSTEMD1
1292 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1293
1294 GsmSystemd *systemd;
1295
1296 systemd = gsm_get_systemd ();
1297
1298 /* lock the screen before we suspend */
1299 manager_perhaps_lock (manager);
1300
1301 gsm_systemd_attempt_suspend (systemd);
1302 }
1303 else {
1304#endif
1305 GsmConsolekit *consolekit;
1306 consolekit = gsm_get_consolekit ();
1307
1308 gboolean can_suspend = gsm_consolekit_can_suspend (consolekit);
1309 if (can_suspend) {
1310 /* lock the screen before we suspend */
1311 manager_perhaps_lock (manager);
1312
1313 gsm_consolekit_attempt_suspend (consolekit);
1314 }
1315#ifdef HAVE_SYSTEMD1
1316 }
1317#endif
1318}
1319
1320static void
1321do_inhibit_dialog_action (GsmManager *manager,
1322 int action)
1323{
1324 GsmManagerPrivate *priv;
1325
1326 priv = gsm_manager_get_instance_private (manager);
1327 switch (action) {
1328 case GSM_LOGOUT_ACTION_SWITCH_USER:
1329 manager_switch_user (manager);
1330 break;
1331 case GSM_LOGOUT_ACTION_HIBERNATE:
1332 manager_attempt_hibernate (manager);
1333 break;
1334 case GSM_LOGOUT_ACTION_SLEEP:
1335 manager_attempt_suspend (manager);
1336 break;
1337 case GSM_LOGOUT_ACTION_SHUTDOWN:
1338 case GSM_LOGOUT_ACTION_REBOOT:
1339 case GSM_LOGOUT_ACTION_LOGOUT:
1340 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_FORCE;
1341 end_phase (manager);
1342 break;
1343 default:
1344 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1344, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1345 break;
1346 }
1347}
1348
1349static void
1350inhibit_dialog_response (GsmInhibitDialog *dialog,
1351 guint response_id,
1352 GsmManager *manager)
1353{
1354 int action;
1355 GsmManagerPrivate *priv;
1356
1357 g_debug ("GsmManager: Inhibit dialog response: %d", response_id);
1358
1359 priv = gsm_manager_get_instance_private (manager);
1360 /* must destroy dialog before cancelling since we'll
1361 remove JIT inhibitors and we don't want to trigger
1362 action. */
1363 g_object_get (dialog, "action", &action, NULL((void*)0));
1364 gtk_widget_destroy (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
);
1365 priv->inhibit_dialog = NULL((void*)0);
1366
1367 /* In case of dialog cancel, switch user, hibernate and
1368 * suspend, we just perform the respective action and return,
1369 * without shutting down the session. */
1370 switch (response_id) {
1371 case GTK_RESPONSE_CANCEL:
1372 case GTK_RESPONSE_NONE:
1373 case GTK_RESPONSE_DELETE_EVENT:
1374 if (action == GSM_LOGOUT_ACTION_LOGOUT
1375 || action == GSM_LOGOUT_ACTION_SHUTDOWN
1376 || action == GSM_LOGOUT_ACTION_REBOOT) {
1377 cancel_end_session (manager);
1378 }
1379 break;
1380 case GTK_RESPONSE_ACCEPT:
1381 g_debug ("GsmManager: doing action %d", action);
1382 do_inhibit_dialog_action (manager, action);
1383 break;
1384 default:
1385 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1385, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1386 break;
1387 }
1388}
1389
1390static void
1391query_end_session_complete (GsmManager *manager)
1392{
1393 GsmLogoutAction action;
1394 GsmManagerPrivate *priv;
1395
1396 priv = gsm_manager_get_instance_private (manager);
1397
1398 g_debug ("GsmManager: query end session complete");
1399
1400 /* Remove the timeout since this can be called from outside the timer
1401 * and we don't want to have it called twice */
1402 if (priv->query_timeout_id > 0) {
1403 g_source_remove (priv->query_timeout_id);
1404 priv->query_timeout_id = 0;
1405 }
1406
1407 if (! gsm_manager_is_logout_inhibited (manager)) {
1408 end_phase (manager);
1409 return;
1410 }
1411
1412 if (priv->inhibit_dialog != NULL((void*)0)) {
1413 g_debug ("GsmManager: inhibit dialog already up");
1414 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
1415 return;
1416 }
1417
1418 switch (priv->logout_type) {
1419 case GSM_MANAGER_LOGOUT_LOGOUT:
1420 action = GSM_LOGOUT_ACTION_LOGOUT;
1421 break;
1422 case GSM_MANAGER_LOGOUT_REBOOT:
1423 case GSM_MANAGER_LOGOUT_REBOOT_INTERACT:
1424 case GSM_MANAGER_LOGOUT_REBOOT_MDM:
1425 action = GSM_LOGOUT_ACTION_REBOOT;
1426 break;
1427 case GSM_MANAGER_LOGOUT_SHUTDOWN:
1428 case GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
1429 case GSM_MANAGER_LOGOUT_SHUTDOWN_MDM:
1430 action = GSM_LOGOUT_ACTION_SHUTDOWN;
1431 break;
1432 default:
1433 g_warning ("Unexpected logout type %d when creating inhibit dialog",
1434 priv->logout_type);
1435 action = GSM_LOGOUT_ACTION_LOGOUT;
1436 break;
1437 }
1438
1439 /* Note: GSM_LOGOUT_ACTION_SHUTDOWN and GSM_LOGOUT_ACTION_REBOOT are
1440 * actually handled the same way as GSM_LOGOUT_ACTION_LOGOUT in the
1441 * inhibit dialog; the action, if the button is clicked, will be to
1442 * simply go to the next phase. */
1443 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
1444 priv->clients,
1445 action);
1446
1447 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1448 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1449 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1450 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
1451 gtk_widget_show (priv->inhibit_dialog);
1452
1453}
1454
1455static guint32
1456generate_cookie (void)
1457{
1458 guint32 cookie;
1459
1460 cookie = (guint32)g_random_int_range (1, G_MAXINT32((gint32) 0x7fffffff));
1461
1462 return cookie;
1463}
1464
1465static guint32
1466_generate_unique_cookie (GsmManager *manager)
1467{
1468 guint32 cookie;
1469 GsmManagerPrivate *priv;
1470
1471 priv = gsm_manager_get_instance_private (manager);
1472
1473 do {
1474 cookie = generate_cookie ();
1475 } while (gsm_store_find (priv->inhibitors, (GsmStoreFunc)_find_by_cookie, &cookie) != NULL((void*)0));
1476
1477 return cookie;
1478}
1479
1480static gboolean
1481_on_query_end_session_timeout (GsmManager *manager)
1482{
1483 GSList *l;
1484 GsmManagerPrivate *priv;
1485
1486 priv = gsm_manager_get_instance_private (manager);
1487
1488 priv->query_timeout_id = 0;
1489
1490 g_debug ("GsmManager: query end session timed out");
1491
1492 for (l = priv->query_clients; l != NULL((void*)0); l = l->next) {
1493 guint cookie;
1494 GsmInhibitor *inhibitor;
1495 const char *bus_name;
1496 char *app_id;
1497
1498 g_warning ("Client '%s' failed to reply before timeout",
1499 gsm_client_peek_id (l->data));
1500
1501 /* Don't add "not responding" inhibitors if logout is forced
1502 */
1503 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
1504 continue;
1505 }
1506
1507 /* Add JIT inhibit for unresponsive client */
1508 if (GSM_IS_DBUS_CLIENT (l->data)) {
1509 bus_name = gsm_dbus_client_get_bus_name (l->data);
1510 } else {
1511 bus_name = NULL((void*)0);
1512 }
1513
1514 app_id = g_strdup (gsm_client_peek_app_id (l->data))g_strdup_inline (gsm_client_peek_app_id (l->data));
1515 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1516 /* XSMP clients don't give us an app id unless we start them */
1517 g_free (app_id);
1518 app_id = gsm_client_get_app_name (l->data);
1519 }
1520
1521 cookie = _generate_unique_cookie (manager);
1522 inhibitor = gsm_inhibitor_new_for_client (gsm_client_peek_id (l->data),
1523 app_id,
1524 GSM_INHIBITOR_FLAG_LOGOUT,
1525 _("Not responding")gettext ("Not responding"),
1526 bus_name,
1527 cookie);
1528 g_free (app_id);
1529 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
1530 g_object_unref (inhibitor);
1531 }
1532
1533 g_slist_free (priv->query_clients);
1534 priv->query_clients = NULL((void*)0);
1535
1536 query_end_session_complete (manager);
1537
1538 return FALSE(0);
1539}
1540
1541static void
1542do_phase_query_end_session (GsmManager *manager)
1543{
1544 ClientEndSessionData data;
1545 GsmManagerPrivate *priv;
1546
1547 data.manager = manager;
1548 data.flags = 0;
1549 priv = gsm_manager_get_instance_private (manager);
1550
1551 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
1552 data.flags |= GSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
1553 }
1554 /* We only query if an app is ready to log out, so we don't use
1555 * GSM_CLIENT_END_SESSION_FLAG_SAVE here.
1556 */
1557
1558 debug_clients (manager);
1559 g_debug ("GsmManager: sending query-end-session to clients (logout mode: %s)",
1560 priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL? "normal" :
1561 priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE? "forceful":
1562 "no confirmation");
1563 gsm_store_foreach (priv->clients,
1564 (GsmStoreFunc)_client_query_end_session,
1565 &data);
1566
1567 /* This phase doesn't time out unless logout is forced. Typically, this
1568 * separate timer is only used to show UI. */
1569 priv->query_timeout_id = g_timeout_add_seconds (1, (GSourceFunc)_on_query_end_session_timeout, manager);
1570}
1571
1572static void
1573update_idle (GsmManager *manager)
1574{
1575 GsmManagerPrivate *priv;
1576
1577 priv = gsm_manager_get_instance_private (manager);
1578 if (gsm_manager_is_idle_inhibited (manager)) {
1579 gsm_presence_set_idle_enabled (priv->presence, FALSE(0));
1580 } else {
1581 gsm_presence_set_idle_enabled (priv->presence, TRUE(!(0)));
1582 }
1583}
1584
1585static void
1586start_phase (GsmManager *manager)
1587{
1588 GsmManagerPrivate *priv;
1589
1590 priv = gsm_manager_get_instance_private (manager);
1591
1592 g_debug ("GsmManager: starting phase %s\n",
1593 phase_num_to_name (priv->phase));
1594
1595 /* reset state */
1596 g_slist_free (priv->pending_apps);
1597 priv->pending_apps = NULL((void*)0);
1598 g_slist_free (priv->query_clients);
1599 priv->query_clients = NULL((void*)0);
1600 g_slist_free (priv->next_query_clients);
1601 priv->next_query_clients = NULL((void*)0);
1602
1603 if (priv->query_timeout_id > 0) {
1604 g_source_remove (priv->query_timeout_id);
1605 priv->query_timeout_id = 0;
1606 }
1607 if (priv->phase_timeout_id > 0) {
1608 g_source_remove (priv->phase_timeout_id);
1609 priv->phase_timeout_id = 0;
1610 }
1611
1612 switch (priv->phase) {
1613 case GSM_MANAGER_PHASE_STARTUP:
1614 case GSM_MANAGER_PHASE_INITIALIZATION:
1615 case GSM_MANAGER_PHASE_WINDOW_MANAGER:
1616 case GSM_MANAGER_PHASE_PANEL:
1617 case GSM_MANAGER_PHASE_DESKTOP:
1618 case GSM_MANAGER_PHASE_APPLICATION:
1619 do_phase_startup (manager);
1620 break;
1621 case GSM_MANAGER_PHASE_RUNNING:
1622 g_signal_emit (manager, signals[SESSION_RUNNING], 0);
1623 update_idle (manager);
1624 break;
1625 case GSM_MANAGER_PHASE_QUERY_END_SESSION:
1626 do_phase_query_end_session (manager);
1627 break;
1628 case GSM_MANAGER_PHASE_END_SESSION:
1629 do_phase_end_session (manager);
1630 break;
1631 case GSM_MANAGER_PHASE_EXIT:
1632 do_phase_exit (manager);
1633 break;
1634 default:
1635 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
1635, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1636 break;
1637 }
1638}
1639
1640static gboolean
1641_debug_app_for_phase (const char *id,
1642 GsmApp *app,
1643 gpointer data)
1644{
1645 guint phase;
1646
1647 phase = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
1648
1649 if (gsm_app_peek_phase (app) != phase) {
1650 return FALSE(0);
1651 }
1652
1653 g_debug ("GsmManager:\tID: %s\tapp-id:%s\tis-disabled:%d\tis-conditionally-disabled:%d\tis-delayed:%d",
1654 gsm_app_peek_id (app),
1655 gsm_app_peek_app_id (app),
1656 gsm_app_peek_is_disabled (app),
1657 gsm_app_peek_is_conditionally_disabled (app),
1658 (gsm_app_peek_autostart_delay (app) > 0));
1659
1660 return FALSE(0);
1661}
1662
1663static void
1664debug_app_summary (GsmManager *manager)
1665{
1666 guint phase;
1667 GsmManagerPrivate *priv;
1668
1669 priv = gsm_manager_get_instance_private (manager);
1670
1671 g_debug ("GsmManager: App startup summary");
1672 for (phase = GSM_MANAGER_PHASE_INITIALIZATION; phase < GSM_MANAGER_PHASE_RUNNING; phase++) {
1673 g_debug ("GsmManager: Phase %s", phase_num_to_name (phase));
1674 gsm_store_foreach (priv->apps,
1675 (GsmStoreFunc)_debug_app_for_phase,
1676 GUINT_TO_POINTER (phase)((gpointer) (gulong) (phase)));
1677 }
1678}
1679
1680void
1681gsm_manager_start (GsmManager *manager)
1682{
1683 g_debug ("GsmManager: GSM starting to manage");
1684
1685 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
1686
1687 gsm_manager_set_phase (manager, GSM_MANAGER_PHASE_INITIALIZATION);
1688 debug_app_summary (manager);
1689 start_phase (manager);
1690}
1691
1692void
1693_gsm_manager_set_renderer (GsmManager *manager,
1694 const char *renderer)
1695{
1696 GsmManagerPrivate *priv;
1697 priv = gsm_manager_get_instance_private (manager);
1698 g_free (priv->renderer);
1699 priv->renderer = g_strdup (renderer)g_strdup_inline (renderer);
1700}
1701
1702static gboolean
1703_app_has_app_id (const char *id,
1704 GsmApp *app,
1705 const char *app_id_a)
1706{
1707 const char *app_id_b;
1708
1709 app_id_b = gsm_app_peek_app_id (app);
1710 return (app_id_b != NULL((void*)0) && strcmp (app_id_a, app_id_b) == 0);
1711}
1712
1713static GsmApp *
1714find_app_for_app_id (GsmManager *manager,
1715 const char *app_id)
1716{
1717 GsmApp *app;
1718 GsmManagerPrivate *priv;
1719
1720 priv = gsm_manager_get_instance_private (manager);
1721 app = (GsmApp *)gsm_store_find (priv->apps,
1722 (GsmStoreFunc)_app_has_app_id,
1723 (char *)app_id);
1724 return app;
1725}
1726
1727static gboolean
1728inhibitor_has_client_id (gpointer key,
1729 GsmInhibitor *inhibitor,
1730 const char *client_id_a)
1731{
1732 gboolean matches;
1733 const char *client_id_b;
1734
1735 client_id_b = gsm_inhibitor_peek_client_id (inhibitor);
1736
1737 matches = FALSE(0);
1738 if (! IS_STRING_EMPTY (client_id_a)((client_id_a)==((void*)0)||(client_id_a)[0]=='\0') && ! IS_STRING_EMPTY (client_id_b)((client_id_b)==((void*)0)||(client_id_b)[0]=='\0')) {
1739 matches = (strcmp (client_id_a, client_id_b) == 0);
1740 if (matches) {
1741 g_debug ("GsmManager: removing JIT inhibitor for %s for reason '%s'",
1742 gsm_inhibitor_peek_client_id (inhibitor),
1743 gsm_inhibitor_peek_reason (inhibitor));
1744 }
1745 }
1746
1747 return matches;
1748}
1749
1750static gboolean
1751_app_has_startup_id (const char *id,
1752 GsmApp *app,
1753 const char *startup_id_a)
1754{
1755 const char *startup_id_b;
1756
1757 startup_id_b = gsm_app_peek_startup_id (app);
1758
1759 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
1760 return FALSE(0);
1761 }
1762
1763 return (strcmp (startup_id_a, startup_id_b) == 0);
1764}
1765
1766static GsmApp *
1767find_app_for_startup_id (GsmManager *manager,
1768 const char *startup_id)
1769{
1770 GsmApp *found_app;
1771 GSList *a;
1772 GsmManagerPrivate *priv;
1773
1774 found_app = NULL((void*)0);
1775 priv = gsm_manager_get_instance_private (manager);
1776
1777 /* If we're starting up the session, try to match the new client
1778 * with one pending apps for the current phase. If not, try to match
1779 * with any of the autostarted apps. */
1780 if (priv->phase < GSM_MANAGER_PHASE_APPLICATION) {
1781 for (a = priv->pending_apps; a != NULL((void*)0); a = a->next) {
1782 GsmApp *app = GSM_APP (a->data);
1783
1784 if (strcmp (startup_id, gsm_app_peek_startup_id (app)) == 0) {
1785 found_app = app;
1786 goto out;
1787 }
1788 }
1789 } else {
1790 GsmApp *app;
1791
1792 app = (GsmApp *)gsm_store_find (priv->apps,
1793 (GsmStoreFunc)_app_has_startup_id,
1794 (char *)startup_id);
1795 if (app != NULL((void*)0)) {
1796 found_app = app;
1797 goto out;
1798 }
1799 }
1800 out:
1801 return found_app;
1802}
1803
1804static void
1805_disconnect_client (GsmManager *manager,
1806 GsmClient *client)
1807{
1808 gboolean is_condition_client;
1809 GsmApp *app;
1810 GError *error;
1811 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
1812 const char *app_id;
1813 const char *startup_id;
1814 gboolean app_restart;
1815 GsmClientRestartStyle client_restart_hint;
1816 GsmManagerPrivate *priv;
1817
1818 g_debug ("GsmManager: disconnect client: %s", gsm_client_peek_id (client));
1819
1820 /* take a ref so it doesn't get finalized */
1821 g_object_ref (client)((__typeof__ (client)) (g_object_ref) (client));
1822
1823 gsm_client_set_status (client, GSM_CLIENT_FINISHED);
1824
1825 is_condition_client = FALSE(0);
1826 priv = gsm_manager_get_instance_private (manager);
1827 if (g_slist_find (priv->condition_clients, client)) {
1828 priv->condition_clients = g_slist_remove (priv->condition_clients, client);
1829
1830 is_condition_client = TRUE(!(0));
1831 }
1832
1833 /* remove any inhibitors for this client */
1834 gsm_store_foreach_remove (priv->inhibitors,
1835 (GsmStoreFunc)inhibitor_has_client_id,
1836 (gpointer)gsm_client_peek_id (client));
1837
1838 app = NULL((void*)0);
1839
1840 /* first try to match on startup ID */
1841 startup_id = gsm_client_peek_startup_id (client);
1842 if (! IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
1843 app = find_app_for_startup_id (manager, startup_id);
1844
1845 }
1846
1847 /* then try to find matching app-id */
1848 if (app == NULL((void*)0)) {
1849 app_id = gsm_client_peek_app_id (client);
1850 if (! IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1851 g_debug ("GsmManager: disconnect for app '%s'", app_id);
1852 app = find_app_for_app_id (manager, app_id);
1853 }
1854 }
1855
1856 if (priv->phase == GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1857 /* Instead of answering our end session query, the client just exited.
1858 * Treat that as an "okay, end the session" answer.
1859 *
1860 * This call implicitly removes any inhibitors for the client, along
1861 * with removing the client from the pending query list.
1862 */
1863 _handle_client_end_session_response (manager,
1864 client,
1865 TRUE(!(0)),
1866 FALSE(0),
1867 FALSE(0),
1868 "Client exited in "
1869 "query end session phase "
1870 "instead of end session "
1871 "phase");
1872 }
1873
1874 if (priv->dbus_disconnected && GSM_IS_DBUS_CLIENT (client)) {
1875 g_debug ("GsmManager: dbus disconnected, not restarting application");
1876 goto out;
1877 }
1878
1879 if (app == NULL((void*)0)) {
1880 g_debug ("GsmManager: unable to find application for client - not restarting");
1881 goto out;
1882 }
1883
1884 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
1885 g_debug ("GsmManager: in shutdown, not restarting application");
1886 goto out;
1887 }
1888
1889 app_restart = gsm_app_peek_autorestart (app);
1890 client_restart_hint = gsm_client_peek_restart_style_hint (client);
1891
1892 /* allow legacy clients to override the app info */
1893 if (! app_restart
1894 && client_restart_hint != GSM_CLIENT_RESTART_IMMEDIATELY) {
1895 g_debug ("GsmManager: autorestart not set, not restarting application");
1896 goto out;
1897 }
1898
1899 if (is_condition_client) {
1900 g_debug ("GsmManager: app conditionally disabled, not restarting application");
1901 goto out;
1902 }
1903
1904 g_debug ("GsmManager: restarting app");
1905
1906 error = NULL((void*)0);
1907 res = gsm_app_restart (app, &error);
1908 if (error != NULL((void*)0)) {
1909 g_warning ("Error on restarting session managed app: %s", error->message);
1910 g_error_free (error);
1911 }
1912
1913 out:
1914 g_object_unref (client);
1915}
1916
1917typedef struct {
1918 const char *service_name;
1919 GsmManager *manager;
1920} RemoveClientData;
1921
1922static gboolean
1923_disconnect_dbus_client (const char *id,
1924 GsmClient *client,
1925 RemoveClientData *data)
1926{
1927 const char *name;
1928
1929 if (! GSM_IS_DBUS_CLIENT (client)) {
1930 return FALSE(0);
1931 }
1932
1933 /* If no service name, then we simply disconnect all clients */
1934 if (!data->service_name) {
1935 _disconnect_client (data->manager, client);
1936 return TRUE(!(0));
1937 }
1938
1939 name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
1940 if (IS_STRING_EMPTY (name)((name)==((void*)0)||(name)[0]=='\0')) {
1941 return FALSE(0);
1942 }
1943
1944 if (strcmp (data->service_name, name) == 0) {
1945 _disconnect_client (data->manager, client);
1946 return TRUE(!(0));
1947 }
1948
1949 return FALSE(0);
1950}
1951
1952/**
1953 * remove_clients_for_connection:
1954 * @manager: a #GsmManager
1955 * @service_name: a service name
1956 *
1957 * Disconnects clients that own @service_name.
1958 *
1959 * If @service_name is NULL, then disconnects all clients for the connection.
1960 */
1961static void
1962remove_clients_for_connection (GsmManager *manager,
1963 const char *service_name)
1964{
1965 RemoveClientData data;
1966 GsmManagerPrivate *priv;
1967
1968 data.service_name = service_name;
1969 data.manager = manager;
1970 priv = gsm_manager_get_instance_private (manager);
1971
1972 /* disconnect dbus clients for name */
1973 gsm_store_foreach_remove (priv->clients,
1974 (GsmStoreFunc)_disconnect_dbus_client,
1975 &data);
1976
1977 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION
1978 && gsm_store_size (priv->clients) == 0) {
1979 g_debug ("GsmManager: last client disconnected - exiting");
1980 end_phase (manager);
1981 }
1982}
1983
1984static gboolean
1985inhibitor_has_bus_name (gpointer key,
1986 GsmInhibitor *inhibitor,
1987 RemoveClientData *data)
1988{
1989 gboolean matches;
1990 const char *bus_name_b;
1991
1992 bus_name_b = gsm_inhibitor_peek_bus_name (inhibitor);
1993
1994 matches = FALSE(0);
1995 if (! IS_STRING_EMPTY (data->service_name)((data->service_name)==((void*)0)||(data->service_name)
[0]=='\0')
&& ! IS_STRING_EMPTY (bus_name_b)((bus_name_b)==((void*)0)||(bus_name_b)[0]=='\0')) {
1996 matches = (strcmp (data->service_name, bus_name_b) == 0);
1997 if (matches) {
1998 g_debug ("GsmManager: removing inhibitor from %s for reason '%s' on connection %s",
1999 gsm_inhibitor_peek_app_id (inhibitor),
2000 gsm_inhibitor_peek_reason (inhibitor),
2001 gsm_inhibitor_peek_bus_name (inhibitor));
2002 }
2003 }
2004
2005 return matches;
2006}
2007
2008static void
2009remove_inhibitors_for_connection (GsmManager *manager,
2010 const char *service_name)
2011{
2012 guint UNUSED_VARIABLE__attribute__ ((unused)) n_removed;
2013 RemoveClientData data;
2014 GsmManagerPrivate *priv;
2015
2016 data.service_name = service_name;
2017 data.manager = manager;
2018 priv = gsm_manager_get_instance_private (manager);
2019
2020 debug_inhibitors (manager);
2021
2022 n_removed = gsm_store_foreach_remove (priv->inhibitors,
2023 (GsmStoreFunc)inhibitor_has_bus_name,
2024 &data);
2025}
2026
2027static void
2028bus_name_owner_changed (DBusGProxy *bus_proxy,
2029 const char *service_name,
2030 const char *old_service_name,
2031 const char *new_service_name,
2032 GsmManager *manager)
2033{
2034 if (strlen (new_service_name) == 0
2035 && strlen (old_service_name) > 0) {
2036 /* service removed */
2037 remove_inhibitors_for_connection (manager, old_service_name);
2038 remove_clients_for_connection (manager, old_service_name);
2039 } else if (strlen (old_service_name) == 0
2040 && strlen (new_service_name) > 0) {
2041 /* service added */
2042
2043 /* use this if we support automatically registering
2044 * well known bus names */
2045 }
2046}
2047
2048static DBusHandlerResult
2049gsm_manager_bus_filter (DBusConnection *connection,
2050 DBusMessage *message,
2051 void *user_data)
2052{
2053 GsmManager *manager;
2054 GsmManagerPrivate *priv;
2055
2056 manager = GSM_MANAGER (user_data);
2057 priv = gsm_manager_get_instance_private (manager);
2058
2059 if (dbus_message_is_signal (message,
2060 DBUS_INTERFACE_LOCAL"org.freedesktop.DBus.Local", "Disconnected") &&
2061 strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL"/org/freedesktop/DBus/Local") == 0) {
2062 g_debug ("GsmManager: dbus disconnected; disconnecting dbus clients...");
2063 priv->dbus_disconnected = TRUE(!(0));
2064 remove_clients_for_connection (manager, NULL((void*)0));
2065 /* let other filters get this disconnected signal, so that they
2066 * can handle it too */
2067 }
2068
2069 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2070}
2071
2072static gboolean
2073register_manager (GsmManager *manager)
2074{
2075 GError *error = NULL((void*)0);
2076 GsmManagerPrivate *priv;
2077 DBusConnection *connection;
2078
2079 error = NULL((void*)0);
2080 priv = gsm_manager_get_instance_private (manager);
2081
2082 priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
2083 if (priv->connection == NULL((void*)0)) {
2084 if (error != NULL((void*)0)) {
2085 g_critical ("error getting session bus: %s", error->message);
2086 g_error_free (error);
2087 }
2088 exit (1);
2089 }
2090
2091 connection = dbus_g_connection_get_connection (priv->connection);
2092 dbus_connection_add_filter (connection,
2093 gsm_manager_bus_filter,
2094 manager, NULL((void*)0));
2095 priv->dbus_disconnected = FALSE(0);
2096
2097 priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
2098 DBUS_SERVICE_DBUS"org.freedesktop.DBus",
2099 DBUS_PATH_DBUS"/org/freedesktop/DBus",
2100 DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
2101 dbus_g_proxy_add_signal (priv->bus_proxy,
2102 "NameOwnerChanged",
2103 G_TYPE_STRING((GType) ((16) << (2))),
2104 G_TYPE_STRING((GType) ((16) << (2))),
2105 G_TYPE_STRING((GType) ((16) << (2))),
2106 G_TYPE_INVALID((GType) ((0) << (2))));
2107 dbus_g_proxy_connect_signal (priv->bus_proxy,
2108 "NameOwnerChanged",
2109 G_CALLBACK (bus_name_owner_changed)((GCallback) (bus_name_owner_changed)),
2110 manager,
2111 NULL((void*)0));
2112
2113 dbus_g_connection_register_g_object (priv->connection, GSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager", G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
);
2114
2115 return TRUE(!(0));
2116}
2117
2118static void
2119gsm_manager_set_failsafe (GsmManager *manager,
2120 gboolean enabled)
2121{
2122 GsmManagerPrivate *priv;
2123
2124 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2125
2126 priv = gsm_manager_get_instance_private (manager);
2127
2128 priv->failsafe = enabled;
2129}
2130
2131static gboolean
2132_client_has_startup_id (const char *id,
2133 GsmClient *client,
2134 const char *startup_id_a)
2135{
2136 const char *startup_id_b;
2137
2138 startup_id_b = gsm_client_peek_startup_id (client);
2139
2140 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
2141 return FALSE(0);
2142 }
2143
2144 return (strcmp (startup_id_a, startup_id_b) == 0);
2145}
2146
2147static void
2148on_client_disconnected (GsmClient *client,
2149 GsmManager *manager)
2150{
2151 GsmManagerPrivate *priv;
2152
2153 g_debug ("GsmManager: disconnect client");
2154
2155 priv = gsm_manager_get_instance_private (manager);
2156
2157 _disconnect_client (manager, client);
2158 gsm_store_remove (priv->clients, gsm_client_peek_id (client));
2159 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION
2160 && gsm_store_size (priv->clients) == 0) {
2161 g_debug ("GsmManager: last client disconnected - exiting");
2162 end_phase (manager);
2163 }
2164}
2165
2166static gboolean
2167on_xsmp_client_register_request (GsmXSMPClient *client,
2168 char **id,
2169 GsmManager *manager)
2170{
2171 gboolean handled;
2172 char *new_id;
2173 GsmApp *app;
2174 GsmManagerPrivate *priv;
2175
2176 handled = TRUE(!(0));
2177 new_id = NULL((void*)0);
2178 priv = gsm_manager_get_instance_private (manager);
2179
2180 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2181 goto out;
2182 }
2183
2184 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2185 new_id = gsm_util_generate_startup_id ();
2186 } else {
2187 GsmClient *sm_client;
2188
2189 sm_client = (GsmClient *)gsm_store_find (priv->clients,
2190 (GsmStoreFunc)_client_has_startup_id,
2191 *id);
2192 /* We can't have two clients with the same id. */
2193 if (sm_client != NULL((void*)0)) {
2194 goto out;
2195 }
2196
2197 new_id = g_strdup (*id)g_strdup_inline (*id);
2198 }
2199
2200 g_debug ("GsmManager: Adding new client %s to session", new_id);
2201
2202 g_signal_connect (client,g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2203 "disconnected",g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2204 G_CALLBACK (on_client_disconnected),g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2205 manager)g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2206
2207 /* If it's a brand new client id, we just accept the client*/
2208 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2209 goto out;
2210 }
2211
2212 app = find_app_for_startup_id (manager, new_id);
2213 if (app != NULL((void*)0)) {
2214 gsm_client_set_app_id (GSM_CLIENT (client), gsm_app_peek_app_id (app));
2215 gsm_app_registered (app);
2216 goto out;
2217 }
2218
2219 /* app not found */
2220 g_free (new_id);
2221 new_id = NULL((void*)0);
2222
2223 out:
2224 g_free (*id);
2225 *id = new_id;
2226
2227 return handled;
2228}
2229
2230static gboolean
2231auto_save_is_enabled (GsmManager *manager)
2232{
2233 GsmManagerPrivate *priv;
2234
2235 priv = gsm_manager_get_instance_private (manager);
2236 return g_settings_get_boolean (priv->settings_session,
2237 KEY_AUTOSAVE"auto-save-session");
2238}
2239
2240static void
2241maybe_save_session (GsmManager *manager)
2242{
2243 GsmConsolekit *consolekit = NULL((void*)0);
2244#ifdef HAVE_SYSTEMD1
2245 GsmSystemd *systemd = NULL((void*)0);
2246#endif
2247 char *session_type;
2248 GError *error;
2249 GsmManagerPrivate *priv;
2250
2251#ifdef HAVE_SYSTEMD1
2252 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2253 systemd = gsm_get_systemd ();
2254 session_type = gsm_systemd_get_current_session_type (systemd);
2255
2256 if (g_strcmp0 (session_type, GSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0) {
2257 goto out;
2258 }
2259 }
2260 else {
2261#endif
2262 consolekit = gsm_get_consolekit ();
2263 session_type = gsm_consolekit_get_current_session_type (consolekit);
2264
2265 if (g_strcmp0 (session_type, GSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0) {
2266 goto out;
2267 }
2268#ifdef HAVE_SYSTEMD1
2269 }
2270#endif
2271
2272 priv = gsm_manager_get_instance_private (manager);
2273 /* We only allow session saving when session is running or when
2274 * logging out */
2275 if (priv->phase != GSM_MANAGER_PHASE_RUNNING &&
2276 priv->phase != GSM_MANAGER_PHASE_END_SESSION) {
2277 goto out;
2278 }
2279
2280 error = NULL((void*)0);
2281 gsm_session_save (priv->clients, &error);
2282
2283 if (error) {
2284 g_warning ("Error saving session: %s", error->message);
2285 g_error_free (error);
2286 }
2287
2288out:
2289 if (consolekit != NULL((void*)0))
2290 g_object_unref (consolekit);
2291#ifdef HAVE_SYSTEMD1
2292 if (systemd != NULL((void*)0))
2293 g_object_unref (systemd);
2294#endif
2295 g_free (session_type);
2296}
2297
2298static void
2299_handle_client_end_session_response (GsmManager *manager,
2300 GsmClient *client,
2301 gboolean is_ok,
2302 gboolean do_last,
2303 gboolean cancel,
2304 const char *reason)
2305{
2306 GsmManagerPrivate *priv;
2307
2308 priv = gsm_manager_get_instance_private (manager);
2309 /* just ignore if received outside of shutdown */
2310 if (priv->phase < GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2311 return;
2312 }
2313
2314 g_debug ("GsmManager: Response from end session request: is-ok=%d do-last=%d cancel=%d reason=%s", is_ok, do_last, cancel, reason ? reason :"");
2315
2316 if (cancel) {
2317 cancel_end_session (manager);
2318 return;
2319 }
2320
2321 priv->query_clients = g_slist_remove (priv->query_clients, client);
2322
2323 if (! is_ok && priv->logout_mode != GSM_MANAGER_LOGOUT_MODE_FORCE) {
2324 guint cookie;
2325 GsmInhibitor *inhibitor;
2326 char *app_id;
2327 const char *bus_name;
2328
2329 /* FIXME: do we support updating the reason? */
2330
2331 /* Create JIT inhibit */
2332 if (GSM_IS_DBUS_CLIENT (client)) {
2333 bus_name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
2334 } else {
2335 bus_name = NULL((void*)0);
2336 }
2337
2338 app_id = g_strdup (gsm_client_peek_app_id (client))g_strdup_inline (gsm_client_peek_app_id (client));
2339 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
2340 /* XSMP clients don't give us an app id unless we start them */
2341 g_free (app_id);
2342 app_id = gsm_client_get_app_name (client);
2343 }
2344
2345 cookie = _generate_unique_cookie (manager);
2346 inhibitor = gsm_inhibitor_new_for_client (gsm_client_peek_id (client),
2347 app_id,
2348 GSM_INHIBITOR_FLAG_LOGOUT,
2349 reason != NULL((void*)0) ? reason : _("Not responding")gettext ("Not responding"),
2350 bus_name,
2351 cookie);
2352 g_free (app_id);
2353 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
2354 g_object_unref (inhibitor);
2355 } else {
2356 gsm_store_foreach_remove (priv->inhibitors,
2357 (GsmStoreFunc)inhibitor_has_client_id,
2358 (gpointer)gsm_client_peek_id (client));
2359 }
2360
2361 if (priv->phase == GSM_MANAGER_PHASE_QUERY_END_SESSION) {
2362 if (priv->query_clients == NULL((void*)0)) {
2363 query_end_session_complete (manager);
2364 }
2365 } else if (priv->phase == GSM_MANAGER_PHASE_END_SESSION) {
2366 if (do_last) {
2367 /* This only makes sense if we're in part 1 of
2368 * GSM_MANAGER_PHASE_END_SESSION. Doing this in part 2
2369 * can only happen because of a buggy client that loops
2370 * wanting to be last again and again. The phase
2371 * timeout will take care of this issue. */
2372 priv->next_query_clients = g_slist_prepend (priv->next_query_clients,
2373 client);
2374 }
2375
2376 /* we can continue to the next step if all clients have replied
2377 * and if there's no inhibitor */
2378 if (priv->query_clients != NULL((void*)0)
2379 || gsm_manager_is_logout_inhibited (manager)) {
2380 return;
2381 }
2382
2383 if (priv->next_query_clients != NULL((void*)0)) {
2384 do_phase_end_session_part_2 (manager);
2385 } else {
2386 end_phase (manager);
2387 }
2388 }
2389}
2390
2391static void
2392on_client_end_session_response (GsmClient *client,
2393 gboolean is_ok,
2394 gboolean do_last,
2395 gboolean cancel,
2396 const char *reason,
2397 GsmManager *manager)
2398{
2399 _handle_client_end_session_response (manager,
2400 client,
2401 is_ok,
2402 do_last,
2403 cancel,
2404 reason);
2405}
2406
2407static void
2408on_xsmp_client_logout_request (GsmXSMPClient *client,
2409 gboolean show_dialog,
2410 GsmManager *manager)
2411{
2412 GError *error;
2413 int logout_mode;
2414
2415 if (show_dialog) {
2416 logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
2417 } else {
2418 logout_mode = GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION;
2419 }
2420
2421 error = NULL((void*)0);
2422 gsm_manager_logout (manager, logout_mode, &error);
2423 if (error != NULL((void*)0)) {
2424 g_warning ("Unable to logout: %s", error->message);
2425 g_error_free (error);
2426 }
2427}
2428
2429static void
2430on_store_client_added (GsmStore *store,
2431 const char *id,
2432 GsmManager *manager)
2433{
2434 GsmClient *client;
2435
2436 g_debug ("GsmManager: Client added: %s", id);
2437
2438 client = (GsmClient *)gsm_store_lookup (store, id);
2439
2440 /* a bit hacky */
2441 if (GSM_IS_XSMP_CLIENT (client)) {
2442 g_signal_connect (client,g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2443 "register-request",g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2444 G_CALLBACK (on_xsmp_client_register_request),g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2445 manager)g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
;
2446 g_signal_connect (client,g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2447 "logout-request",g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2448 G_CALLBACK (on_xsmp_client_logout_request),g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2449 manager)g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
;
2450 }
2451
2452 g_signal_connect (client,g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2453 "end-session-response",g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2454 G_CALLBACK (on_client_end_session_response),g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2455 manager)g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
;
2456
2457 g_signal_emit (manager, signals [CLIENT_ADDED], 0, id);
2458 /* FIXME: disconnect signal handler */
2459}
2460
2461static void
2462on_store_client_removed (GsmStore *store,
2463 const char *id,
2464 GsmManager *manager)
2465{
2466 g_debug ("GsmManager: Client removed: %s", id);
2467
2468 g_signal_emit (manager, signals [CLIENT_REMOVED], 0, id);
2469}
2470
2471static void
2472gsm_manager_set_client_store (GsmManager *manager,
2473 GsmStore *store)
2474{
2475 GsmManagerPrivate *priv;
2476
2477 g_return_if_fail (GSM_IS_MANAGER (manager))do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2478 priv = gsm_manager_get_instance_private (manager);
2479
2480 if (store != NULL((void*)0)) {
2481 g_object_ref (store)((__typeof__ (store)) (g_object_ref) (store));
2482 }
2483
2484 if (priv->clients != NULL((void*)0)) {
2485 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2486 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2487 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2488 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2489 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2490 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2491
2492 g_object_unref (priv->clients);
2493 }
2494
2495 g_debug ("GsmManager: setting client store %p", store);
2496
2497 priv->clients = store;
2498
2499 if (priv->clients != NULL((void*)0)) {
2500 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2501 "added",g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2502 G_CALLBACK (on_store_client_added),g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2503 manager)g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2504 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2505 "removed",g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2506 G_CALLBACK (on_store_client_removed),g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2507 manager)g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2508 }
2509}
2510
2511static void
2512gsm_manager_set_property (GObject *object,
2513 guint prop_id,
2514 const GValue *value,
2515 GParamSpec *pspec)
2516{
2517 GsmManager *self;
2518
2519 self = GSM_MANAGER (object);
2520
2521 switch (prop_id) {
2522 case PROP_FAILSAFE:
2523 gsm_manager_set_failsafe (self, g_value_get_boolean (value));
2524 break;
2525 case PROP_CLIENT_STORE:
2526 gsm_manager_set_client_store (self, g_value_get_object (value));
2527 break;
2528 default:
2529 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-manager.c", 2529, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2530 break;
2531 }
2532}
2533
2534static void
2535gsm_manager_get_property (GObject *object,
2536 guint prop_id,
2537 GValue *value,
2538 GParamSpec *pspec)
2539{
2540 GsmManager *self;
2541 GsmManagerPrivate *priv;
2542
2543 self = GSM_MANAGER (object);
2544 priv = gsm_manager_get_instance_private (self);
2545
2546 switch (prop_id) {
2547 case PROP_FAILSAFE:
2548 g_value_set_boolean (value, priv->failsafe);
2549 break;
2550 case PROP_CLIENT_STORE:
2551 g_value_set_object (value, priv->clients);
2552 break;
2553 case PROP_RENDERER:
2554 g_value_set_string (value, priv->renderer);
2555 break;
2556 default:
2557 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "gsm-manager.c", 2557, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2558 break;
2559 }
2560}
2561
2562static gboolean
2563_find_app_provides (const char *id,
2564 GsmApp *app,
2565 const char *service)
2566{
2567 return gsm_app_provides (app, service);
2568}
2569
2570static GObject *
2571gsm_manager_constructor (GType type,
2572 guint n_construct_properties,
2573 GObjectConstructParam *construct_properties)
2574{
2575 GsmManager *manager;
2576
2577 manager = GSM_MANAGER (G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->constructor (type,
2578 n_construct_properties,
2579 construct_properties));
2580 return G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
;
2581}
2582
2583static void
2584on_store_inhibitor_added (GsmStore *store,
2585 const char *id,
2586 GsmManager *manager)
2587{
2588 g_debug ("GsmManager: Inhibitor added: %s", id);
2589 g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
2590 update_idle (manager);
2591}
2592
2593static void
2594on_store_inhibitor_removed (GsmStore *store,
2595 const char *id,
2596 GsmManager *manager)
2597{
2598 g_debug ("GsmManager: Inhibitor removed: %s", id);
2599 g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
2600 update_idle (manager);
2601}
2602
2603static void
2604gsm_manager_dispose (GObject *object)
2605{
2606 GsmManagerPrivate *priv;
2607 GsmManager *manager = GSM_MANAGER (object);
2608
2609 g_debug ("GsmManager: disposing manager");
2610
2611 priv = gsm_manager_get_instance_private (manager);
2612
2613 if (priv->clients != NULL((void*)0)) {
2614 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2615 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2616 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2617 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2618 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2619 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2620 g_object_unref (priv->clients);
2621 priv->clients = NULL((void*)0);
2622 }
2623
2624 if (priv->apps != NULL((void*)0)) {
2625 g_object_unref (priv->apps);
2626 priv->apps = NULL((void*)0);
2627 }
2628
2629 if (priv->inhibitors != NULL((void*)0)) {
2630 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2631 on_store_inhibitor_added,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2632 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
;
2633 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2634 on_store_inhibitor_removed,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2635 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
;
2636
2637 g_object_unref (priv->inhibitors);
2638 priv->inhibitors = NULL((void*)0);
2639 }
2640
2641 if (priv->presence != NULL((void*)0)) {
2642 g_object_unref (priv->presence);
2643 priv->presence = NULL((void*)0);
2644 }
2645
2646 if (priv->settings_session) {
2647 g_object_unref (priv->settings_session);
2648 priv->settings_session = NULL((void*)0);
2649 }
2650
2651 if (priv->settings_lockdown) {
2652 g_object_unref (priv->settings_lockdown);
2653 priv->settings_lockdown = NULL((void*)0);
2654 }
2655
2656 if (priv->settings_screensaver) {
2657 g_object_unref (priv->settings_screensaver);
2658 priv->settings_screensaver = NULL((void*)0);
2659 }
2660
2661 g_clear_pointer (&priv->renderer, g_free)do { _Static_assert (sizeof *(&priv->renderer) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
priv->renderer)) _pp = (&priv->renderer); __typeof__
(*(&priv->renderer)) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_free) (_ptr); } while (0)
;
2662
2663 G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->dispose (object);
2664}
2665
2666static void
2667gsm_manager_class_init (GsmManagerClass *klass)
2668{
2669 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
2670
2671 object_class->get_property = gsm_manager_get_property;
2672 object_class->set_property = gsm_manager_set_property;
2673 object_class->constructor = gsm_manager_constructor;
2674 object_class->finalize = gsm_manager_finalize;
2675 object_class->dispose = gsm_manager_dispose;
2676
2677 signals [PHASE_CHANGED] =
2678 g_signal_new ("phase-changed",
2679 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2680 G_SIGNAL_RUN_LAST,
2681 G_STRUCT_OFFSET (GsmManagerClass, phase_changed)((glong) __builtin_offsetof(GsmManagerClass, phase_changed)),
2682 NULL((void*)0),
2683 NULL((void*)0),
2684 g_cclosure_marshal_VOID__STRING,
2685 G_TYPE_NONE((GType) ((1) << (2))),
2686 1, G_TYPE_STRING((GType) ((16) << (2))));
2687
2688 signals [SESSION_RUNNING] =
2689 g_signal_new ("session-running",
2690 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2691 G_SIGNAL_RUN_LAST,
2692 G_STRUCT_OFFSET (GsmManagerClass, session_running)((glong) __builtin_offsetof(GsmManagerClass, session_running)
)
,
2693 NULL((void*)0),
2694 NULL((void*)0),
2695 g_cclosure_marshal_VOID__VOID,
2696 G_TYPE_NONE((GType) ((1) << (2))),
2697 0);
2698
2699 signals [SESSION_OVER] =
2700 g_signal_new ("session-over",
2701 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2702 G_SIGNAL_RUN_LAST,
2703 G_STRUCT_OFFSET (GsmManagerClass, session_over)((glong) __builtin_offsetof(GsmManagerClass, session_over)),
2704 NULL((void*)0), NULL((void*)0),
2705 g_cclosure_marshal_VOID__VOID,
2706 G_TYPE_NONE((GType) ((1) << (2))),
2707 0);
2708 signals [CLIENT_ADDED] =
2709 g_signal_new ("client-added",
2710 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2711 G_SIGNAL_RUN_LAST,
2712 G_STRUCT_OFFSET (GsmManagerClass, client_added)((glong) __builtin_offsetof(GsmManagerClass, client_added)),
2713 NULL((void*)0),
2714 NULL((void*)0),
2715 g_cclosure_marshal_VOID__BOXED,
2716 G_TYPE_NONE((GType) ((1) << (2))),
2717 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2718 signals [CLIENT_REMOVED] =
2719 g_signal_new ("client-removed",
2720 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2721 G_SIGNAL_RUN_LAST,
2722 G_STRUCT_OFFSET (GsmManagerClass, client_removed)((glong) __builtin_offsetof(GsmManagerClass, client_removed)),
2723 NULL((void*)0),
2724 NULL((void*)0),
2725 g_cclosure_marshal_VOID__BOXED,
2726 G_TYPE_NONE((GType) ((1) << (2))),
2727 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2728 signals [INHIBITOR_ADDED] =
2729 g_signal_new ("inhibitor-added",
2730 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2731 G_SIGNAL_RUN_LAST,
2732 G_STRUCT_OFFSET (GsmManagerClass, inhibitor_added)((glong) __builtin_offsetof(GsmManagerClass, inhibitor_added)
)
,
2733 NULL((void*)0),
2734 NULL((void*)0),
2735 g_cclosure_marshal_VOID__BOXED,
2736 G_TYPE_NONE((GType) ((1) << (2))),
2737 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2738 signals [INHIBITOR_REMOVED] =
2739 g_signal_new ("inhibitor-removed",
2740 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2741 G_SIGNAL_RUN_LAST,
2742 G_STRUCT_OFFSET (GsmManagerClass, inhibitor_removed)((glong) __builtin_offsetof(GsmManagerClass, inhibitor_removed
))
,
2743 NULL((void*)0),
2744 NULL((void*)0),
2745 g_cclosure_marshal_VOID__BOXED,
2746 G_TYPE_NONE((GType) ((1) << (2))),
2747 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2748
2749 g_object_class_install_property (object_class,
2750 PROP_FAILSAFE,
2751 g_param_spec_boolean ("failsafe",
2752 NULL((void*)0),
2753 NULL((void*)0),
2754 FALSE(0),
2755 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2756 g_object_class_install_property (object_class,
2757 PROP_CLIENT_STORE,
2758 g_param_spec_object ("client-store",
2759 NULL((void*)0),
2760 NULL((void*)0),
2761 GSM_TYPE_STORE(gsm_store_get_type ()),
2762 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2763
2764 g_object_class_install_property (object_class,
2765 PROP_RENDERER,
2766 g_param_spec_string ("renderer",
2767 NULL((void*)0),
2768 NULL((void*)0),
2769 NULL((void*)0),
2770 G_PARAM_READABLE));
2771
2772 dbus_g_object_type_install_info (GSM_TYPE_MANAGER(gsm_manager_get_type ()), &dbus_glib_gsm_manager_object_info);
2773 dbus_g_error_domain_register (GSM_MANAGER_ERRORgsm_manager_error_quark (), NULL((void*)0), GSM_MANAGER_TYPE_ERROR(gsm_manager_error_get_type ()));
2774}
2775
2776static void
2777load_idle_delay_from_gsettings (GsmManager *manager)
2778{
2779 glong value;
2780 GsmManagerPrivate *priv;
2781
2782 priv = gsm_manager_get_instance_private (manager);
2783 value = g_settings_get_int (priv->settings_session,
2784 KEY_IDLE_DELAY"idle-delay");
2785 gsm_presence_set_idle_timeout (priv->presence, value * 60000);
2786}
2787
2788static void
2789on_gsettings_key_changed (GSettings *settings,
2790 gchar *key,
2791 GsmManager *manager)
2792{
2793 GsmManagerPrivate *priv;
2794
2795 priv = gsm_manager_get_instance_private (manager);
2796 if (g_strcmp0 (key, KEY_IDLE_DELAY"idle-delay") == 0) {
2797 int delay;
2798 delay = g_settings_get_int (settings, key);
2799 gsm_presence_set_idle_timeout (priv->presence, delay * 60000);
2800 } else if (g_strcmp0 (key, KEY_LOCK_DISABLE"disable-lock-screen") == 0) {
2801 /* ??? */
2802 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2803 disabled = g_settings_get_boolean (settings, key);
2804 } else if (g_strcmp0 (key, KEY_USER_SWITCH_DISABLE"disable-user-switching") == 0) {
2805 /* ??? */
2806 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2807 disabled = g_settings_get_boolean (settings, key);
2808 } else {
2809 g_debug ("Config key not handled: %s", key);
2810 }
2811}
2812
2813static void
2814on_presence_status_changed (GsmPresence *presence,
2815 guint status,
2816 GsmManager *manager)
2817{
2818#ifdef HAVE_SYSTEMD1
2819 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2820 GsmSystemd *systemd;
2821
2822 systemd = gsm_get_systemd ();
2823 gsm_systemd_set_session_idle (systemd,
2824 (status == GSM_PRESENCE_STATUS_IDLE));
2825 }
2826 else {
2827#endif
2828 GsmConsolekit *consolekit;
2829
2830 consolekit = gsm_get_consolekit ();
2831 gsm_consolekit_set_session_idle (consolekit,
2832 (status == GSM_PRESENCE_STATUS_IDLE));
2833#ifdef HAVE_SYSTEMD1
2834 }
2835#endif
2836}
2837
2838static void
2839gsm_manager_init (GsmManager *manager)
2840{
2841 gchar **schemas = NULL((void*)0);
2842 gboolean schema_exists;
2843 guint i;
2844 GsmManagerPrivate *priv;
2845
2846 priv = gsm_manager_get_instance_private (manager);
2847
2848 priv->settings_session = g_settings_new (SESSION_SCHEMA"org.mate.session");
2849 priv->settings_lockdown = g_settings_new (LOCKDOWN_SCHEMA"org.mate.lockdown");
2850
2851 /* check if mate-screensaver is installed */
2852 g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (), TRUE(!(0)), &schemas, NULL((void*)0));
2853 schema_exists = FALSE(0);
2854 for (i = 0; schemas[i] != NULL((void*)0); i++) {
2855 if (g_str_equal (schemas[i], SCREENSAVER_SCHEMA)(strcmp ((const char *) (schemas[i]), (const char *) ("org.mate.screensaver"
)) == 0)
) {
2856 schema_exists = TRUE(!(0));
2857 break;
2858 }
2859 }
2860
2861 g_strfreev (schemas);
2862
2863 if (schema_exists == TRUE(!(0)))
2864 priv->settings_screensaver = g_settings_new (SCREENSAVER_SCHEMA"org.mate.screensaver");
2865 else
2866 priv->settings_screensaver = NULL((void*)0);
2867
2868 priv->inhibitors = gsm_store_new ();
2869 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2870 "added",g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2871 G_CALLBACK (on_store_inhibitor_added),g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2872 manager)g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2873 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2874 "removed",g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2875 G_CALLBACK (on_store_inhibitor_removed),g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2876 manager)g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2877
2878 priv->apps = gsm_store_new ();
2879
2880 priv->presence = gsm_presence_new ();
2881 g_signal_connect (priv->presence,g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2882 "status-changed",g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2883 G_CALLBACK (on_presence_status_changed),g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2884 manager)g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
;
2885 g_signal_connect (priv->settings_session,g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2886 "changed",g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2887 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2888 manager)g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2889 g_signal_connect (priv->settings_lockdown,g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2890 "changed",g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2891 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2892 manager)g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2893
2894 load_idle_delay_from_gsettings (manager);
2895}
2896
2897static void
2898gsm_manager_finalize (GObject *object)
2899{
2900 GsmManager *manager;
2901 GsmManagerPrivate *priv;
2902
2903 g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
2904 g_return_if_fail (GSM_IS_MANAGER (object))do { if ((GSM_IS_MANAGER (object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (object)"
); return; } } while (0)
;
2905
2906 manager = GSM_MANAGER (object);
2907 priv = gsm_manager_get_instance_private (manager);
2908
2909 g_return_if_fail (priv != NULL)do { if ((priv != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "priv != NULL"); return
; } } while (0)
;
2910
2911 G_OBJECT_CLASS (gsm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((gsm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->finalize (object);
2912}
2913
2914GsmManager *
2915gsm_manager_new (GsmStore *client_store,
2916 gboolean failsafe)
2917{
2918 if (manager_object != NULL((void*)0)) {
2919 g_object_ref (manager_object)((__typeof__ (manager_object)) (g_object_ref) (manager_object
))
;
2920 } else {
2921 gboolean res;
2922
2923 manager_object = g_object_new (GSM_TYPE_MANAGER(gsm_manager_get_type ()),
2924 "client-store", client_store,
2925 "failsafe", failsafe,
2926 NULL((void*)0));
2927
2928 g_object_add_weak_pointer (manager_object,
2929 (gpointer *) &manager_object);
2930 res = register_manager (manager_object);
2931 if (! res) {
2932 g_object_unref (manager_object);
2933 return NULL((void*)0);
2934 }
2935 }
2936
2937 return GSM_MANAGER (manager_object);
2938}
2939
2940gboolean
2941gsm_manager_setenv (GsmManager *manager,
2942 const char *variable,
2943 const char *value,
2944 GError **error)
2945{
2946 GsmManagerPrivate *priv;
2947
2948 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2949
2950 priv = gsm_manager_get_instance_private (manager);
2951 if (priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
2952 g_set_error (error,
2953 GSM_MANAGER_ERRORgsm_manager_error_quark (),
2954 GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2955 "Setenv interface is only available during the Initialization phase");
2956 return FALSE(0);
2957 }
2958
2959 gsm_util_setenv (variable, value);
2960
2961 return TRUE(!(0));
2962}
2963
2964gboolean
2965gsm_manager_initialization_error (GsmManager *manager,
2966 const char *message,
2967 gboolean fatal,
2968 GError **error)
2969{
2970 GsmManagerPrivate *priv;
2971 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2972
2973 priv = gsm_manager_get_instance_private (manager);
2974
2975 if (priv->phase > GSM_MANAGER_PHASE_INITIALIZATION) {
2976 g_set_error (error,
2977 GSM_MANAGER_ERRORgsm_manager_error_quark (),
2978 GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2979 "InitializationError interface is only available during the Initialization phase");
2980 return FALSE(0);
2981 }
2982
2983 gsm_util_init_error (fatal, "%s", message);
2984
2985 return TRUE(!(0));
2986}
2987
2988static gboolean
2989gsm_manager_is_switch_user_inhibited (GsmManager *manager)
2990{
2991 GsmInhibitor *inhibitor;
2992 GsmManagerPrivate *priv;
2993
2994 priv = gsm_manager_get_instance_private (manager);
2995
2996 if (priv->inhibitors == NULL((void*)0)) {
2997 return FALSE(0);
2998 }
2999
3000 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3001 (GsmStoreFunc)inhibitor_has_flag,
3002 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_SWITCH_USER)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_SWITCH_USER)));
3003 if (inhibitor == NULL((void*)0)) {
3004 return FALSE(0);
3005 }
3006 return TRUE(!(0));
3007}
3008
3009static gboolean
3010gsm_manager_is_suspend_inhibited (GsmManager *manager)
3011{
3012 GsmInhibitor *inhibitor;
3013 GsmManagerPrivate *priv;
3014
3015 priv = gsm_manager_get_instance_private (manager);
3016
3017 if (priv->inhibitors == NULL((void*)0)) {
3018 return FALSE(0);
3019 }
3020
3021 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3022 (GsmStoreFunc)inhibitor_has_flag,
3023 GUINT_TO_POINTER (GSM_INHIBITOR_FLAG_SUSPEND)((gpointer) (gulong) (GSM_INHIBITOR_FLAG_SUSPEND)));
3024 if (inhibitor == NULL((void*)0)) {
3025 return FALSE(0);
3026 }
3027 return TRUE(!(0));
3028}
3029
3030static void
3031request_reboot_privileges_completed_consolekit (GsmConsolekit *consolekit,
3032 gboolean success,
3033 gboolean ask_later,
3034 GError *error,
3035 GsmManager *manager)
3036{
3037 GsmManagerPrivate *priv;
3038
3039 priv = gsm_manager_get_instance_private (manager);
3040 /* make sure we disconnect the signal handler so that it's not called
3041 * again next time the event is fired -- this can happen if the reboot
3042 * is cancelled. */
3043 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3044 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3045 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3046
3047 g_object_unref (consolekit);
3048
3049 if (success) {
3050 if (ask_later) {
3051 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3052 } else {
3053 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT;
3054 }
3055
3056 end_phase (manager);
3057 }
3058}
3059
3060#ifdef HAVE_SYSTEMD1
3061static void
3062request_reboot_privileges_completed_systemd (GsmSystemd *systemd,
3063 gboolean success,
3064 gboolean ask_later,
3065 GError *error,
3066 GsmManager *manager)
3067{
3068 GsmManagerPrivate *priv;
3069
3070 priv = gsm_manager_get_instance_private (manager);
3071 /* make sure we disconnect the signal handler so that it's not called
3072 * again next time the event is fired -- this can happen if the reboot
3073 * is cancelled. */
3074 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3075 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3076 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3077
3078 g_object_unref (systemd);
3079
3080 if (success) {
3081 if (ask_later) {
3082 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3083 } else {
3084 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT;
3085 }
3086
3087 end_phase (manager);
3088 }
3089}
3090#endif
3091
3092static void
3093request_reboot (GsmManager *manager)
3094{
3095 GsmConsolekit *consolekit;
3096#ifdef HAVE_SYSTEMD1
3097 GsmSystemd *systemd;
3098#endif
3099 gboolean success;
3100 GsmManagerPrivate *priv;
3101
3102 g_debug ("GsmManager: requesting reboot");
3103
3104 priv = gsm_manager_get_instance_private (manager);
3105
3106 /* We request the privileges before doing anything. There are a few
3107 * different cases here:
3108 *
3109 * - no systemd: we fallback on ConsoleKit
3110 * - no ConsoleKit: we fallback on MDM
3111 * - no password required: everything is fine
3112 * - password asked once: we ask for it now. If the user enters it
3113 * fine, then all is great. If the user doesn't enter it fine, we
3114 * don't do anything (so no logout).
3115 * - password asked each time: we don't ask it for now since we don't
3116 * want to ask for it twice. Instead we'll ask for it at the very
3117 * end. If the user will enter it fine, then all is great again. If
3118 * the user doesn't enter it fine, then we'll just fallback to MDM.
3119 *
3120 * The last case (password asked each time) is a bit broken, but
3121 * there's really nothing we can do about it. Generally speaking,
3122 * though, the password will only be asked once (unless the system is
3123 * configured in paranoid mode), and most probably only if there are
3124 * more than one user connected. So the general case is that it will
3125 * just work fine.
3126 */
3127
3128#ifdef HAVE_SYSTEMD1
3129 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3130 systemd = gsm_get_systemd ();
3131 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3132 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3133 G_CALLBACK (request_reboot_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3134 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
;
3135 success = gsm_systemd_get_restart_privileges (systemd);
3136
3137 if (!success) {
3138 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3139 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3140 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3141 g_object_unref (systemd);
3142
3143 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_MDM;
3144 end_phase (manager);
3145 }
3146 }
3147 else {
3148#endif
3149 consolekit = gsm_get_consolekit ();
3150 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3151 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3152 G_CALLBACK (request_reboot_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3153 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3154 success = gsm_consolekit_get_restart_privileges (consolekit);
3155
3156 if (!success) {
3157 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3158 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3159 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3160 g_object_unref (consolekit);
3161
3162 priv->logout_type = GSM_MANAGER_LOGOUT_REBOOT_MDM;
3163 end_phase (manager);
3164 }
3165#ifdef HAVE_SYSTEMD1
3166 }
3167#endif
3168}
3169
3170static void
3171request_shutdown_privileges_completed_consolekit (GsmConsolekit *consolekit,
3172 gboolean success,
3173 gboolean ask_later,
3174 GError *error,
3175 GsmManager *manager)
3176{
3177 GsmManagerPrivate *priv;
3178
3179 priv = gsm_manager_get_instance_private (manager);
3180 /* make sure we disconnect the signal handler so that it's not called
3181 * again next time the event is fired -- this can happen if the reboot
3182 * is cancelled. */
3183 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3184 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3185 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3186
3187 g_object_unref (consolekit);
3188
3189 if (success) {
3190 if (ask_later) {
3191 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3192 } else {
3193 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN;
3194 }
3195
3196 end_phase (manager);
3197 }
3198}
3199
3200#ifdef HAVE_SYSTEMD1
3201static void
3202request_shutdown_privileges_completed_systemd (GsmSystemd *systemd,
3203 gboolean success,
3204 gboolean ask_later,
3205 GError *error,
3206 GsmManager *manager)
3207{
3208 GsmManagerPrivate *priv;
3209
3210 priv = gsm_manager_get_instance_private (manager);
3211 /* make sure we disconnect the signal handler so that it's not called
3212 * again next time the event is fired -- this can happen if the reboot
3213 * is cancelled. */
3214 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3215 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3216 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3217
3218 g_object_unref (systemd);
3219
3220 if (success) {
3221 if (ask_later) {
3222 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3223 } else {
3224 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN;
3225 }
3226
3227 end_phase (manager);
3228 }
3229}
3230#endif
3231
3232static void
3233request_shutdown (GsmManager *manager)
3234{
3235 GsmConsolekit *consolekit;
3236#ifdef HAVE_SYSTEMD1
3237 GsmSystemd *systemd;
3238#endif
3239 gboolean success;
3240 GsmManagerPrivate *priv;
3241
3242 g_debug ("GsmManager: requesting shutdown");
3243
3244 priv = gsm_manager_get_instance_private (manager);
3245
3246 /* See the comment in request_reboot() for some more details about how
3247 * this works. */
3248
3249#ifdef HAVE_SYSTEMD1
3250 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3251 systemd = gsm_get_systemd ();
3252 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3253 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3254 G_CALLBACK (request_shutdown_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3255 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
;
3256 success = gsm_systemd_get_stop_privileges (systemd);
3257
3258 if (!success) {
3259 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3260 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3261 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3262 g_object_unref (systemd);
3263
3264 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_MDM;
3265 end_phase (manager);
3266 }
3267 }
3268 else {
3269#endif
3270 consolekit = gsm_get_consolekit ();
3271 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3272 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3273 G_CALLBACK (request_shutdown_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3274 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3275 success = gsm_consolekit_get_stop_privileges (consolekit);
3276
3277 if (!success) {
3278 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3279 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3280 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3281 g_object_unref (consolekit);
3282
3283 priv->logout_type = GSM_MANAGER_LOGOUT_SHUTDOWN_MDM;
3284 end_phase (manager);
3285 }
3286#ifdef HAVE_SYSTEMD1
3287 }
3288#endif
3289}
3290
3291static void
3292request_suspend (GsmManager *manager)
3293{
3294 GsmManagerPrivate *priv;
3295
3296 g_debug ("GsmManager: requesting suspend");
3297
3298 if (! gsm_manager_is_suspend_inhibited (manager)) {
3299 manager_attempt_suspend (manager);
3300 return;
3301 }
3302
3303 priv = gsm_manager_get_instance_private (manager);
3304 if (priv->inhibit_dialog != NULL((void*)0)) {
3305 g_debug ("GsmManager: inhibit dialog already up");
3306 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3307 return;
3308 }
3309
3310 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3311 priv->clients,
3312 GSM_LOGOUT_ACTION_SLEEP);
3313
3314 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3315 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3316 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3317 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3318 gtk_widget_show (priv->inhibit_dialog);
3319}
3320
3321static void
3322request_hibernate (GsmManager *manager)
3323{
3324 GsmManagerPrivate *priv;
3325
3326 g_debug ("GsmManager: requesting hibernate");
3327
3328 /* hibernate uses suspend inhibit */
3329 if (! gsm_manager_is_suspend_inhibited (manager)) {
3330 manager_attempt_hibernate (manager);
3331 return;
3332 }
3333
3334 priv = gsm_manager_get_instance_private (manager);
3335 if (priv->inhibit_dialog != NULL((void*)0)) {
3336 g_debug ("GsmManager: inhibit dialog already up");
3337 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3338 return;
3339 }
3340
3341 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3342 priv->clients,
3343 GSM_LOGOUT_ACTION_HIBERNATE);
3344
3345 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3346 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3347 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3348 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3349 gtk_widget_show (priv->inhibit_dialog);
3350}
3351
3352static void
3353request_logout (GsmManager *manager,
3354 GsmManagerLogoutMode mode)
3355{
3356 GsmManagerPrivate *priv;
3357
3358 g_debug ("GsmManager: requesting logout");
3359
3360 priv = gsm_manager_get_instance_private (manager);
3361
3362 priv->logout_mode = mode;
3363 priv->logout_type = GSM_MANAGER_LOGOUT_LOGOUT;
3364
3365 end_phase (manager);
3366}
3367
3368static void
3369request_switch_user (GsmManager *manager)
3370{
3371 GsmManagerPrivate *priv;
3372
3373 g_debug ("GsmManager: requesting user switch");
3374
3375 /* See comment in manager_switch_user() to understand why we do this in
3376 * both functions. */
3377 if (_switch_user_is_locked_down (manager)) {
3378 g_warning ("Unable to switch user: User switching has been locked down");
3379 return;
3380 }
3381
3382 if (! gsm_manager_is_switch_user_inhibited (manager)) {
3383 manager_switch_user (manager);
3384 return;
3385 }
3386
3387 priv = gsm_manager_get_instance_private (manager);
3388 if (priv->inhibit_dialog != NULL((void*)0)) {
3389 g_debug ("GsmManager: inhibit dialog already up");
3390 gtk_window_present (GTK_WINDOW (priv->inhibit_dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((gtk_window_get_type ())))))
)
);
3391 return;
3392 }
3393
3394 priv->inhibit_dialog = gsm_inhibit_dialog_new (priv->inhibitors,
3395 priv->clients,
3396 GSM_LOGOUT_ACTION_SWITCH_USER);
3397
3398 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3399 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3400 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3401 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3402 gtk_widget_show (priv->inhibit_dialog);
3403}
3404
3405static void
3406logout_dialog_response (GsmLogoutDialog *logout_dialog,
3407 guint response_id,
3408 GsmManager *manager)
3409{
3410 GsmManagerPrivate *priv;
3411
3412 priv = gsm_manager_get_instance_private (manager);
3413 /* We should only be here if mode has already have been set from
3414 * show_fallback_shutdown/logout_dialog
3415 */
3416 g_assert (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL)do { if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL
) ; else g_assertion_message_expr (((gchar*) 0), "gsm-manager.c"
, 3416, ((const char*) (__func__)), "priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_NORMAL"
); } while (0)
;
3417
3418 g_debug ("GsmManager: Logout dialog response: %d", response_id);
3419
3420 gtk_widget_destroy (GTK_WIDGET (logout_dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((gtk_widget_get_type ()))))))
);
3421
3422 /* In case of dialog cancel, switch user, hibernate and
3423 * suspend, we just perform the respective action and return,
3424 * without shutting down the session. */
3425 switch (response_id) {
3426 case GTK_RESPONSE_CANCEL:
3427 case GTK_RESPONSE_NONE:
3428 case GTK_RESPONSE_DELETE_EVENT:
3429 break;
3430 case GSM_LOGOUT_RESPONSE_SWITCH_USER:
3431 request_switch_user (manager);
3432 break;
3433 case GSM_LOGOUT_RESPONSE_HIBERNATE:
3434 request_hibernate (manager);
3435 break;
3436 case GSM_LOGOUT_RESPONSE_SLEEP:
3437 request_suspend (manager);
3438 break;
3439 case GSM_LOGOUT_RESPONSE_SHUTDOWN:
3440 request_shutdown (manager);
3441 break;
3442 case GSM_LOGOUT_RESPONSE_REBOOT:
3443 request_reboot (manager);
3444 break;
3445 case GSM_LOGOUT_RESPONSE_LOGOUT:
3446 /* We've already gotten confirmation from the user so
3447 * initiate the logout in NO_CONFIRMATION mode.
3448 *
3449 * (it shouldn't matter whether we use NO_CONFIRMATION or stay
3450 * with NORMAL, unless the shell happens to start after the
3451 * user confirmed)
3452 */
3453 request_logout (manager, GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION);
3454 break;
3455 default:
3456 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "gsm-manager.c",
3456, ((const char*) (__func__)), ((void*)0)); } while (0)
;
3457 break;
3458 }
3459}
3460
3461static void
3462show_shutdown_dialog (GsmManager *manager)
3463{
3464 GtkWidget *dialog;
3465 GsmManagerPrivate *priv;
3466
3467 priv = gsm_manager_get_instance_private (manager);
3468 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3469 /* Already shutting down, nothing more to do */
3470 return;
3471 }
3472
3473 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
3474
3475 dialog = gsm_get_shutdown_dialog (gdk_screen_get_default (),
3476 gtk_get_current_event_time ());
3477
3478 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3479 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3480 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3481 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3482 gtk_widget_show (dialog);
3483 gtk_window_present_with_time (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
3484 gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
)));
3485}
3486
3487static void
3488show_logout_dialog (GsmManager *manager)
3489{
3490 GtkWidget *dialog;
3491 GsmManagerPrivate *priv;
3492
3493 priv = gsm_manager_get_instance_private (manager);
3494 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3495 /* Already shutting down, nothing more to do */
3496 return;
3497 }
3498
3499 priv->logout_mode = GSM_MANAGER_LOGOUT_MODE_NORMAL;
3500
3501 dialog = gsm_get_logout_dialog (gdk_screen_get_default (),
3502 gtk_get_current_event_time ());
3503
3504 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3505 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3506 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3507 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3508 gtk_widget_show (dialog);
3509 gtk_window_present_with_time (GTK_WINDOW (dialog)((((GtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_window_get_type ()))))))
,
3510 gdk_x11_get_server_time (gtk_widget_get_window (GTK_WIDGET (dialog)((((GtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((gtk_widget_get_type ()))))))
)));
3511}
3512
3513static void
3514user_logout (GsmManager *manager,
3515 GsmManagerLogoutMode mode)
3516{
3517 gboolean logout_prompt;
3518 GsmManagerPrivate *priv;
3519
3520 priv = gsm_manager_get_instance_private (manager);
3521
3522 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3523 /* Already shutting down, nothing more to do */
3524 return;
3525 }
3526
3527 logout_prompt =
3528 g_settings_get_boolean (priv->settings_session,
3529 "logout-prompt");
3530
3531 /* If the shell isn't running, and this isn't a non-interative logout request,
3532 * and the user has their settings configured to show a confirmation dialog for
3533 * logout, then go ahead and show the confirmation dialog now.
3534 */
3535 if (mode == GSM_MANAGER_LOGOUT_MODE_NORMAL && logout_prompt) {
3536 show_logout_dialog (manager);
3537 } else {
3538 request_logout (manager, mode);
3539 }
3540}
3541
3542/*
3543 dbus-send --session --type=method_call --print-reply
3544 --dest=org.gnome.SessionManager
3545 /org/gnome/SessionManager
3546 org.freedesktop.DBus.Introspectable.Introspect
3547*/
3548
3549gboolean
3550gsm_manager_set_phase (GsmManager *manager,
3551 GsmManagerPhase phase)
3552{
3553 GsmManagerPrivate *priv;
3554
3555 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3556
3557 priv = gsm_manager_get_instance_private (manager);
3558 priv->phase = phase;
3559 return (TRUE(!(0)));
3560}
3561
3562gboolean
3563gsm_manager_request_shutdown (GsmManager *manager,
3564 GError **error)
3565{
3566 GsmManagerPrivate *priv;
3567 g_debug ("GsmManager: RequestShutdown called");
3568
3569 g_return_val_if_fail(GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3570
3571 priv = gsm_manager_get_instance_private (manager);
3572 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3573 g_set_error (error,
3574 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3575 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3576 "RequestShutdown interface is only available during the Running phase");
3577 return FALSE(0);
3578 }
3579
3580 request_shutdown (manager);
3581
3582 return TRUE(!(0));
3583}
3584
3585gboolean
3586gsm_manager_request_reboot (GsmManager *manager,
3587 GError **error)
3588{
3589 GsmManagerPrivate *priv;
3590
3591 g_debug ("GsmManager: RequestReboot called");
3592
3593 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3594
3595 priv = gsm_manager_get_instance_private (manager);
3596 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3597 g_set_error (error,
3598 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3599 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3600 "RequestReboot interface is only available during the running phase");
3601 return FALSE(0);
3602 }
3603
3604 request_reboot (manager);
3605
3606 return TRUE(!(0));
3607}
3608
3609static gboolean
3610_log_out_is_locked_down (GsmManager *manager)
3611{
3612 GsmManagerPrivate *priv;
3613
3614 priv = gsm_manager_get_instance_private (manager);
3615
3616 return g_settings_get_boolean (priv->settings_lockdown,
3617 KEY_LOG_OUT_DISABLE"disable-log-out");
3618}
3619
3620static gboolean
3621_switch_user_is_locked_down (GsmManager *manager)
3622{
3623 GsmManagerPrivate *priv;
3624
3625 priv = gsm_manager_get_instance_private (manager);
3626 return g_settings_get_boolean (priv->settings_lockdown,
3627 KEY_USER_SWITCH_DISABLE"disable-user-switching");
3628}
3629
3630gboolean
3631gsm_manager_shutdown (GsmManager *manager,
3632 GError **error)
3633{
3634 GsmManagerPrivate *priv;
3635 g_debug ("GsmManager: Shutdown called");
3636
3637 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3638
3639 priv = gsm_manager_get_instance_private (manager);
3640 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3641 g_set_error (error,
3642 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3643 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3644 "Shutdown interface is only available during the Running phase");
3645 return FALSE(0);
3646 }
3647
3648 if (_log_out_is_locked_down (manager)) {
3649 g_set_error (error,
3650 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3651 GSM_MANAGER_ERROR_LOCKED_DOWN,
3652 "Logout has been locked down");
3653 return FALSE(0);
3654 }
3655
3656 show_shutdown_dialog (manager);
3657
3658 return TRUE(!(0));
3659}
3660
3661gboolean
3662gsm_manager_can_shutdown (GsmManager *manager,
3663 gboolean *shutdown_available,
3664 GError **error)
3665{
3666 GsmConsolekit *consolekit;
3667#ifdef HAVE_SYSTEMD1
3668 GsmSystemd *systemd;
3669#endif
3670 g_debug ("GsmManager: CanShutdown called");
3671
3672 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3673
3674#ifdef HAVE_SYSTEMD1
3675 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3676 systemd = gsm_get_systemd ();
3677 *shutdown_available = gsm_systemd_can_stop (systemd)
3678 || gsm_systemd_can_restart (systemd)
3679 || gsm_systemd_can_suspend (systemd)
3680 || gsm_systemd_can_hibernate (systemd);
3681 g_object_unref (systemd);
3682 }
3683 else {
3684#endif
3685 consolekit = gsm_get_consolekit ();
3686 *shutdown_available = !_log_out_is_locked_down (manager) &&
3687 (gsm_consolekit_can_stop (consolekit)
3688 || gsm_consolekit_can_restart (consolekit)
3689 || gsm_consolekit_can_suspend (consolekit)
3690 || gsm_consolekit_can_hibernate (consolekit));
3691 g_object_unref (consolekit);
3692#ifdef HAVE_SYSTEMD1
3693 }
3694#endif
3695
3696 return TRUE(!(0));
3697}
3698
3699gboolean
3700gsm_manager_logout (GsmManager *manager,
3701 guint logout_mode,
3702 GError **error)
3703{
3704 GsmManagerPrivate *priv;
3705 g_debug ("GsmManager: Logout called");
3706
3707 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3708
3709 priv = gsm_manager_get_instance_private (manager);
3710 if (priv->phase != GSM_MANAGER_PHASE_RUNNING) {
3711 g_set_error (error,
3712 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3713 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3714 "Shutdown interface is only available during the Running phase");
3715 return FALSE(0);
3716 }
3717
3718 if (_log_out_is_locked_down (manager)) {
3719 g_set_error (error,
3720 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3721 GSM_MANAGER_ERROR_LOCKED_DOWN,
3722 "Logout has been locked down");
3723 return FALSE(0);
3724 }
3725
3726 switch (logout_mode) {
3727 case GSM_MANAGER_LOGOUT_MODE_NORMAL:
3728 case GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
3729 case GSM_MANAGER_LOGOUT_MODE_FORCE:
3730 user_logout (manager, logout_mode);
3731 break;
3732
3733 default:
3734 g_debug ("Unknown logout mode option");
3735
3736 g_set_error (error,
3737 GSM_MANAGER_ERRORgsm_manager_error_quark (),
3738 GSM_MANAGER_ERROR_INVALID_OPTION,
3739 "Unknown logout mode flag");
3740 return FALSE(0);
3741 }
3742
3743 return TRUE(!(0));
3744}
3745
3746gboolean
3747gsm_manager_register_client (GsmManager *manager,
3748 const char *app_id,
3749 const char *startup_id,
3750 DBusGMethodInvocation *context)
3751{
3752 char *new_startup_id;
3753 char *sender;
3754 GsmClient *client;
3755 GsmApp *app;
3756 GsmManagerPrivate *priv;
3757
3758 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3759
3760 app = NULL((void*)0);
3761 client = NULL((void*)0);
3762
3763 g_debug ("GsmManager: RegisterClient %s", startup_id);
3764
3765 priv = gsm_manager_get_instance_private (manager);
3766 if (priv->phase >= GSM_MANAGER_PHASE_QUERY_END_SESSION) {
3767 GError *new_error;
3768
3769 g_debug ("Unable to register client: shutting down");
3770
3771 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3772 GSM_MANAGER_ERROR_NOT_IN_RUNNING,
3773 "Unable to register client");
3774 dbus_g_method_return_error (context, new_error);
3775 g_error_free (new_error);
3776 return FALSE(0);
3777 }
3778
3779 if (IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3780 new_startup_id = gsm_util_generate_startup_id ();
3781 } else {
3782
3783 client = (GsmClient *)gsm_store_find (priv->clients,
3784 (GsmStoreFunc)_client_has_startup_id,
3785 (char *)startup_id);
3786 /* We can't have two clients with the same startup id. */
3787 if (client != NULL((void*)0)) {
3788 GError *new_error;
3789
3790 g_debug ("Unable to register client: already registered");
3791
3792 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3793 GSM_MANAGER_ERROR_ALREADY_REGISTERED,
3794 "Unable to register client");
3795 dbus_g_method_return_error (context, new_error);
3796 g_error_free (new_error);
3797 return FALSE(0);
3798 }
3799
3800 new_startup_id = g_strdup (startup_id)g_strdup_inline (startup_id);
3801 }
3802
3803 g_debug ("GsmManager: Adding new client %s to session", new_startup_id);
3804
3805 if (app == NULL((void*)0) && !IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3806 app = find_app_for_startup_id (manager, startup_id);
3807 }
3808 if (app == NULL((void*)0) && !IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3809 /* try to associate this app id with a known app */
3810 app = find_app_for_app_id (manager, app_id);
3811 }
3812
3813 sender = dbus_g_method_get_sender (context);
3814 client = gsm_dbus_client_new (new_startup_id, sender);
3815 g_free (sender);
3816 if (client == NULL((void*)0)) {
3817 GError *new_error;
3818
3819 g_debug ("Unable to create client");
3820
3821 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3822 GSM_MANAGER_ERROR_GENERAL,
3823 "Unable to register client");
3824 dbus_g_method_return_error (context, new_error);
3825 g_error_free (new_error);
3826 return FALSE(0);
3827 }
3828
3829 gsm_store_add (priv->clients, gsm_client_peek_id (client), G_OBJECT (client)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((client)), (((GType) ((20) << (2))))))))
);
3830 /* the store will own the ref */
3831 g_object_unref (client);
3832
3833 if (app != NULL((void*)0)) {
3834 gsm_client_set_app_id (client, gsm_app_peek_app_id (app));
3835 gsm_app_registered (app);
3836 } else {
3837 /* if an app id is specified store it in the client
3838 so we can save it later */
3839 gsm_client_set_app_id (client, app_id);
3840 }
3841
3842 gsm_client_set_status (client, GSM_CLIENT_REGISTERED);
3843
3844 g_assert (new_startup_id != NULL)do { if (new_startup_id != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "gsm-manager.c", 3844, ((const char*) (__func__
)), "new_startup_id != NULL"); } while (0)
;
3845 g_free (new_startup_id);
3846
3847 dbus_g_method_return (context, gsm_client_peek_id (client));
3848
3849 return TRUE(!(0));
3850}
3851
3852gboolean
3853gsm_manager_unregister_client (GsmManager *manager,
3854 const char *client_id,
3855 DBusGMethodInvocation *context)
3856{
3857 GsmClient *client;
3858 GsmManagerPrivate *priv;
3859
3860 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3861
3862 g_debug ("GsmManager: UnregisterClient %s", client_id);
3863
3864 priv = gsm_manager_get_instance_private (manager);
3865 client = (GsmClient *)gsm_store_lookup (priv->clients, client_id);
3866 if (client == NULL((void*)0)) {
3867 GError *new_error;
3868
3869 g_debug ("Unable to unregister client: not registered");
3870
3871 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3872 GSM_MANAGER_ERROR_NOT_REGISTERED,
3873 "Unable to unregister client");
3874 dbus_g_method_return_error (context, new_error);
3875 g_error_free (new_error);
3876 return FALSE(0);
3877 }
3878
3879 /* don't disconnect client here, only change the status.
3880 Wait until it leaves the bus before disconnecting it */
3881 gsm_client_set_status (client, GSM_CLIENT_UNREGISTERED);
3882
3883 dbus_g_method_return (context);
3884
3885 return TRUE(!(0));
3886}
3887
3888gboolean
3889gsm_manager_inhibit (GsmManager *manager,
3890 const char *app_id,
3891 guint toplevel_xid,
3892 const char *reason,
3893 guint flags,
3894 DBusGMethodInvocation *context)
3895{
3896 GsmInhibitor *inhibitor;
3897 guint cookie;
3898 GsmManagerPrivate *priv;
3899
3900 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3901
3902 g_debug ("GsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u",
3903 toplevel_xid,
3904 app_id,
3905 reason,
3906 flags);
3907
3908 priv = gsm_manager_get_instance_private (manager);
3909 if (priv->logout_mode == GSM_MANAGER_LOGOUT_MODE_FORCE) {
3910 GError *new_error;
3911
3912 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3913 GSM_MANAGER_ERROR_GENERAL,
3914 "Forced logout cannot be inhibited");
3915 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3916 dbus_g_method_return_error (context, new_error);
3917 g_error_free (new_error);
3918 return FALSE(0);
3919 }
3920
3921 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3922 GError *new_error;
3923
3924 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3925 GSM_MANAGER_ERROR_GENERAL,
3926 "Application ID not specified");
3927 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3928 dbus_g_method_return_error (context, new_error);
3929 g_error_free (new_error);
3930 return FALSE(0);
3931 }
3932
3933 if (IS_STRING_EMPTY (reason)((reason)==((void*)0)||(reason)[0]=='\0')) {
3934 GError *new_error;
3935
3936 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3937 GSM_MANAGER_ERROR_GENERAL,
3938 "Reason not specified");
3939 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3940 dbus_g_method_return_error (context, new_error);
3941 g_error_free (new_error);
3942 return FALSE(0);
3943 }
3944
3945 if (flags == 0) {
3946 GError *new_error;
3947
3948 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3949 GSM_MANAGER_ERROR_GENERAL,
3950 "Invalid inhibit flags");
3951 g_debug ("GsmManager: Unable to inhibit: %s", new_error->message);
3952 dbus_g_method_return_error (context, new_error);
3953 g_error_free (new_error);
3954 return FALSE(0);
3955 }
3956
3957 cookie = _generate_unique_cookie (manager);
3958 inhibitor = gsm_inhibitor_new (app_id,
3959 toplevel_xid,
3960 flags,
3961 reason,
3962 dbus_g_method_get_sender (context),
3963 cookie);
3964 gsm_store_add (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
3965 g_object_unref (inhibitor);
3966
3967 dbus_g_method_return (context, cookie);
3968
3969 return TRUE(!(0));
3970}
3971
3972gboolean
3973gsm_manager_uninhibit (GsmManager *manager,
3974 guint cookie,
3975 DBusGMethodInvocation *context)
3976{
3977 GsmInhibitor *inhibitor;
3978 GsmManagerPrivate *priv;
3979
3980 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3981
3982 g_debug ("GsmManager: Uninhibit %u", cookie);
3983
3984 priv = gsm_manager_get_instance_private (manager);
3985 inhibitor = (GsmInhibitor *)gsm_store_find (priv->inhibitors,
3986 (GsmStoreFunc)_find_by_cookie,
3987 &cookie);
3988 if (inhibitor == NULL((void*)0)) {
3989 GError *new_error;
3990
3991 new_error = g_error_new (GSM_MANAGER_ERRORgsm_manager_error_quark (),
3992 GSM_MANAGER_ERROR_GENERAL,
3993 "Unable to uninhibit: Invalid cookie");
3994 dbus_g_method_return_error (context, new_error);
3995 g_debug ("Unable to uninhibit: %s", new_error->message);
3996 g_error_free (new_error);
3997 return FALSE(0);
3998 }
3999
4000 g_debug ("GsmManager: removing inhibitor %s %u reason '%s' %u connection %s",
4001 gsm_inhibitor_peek_app_id (inhibitor),
4002 gsm_inhibitor_peek_toplevel_xid (inhibitor),
4003 gsm_inhibitor_peek_reason (inhibitor),
4004 gsm_inhibitor_peek_flags (inhibitor),
4005 gsm_inhibitor_peek_bus_name (inhibitor));
4006
4007 gsm_store_remove (priv->inhibitors, gsm_inhibitor_peek_id (inhibitor));
4008
4009 dbus_g_method_return (context);
4010
4011 return TRUE(!(0));
4012}
4013
4014gboolean
4015gsm_manager_is_inhibited (GsmManager *manager,
4016 guint flags,
4017 gboolean *is_inhibited,
4018 GError *error)
4019{
4020 GsmInhibitor *inhibitor;
4021 GsmManagerPrivate *priv;
4022
4023 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4024
4025 priv = gsm_manager_get_instance_private (manager);
4026 if (priv->inhibitors == NULL((void*)0)
4027 || gsm_store_size (priv->inhibitors) == 0) {
4028 *is_inhibited = FALSE(0);
4029 return TRUE(!(0));
4030 }
4031
4032 inhibitor = (GsmInhibitor *) gsm_store_find (priv->inhibitors,
4033 (GsmStoreFunc)inhibitor_has_flag,
4034 GUINT_TO_POINTER (flags)((gpointer) (gulong) (flags)));
4035 if (inhibitor == NULL((void*)0)) {
4036 *is_inhibited = FALSE(0);
4037 } else {
4038 *is_inhibited = TRUE(!(0));
4039 }
4040
4041 return TRUE(!(0));
4042
4043}
4044
4045static gboolean
4046listify_store_ids (char *id,
4047 GObject *object,
4048 GPtrArray **array)
4049{
4050 g_ptr_array_add (*array, g_strdup (id)g_strdup_inline (id));
4051 return FALSE(0);
4052}
4053
4054gboolean
4055gsm_manager_get_clients (GsmManager *manager,
4056 GPtrArray **clients,
4057 GError **error)
4058{
4059 GsmManagerPrivate *priv;
4060 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4061
4062 if (clients == NULL((void*)0)) {
4063 return FALSE(0);
4064 }
4065
4066 *clients = g_ptr_array_new ();
4067 priv = gsm_manager_get_instance_private (manager);
4068 gsm_store_foreach (priv->clients, (GsmStoreFunc)listify_store_ids, clients);
4069
4070 return TRUE(!(0));
4071}
4072
4073gboolean
4074gsm_manager_get_inhibitors (GsmManager *manager,
4075 GPtrArray **inhibitors,
4076 GError **error)
4077{
4078 GsmManagerPrivate *priv;
4079
4080 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4081
4082 if (inhibitors == NULL((void*)0)) {
4083 return FALSE(0);
4084 }
4085
4086 *inhibitors = g_ptr_array_new ();
4087 priv = gsm_manager_get_instance_private (manager);
4088 gsm_store_foreach (priv->inhibitors,
4089 (GsmStoreFunc) listify_store_ids,
4090 inhibitors);
4091
4092 return TRUE(!(0));
4093}
4094
4095static gboolean
4096_app_has_autostart_condition (const char *id,
4097 GsmApp *app,
4098 const char *condition)
4099{
4100 gboolean has;
4101 gboolean disabled;
4102
4103 has = gsm_app_has_autostart_condition (app, condition);
4104 disabled = gsm_app_peek_is_disabled (app);
4105
4106 return has && !disabled;
4107}
4108
4109gboolean
4110gsm_manager_is_autostart_condition_handled (GsmManager *manager,
4111 const char *condition,
4112 gboolean *handled,
4113 GError **error)
4114{
4115 GsmApp *app;
4116 GsmManagerPrivate *priv;
4117
4118 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4119
4120 priv = gsm_manager_get_instance_private (manager);
4121 app = (GsmApp *) gsm_store_find (priv->apps,(
4122 GsmStoreFunc) _app_has_autostart_condition,
4123 (char *)condition);
4124
4125 if (app != NULL((void*)0)) {
4126 *handled = TRUE(!(0));
4127 } else {
4128 *handled = FALSE(0);
4129 }
4130
4131 return TRUE(!(0));
4132}
4133
4134static void
4135append_app (GsmManager *manager,
4136 GsmApp *app)
4137{
4138 const char *id;
4139 const char *app_id;
4140 GsmApp *dup;
4141 GsmManagerPrivate *priv;
4142
4143 id = gsm_app_peek_id (app);
4144 if (IS_STRING_EMPTY (id)((id)==((void*)0)||(id)[0]=='\0')) {
4145 g_debug ("GsmManager: not adding app: no id");
4146 return;
4147 }
4148
4149 priv = gsm_manager_get_instance_private (manager);
4150 dup = (GsmApp *)gsm_store_lookup (priv->apps, id);
4151 if (dup != NULL((void*)0)) {
4152 g_debug ("GsmManager: not adding app: already added");
4153 return;
4154 }
4155
4156 app_id = gsm_app_peek_app_id (app);
4157 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
4158 g_debug ("GsmManager: not adding app: no app-id");
4159 return;
4160 }
4161
4162 dup = find_app_for_app_id (manager, app_id);
4163 if (dup != NULL((void*)0)) {
4164 g_debug ("GsmManager: not adding app: app-id already exists");
4165 return;
4166 }
4167
4168 gsm_store_add (priv->apps, id, G_OBJECT (app)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), (((GType) ((20) << (2))))))))
);
4169}
4170
4171gboolean
4172gsm_manager_add_autostart_app (GsmManager *manager,
4173 const char *path,
4174 const char *provides)
4175{
4176 GsmApp *app;
4177 GsmManagerPrivate *priv;
4178
4179 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4180 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4181
4182 priv = gsm_manager_get_instance_private (manager);
4183 /* first check to see if service is already provided */
4184 if (provides != NULL((void*)0)) {
4185 GsmApp *dup;
4186
4187 dup = (GsmApp *)gsm_store_find (priv->apps,
4188 (GsmStoreFunc)_find_app_provides,
4189 (char *)provides);
4190 if (dup != NULL((void*)0)) {
4191 g_debug ("GsmManager: service '%s' is already provided", provides);
4192 return FALSE(0);
4193 }
4194 }
4195
4196 app = gsm_autostart_app_new (path);
4197 if (app == NULL((void*)0)) {
4198 g_warning ("could not read %s", path);
4199 return FALSE(0);
4200 }
4201
4202 g_debug ("GsmManager: read %s", path);
4203 append_app (manager, app);
4204 g_object_unref (app);
4205
4206 return TRUE(!(0));
4207}
4208
4209gboolean
4210gsm_manager_add_autostart_apps_from_dir (GsmManager *manager,
4211 const char *path)
4212{
4213 GDir *dir;
4214 const char *name;
4215
4216 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4217 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4218
4219 g_debug ("GsmManager: *** Adding autostart apps for %s", path);
4220
4221 dir = g_dir_open (path, 0, NULL((void*)0));
4222 if (dir == NULL((void*)0)) {
4223 return FALSE(0);
4224 }
4225
4226 while ((name = g_dir_read_name (dir))) {
4227 char *desktop_file;
4228
4229 if (!g_str_has_suffix (name, ".desktop")(__builtin_constant_p (".desktop")? __extension__ ({ const char
* const __str = (name); const char * const __suffix = (".desktop"
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (name, ".desktop"
) )
) {
4230 continue;
4231 }
4232
4233 desktop_file = g_build_filename (path, name, NULL((void*)0));
4234 gsm_manager_add_autostart_app (manager, desktop_file, NULL((void*)0));
4235 g_free (desktop_file);
4236 }
4237
4238 g_dir_close (dir);
4239
4240 return TRUE(!(0));
4241}
4242
4243gboolean
4244gsm_manager_is_session_running (GsmManager *manager,
4245 gboolean *running,
4246 GError **error)
4247{
4248 GsmManagerPrivate *priv;
4249
4250 g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE)do { if ((GSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "GSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4251
4252 priv = gsm_manager_get_instance_private (manager);
4253 *running = (priv->phase == GSM_MANAGER_PHASE_RUNNING);
4254 return TRUE(!(0));
4255}
diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/scanview.css b/2023-09-04-022211-5825-1@c70944f84e08_revert/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/scanview.css @@ -0,0 +1,62 @@ +body { color:#000000; background-color:#ffffff } +body { font-family: Helvetica, sans-serif; font-size:9pt } +h1 { font-size: 14pt; } +h2 { font-size: 12pt; } +table { font-size:9pt } +table { border-spacing: 0px; border: 1px solid black } +th, table thead { + background-color:#eee; color:#666666; + font-weight: bold; cursor: default; + text-align:center; + font-weight: bold; font-family: Verdana; + white-space:nowrap; +} +.W { font-size:0px } +th, td { padding:5px; padding-left:8px; text-align:left } +td.SUMM_DESC { padding-left:12px } +td.DESC { white-space:pre } +td.Q { text-align:right } +td { text-align:left } +tbody.scrollContent { overflow:auto } + +table.form_group { + background-color: #ccc; + border: 1px solid #333; + padding: 2px; +} + +table.form_inner_group { + background-color: #ccc; + border: 1px solid #333; + padding: 0px; +} + +table.form { + background-color: #999; + border: 1px solid #333; + padding: 2px; +} + +td.form_label { + text-align: right; + vertical-align: top; +} +/* For one line entires */ +td.form_clabel { + text-align: right; + vertical-align: center; +} +td.form_value { + text-align: left; + vertical-align: top; +} +td.form_submit { + text-align: right; + vertical-align: top; +} + +h1.SubmitFail { + color: #f00; +} +h1.SubmitOk { +} diff --git a/2023-09-04-022211-5825-1@c70944f84e08_revert/sorttable.js b/2023-09-04-022211-5825-1@c70944f84e08_revert/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2023-09-04-022211-5825-1@c70944f84e08_revert/sorttable.js @@ -0,0 +1,492 @@ +/* + SortTable + version 2 + 7th April 2007 + Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ + + Instructions: + Download this file + Add to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. +*/ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function() { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function(table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function(table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the,table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backward compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i=0; i5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function(cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse',''); + cell.className = cell.className.replace('sorttable_sorted',''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j=0; j 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function(node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function(tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i=0; i=0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function(a,b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); + if (isNaN(bb)) bb = 0; + return aa-bb; + }, + sort_alpha: function(a,b) { + if (a[0]==b[0]) return 0; + if (a[0] 0 ) { + var q = list[i]; list[i] = list[i+1]; list[i+1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for(var i = t; i > b; --i) { + if ( comp_func(list[i], list[i-1]) < 0 ) { + var q = list[i]; list[i] = list[i-1]; list[i-1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write("