From 2232685fe934caf698000813f6394b4e101c7d6c Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" Date: Thu, 22 Feb 2024 00:11:02 +0000 Subject: Deploy mate-desktop/mate-sensors-applet to github.com/mate-desktop/mate-sensors-applet.git:gh-pages --- .../index.html | 124 ++ .../report-1191e2.html | 1133 +++++++++++ .../report-1e32d3.html | 1133 +++++++++++ .../report-407f6f.html | 2005 +++++++++++++++++++ .../report-48fbd5.html | 1133 +++++++++++ .../report-5f1566.html | 2005 +++++++++++++++++++ .../report-699f6d.html | 2005 +++++++++++++++++++ .../report-782a54.html | 1133 +++++++++++ .../report-e082ac.html | 1133 +++++++++++ .../report-f0c410.html | 2042 ++++++++++++++++++++ .../report-f7fb7e.html | 1133 +++++++++++ .../scanview.css | 62 + .../sorttable.js | 492 +++++ 13 files changed, 15533 insertions(+) create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/index.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-1191e2.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-1e32d3.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-407f6f.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-48fbd5.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-5f1566.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-699f6d.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-782a54.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-e082ac.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-f0c410.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/report-f7fb7e.html create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/scanview.css create mode 100644 2023-06-14-024037-6156-1@50207d611f25_master/sorttable.js (limited to '2023-06-14-024037-6156-1@50207d611f25_master') diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/index.html b/2023-06-14-024037-6156-1@50207d611f25_master/index.html new file mode 100644 index 0000000..229664e --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/index.html @@ -0,0 +1,124 @@ + + +rootdir - scan-build results + + + + + + +

rootdir - scan-build results

+ + + + + + + +
User:root@963e31bb8910
Working Directory:/rootdir
Command Line:make -j 2
Clang Version:clang version 16.0.5 (Fedora 16.0.5-1.fc38) +
Date:Wed Jun 14 02:40:37 2023
+

Bug Summary

+ + + + + + + +
Bug TypeQuantityDisplay?
All Bugs10
Logic error
Cast from non-struct type to struct type7
Division by zero1
Unused code
Dead assignment2
+

Reports

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors3151View Report
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors2951View Report
Logic errorCast from non-struct type to struct typesensors-applet/sensors-applet.cprefs_cb611View Report
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors3161View Report
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors3191View Report
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors3181View Report
Logic errorCast from non-struct type to struct typeplugins/udisks2/udisks2-plugin.cudisks2_plugin_get_sensors2961View Report
Unused codeDead assignmentsensors-applet/sensors-applet.csensors_applet_add_sensor8601View Report
Unused codeDead assignmentsensors-applet/sensors-applet.csensors_applet_add_sensor8871View Report
Logic errorDivision by zerosensors-applet/sensors-applet.csensors_applet_pack_display52913View Report
+ + diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-1191e2.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-1191e2.html new file mode 100644 index 0000000..9a5fcf8 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-1191e2.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 315, column 90
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_16
; if (info != ((void*)0)) _g_boolean_var_16 = 1; else _g_boolean_var_16
= 0; _g_boolean_var_16; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_17
; if (connection != ((void*)0)) _g_boolean_var_17 = 1; else _g_boolean_var_17
= 0; _g_boolean_var_17; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-1e32d3.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-1e32d3.html new file mode 100644 index 0000000..67f3695 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-1e32d3.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 295, column 82
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_12
; if (info != ((void*)0)) _g_boolean_var_12 = 1; else _g_boolean_var_12
= 0; _g_boolean_var_12; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_13
; if (connection != ((void*)0)) _g_boolean_var_13 = 1; else _g_boolean_var_13
= 0; _g_boolean_var_13; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-407f6f.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-407f6f.html new file mode 100644 index 0000000..49f882a --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-407f6f.html @@ -0,0 +1,2005 @@ + + + +sensors-applet.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:sensors-applet/sensors-applet.c
Warning:line 61, column 22
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 sensors-applet.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=none -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/sensors-applet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D UIDIR="/usr/local/share/mate-sensors-applet/ui" -D SENSORS_APPLET_PLUGIN_DIR="/usr/local/lib/mate-sensors-applet/plugins" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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/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 -I /usr/include/mate-panel-4.0/libmate-panel-applet -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 /usr/include/cairo -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libxml2 -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -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 -O2 -Wno-unused-parameter -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/sensors-applet -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c sensors-applet.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/** Contain the functions for operating on the SensorsApplet structure
21 * (represents the applet itself, and its associated variables.
22 */
23
24#ifdef HAVE_CONFIG_H1
25#include "config.h"
26#endif /* HAVE_CONFIG_H */
27
28#ifdef HAVE_UNISTD_H1
29#include <unistd.h>
30#endif /* HAVE_UNISTD_H */
31
32#include <glib/gi18n.h>
33#include <glib/gprintf.h>
34#include <gio/gio.h>
35#include "sensors-applet.h"
36#include "active-sensor.h"
37#include "sensors-applet-settings.h"
38#include "sensors-applet-plugins.h"
39
40#ifdef HAVE_LIBNOTIFY1
41#include "active-sensor-libnotify.h"
42#define DEFAULT_NOTIFY_TIMEOUT3000 3000
43#endif
44
45#include "prefs-dialog.h"
46#include "about-dialog.h"
47
48#define SENSORS_APPLET_MENU_FILE"SensorsApplet.xml" "SensorsApplet.xml"
49/* initially set as sensors_applet->size to ensure a real value is stored */
50#define DEFAULT_APPLET_SIZE24 24
51#define COLUMN_SPACING2 2
52#define ROW_SPACING1 1
53
54/* builder for sensor sorting verification */
55static GVariantBuilder gvb_sensors_hash_list;
56
57/* callbacks for panel menu */
58static void prefs_cb(GtkAction *action, gpointer *data) {
59
60 SensorsApplet *sensors_applet;
61 sensors_applet = (SensorsApplet *)data;
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
62
63 if (sensors_applet->prefs_dialog) {
64 gtk_window_present(GTK_WINDOW(sensors_applet->prefs_dialog->dialog)((((GtkWindow*) (void *) ((sensors_applet->prefs_dialog->
dialog)))))
);
65 return;
66 }
67 prefs_dialog_open(sensors_applet);
68}
69
70static void about_cb(GtkAction *action, gpointer data) {
71 SensorsApplet *sensors_applet;
72 sensors_applet = (SensorsApplet *)data;
73
74 about_dialog_open(sensors_applet);
75}
76
77static void help_cb(GtkAction *action, gpointer data) {
78
79 GError *error = NULL((void*)0);
80
81 gtk_show_uri_on_window(NULL((void*)0), "help:mate-sensors-applet",
82
83 gtk_get_current_event_time(),
84 &error);
85
86 if (error) {
87 g_debug("Could not open help document: %s ",error->message);
88 g_error_free(error);
89 }
90}
91
92static void destroy_cb(GtkWidget *widget, gpointer data) {
93 SensorsApplet *sensors_applet;
94 sensors_applet = (SensorsApplet *)data;
95
96 /* destroy dialogs, remove timeout and clear sensors tree and finally the applet */
97 if (sensors_applet->prefs_dialog != NULL((void*)0)) {
98 /* destroy's dialog too */
99 prefs_dialog_close(sensors_applet);
100 }
101
102 if (sensors_applet->timeout_id) {
103 g_source_remove(sensors_applet->timeout_id);
104 }
105
106 if (sensors_applet->settings) {
107 g_object_unref (sensors_applet->settings);
108 sensors_applet->settings = NULL((void*)0);
109 }
110
111 /* destroy all active sensors */
112 g_list_foreach(sensors_applet->active_sensors,
113 (GFunc)active_sensor_destroy,
114 NULL((void*)0));
115
116 if (sensors_applet->sensors != NULL((void*)0)) {
117 gtk_tree_store_clear(sensors_applet->sensors);
118 }
119
120 gtk_widget_destroy(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
121
122 g_free(sensors_applet);
123 return;
124}
125
126static void change_orient_cb (MatePanelApplet *applet,
127 MatePanelAppletOrient orient,
128 gpointer data) {
129
130 SensorsApplet *sensors_applet;
131 sensors_applet = (SensorsApplet *)data;
132
133 sensors_applet_display_layout_changed(sensors_applet);
134}
135
136static void size_allocate_cb(MatePanelApplet *applet,
137 GtkAllocation *allocation,
138 gpointer data) {
139
140 SensorsApplet *sensors_applet;
141 MatePanelAppletOrient orient;
142
143 sensors_applet = (SensorsApplet *)data;
144 orient = mate_panel_applet_get_orient(sensors_applet->applet);
145
146 if ((orient == MATE_PANEL_APPLET_ORIENT_LEFT) ||
147 (orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
148
149 if (sensors_applet->size == allocation->width)
150 return;
151 sensors_applet->size = allocation->width;
152 } else {
153 if (sensors_applet->size == allocation->height)
154 return;
155 sensors_applet->size = allocation->height;
156 }
157
158 /* update if new value */
159 sensors_applet_graph_size_changed(sensors_applet);
160 sensors_applet_display_layout_changed(sensors_applet);
161}
162
163static void style_set_cb(GtkWidget *widget, GtkStyle *old_style, gpointer data) {
164
165 /* update all icons in the sensors tree and update all active sensors */
166 GtkTreeIter interfaces_iter, sensors_iter;
167 gboolean not_end_of_interfaces = TRUE(!(0)), not_end_of_sensors = TRUE(!(0));
168 IconType icon_type;
169 gboolean enabled;
170 SensorsApplet *sensors_applet;
171 DisplayMode display_mode;
172
173 sensors_applet = (SensorsApplet *)data;
174
175 display_mode = g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
176 if (sensors_applet->sensors) {
177 for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
178 not_end_of_interfaces;
179 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
180
181 /* reset sensors sentinel */
182 not_end_of_sensors = TRUE(!(0));
183
184 for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
185 not_end_of_sensors;
186 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
187
188 GdkPixbuf *new_icon;
189
190 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))),
191 &sensors_iter,
192 ENABLE_COLUMN, &enabled,
193 ICON_TYPE_COLUMN, &icon_type,
194 -1);
195 /* update icons */
196 new_icon = sensors_applet_load_icon(icon_type);
197
198 gtk_tree_store_set(sensors_applet->sensors,
199 &sensors_iter,
200 ICON_PIXBUF_COLUMN, new_icon,
201 -1);
202 g_object_unref(new_icon);
203
204 /* update icons only if currently being displayed */
205 if (enabled &&
206 (display_mode == DISPLAY_ICON ||
207 display_mode == DISPLAY_ICON_WITH_VALUE)) {
208
209 GtkTreePath *path;
210
211 path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
212 sensors_applet_icon_changed(sensors_applet, path);
213 gtk_tree_path_free(path);
214 }
215 }
216 }
217 /* now update layout as size may have changed */
218 sensors_applet_display_layout_changed(sensors_applet);
219 }
220
221}
222
223static gboolean mouse_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
224{
225 SensorsApplet *sensor_applet = data;
226 sensor_applet->show_tooltip = TRUE(!(0));
227 sensors_applet_update_active_sensors(sensor_applet);
228 return TRUE(!(0));
229}
230
231static gboolean mouse_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
232{
233 SensorsApplet *sensor_applet = data;
234 sensor_applet->show_tooltip = FALSE(0);
235 return TRUE(!(0));
236}
237
238static const GtkActionEntry sensors_applet_menu_actions[] = {
239 { "Preferences", "document-properties", N_("_Preferences")("_Preferences"),
240 NULL((void*)0), NULL((void*)0),
241 G_CALLBACK(prefs_cb)((GCallback) (prefs_cb)) },
242 { "Help", "help-browser", N_("_Help")("_Help"),
243 NULL((void*)0), NULL((void*)0),
244 G_CALLBACK(help_cb)((GCallback) (help_cb)) },
245 { "About", "help-about", N_("_About")("_About"),
246 NULL((void*)0), NULL((void*)0),
247 G_CALLBACK(about_cb)((GCallback) (about_cb)) }
248};
249
250void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type) {
251#ifdef HAVE_LIBNOTIFY1
252
253 SensorsApplet *sensors_applet;
254 gchar *summary, *message;
255 gint timeout_msecs;
256 gchar *sensor_label;
257 gchar *sensor_path;
258 SensorType sensor_type;
259 TemperatureScale temp_scale;
260 GtkTreeIter iter;
261 GtkTreePath *path;
262 const gchar *unit_type = NULL((void*)0);
263 const gchar *unit_type_title = NULL((void*)0);
264 const gchar *relation = NULL((void*)0);
265 const gchar *limit_type = NULL((void*)0);
266 const gchar *units = NULL((void*)0);
267 gdouble limit_value;
268 gdouble seconds;
269 gboolean show_notification = TRUE(!(0));
270
271 sensors_applet = active_sensor->sensors_applet;
272
273 if (!g_settings_get_boolean (sensors_applet->settings, DISPLAY_NOTIFICATIONS"display-notifications")) {
274 g_debug("Wanted to display notification, but user has disabled them");
275 return;
276 }
277
278 path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
279 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter, path)) {
280
281 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter,
282 LABEL_COLUMN, &sensor_label,
283 PATH_COLUMN, &sensor_path,
284 SENSOR_TYPE_COLUMN, &sensor_type,
285 -1);
286 } else {
287 g_warning("Error getting data from tree for notification...");
288 gtk_tree_path_free(path);
289 return;
290 }
291
292 gtk_tree_path_free(path);
293
294 /* do different stuff for different notif types */
295 switch (notif_type) {
296 case LOW_ALARM: /* fall thru */
297 case HIGH_ALARM:
298 if (active_sensor->sensor_values[0] <= active_sensor->sensor_low_value && notif_type == LOW_ALARM) {
299
300 relation = _("is very low")dcgettext (((void*)0), "is very low", 5);
301 limit_type = _("lower limit")dcgettext (((void*)0), "lower limit", 5);
302 limit_value = active_sensor->sensor_low_value;
303 } else if (active_sensor->sensor_values[0] >= active_sensor->sensor_high_value && notif_type == HIGH_ALARM) {
304
305 /* assume high alarm condition */
306 relation = _("is very high")dcgettext (((void*)0), "is very high", 5);
307 limit_type = _("upper limit")dcgettext (((void*)0), "upper limit", 5);
308 limit_value = active_sensor->sensor_high_value;
309 } else {
310 g_warning("Alarm notify called when no alarm condition!");
311 g_free(sensor_path);
312 g_free(sensor_label);
313 return;
314 }
315
316 switch ((SensorType)sensor_type) {
317 case TEMP_SENSOR:
318 unit_type_title = _("Temperature")dcgettext (((void*)0), "Temperature", 5);
319 unit_type = _("temperature")dcgettext (((void*)0), "temperature", 5);
320 temp_scale = (TemperatureScale) g_settings_get_int (active_sensor->sensors_applet->settings, TEMPERATURE_SCALE"temperature-scale");
321
322 switch (temp_scale) {
323 case CELSIUS:
324 units = UNITS_CELSIUS"\302\260C";
325 break;
326 case FAHRENHEIT:
327 units = UNITS_FAHRENHEIT"\302\260F";
328 break;
329 case KELVIN:
330 units = UNITS_KELVIN"";
331 break;
332 default:
333 units = NULL((void*)0);
334 }
335 break;
336
337 case VOLTAGE_SENSOR:
338 unit_type_title = _("Voltage")dcgettext (((void*)0), "Voltage", 5);
339 unit_type = _("voltage")dcgettext (((void*)0), "voltage", 5);
340 units = UNITS_VOLTAGEdcgettext (((void*)0), "V", 5);
341 break;
342
343 case FAN_SENSOR:
344 unit_type_title = _("Fan Speed")dcgettext (((void*)0), "Fan Speed", 5);
345 unit_type = _("fan speed")dcgettext (((void*)0), "fan speed", 5);
346 units = UNITS_RPMdcgettext (((void*)0), "RPM", 5);
347 break;
348
349 case CURRENT_SENSOR:
350 unit_type_title = _("Current")dcgettext (((void*)0), "Current", 5);
351 unit_type = _("current")dcgettext (((void*)0), "current", 5);
352 units = UNITS_CURRENTdcgettext (((void*)0), "A", 5);
353 break;
354 }
355
356 timeout_msecs = (active_sensor->alarm_timeout ? MIN(DEFAULT_NOTIFY_TIMEOUT, (active_sensor->alarm_timeout * 1000))(((3000) < ((active_sensor->alarm_timeout * 1000))) ? (
3000) : ((active_sensor->alarm_timeout * 1000)))
: DEFAULT_NOTIFY_TIMEOUT3000);
357
358 summary = g_strdup_printf("%s %s %s", sensor_label, unit_type_title, _("Alarm")dcgettext (((void*)0), "Alarm", 5));
359 message = g_strdup_printf("%s %s %s (%s %2.0f%s)", sensor_label, unit_type, relation, limit_type, limit_value, units);
360 break;
361
362 case SENSOR_INTERFACE_ERROR:
363 /* get time since the last error */
364 seconds = difftime(time(NULL((void*)0)), active_sensor->ierror_ts);
365
366 /* if the last error happened less than 10 seconds ago, don't display this one
367 * this should prevent recurring popups for removed sensors, like USB-HDDs */
368 if (seconds < 11.0) {
369 show_notification = FALSE(0);
370 }
371
372 summary = g_strdup_printf(_("Error updating sensor %s")dcgettext (((void*)0), "Error updating sensor %s", 5), sensor_label);
373 message = g_strdup_printf(_("An error occurred while trying to update the value of the sensor %s located at %s.")dcgettext (((void*)0), "An error occurred while trying to update the value of the sensor %s located at %s."
, 5)
, sensor_label, sensor_path);
374 timeout_msecs = g_settings_get_int (active_sensor->sensors_applet->settings, TIMEOUT"timeout-delay");
375
376 /* update timestamp */
377 time(&(active_sensor->ierror_ts));
378 break;
379
380 default:
381 g_assert_not_reached()do { g_assertion_message_expr ("sensors-applet", "sensors-applet.c"
, 381, ((const char*) (__func__)), ((void*)0)); } while (0)
;
382 }
383
384 if (show_notification) {
385 active_sensor_libnotify_notify(active_sensor,
386 notif_type,
387 summary,
388 message,
389 "dialog-warning",
390 timeout_msecs);
391 }
392
393 g_free(sensor_path);
394 g_free(sensor_label);
395 g_free(summary);
396 g_free(message);
397#endif
398}
399
400void sensors_applet_notify_end(ActiveSensor *active_sensor, NotifType notif_type) {
401#ifdef HAVE_LIBNOTIFY1
402 active_sensor_libnotify_notify_end(active_sensor, notif_type);
403#endif
404}
405
406#ifdef HAVE_LIBNOTIFY1
407static void sensors_applet_notify_end_all_gfunc(ActiveSensor *active_sensor, gpointer data) {
408 active_sensor_libnotify_notify_end(active_sensor, LOW_ALARM);
409 active_sensor_libnotify_notify_end(active_sensor, HIGH_ALARM);
410}
411#endif
412
413void sensors_applet_notify_end_all(SensorsApplet *sensors_applet) {
414#ifdef HAVE_LIBNOTIFY1
415 g_list_foreach(sensors_applet->active_sensors, (GFunc)sensors_applet_notify_end_all_gfunc, NULL((void*)0));
416#endif
417}
418
419/* internal helper functions for updating display etc */
420
421/* should be called as a g_container_foreach at the start of
422 * pack_display if the grid already exists to remove but keep alive
423 * all children of the grid before repacking it */
424static void sensors_applet_pack_display_empty_grid_cb(GtkWidget *widget, gpointer data)
425{
426 GtkContainer *container;
427
428 container = GTK_CONTAINER(data)((((GtkContainer*) (void *) ((data)))));
429
430 /* ref then remove widget */
431 g_object_ref(widget)((__typeof__ (widget)) (g_object_ref) (widget));
432 gtk_container_remove(container, widget);
433}
434
435/* should be called as a g_container_foreach at the end of
436 * pack_display to unref any of the old children that we have readdded
437 * to the table to stop reference creep from the g_object_ref called
438 * on each child at the start of pack labels */
439static void sensors_applet_pack_display_cleanup_refs_cb(GtkWidget *widget, gpointer data) {
440
441 GList *old_children;
442
443 old_children = (GList *)data;
444 if (g_list_find(old_children, widget)) {
445 g_object_unref(widget);
446 }
447}
448
449static void sensors_applet_pack_display(SensorsApplet *sensors_applet) {
450 /* note the if () around each widget is to ensure we only
451 * operate on those that actually exist */
452 GtkLabel *no_sensors_enabled_label = NULL((void*)0);
453 gint num_active_sensors = 0, num_sensors_per_group = 0, rows, cols, i, j;
454 GList *old_grid_children = NULL((void*)0);
455
456 GList *current_sensor;
457
458 DisplayMode display_mode;
459 LayoutMode layout_mode;
460
461 gboolean horizontal;
462 gint label_width, icon_width, value_width;
463 gint label_height, icon_height, value_height;
464
465 GtkRequisition req;
466
467 ActiveSensor *first_sensor;
468
469 /* it is possible that there could be no active sensors so
470 * handle that case first - make sure we dont do a NULL
471 * pointer access first though */
472 if (sensors_applet->active_sensors == NULL((void*)0) || g_list_length(sensors_applet->active_sensors) == 0) {
473 g_debug("no active sensors to pack in grid");
474 no_sensors_enabled_label = g_object_new(GTK_TYPE_LABEL(gtk_label_get_type ()), "label", _("No sensors enabled!")dcgettext (((void*)0), "No sensors enabled!", 5), NULL((void*)0));
475
476 if (sensors_applet->grid == NULL((void*)0)) {
477 /* only need 1 row and 1 col */
478 sensors_applet->grid = gtk_grid_new();
479 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
480 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
481 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
482 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
483 /* add grid to applet */
484 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
485 } else {
486 /* destroy existing widgets - could be an
487 * existing version of no sensors label - okay
488 * to just add again though if destroy first */
489 g_debug("destroying any existing widgets in container");
490 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))), (GtkCallback)gtk_widget_destroy, NULL((void*)0));
491 }
492 g_debug("packing no sensors enabled label");
493 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
494 GTK_WIDGET(no_sensors_enabled_label)((((GtkWidget*) (void *) ((no_sensors_enabled_label))))),
495 0, 0, 1, 1);
496 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
497 return;
498 }
499 /* otherwise can acess active_sensors without any worries */
500 num_active_sensors = g_list_length(sensors_applet->active_sensors);
501
502 display_mode = (DisplayMode) g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
503 layout_mode = (LayoutMode) g_settings_get_int (sensors_applet->settings, LAYOUT_MODE"layout-mode");
504
505 horizontal = (((mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP) ||
506 (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN)));
507
508 /* figure out num rows / cols by how high / wide sensors
509 * labels / icons are and how much size we have to put them in */
510
511 /* get the first active sensor */
512 first_sensor = (ActiveSensor *)sensors_applet->active_sensors->data;
513
514 switch (display_mode) {
515 case DISPLAY_VALUE:
516 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
517 value_width = req.width + COLUMN_SPACING2;
518 value_height = req.height + ROW_SPACING1;
519
520 /* make sure all widths and heights are non zero,
521 * otherwise will get a divide by zero exception below
522 * - is a non critical error since can happen when
523 * elements first added to list, so simply return - is
524 * not a programming error */
525 if (value_width == 0 && value_height == 0) {
526 return;
527 }
528
529 num_sensors_per_group = (sensors_applet->size / (horizontal ? value_height : value_width));
530 break;
531
532 case DISPLAY_LABEL_WITH_VALUE:
533 /* even though we end up packing the event boxes into the
534 * panel, these dont give back request sizes, so need to ask
535 * widgets directly */
536 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
537
538 value_width = req.width + COLUMN_SPACING2;
539 value_height = req.height + ROW_SPACING1;
540
541 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->label)((((GtkWidget*) (void *) ((first_sensor->label))))), &req, NULL((void*)0));
542 label_width = req.width + COLUMN_SPACING2;
543 label_height = req.height + ROW_SPACING1;
544
545 /* make sure all widths and heights are non zero, otherwise
546 * will get a divide by zero exception below
547 * - is a non critical error since can happen when
548 * elements first added to list, so simply return - is
549 * not a programming error */
550 if (!(label_width && label_height && value_width && value_height)) {
551 return;
552 }
553
554 switch (layout_mode) {
555 case VALUE_BESIDE_LABEL:
556 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(label_height, value_height)(((label_height) > (value_height)) ? (label_height) : (value_height
))
: (label_width + value_width)));
557 break;
558 case VALUE_BELOW_LABEL:
559 num_sensors_per_group = (sensors_applet->size / (horizontal ? (label_height + value_height) : MAX(label_width, value_width)(((label_width) > (value_width)) ? (label_width) : (value_width
))
));
560 break;
561 }
562 break;
563
564 case DISPLAY_ICON_WITH_VALUE:
565 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
566 value_width = req.width + COLUMN_SPACING2;
567 value_height = req.height + ROW_SPACING1;
568
569 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
570 icon_width = req.width + COLUMN_SPACING2;
571 icon_height = req.height + ROW_SPACING1;
572
573 if (!(icon_width && icon_height && value_width && value_height)) {
574 return;
575 }
576
577 switch (layout_mode) {
578 case VALUE_BESIDE_LABEL:
579 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(icon_height, value_height)(((icon_height) > (value_height)) ? (icon_height) : (value_height
))
: (icon_width + value_width)));
580 break;
581
582 case VALUE_BELOW_LABEL:
583 num_sensors_per_group = (sensors_applet->size / (horizontal ? (icon_height + value_height) : MAX(icon_width, value_width)(((icon_width) > (value_width)) ? (icon_width) : (value_width
))
));
584 break;
585 }
586 break;
587
588 case DISPLAY_ICON:
589 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
590 icon_width = req.width + COLUMN_SPACING2;
591 icon_height = req.height + ROW_SPACING1;
592
593 if (!(icon_width && icon_height)) {
594 return;
595 }
596
597 num_sensors_per_group = (sensors_applet->size / (horizontal ? icon_height : icon_width));
598 break;
599
600 case DISPLAY_GRAPH:
601 /* only show graphs in a line like System Monitor applet */
602 num_sensors_per_group = 1;
603 break;
604 }
605
606 /* ensure always atleast 1 sensor per group */
607 if (num_sensors_per_group < 1) {
608 /* force a better layout */
609 if (horizontal && layout_mode == VALUE_BELOW_LABEL) {
610 layout_mode = VALUE_BESIDE_LABEL;
611 } else if (!horizontal && layout_mode == VALUE_BESIDE_LABEL) {
612 layout_mode = VALUE_BELOW_LABEL;
613 }
614 num_sensors_per_group = 1;
615 }
616
617 if (horizontal) {
618 /* if oriented horizontally, want as many
619 sensors per column as user has defined, then
620 enough columns to hold all the widgets */
621 rows = num_sensors_per_group;
622 cols = num_active_sensors / num_sensors_per_group;
623 while (rows * cols < num_active_sensors || cols == 0) {
624 cols++;
625 }
626
627 } else {
628 /* if oriented vertically, want as many
629 sensors per row as user has defined, then
630 enough rows to hold all the widgets*/
631 cols = num_sensors_per_group;
632 rows = num_active_sensors / num_sensors_per_group;
633 while (rows * cols < num_active_sensors || rows == 0) {
634 rows++;
635 }
636
637 }
638
639 /* if displaying labels / icons and values need to modify
640 number of rows / colums to accomodate this */
641 if (display_mode == DISPLAY_LABEL_WITH_VALUE || display_mode == DISPLAY_ICON_WITH_VALUE) {
642 if (layout_mode == VALUE_BESIDE_LABEL) {
643 /* to display labels next to values need twice as many columns */
644 cols *= 2;
645 } else {
646 /* to display labels above values, we need twice as many rows as without */
647 rows *= 2;
648 }
649 }
650
651 if (sensors_applet->grid == NULL((void*)0)) {
652 /* create grid and add to applet */
653 sensors_applet->grid = gtk_grid_new();
654 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
655 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
656 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
657 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
658 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
659 } else {
660 /* remove all children if grid already exists so we can start again */
661 /* save a list of the old children for later */
662 old_grid_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))));
663
664 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
665 sensors_applet_pack_display_empty_grid_cb,
666 sensors_applet->grid);
667 }
668 /* pack icons / labels and values into grid */
669 current_sensor = sensors_applet->active_sensors;
670
671 /* if showing labels / icons and values, need to pack labels / icons these first */
672 if (display_mode == DISPLAY_ICON_WITH_VALUE || display_mode == DISPLAY_LABEL_WITH_VALUE) {
673 /* loop through columns */
674 for (i = 0; current_sensor != NULL((void*)0) && i < cols; /* increments depends on how we lay them out - see below */) {
675
676 /* loop through rows in a column */
677 for (j = 0; current_sensor && j < rows; /* see bottom of for loop*/) {
678 /* attach label / icon at this point */
679 if (display_mode == DISPLAY_ICON_WITH_VALUE) {
680 if (((ActiveSensor *)(current_sensor->data))->icon) {
681 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
682 ((ActiveSensor *)(current_sensor->data))->icon,
683 i, j, 1, 1);
684 }
685 } else {
686 if (((ActiveSensor *)(current_sensor->data))->label) {
687 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
688 ((ActiveSensor *)(current_sensor->data))->label,
689 i, j, 1, 1);
690 }
691 }
692 /* now attach sensor value to either row below or column next to */
693 if (layout_mode == VALUE_BESIDE_LABEL) {
694 /* left align labels */
695 if (((ActiveSensor *)(current_sensor->data))->icon) {
696 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_START);
697 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
698 }
699 if (((ActiveSensor *)(current_sensor->data))->label) {
700 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0);
701 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
702 }
703 if (((ActiveSensor *)(current_sensor->data))->value) {
704 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_START);
705 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
706 }
707
708 /* place value next to label */
709 if (((ActiveSensor *)(current_sensor->data))->value) {
710 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
711 ((ActiveSensor *)(current_sensor->data))->value,
712 i + 1, j, 1, 1);
713 }
714 j++;
715 } else { /* place value below label */
716
717 /* center align labels */
718 if (((ActiveSensor *)(current_sensor->data))->icon) {
719 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
720 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
721 }
722 if (((ActiveSensor *)(current_sensor->data))->label) {
723 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
724 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
725 }
726 if (((ActiveSensor *)(current_sensor->data))->value) {
727 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
728 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
729 }
730
731 if (((ActiveSensor *)(current_sensor->data))->value) {
732 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
733 ((ActiveSensor *)(current_sensor->data))->value,
734 i, j + 1, 1, 1);
735 }
736 j += 2;
737 }
738 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
739 } /* end row loop */
740
741 /* now increment column index as needed */
742 if (layout_mode == VALUE_BESIDE_LABEL) { /* place value next to label */
743 i += 2;
744 } else {
745 i++;
746 }
747 } /* end column loop */
748
749 } else { /* not showing labels and icons with values, so just pack either only icons or values */
750 for (i = 0; current_sensor != NULL((void*)0) && i < cols; ++i) {
751 for (j = 0; current_sensor!= NULL((void*)0) && j < rows; ++j) {
752 if (display_mode == DISPLAY_VALUE) {
753 if (((ActiveSensor *)(current_sensor->data))->value) {
754 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
755 ((ActiveSensor *)(current_sensor->data))->value,
756 i, j, 1, 1);
757 }
758 } else if (display_mode == DISPLAY_ICON) {
759 if (((ActiveSensor *)(current_sensor->data))->value) {
760 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
761 ((ActiveSensor *)(current_sensor->data))->icon,
762 i, j, 1, 1);
763 }
764 } else if (display_mode == DISPLAY_GRAPH) {
765 if (((ActiveSensor *)(current_sensor->data))->graph) {
766 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
767 ((ActiveSensor *)(current_sensor->data))->graph_frame,
768 i, j, 1, 1);
769 }
770 }
771
772 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
773 }
774 }
775 }
776
777 if (old_grid_children != NULL((void*)0)) {
778 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
779 sensors_applet_pack_display_cleanup_refs_cb,
780 old_grid_children);
781 g_list_free(old_grid_children);
782 }
783 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
784
785}
786
787/* must unref when done with returned pixbuf */
788GdkPixbuf *sensors_applet_load_icon(IconType icon_type) {
789 GtkIconTheme *icon_theme;
790 GdkPixbuf *icon = NULL((void*)0);
791 GError *error = NULL((void*)0);
792
793 /* try to load the icon */
794
795 /* not allowed to unref or ref icon_theme once we have it */
796 icon_theme = gtk_icon_theme_get_default();
797 icon = gtk_icon_theme_load_icon(icon_theme,
798 stock_icons[icon_type],
799 DEFAULT_ICON_SIZE22,
800 GTK_ICON_LOOKUP_USE_BUILTIN,
801 &error);
802
803 if (error) {
804 g_warning ("Could not load icon: %s", error->message);
805 g_error_free(error);
806 error = NULL((void*)0);
807
808 /* try again with default icon */
809 icon = gtk_icon_theme_load_icon(icon_theme,
810 "image-missing",
811 DEFAULT_ICON_SIZE22,
812 GTK_ICON_LOOKUP_USE_BUILTIN,
813 &error);
814
815 if (error) {
816 /* this will quit sensors-applet but it is a pretty major error so may as well */
817 g_error("Could not load GTK_STOCK_MISSING_IMAGE - major error!!!: %s", error->message);
818 g_error_free(error);
819 error = NULL((void*)0);
820 }
821
822 }
823 return icon;
824}
825
826// MUST FREE STRINGS AFTER CALLING THIS FUNCTION!!
827gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet,
828 const gchar *path,
829 const gchar *id,
830 const gchar *label,
831 const gchar *interface,
832 SensorType type,
833 gboolean enable,
834 gdouble low_value,
835 gdouble high_value,
836 gboolean alarm_enable,
837 const gchar *low_alarm_command,
838 const gchar *high_alarm_command,
839 gint alarm_timeout,
840 gdouble multiplier,
841 gdouble offset,
842 IconType icon_type,
843 const gchar *graph_color) {
844
845 GtkTreeIter interfaces_iter, sensors_iter;
846 gboolean not_empty_tree;
847
848 gchar *node_interface;
849 gboolean not_end_of_interfaces = TRUE(!(0)), interface_exists = FALSE(0);
850 gboolean not_end_of_sensors = TRUE(!(0));
851 gchar *sensor_id;
852 gchar *sensor_path;
853 SensorType sensor_type;
854 GdkPixbuf *icon;
855 GtkTreePath *tree_path;
856
857 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_23
; if (sensors_applet) _g_boolean_var_23 = 1; else _g_boolean_var_23
= 0; _g_boolean_var_23; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 857, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
858
859 /* assume tree is not empty */
860 not_empty_tree = TRUE(!(0));
861
862 if (NULL((void*)0) == sensors_applet->sensors) {
863
864 sensors_applet->sensors = gtk_tree_store_new(N_COLUMNS,
865 G_TYPE_STRING((GType) ((16) << (2))), /* path */
866 G_TYPE_STRING((GType) ((16) << (2))), /* id */
867 G_TYPE_STRING((GType) ((16) << (2))), /* label */
868 G_TYPE_STRING((GType) ((16) << (2))), /* interface */
869 G_TYPE_UINT((GType) ((7) << (2))), /* sensor type */
870 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* enable */
871 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* visible */
872 G_TYPE_DOUBLE((GType) ((15) << (2))), /* low value */
873 G_TYPE_DOUBLE((GType) ((15) << (2))), /* high type */
874 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* alarm enable */
875 G_TYPE_STRING((GType) ((16) << (2))), /* low alarm command */
876 G_TYPE_STRING((GType) ((16) << (2))), /* high alarm command */
877 G_TYPE_UINT((GType) ((7) << (2))), /* alarm timeout */
878 G_TYPE_DOUBLE((GType) ((15) << (2))), /* multiplier */
879 G_TYPE_DOUBLE((GType) ((15) << (2))), /* offset */
880 G_TYPE_UINT((GType) ((7) << (2))), /* icon type */
881 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()), /* icon pixbuf */
882 G_TYPE_STRING((GType) ((16) << (2)))); /* graph color */
883
884 g_debug("Sensor tree created.");
885
886 /* we know tree is actually empty since we just created it */
887 not_empty_tree = FALSE(0);
888 }
889
890 /* search sensor tree for the parent interface to place this sensor under */
891 for (not_empty_tree = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
892 not_empty_tree && not_end_of_interfaces && !interface_exists;
893 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
894
895 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter, INTERFACE_COLUMN, &node_interface, -1);
896 if (g_ascii_strcasecmp(interface, node_interface) == 0) {
897 /* found interface in tree */
898 interface_exists = TRUE(!(0));
899
900 /* now see if this actual sensor already exists within this interface - don't want to add duplicates */
901 /* see if have children */
902 for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
903 not_end_of_sensors;
904 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
905
906 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter,
907 PATH_COLUMN, &sensor_path,
908 ID_COLUMN, &sensor_id,
909 SENSOR_TYPE_COLUMN, &sensor_type,
910 -1);
911 if (g_ascii_strcasecmp(sensor_id, id) == 0 && g_ascii_strcasecmp(sensor_path, path) == 0 && sensor_type == type) {
912 /* sensor already exists so dont add a second time */
913 g_debug("sensor with path: %s, id: %s already exists in tree, not adding a second time", sensor_path, sensor_id);
914 g_free(sensor_id);
915 g_free(sensor_path);
916 g_free(node_interface);
917 return FALSE(0);
918 }
919 g_free(sensor_id);
920 g_free(sensor_path);
921 }
922 g_free(node_interface);
923 break;
924 }
925 g_free(node_interface);
926 }
927
928 if (!interface_exists) {
929 /* add to required plugins hash table so we ensure this
930 plugin stays loaded to make sure we have a get sensor
931 value function if possible */
932 g_hash_table_insert(sensors_applet->required_plugins,
933 g_strdup(interface)g_strdup_inline (interface),
934 GINT_TO_POINTER(TRUE)((gpointer) (glong) ((!(0)))));
935 g_debug("added interface %s to required plugins", interface);
936
937 /* wasn't able to find interface root node so create it */
938 gtk_tree_store_append(sensors_applet->sensors,
939 &interfaces_iter,
940 NULL((void*)0));
941
942 gtk_tree_store_set(sensors_applet->sensors,
943 &interfaces_iter,
944 ID_COLUMN, interface,
945 INTERFACE_COLUMN, interface,
946 VISIBLE_COLUMN, FALSE(0),
947 -1);
948 g_debug("Added sensor interface %s to tree", interface);
949 }
950
951 /* then add sensor as a child under interface node - ie assume
952 * we either found it or created it - the inteface node that is */
953
954 /* for now just add sensors all in a single list */
955 gtk_tree_store_append(sensors_applet->sensors, &sensors_iter, &interfaces_iter);
956
957 /* if sensor is already in settings, load values from there */
958 gchar *applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet);
959 gchar *gsuid = sensors_applet_settings_get_unique_id (interface, id, path);
960 gchar *settings_path = g_strdup_printf ("%s%s/", applet_path, gsuid);
961 GSettings *settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", settings_path);
962
963 /* add hash to temp sorting list */
964 g_variant_builder_add (&gvb_sensors_hash_list, "s", gsuid);
965
966 g_free (applet_path);
967 g_free (gsuid);
968 g_free (settings_path);
969
970 gchar *settings_id = g_settings_get_string (settings, ID"id");
971
972 if (settings_id != NULL((void*)0) && settings_id[0] != '\0') {
973 enable = g_settings_get_boolean (settings, ENABLED"enabled");
974 icon = sensors_applet_load_icon(g_settings_get_int (settings, ICON_TYPE"icon-type"));
975 gtk_tree_store_set(sensors_applet->sensors,
976 &sensors_iter,
977 PATH_COLUMN, g_settings_get_string (settings, PATH"path"),
978 ID_COLUMN, settings_id,
979 LABEL_COLUMN, g_settings_get_string (settings, LABEL"label"),
980 INTERFACE_COLUMN, g_settings_get_string (settings, INTERFACE"interface"),
981 SENSOR_TYPE_COLUMN, g_settings_get_int (settings, SENSOR_TYPE"sensor-type"),
982 ENABLE_COLUMN, enable,
983 VISIBLE_COLUMN, TRUE(!(0)),
984 LOW_VALUE_COLUMN, g_settings_get_double (settings, LOW_VALUE"low-value"),
985 HIGH_VALUE_COLUMN, g_settings_get_double (settings, HIGH_VALUE"high-value"),
986 ALARM_ENABLE_COLUMN, g_settings_get_boolean (settings, ALARM_ENABLED"alarm-enabled"),
987 ALARM_TIMEOUT_COLUMN, g_settings_get_int (settings, ALARM_TIMEOUT"alarm-timeout"),
988 LOW_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, LOW_ALARM_COMMAND"low-alarm-command"),
989 HIGH_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, HIGH_ALARM_COMMAND"high-alarm-command"),
990 MULTIPLIER_COLUMN, g_settings_get_double (settings, MULTIPLIER"multiplier"),
991 OFFSET_COLUMN, g_settings_get_double (settings, OFFSET"offset"),
992 ICON_TYPE_COLUMN, g_settings_get_int (settings, ICON_TYPE"icon-type"),
993 ICON_PIXBUF_COLUMN, icon,
994 GRAPH_COLOR_COLUMN, g_settings_get_string (settings, GRAPH_COLOR"graph-color"),
995 -1);
996 g_free (settings_id);
997 } else {
998 icon = sensors_applet_load_icon(icon_type);
999 gtk_tree_store_set(sensors_applet->sensors,
1000 &sensors_iter,
1001 PATH_COLUMN, path,
1002 ID_COLUMN, id,
1003 LABEL_COLUMN, label,
1004 INTERFACE_COLUMN, interface,
1005 SENSOR_TYPE_COLUMN, type,
1006 ENABLE_COLUMN, enable,
1007 VISIBLE_COLUMN, TRUE(!(0)),
1008 LOW_VALUE_COLUMN, low_value,
1009 HIGH_VALUE_COLUMN, high_value,
1010 ALARM_ENABLE_COLUMN, alarm_enable,
1011 ALARM_TIMEOUT_COLUMN, alarm_timeout,
1012 LOW_ALARM_COMMAND_COLUMN, low_alarm_command,
1013 HIGH_ALARM_COMMAND_COLUMN, high_alarm_command,
1014 MULTIPLIER_COLUMN, multiplier,
1015 OFFSET_COLUMN, offset,
1016 ICON_TYPE_COLUMN, icon_type,
1017 ICON_PIXBUF_COLUMN, icon,
1018 GRAPH_COLOR_COLUMN, graph_color,
1019 -1);
1020 }
1021 g_object_unref (settings);
1022 g_debug("added sensor %s to tree", path);
1023
1024 /* remove reference to icon as tree now has ref */
1025 g_object_unref(icon);
1026
1027 /* create the active sensor */
1028 if (enable) {
1029 tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
1030 sensors_applet_sensor_enabled(sensors_applet, tree_path);
1031 gtk_tree_path_free(tree_path);
1032 }
1033 return TRUE(!(0));
1034}
1035
1036static ActiveSensor *sensors_applet_find_active_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1037 GtkTreePath *sensor_tree_path;
1038 GList *current_sensor;
1039
1040 for (current_sensor = sensors_applet->active_sensors; current_sensor != NULL((void*)0); current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
) {
1041 sensor_tree_path = gtk_tree_row_reference_get_path(((ActiveSensor *)(current_sensor->data))->sensor_row);
1042
1043 if (gtk_tree_path_compare(path, sensor_tree_path) == 0) {
1044 gtk_tree_path_free(sensor_tree_path);
1045 return ((ActiveSensor *)(current_sensor->data));
1046 }
1047 gtk_tree_path_free(sensor_tree_path);
1048 }
1049 return NULL((void*)0);
1050}
1051
1052/* path should be the full path to a file representing the sensor (eg
1053 * /dev/hda or /sys/devices/platform/i2c-0/0-0290/temp1_input) */
1054void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet) {
1055 /* update sensors since will need to update icons / graphs etc
1056 * if weren't displayed before */
1057 GList *list = NULL((void*)0);
1058 for (list = sensors_applet->active_sensors; list != NULL((void*)0); list = list->next) {
1059 ActiveSensor *as = (ActiveSensor *)list->data;
1060 as->updated = FALSE(0);
1061 }
1062 sensors_applet_update_active_sensors(sensors_applet);
1063 sensors_applet_pack_display(sensors_applet);
1064}
1065
1066void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
1067 GtkTreePath *path,
1068 NotifType notif_type) {
1069 ActiveSensor *active_sensor;
1070
1071 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1072 active_sensor_alarm_off(active_sensor, notif_type);
1073 }
1074}
1075
1076void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet, GtkTreePath *path) {
1077 sensors_applet_alarm_off(sensors_applet, path, LOW_ALARM);
1078 sensors_applet_alarm_off(sensors_applet, path, HIGH_ALARM);
1079}
1080
1081void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1082 ActiveSensor *active_sensor;
1083
1084 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_24
; if (sensors_applet) _g_boolean_var_24 = 1; else _g_boolean_var_24
= 0; _g_boolean_var_24; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1084, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1085 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_25
; if (path) _g_boolean_var_25 = 1; else _g_boolean_var_25 = 0
; _g_boolean_var_25; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1085, ((const char*) (__func__
)), "path"); } while (0)
;
1086
1087 active_sensor = active_sensor_new(sensors_applet, gtk_tree_row_reference_new(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), path));
1088 active_sensor_update(active_sensor, sensors_applet);
1089
1090 /* keep list sorted */
1091 sensors_applet->active_sensors = g_list_insert_sorted(sensors_applet->active_sensors,
1092 active_sensor,
1093 (GCompareFunc)active_sensor_compare);
1094
1095 sensors_applet_pack_display(sensors_applet);
1096}
1097
1098void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet) {
1099 sensors_applet->active_sensors = g_list_sort(sensors_applet->active_sensors, (GCompareFunc)active_sensor_compare);
1100
1101 sensors_applet_pack_display(sensors_applet);
1102}
1103
1104void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1105
1106 ActiveSensor *active_sensor;
1107
1108 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_26
; if (sensors_applet) _g_boolean_var_26 = 1; else _g_boolean_var_26
= 0; _g_boolean_var_26; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1108, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1109 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_27
; if (path) _g_boolean_var_27 = 1; else _g_boolean_var_27 = 0
; _g_boolean_var_27; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1109, ((const char*) (__func__
)), "path"); } while (0)
;
1110
1111 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1112 g_debug("Destroying active sensor...");
1113
1114 g_debug("-- removing from list...");
1115 sensors_applet->active_sensors = g_list_remove(sensors_applet->active_sensors, active_sensor);
1116 g_debug("-- repacking display....");
1117 sensors_applet_pack_display(sensors_applet);
1118
1119 active_sensor_destroy(active_sensor);
1120 }
1121}
1122
1123void sensors_applet_update_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1124 ActiveSensor *active_sensor;
1125
1126 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_28
; if (sensors_applet) _g_boolean_var_28 = 1; else _g_boolean_var_28
= 0; _g_boolean_var_28; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1126, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1127 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_29
; if (path) _g_boolean_var_29 = 1; else _g_boolean_var_29 = 0
; _g_boolean_var_29; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1127, ((const char*) (__func__
)), "path"); } while (0)
;
1128
1129 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1130 active_sensor_update(active_sensor, sensors_applet);
1131 }
1132}
1133
1134void sensors_applet_icon_changed(SensorsApplet *sensors_applet, GtkTreePath *path) {
1135 ActiveSensor *active_sensor;
1136
1137 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_30
; if (sensors_applet) _g_boolean_var_30 = 1; else _g_boolean_var_30
= 0; _g_boolean_var_30; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1137, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1138 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_31
; if (path) _g_boolean_var_31 = 1; else _g_boolean_var_31 = 0
; _g_boolean_var_31; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1138, ((const char*) (__func__
)), "path"); } while (0)
;
1139
1140 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1141 active_sensor_icon_changed(active_sensor, sensors_applet);
1142 }
1143}
1144
1145/* Cycle thru ActiveSensors and update them all */
1146gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet) {
1147 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_32
; if (sensors_applet) _g_boolean_var_32 = 1; else _g_boolean_var_32
= 0; _g_boolean_var_32; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1147, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1148
1149 if (sensors_applet->active_sensors) {
1150 g_list_foreach(sensors_applet->active_sensors,
1151 (GFunc)active_sensor_update,
1152 sensors_applet);
1153 return TRUE(!(0));
1154 }
1155 return FALSE(0);
1156}
1157
1158/* Cycle thru ActiveSensors and set new graph dimensions */
1159void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet) {
1160 gint dimensions[2];
1161 gint graph_size;
1162 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_33
; if (sensors_applet) _g_boolean_var_33 = 1; else _g_boolean_var_33
= 0; _g_boolean_var_33; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1162, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1163
1164 if (sensors_applet->active_sensors) {
1165
1166 graph_size = g_settings_get_int (sensors_applet->settings, GRAPH_SIZE"graph-size");
1167 if (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP ||
1168 mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN) {
1169
1170 /* is horizontal so set graph_size as width */
1171 dimensions[0] = graph_size;
1172 dimensions[1] = sensors_applet->size;
1173 } else {
1174 dimensions[0] = sensors_applet->size;
1175 dimensions[1] = graph_size;
1176 }
1177
1178 g_list_foreach(sensors_applet->active_sensors,
1179 (GFunc)active_sensor_update_graph_dimensions,
1180 &dimensions);
1181 }
1182
1183}
1184
1185gdouble sensors_applet_convert_temperature(gdouble value, TemperatureScale old, TemperatureScale new) {
1186
1187 switch (old) {
1188 case KELVIN:
1189 switch (new) {
1190 case CELSIUS:
1191 value = value - 273.0;
1192 break;
1193 case FAHRENHEIT:
1194 value = (9.0 * (value - 273) / 5.0) + 32.0;
1195 break;
1196 case KELVIN:
1197 break;
1198 }
1199 break;
1200
1201 case CELSIUS:
1202 switch (new) {
1203 case FAHRENHEIT:
1204 value = (9.0 * value / 5.0) + 32.0;
1205 break;
1206 case KELVIN:
1207 value = value + 273.0;
1208 break;
1209 case CELSIUS:
1210 break;
1211 }
1212 break;
1213
1214 case FAHRENHEIT:
1215 switch (new) {
1216 case CELSIUS:
1217 value = (5.0 * (value - 32.0) / 9.0);
1218 break;
1219 case KELVIN:
1220 value = (5.0 * (value - 32.0) / 9.0) + 273.0;
1221 break;
1222 case FAHRENHEIT:
1223 break;
1224 }
1225 break;
1226 }
1227 return value;
1228}
1229
1230void sensors_applet_init(SensorsApplet *sensors_applet) {
1231
1232 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_34
; if (sensors_applet) _g_boolean_var_34 = 1; else _g_boolean_var_34
= 0; _g_boolean_var_34; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1232, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1233 g_assert(sensors_applet->applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_35
; if (sensors_applet->applet) _g_boolean_var_35 = 1; else _g_boolean_var_35
= 0; _g_boolean_var_35; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1233, ((const char*) (
__func__)), "sensors_applet->applet"); } while (0)
;
1234
1235 GtkActionGroup *action_group;
1236 gchar *ui_path;
1237
1238 /* Have our background automatically painted. */
1239 mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(sensors_applet->applet), GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1240
1241 /* plugin functions are stored as name -> get_value_function pairs so
1242 * use standard string functions on hash table */
1243 sensors_applet->plugins = g_hash_table_new(g_str_hash, g_str_equal);
1244
1245 sensors_applet->required_plugins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL((void*)0));
1246
1247 /* initialise size */
1248 sensors_applet->size = DEFAULT_APPLET_SIZE24;
1249
1250 mate_panel_applet_set_flags(sensors_applet->applet, MATE_PANEL_APPLET_EXPAND_MINOR);
1251
1252 g_signal_connect(sensors_applet->applet, "destroy",g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1253 G_CALLBACK(destroy_cb),g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1254 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
;
1255
1256 /* init gsettings */
1257 sensors_applet->settings = mate_panel_applet_settings_new (sensors_applet->applet, "org.mate.sensors-applet");
1258
1259 /* set up builder for sorting verification */
1260 g_variant_builder_init (&gvb_sensors_hash_list, G_VARIANT_TYPE ("as")(g_variant_type_checked_ (("as"))));
1261
1262 /* set up / load sensors from the plugins */
1263 sensors_applet_plugins_load_all(sensors_applet);
1264
1265 /* set sorting hash array */
1266 GVariant *gv_temp = g_variant_builder_end (&gvb_sensors_hash_list);
1267 sensors_applet->sensors_hash_array = g_variant_dup_strv (gv_temp, NULL((void*)0));
1268 g_variant_unref (gv_temp);
1269
1270 /* sort sensors based on saved sorting */
1271 sensors_applet_settings_sort_sensors(sensors_applet);
1272
1273 /* free hash array */
1274 g_strfreev (sensors_applet->sensors_hash_array);
1275
1276 /* should have created sensors tree above, but if have not was because we couldn't find any sensors */
1277 if (NULL((void*)0) == sensors_applet->sensors) {
1278 GtkWidget *label;
1279 label = gtk_label_new(_("No sensors found!")dcgettext (((void*)0), "No sensors found!", 5));
1280 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), label);
1281 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1282 return;
1283 }
1284
1285 /* only do menu and signal connections if sensors are found */
1286 action_group = gtk_action_group_new ("Sensors Applet Actions");
1287 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE"mate-sensors-applet");
1288 gtk_action_group_add_actions (action_group,
1289 sensors_applet_menu_actions,
1290 G_N_ELEMENTS (sensors_applet_menu_actions)(sizeof (sensors_applet_menu_actions) / sizeof ((sensors_applet_menu_actions
)[0]))
,
1291 sensors_applet);
1292 ui_path = g_build_filename (UIDIR"/usr/local/share/mate-sensors-applet/ui", SENSORS_APPLET_MENU_FILE"SensorsApplet.xml", NULL((void*)0));
1293 mate_panel_applet_setup_menu_from_file (sensors_applet->applet, ui_path, action_group);
1294 g_free (ui_path);
1295 g_object_unref (action_group);
1296
1297 g_signal_connect(sensors_applet->applet, "style-set",g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1298 G_CALLBACK(style_set_cb),g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1299 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
;
1300
1301 g_signal_connect(G_OBJECT(sensors_applet->applet), "change_orient",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1302 G_CALLBACK(change_orient_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1303 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1304
1305 g_signal_connect(G_OBJECT(sensors_applet->applet), "size_allocate",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1306 G_CALLBACK(size_allocate_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1307 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1308
1309 g_signal_connect(G_OBJECT(sensors_applet->applet), "leave_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1310 G_CALLBACK(mouse_leave_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1311 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1312
1313 g_signal_connect(G_OBJECT(sensors_applet->applet), "enter_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1314 G_CALLBACK(mouse_enter_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1315 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1316
1317 sensors_applet_update_active_sensors(sensors_applet);
1318 sensors_applet_pack_display(sensors_applet);
1319
1320 sensors_applet->timeout_id = g_timeout_add_seconds(g_settings_get_int(sensors_applet->settings, TIMEOUT"timeout-delay") / 1000,
1321 (GSourceFunc)sensors_applet_update_active_sensors,
1322 sensors_applet);
1323 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1324}
1325
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-48fbd5.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-48fbd5.html new file mode 100644 index 0000000..4806f84 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-48fbd5.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 316, column 96
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_18
; if (info != ((void*)0)) _g_boolean_var_18 = 1; else _g_boolean_var_18
= 0; _g_boolean_var_18; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_19
; if (connection != ((void*)0)) _g_boolean_var_19 = 1; else _g_boolean_var_19
= 0; _g_boolean_var_19; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-5f1566.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-5f1566.html new file mode 100644 index 0000000..391f65b --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-5f1566.html @@ -0,0 +1,2005 @@ + + + +sensors-applet.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:sensors-applet/sensors-applet.c
Warning:line 860, column 5
Value stored to 'not_empty_tree' 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 sensors-applet.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=none -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/sensors-applet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D UIDIR="/usr/local/share/mate-sensors-applet/ui" -D SENSORS_APPLET_PLUGIN_DIR="/usr/local/lib/mate-sensors-applet/plugins" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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/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 -I /usr/include/mate-panel-4.0/libmate-panel-applet -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 /usr/include/cairo -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libxml2 -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -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 -O2 -Wno-unused-parameter -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/sensors-applet -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c sensors-applet.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/** Contain the functions for operating on the SensorsApplet structure
21 * (represents the applet itself, and its associated variables.
22 */
23
24#ifdef HAVE_CONFIG_H1
25#include "config.h"
26#endif /* HAVE_CONFIG_H */
27
28#ifdef HAVE_UNISTD_H1
29#include <unistd.h>
30#endif /* HAVE_UNISTD_H */
31
32#include <glib/gi18n.h>
33#include <glib/gprintf.h>
34#include <gio/gio.h>
35#include "sensors-applet.h"
36#include "active-sensor.h"
37#include "sensors-applet-settings.h"
38#include "sensors-applet-plugins.h"
39
40#ifdef HAVE_LIBNOTIFY1
41#include "active-sensor-libnotify.h"
42#define DEFAULT_NOTIFY_TIMEOUT3000 3000
43#endif
44
45#include "prefs-dialog.h"
46#include "about-dialog.h"
47
48#define SENSORS_APPLET_MENU_FILE"SensorsApplet.xml" "SensorsApplet.xml"
49/* initially set as sensors_applet->size to ensure a real value is stored */
50#define DEFAULT_APPLET_SIZE24 24
51#define COLUMN_SPACING2 2
52#define ROW_SPACING1 1
53
54/* builder for sensor sorting verification */
55static GVariantBuilder gvb_sensors_hash_list;
56
57/* callbacks for panel menu */
58static void prefs_cb(GtkAction *action, gpointer *data) {
59
60 SensorsApplet *sensors_applet;
61 sensors_applet = (SensorsApplet *)data;
62
63 if (sensors_applet->prefs_dialog) {
64 gtk_window_present(GTK_WINDOW(sensors_applet->prefs_dialog->dialog)((((GtkWindow*) (void *) ((sensors_applet->prefs_dialog->
dialog)))))
);
65 return;
66 }
67 prefs_dialog_open(sensors_applet);
68}
69
70static void about_cb(GtkAction *action, gpointer data) {
71 SensorsApplet *sensors_applet;
72 sensors_applet = (SensorsApplet *)data;
73
74 about_dialog_open(sensors_applet);
75}
76
77static void help_cb(GtkAction *action, gpointer data) {
78
79 GError *error = NULL((void*)0);
80
81 gtk_show_uri_on_window(NULL((void*)0), "help:mate-sensors-applet",
82
83 gtk_get_current_event_time(),
84 &error);
85
86 if (error) {
87 g_debug("Could not open help document: %s ",error->message);
88 g_error_free(error);
89 }
90}
91
92static void destroy_cb(GtkWidget *widget, gpointer data) {
93 SensorsApplet *sensors_applet;
94 sensors_applet = (SensorsApplet *)data;
95
96 /* destroy dialogs, remove timeout and clear sensors tree and finally the applet */
97 if (sensors_applet->prefs_dialog != NULL((void*)0)) {
98 /* destroy's dialog too */
99 prefs_dialog_close(sensors_applet);
100 }
101
102 if (sensors_applet->timeout_id) {
103 g_source_remove(sensors_applet->timeout_id);
104 }
105
106 if (sensors_applet->settings) {
107 g_object_unref (sensors_applet->settings);
108 sensors_applet->settings = NULL((void*)0);
109 }
110
111 /* destroy all active sensors */
112 g_list_foreach(sensors_applet->active_sensors,
113 (GFunc)active_sensor_destroy,
114 NULL((void*)0));
115
116 if (sensors_applet->sensors != NULL((void*)0)) {
117 gtk_tree_store_clear(sensors_applet->sensors);
118 }
119
120 gtk_widget_destroy(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
121
122 g_free(sensors_applet);
123 return;
124}
125
126static void change_orient_cb (MatePanelApplet *applet,
127 MatePanelAppletOrient orient,
128 gpointer data) {
129
130 SensorsApplet *sensors_applet;
131 sensors_applet = (SensorsApplet *)data;
132
133 sensors_applet_display_layout_changed(sensors_applet);
134}
135
136static void size_allocate_cb(MatePanelApplet *applet,
137 GtkAllocation *allocation,
138 gpointer data) {
139
140 SensorsApplet *sensors_applet;
141 MatePanelAppletOrient orient;
142
143 sensors_applet = (SensorsApplet *)data;
144 orient = mate_panel_applet_get_orient(sensors_applet->applet);
145
146 if ((orient == MATE_PANEL_APPLET_ORIENT_LEFT) ||
147 (orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
148
149 if (sensors_applet->size == allocation->width)
150 return;
151 sensors_applet->size = allocation->width;
152 } else {
153 if (sensors_applet->size == allocation->height)
154 return;
155 sensors_applet->size = allocation->height;
156 }
157
158 /* update if new value */
159 sensors_applet_graph_size_changed(sensors_applet);
160 sensors_applet_display_layout_changed(sensors_applet);
161}
162
163static void style_set_cb(GtkWidget *widget, GtkStyle *old_style, gpointer data) {
164
165 /* update all icons in the sensors tree and update all active sensors */
166 GtkTreeIter interfaces_iter, sensors_iter;
167 gboolean not_end_of_interfaces = TRUE(!(0)), not_end_of_sensors = TRUE(!(0));
168 IconType icon_type;
169 gboolean enabled;
170 SensorsApplet *sensors_applet;
171 DisplayMode display_mode;
172
173 sensors_applet = (SensorsApplet *)data;
174
175 display_mode = g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
176 if (sensors_applet->sensors) {
177 for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
178 not_end_of_interfaces;
179 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
180
181 /* reset sensors sentinel */
182 not_end_of_sensors = TRUE(!(0));
183
184 for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
185 not_end_of_sensors;
186 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
187
188 GdkPixbuf *new_icon;
189
190 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))),
191 &sensors_iter,
192 ENABLE_COLUMN, &enabled,
193 ICON_TYPE_COLUMN, &icon_type,
194 -1);
195 /* update icons */
196 new_icon = sensors_applet_load_icon(icon_type);
197
198 gtk_tree_store_set(sensors_applet->sensors,
199 &sensors_iter,
200 ICON_PIXBUF_COLUMN, new_icon,
201 -1);
202 g_object_unref(new_icon);
203
204 /* update icons only if currently being displayed */
205 if (enabled &&
206 (display_mode == DISPLAY_ICON ||
207 display_mode == DISPLAY_ICON_WITH_VALUE)) {
208
209 GtkTreePath *path;
210
211 path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
212 sensors_applet_icon_changed(sensors_applet, path);
213 gtk_tree_path_free(path);
214 }
215 }
216 }
217 /* now update layout as size may have changed */
218 sensors_applet_display_layout_changed(sensors_applet);
219 }
220
221}
222
223static gboolean mouse_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
224{
225 SensorsApplet *sensor_applet = data;
226 sensor_applet->show_tooltip = TRUE(!(0));
227 sensors_applet_update_active_sensors(sensor_applet);
228 return TRUE(!(0));
229}
230
231static gboolean mouse_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
232{
233 SensorsApplet *sensor_applet = data;
234 sensor_applet->show_tooltip = FALSE(0);
235 return TRUE(!(0));
236}
237
238static const GtkActionEntry sensors_applet_menu_actions[] = {
239 { "Preferences", "document-properties", N_("_Preferences")("_Preferences"),
240 NULL((void*)0), NULL((void*)0),
241 G_CALLBACK(prefs_cb)((GCallback) (prefs_cb)) },
242 { "Help", "help-browser", N_("_Help")("_Help"),
243 NULL((void*)0), NULL((void*)0),
244 G_CALLBACK(help_cb)((GCallback) (help_cb)) },
245 { "About", "help-about", N_("_About")("_About"),
246 NULL((void*)0), NULL((void*)0),
247 G_CALLBACK(about_cb)((GCallback) (about_cb)) }
248};
249
250void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type) {
251#ifdef HAVE_LIBNOTIFY1
252
253 SensorsApplet *sensors_applet;
254 gchar *summary, *message;
255 gint timeout_msecs;
256 gchar *sensor_label;
257 gchar *sensor_path;
258 SensorType sensor_type;
259 TemperatureScale temp_scale;
260 GtkTreeIter iter;
261 GtkTreePath *path;
262 const gchar *unit_type = NULL((void*)0);
263 const gchar *unit_type_title = NULL((void*)0);
264 const gchar *relation = NULL((void*)0);
265 const gchar *limit_type = NULL((void*)0);
266 const gchar *units = NULL((void*)0);
267 gdouble limit_value;
268 gdouble seconds;
269 gboolean show_notification = TRUE(!(0));
270
271 sensors_applet = active_sensor->sensors_applet;
272
273 if (!g_settings_get_boolean (sensors_applet->settings, DISPLAY_NOTIFICATIONS"display-notifications")) {
274 g_debug("Wanted to display notification, but user has disabled them");
275 return;
276 }
277
278 path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
279 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter, path)) {
280
281 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter,
282 LABEL_COLUMN, &sensor_label,
283 PATH_COLUMN, &sensor_path,
284 SENSOR_TYPE_COLUMN, &sensor_type,
285 -1);
286 } else {
287 g_warning("Error getting data from tree for notification...");
288 gtk_tree_path_free(path);
289 return;
290 }
291
292 gtk_tree_path_free(path);
293
294 /* do different stuff for different notif types */
295 switch (notif_type) {
296 case LOW_ALARM: /* fall thru */
297 case HIGH_ALARM:
298 if (active_sensor->sensor_values[0] <= active_sensor->sensor_low_value && notif_type == LOW_ALARM) {
299
300 relation = _("is very low")dcgettext (((void*)0), "is very low", 5);
301 limit_type = _("lower limit")dcgettext (((void*)0), "lower limit", 5);
302 limit_value = active_sensor->sensor_low_value;
303 } else if (active_sensor->sensor_values[0] >= active_sensor->sensor_high_value && notif_type == HIGH_ALARM) {
304
305 /* assume high alarm condition */
306 relation = _("is very high")dcgettext (((void*)0), "is very high", 5);
307 limit_type = _("upper limit")dcgettext (((void*)0), "upper limit", 5);
308 limit_value = active_sensor->sensor_high_value;
309 } else {
310 g_warning("Alarm notify called when no alarm condition!");
311 g_free(sensor_path);
312 g_free(sensor_label);
313 return;
314 }
315
316 switch ((SensorType)sensor_type) {
317 case TEMP_SENSOR:
318 unit_type_title = _("Temperature")dcgettext (((void*)0), "Temperature", 5);
319 unit_type = _("temperature")dcgettext (((void*)0), "temperature", 5);
320 temp_scale = (TemperatureScale) g_settings_get_int (active_sensor->sensors_applet->settings, TEMPERATURE_SCALE"temperature-scale");
321
322 switch (temp_scale) {
323 case CELSIUS:
324 units = UNITS_CELSIUS"\302\260C";
325 break;
326 case FAHRENHEIT:
327 units = UNITS_FAHRENHEIT"\302\260F";
328 break;
329 case KELVIN:
330 units = UNITS_KELVIN"";
331 break;
332 default:
333 units = NULL((void*)0);
334 }
335 break;
336
337 case VOLTAGE_SENSOR:
338 unit_type_title = _("Voltage")dcgettext (((void*)0), "Voltage", 5);
339 unit_type = _("voltage")dcgettext (((void*)0), "voltage", 5);
340 units = UNITS_VOLTAGEdcgettext (((void*)0), "V", 5);
341 break;
342
343 case FAN_SENSOR:
344 unit_type_title = _("Fan Speed")dcgettext (((void*)0), "Fan Speed", 5);
345 unit_type = _("fan speed")dcgettext (((void*)0), "fan speed", 5);
346 units = UNITS_RPMdcgettext (((void*)0), "RPM", 5);
347 break;
348
349 case CURRENT_SENSOR:
350 unit_type_title = _("Current")dcgettext (((void*)0), "Current", 5);
351 unit_type = _("current")dcgettext (((void*)0), "current", 5);
352 units = UNITS_CURRENTdcgettext (((void*)0), "A", 5);
353 break;
354 }
355
356 timeout_msecs = (active_sensor->alarm_timeout ? MIN(DEFAULT_NOTIFY_TIMEOUT, (active_sensor->alarm_timeout * 1000))(((3000) < ((active_sensor->alarm_timeout * 1000))) ? (
3000) : ((active_sensor->alarm_timeout * 1000)))
: DEFAULT_NOTIFY_TIMEOUT3000);
357
358 summary = g_strdup_printf("%s %s %s", sensor_label, unit_type_title, _("Alarm")dcgettext (((void*)0), "Alarm", 5));
359 message = g_strdup_printf("%s %s %s (%s %2.0f%s)", sensor_label, unit_type, relation, limit_type, limit_value, units);
360 break;
361
362 case SENSOR_INTERFACE_ERROR:
363 /* get time since the last error */
364 seconds = difftime(time(NULL((void*)0)), active_sensor->ierror_ts);
365
366 /* if the last error happened less than 10 seconds ago, don't display this one
367 * this should prevent recurring popups for removed sensors, like USB-HDDs */
368 if (seconds < 11.0) {
369 show_notification = FALSE(0);
370 }
371
372 summary = g_strdup_printf(_("Error updating sensor %s")dcgettext (((void*)0), "Error updating sensor %s", 5), sensor_label);
373 message = g_strdup_printf(_("An error occurred while trying to update the value of the sensor %s located at %s.")dcgettext (((void*)0), "An error occurred while trying to update the value of the sensor %s located at %s."
, 5)
, sensor_label, sensor_path);
374 timeout_msecs = g_settings_get_int (active_sensor->sensors_applet->settings, TIMEOUT"timeout-delay");
375
376 /* update timestamp */
377 time(&(active_sensor->ierror_ts));
378 break;
379
380 default:
381 g_assert_not_reached()do { g_assertion_message_expr ("sensors-applet", "sensors-applet.c"
, 381, ((const char*) (__func__)), ((void*)0)); } while (0)
;
382 }
383
384 if (show_notification) {
385 active_sensor_libnotify_notify(active_sensor,
386 notif_type,
387 summary,
388 message,
389 "dialog-warning",
390 timeout_msecs);
391 }
392
393 g_free(sensor_path);
394 g_free(sensor_label);
395 g_free(summary);
396 g_free(message);
397#endif
398}
399
400void sensors_applet_notify_end(ActiveSensor *active_sensor, NotifType notif_type) {
401#ifdef HAVE_LIBNOTIFY1
402 active_sensor_libnotify_notify_end(active_sensor, notif_type);
403#endif
404}
405
406#ifdef HAVE_LIBNOTIFY1
407static void sensors_applet_notify_end_all_gfunc(ActiveSensor *active_sensor, gpointer data) {
408 active_sensor_libnotify_notify_end(active_sensor, LOW_ALARM);
409 active_sensor_libnotify_notify_end(active_sensor, HIGH_ALARM);
410}
411#endif
412
413void sensors_applet_notify_end_all(SensorsApplet *sensors_applet) {
414#ifdef HAVE_LIBNOTIFY1
415 g_list_foreach(sensors_applet->active_sensors, (GFunc)sensors_applet_notify_end_all_gfunc, NULL((void*)0));
416#endif
417}
418
419/* internal helper functions for updating display etc */
420
421/* should be called as a g_container_foreach at the start of
422 * pack_display if the grid already exists to remove but keep alive
423 * all children of the grid before repacking it */
424static void sensors_applet_pack_display_empty_grid_cb(GtkWidget *widget, gpointer data)
425{
426 GtkContainer *container;
427
428 container = GTK_CONTAINER(data)((((GtkContainer*) (void *) ((data)))));
429
430 /* ref then remove widget */
431 g_object_ref(widget)((__typeof__ (widget)) (g_object_ref) (widget));
432 gtk_container_remove(container, widget);
433}
434
435/* should be called as a g_container_foreach at the end of
436 * pack_display to unref any of the old children that we have readdded
437 * to the table to stop reference creep from the g_object_ref called
438 * on each child at the start of pack labels */
439static void sensors_applet_pack_display_cleanup_refs_cb(GtkWidget *widget, gpointer data) {
440
441 GList *old_children;
442
443 old_children = (GList *)data;
444 if (g_list_find(old_children, widget)) {
445 g_object_unref(widget);
446 }
447}
448
449static void sensors_applet_pack_display(SensorsApplet *sensors_applet) {
450 /* note the if () around each widget is to ensure we only
451 * operate on those that actually exist */
452 GtkLabel *no_sensors_enabled_label = NULL((void*)0);
453 gint num_active_sensors = 0, num_sensors_per_group = 0, rows, cols, i, j;
454 GList *old_grid_children = NULL((void*)0);
455
456 GList *current_sensor;
457
458 DisplayMode display_mode;
459 LayoutMode layout_mode;
460
461 gboolean horizontal;
462 gint label_width, icon_width, value_width;
463 gint label_height, icon_height, value_height;
464
465 GtkRequisition req;
466
467 ActiveSensor *first_sensor;
468
469 /* it is possible that there could be no active sensors so
470 * handle that case first - make sure we dont do a NULL
471 * pointer access first though */
472 if (sensors_applet->active_sensors == NULL((void*)0) || g_list_length(sensors_applet->active_sensors) == 0) {
473 g_debug("no active sensors to pack in grid");
474 no_sensors_enabled_label = g_object_new(GTK_TYPE_LABEL(gtk_label_get_type ()), "label", _("No sensors enabled!")dcgettext (((void*)0), "No sensors enabled!", 5), NULL((void*)0));
475
476 if (sensors_applet->grid == NULL((void*)0)) {
477 /* only need 1 row and 1 col */
478 sensors_applet->grid = gtk_grid_new();
479 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
480 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
481 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
482 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
483 /* add grid to applet */
484 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
485 } else {
486 /* destroy existing widgets - could be an
487 * existing version of no sensors label - okay
488 * to just add again though if destroy first */
489 g_debug("destroying any existing widgets in container");
490 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))), (GtkCallback)gtk_widget_destroy, NULL((void*)0));
491 }
492 g_debug("packing no sensors enabled label");
493 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
494 GTK_WIDGET(no_sensors_enabled_label)((((GtkWidget*) (void *) ((no_sensors_enabled_label))))),
495 0, 0, 1, 1);
496 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
497 return;
498 }
499 /* otherwise can acess active_sensors without any worries */
500 num_active_sensors = g_list_length(sensors_applet->active_sensors);
501
502 display_mode = (DisplayMode) g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
503 layout_mode = (LayoutMode) g_settings_get_int (sensors_applet->settings, LAYOUT_MODE"layout-mode");
504
505 horizontal = (((mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP) ||
506 (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN)));
507
508 /* figure out num rows / cols by how high / wide sensors
509 * labels / icons are and how much size we have to put them in */
510
511 /* get the first active sensor */
512 first_sensor = (ActiveSensor *)sensors_applet->active_sensors->data;
513
514 switch (display_mode) {
515 case DISPLAY_VALUE:
516 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
517 value_width = req.width + COLUMN_SPACING2;
518 value_height = req.height + ROW_SPACING1;
519
520 /* make sure all widths and heights are non zero,
521 * otherwise will get a divide by zero exception below
522 * - is a non critical error since can happen when
523 * elements first added to list, so simply return - is
524 * not a programming error */
525 if (value_width == 0 && value_height == 0) {
526 return;
527 }
528
529 num_sensors_per_group = (sensors_applet->size / (horizontal ? value_height : value_width));
530 break;
531
532 case DISPLAY_LABEL_WITH_VALUE:
533 /* even though we end up packing the event boxes into the
534 * panel, these dont give back request sizes, so need to ask
535 * widgets directly */
536 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
537
538 value_width = req.width + COLUMN_SPACING2;
539 value_height = req.height + ROW_SPACING1;
540
541 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->label)((((GtkWidget*) (void *) ((first_sensor->label))))), &req, NULL((void*)0));
542 label_width = req.width + COLUMN_SPACING2;
543 label_height = req.height + ROW_SPACING1;
544
545 /* make sure all widths and heights are non zero, otherwise
546 * will get a divide by zero exception below
547 * - is a non critical error since can happen when
548 * elements first added to list, so simply return - is
549 * not a programming error */
550 if (!(label_width && label_height && value_width && value_height)) {
551 return;
552 }
553
554 switch (layout_mode) {
555 case VALUE_BESIDE_LABEL:
556 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(label_height, value_height)(((label_height) > (value_height)) ? (label_height) : (value_height
))
: (label_width + value_width)));
557 break;
558 case VALUE_BELOW_LABEL:
559 num_sensors_per_group = (sensors_applet->size / (horizontal ? (label_height + value_height) : MAX(label_width, value_width)(((label_width) > (value_width)) ? (label_width) : (value_width
))
));
560 break;
561 }
562 break;
563
564 case DISPLAY_ICON_WITH_VALUE:
565 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
566 value_width = req.width + COLUMN_SPACING2;
567 value_height = req.height + ROW_SPACING1;
568
569 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
570 icon_width = req.width + COLUMN_SPACING2;
571 icon_height = req.height + ROW_SPACING1;
572
573 if (!(icon_width && icon_height && value_width && value_height)) {
574 return;
575 }
576
577 switch (layout_mode) {
578 case VALUE_BESIDE_LABEL:
579 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(icon_height, value_height)(((icon_height) > (value_height)) ? (icon_height) : (value_height
))
: (icon_width + value_width)));
580 break;
581
582 case VALUE_BELOW_LABEL:
583 num_sensors_per_group = (sensors_applet->size / (horizontal ? (icon_height + value_height) : MAX(icon_width, value_width)(((icon_width) > (value_width)) ? (icon_width) : (value_width
))
));
584 break;
585 }
586 break;
587
588 case DISPLAY_ICON:
589 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
590 icon_width = req.width + COLUMN_SPACING2;
591 icon_height = req.height + ROW_SPACING1;
592
593 if (!(icon_width && icon_height)) {
594 return;
595 }
596
597 num_sensors_per_group = (sensors_applet->size / (horizontal ? icon_height : icon_width));
598 break;
599
600 case DISPLAY_GRAPH:
601 /* only show graphs in a line like System Monitor applet */
602 num_sensors_per_group = 1;
603 break;
604 }
605
606 /* ensure always atleast 1 sensor per group */
607 if (num_sensors_per_group < 1) {
608 /* force a better layout */
609 if (horizontal && layout_mode == VALUE_BELOW_LABEL) {
610 layout_mode = VALUE_BESIDE_LABEL;
611 } else if (!horizontal && layout_mode == VALUE_BESIDE_LABEL) {
612 layout_mode = VALUE_BELOW_LABEL;
613 }
614 num_sensors_per_group = 1;
615 }
616
617 if (horizontal) {
618 /* if oriented horizontally, want as many
619 sensors per column as user has defined, then
620 enough columns to hold all the widgets */
621 rows = num_sensors_per_group;
622 cols = num_active_sensors / num_sensors_per_group;
623 while (rows * cols < num_active_sensors || cols == 0) {
624 cols++;
625 }
626
627 } else {
628 /* if oriented vertically, want as many
629 sensors per row as user has defined, then
630 enough rows to hold all the widgets*/
631 cols = num_sensors_per_group;
632 rows = num_active_sensors / num_sensors_per_group;
633 while (rows * cols < num_active_sensors || rows == 0) {
634 rows++;
635 }
636
637 }
638
639 /* if displaying labels / icons and values need to modify
640 number of rows / colums to accomodate this */
641 if (display_mode == DISPLAY_LABEL_WITH_VALUE || display_mode == DISPLAY_ICON_WITH_VALUE) {
642 if (layout_mode == VALUE_BESIDE_LABEL) {
643 /* to display labels next to values need twice as many columns */
644 cols *= 2;
645 } else {
646 /* to display labels above values, we need twice as many rows as without */
647 rows *= 2;
648 }
649 }
650
651 if (sensors_applet->grid == NULL((void*)0)) {
652 /* create grid and add to applet */
653 sensors_applet->grid = gtk_grid_new();
654 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
655 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
656 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
657 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
658 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
659 } else {
660 /* remove all children if grid already exists so we can start again */
661 /* save a list of the old children for later */
662 old_grid_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))));
663
664 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
665 sensors_applet_pack_display_empty_grid_cb,
666 sensors_applet->grid);
667 }
668 /* pack icons / labels and values into grid */
669 current_sensor = sensors_applet->active_sensors;
670
671 /* if showing labels / icons and values, need to pack labels / icons these first */
672 if (display_mode == DISPLAY_ICON_WITH_VALUE || display_mode == DISPLAY_LABEL_WITH_VALUE) {
673 /* loop through columns */
674 for (i = 0; current_sensor != NULL((void*)0) && i < cols; /* increments depends on how we lay them out - see below */) {
675
676 /* loop through rows in a column */
677 for (j = 0; current_sensor && j < rows; /* see bottom of for loop*/) {
678 /* attach label / icon at this point */
679 if (display_mode == DISPLAY_ICON_WITH_VALUE) {
680 if (((ActiveSensor *)(current_sensor->data))->icon) {
681 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
682 ((ActiveSensor *)(current_sensor->data))->icon,
683 i, j, 1, 1);
684 }
685 } else {
686 if (((ActiveSensor *)(current_sensor->data))->label) {
687 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
688 ((ActiveSensor *)(current_sensor->data))->label,
689 i, j, 1, 1);
690 }
691 }
692 /* now attach sensor value to either row below or column next to */
693 if (layout_mode == VALUE_BESIDE_LABEL) {
694 /* left align labels */
695 if (((ActiveSensor *)(current_sensor->data))->icon) {
696 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_START);
697 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
698 }
699 if (((ActiveSensor *)(current_sensor->data))->label) {
700 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0);
701 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
702 }
703 if (((ActiveSensor *)(current_sensor->data))->value) {
704 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_START);
705 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
706 }
707
708 /* place value next to label */
709 if (((ActiveSensor *)(current_sensor->data))->value) {
710 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
711 ((ActiveSensor *)(current_sensor->data))->value,
712 i + 1, j, 1, 1);
713 }
714 j++;
715 } else { /* place value below label */
716
717 /* center align labels */
718 if (((ActiveSensor *)(current_sensor->data))->icon) {
719 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
720 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
721 }
722 if (((ActiveSensor *)(current_sensor->data))->label) {
723 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
724 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
725 }
726 if (((ActiveSensor *)(current_sensor->data))->value) {
727 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
728 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
729 }
730
731 if (((ActiveSensor *)(current_sensor->data))->value) {
732 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
733 ((ActiveSensor *)(current_sensor->data))->value,
734 i, j + 1, 1, 1);
735 }
736 j += 2;
737 }
738 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
739 } /* end row loop */
740
741 /* now increment column index as needed */
742 if (layout_mode == VALUE_BESIDE_LABEL) { /* place value next to label */
743 i += 2;
744 } else {
745 i++;
746 }
747 } /* end column loop */
748
749 } else { /* not showing labels and icons with values, so just pack either only icons or values */
750 for (i = 0; current_sensor != NULL((void*)0) && i < cols; ++i) {
751 for (j = 0; current_sensor!= NULL((void*)0) && j < rows; ++j) {
752 if (display_mode == DISPLAY_VALUE) {
753 if (((ActiveSensor *)(current_sensor->data))->value) {
754 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
755 ((ActiveSensor *)(current_sensor->data))->value,
756 i, j, 1, 1);
757 }
758 } else if (display_mode == DISPLAY_ICON) {
759 if (((ActiveSensor *)(current_sensor->data))->value) {
760 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
761 ((ActiveSensor *)(current_sensor->data))->icon,
762 i, j, 1, 1);
763 }
764 } else if (display_mode == DISPLAY_GRAPH) {
765 if (((ActiveSensor *)(current_sensor->data))->graph) {
766 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
767 ((ActiveSensor *)(current_sensor->data))->graph_frame,
768 i, j, 1, 1);
769 }
770 }
771
772 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
773 }
774 }
775 }
776
777 if (old_grid_children != NULL((void*)0)) {
778 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
779 sensors_applet_pack_display_cleanup_refs_cb,
780 old_grid_children);
781 g_list_free(old_grid_children);
782 }
783 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
784
785}
786
787/* must unref when done with returned pixbuf */
788GdkPixbuf *sensors_applet_load_icon(IconType icon_type) {
789 GtkIconTheme *icon_theme;
790 GdkPixbuf *icon = NULL((void*)0);
791 GError *error = NULL((void*)0);
792
793 /* try to load the icon */
794
795 /* not allowed to unref or ref icon_theme once we have it */
796 icon_theme = gtk_icon_theme_get_default();
797 icon = gtk_icon_theme_load_icon(icon_theme,
798 stock_icons[icon_type],
799 DEFAULT_ICON_SIZE22,
800 GTK_ICON_LOOKUP_USE_BUILTIN,
801 &error);
802
803 if (error) {
804 g_warning ("Could not load icon: %s", error->message);
805 g_error_free(error);
806 error = NULL((void*)0);
807
808 /* try again with default icon */
809 icon = gtk_icon_theme_load_icon(icon_theme,
810 "image-missing",
811 DEFAULT_ICON_SIZE22,
812 GTK_ICON_LOOKUP_USE_BUILTIN,
813 &error);
814
815 if (error) {
816 /* this will quit sensors-applet but it is a pretty major error so may as well */
817 g_error("Could not load GTK_STOCK_MISSING_IMAGE - major error!!!: %s", error->message);
818 g_error_free(error);
819 error = NULL((void*)0);
820 }
821
822 }
823 return icon;
824}
825
826// MUST FREE STRINGS AFTER CALLING THIS FUNCTION!!
827gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet,
828 const gchar *path,
829 const gchar *id,
830 const gchar *label,
831 const gchar *interface,
832 SensorType type,
833 gboolean enable,
834 gdouble low_value,
835 gdouble high_value,
836 gboolean alarm_enable,
837 const gchar *low_alarm_command,
838 const gchar *high_alarm_command,
839 gint alarm_timeout,
840 gdouble multiplier,
841 gdouble offset,
842 IconType icon_type,
843 const gchar *graph_color) {
844
845 GtkTreeIter interfaces_iter, sensors_iter;
846 gboolean not_empty_tree;
847
848 gchar *node_interface;
849 gboolean not_end_of_interfaces = TRUE(!(0)), interface_exists = FALSE(0);
850 gboolean not_end_of_sensors = TRUE(!(0));
851 gchar *sensor_id;
852 gchar *sensor_path;
853 SensorType sensor_type;
854 GdkPixbuf *icon;
855 GtkTreePath *tree_path;
856
857 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_49
; if (sensors_applet) _g_boolean_var_49 = 1; else _g_boolean_var_49
= 0; _g_boolean_var_49; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 857, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
858
859 /* assume tree is not empty */
860 not_empty_tree = TRUE(!(0));
Value stored to 'not_empty_tree' is never read
861
862 if (NULL((void*)0) == sensors_applet->sensors) {
863
864 sensors_applet->sensors = gtk_tree_store_new(N_COLUMNS,
865 G_TYPE_STRING((GType) ((16) << (2))), /* path */
866 G_TYPE_STRING((GType) ((16) << (2))), /* id */
867 G_TYPE_STRING((GType) ((16) << (2))), /* label */
868 G_TYPE_STRING((GType) ((16) << (2))), /* interface */
869 G_TYPE_UINT((GType) ((7) << (2))), /* sensor type */
870 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* enable */
871 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* visible */
872 G_TYPE_DOUBLE((GType) ((15) << (2))), /* low value */
873 G_TYPE_DOUBLE((GType) ((15) << (2))), /* high type */
874 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* alarm enable */
875 G_TYPE_STRING((GType) ((16) << (2))), /* low alarm command */
876 G_TYPE_STRING((GType) ((16) << (2))), /* high alarm command */
877 G_TYPE_UINT((GType) ((7) << (2))), /* alarm timeout */
878 G_TYPE_DOUBLE((GType) ((15) << (2))), /* multiplier */
879 G_TYPE_DOUBLE((GType) ((15) << (2))), /* offset */
880 G_TYPE_UINT((GType) ((7) << (2))), /* icon type */
881 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()), /* icon pixbuf */
882 G_TYPE_STRING((GType) ((16) << (2)))); /* graph color */
883
884 g_debug("Sensor tree created.");
885
886 /* we know tree is actually empty since we just created it */
887 not_empty_tree = FALSE(0);
888 }
889
890 /* search sensor tree for the parent interface to place this sensor under */
891 for (not_empty_tree = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
892 not_empty_tree && not_end_of_interfaces && !interface_exists;
893 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
894
895 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter, INTERFACE_COLUMN, &node_interface, -1);
896 if (g_ascii_strcasecmp(interface, node_interface) == 0) {
897 /* found interface in tree */
898 interface_exists = TRUE(!(0));
899
900 /* now see if this actual sensor already exists within this interface - don't want to add duplicates */
901 /* see if have children */
902 for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
903 not_end_of_sensors;
904 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
905
906 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter,
907 PATH_COLUMN, &sensor_path,
908 ID_COLUMN, &sensor_id,
909 SENSOR_TYPE_COLUMN, &sensor_type,
910 -1);
911 if (g_ascii_strcasecmp(sensor_id, id) == 0 && g_ascii_strcasecmp(sensor_path, path) == 0 && sensor_type == type) {
912 /* sensor already exists so dont add a second time */
913 g_debug("sensor with path: %s, id: %s already exists in tree, not adding a second time", sensor_path, sensor_id);
914 g_free(sensor_id);
915 g_free(sensor_path);
916 g_free(node_interface);
917 return FALSE(0);
918 }
919 g_free(sensor_id);
920 g_free(sensor_path);
921 }
922 g_free(node_interface);
923 break;
924 }
925 g_free(node_interface);
926 }
927
928 if (!interface_exists) {
929 /* add to required plugins hash table so we ensure this
930 plugin stays loaded to make sure we have a get sensor
931 value function if possible */
932 g_hash_table_insert(sensors_applet->required_plugins,
933 g_strdup(interface)g_strdup_inline (interface),
934 GINT_TO_POINTER(TRUE)((gpointer) (glong) ((!(0)))));
935 g_debug("added interface %s to required plugins", interface);
936
937 /* wasn't able to find interface root node so create it */
938 gtk_tree_store_append(sensors_applet->sensors,
939 &interfaces_iter,
940 NULL((void*)0));
941
942 gtk_tree_store_set(sensors_applet->sensors,
943 &interfaces_iter,
944 ID_COLUMN, interface,
945 INTERFACE_COLUMN, interface,
946 VISIBLE_COLUMN, FALSE(0),
947 -1);
948 g_debug("Added sensor interface %s to tree", interface);
949 }
950
951 /* then add sensor as a child under interface node - ie assume
952 * we either found it or created it - the inteface node that is */
953
954 /* for now just add sensors all in a single list */
955 gtk_tree_store_append(sensors_applet->sensors, &sensors_iter, &interfaces_iter);
956
957 /* if sensor is already in settings, load values from there */
958 gchar *applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet);
959 gchar *gsuid = sensors_applet_settings_get_unique_id (interface, id, path);
960 gchar *settings_path = g_strdup_printf ("%s%s/", applet_path, gsuid);
961 GSettings *settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", settings_path);
962
963 /* add hash to temp sorting list */
964 g_variant_builder_add (&gvb_sensors_hash_list, "s", gsuid);
965
966 g_free (applet_path);
967 g_free (gsuid);
968 g_free (settings_path);
969
970 gchar *settings_id = g_settings_get_string (settings, ID"id");
971
972 if (settings_id != NULL((void*)0) && settings_id[0] != '\0') {
973 enable = g_settings_get_boolean (settings, ENABLED"enabled");
974 icon = sensors_applet_load_icon(g_settings_get_int (settings, ICON_TYPE"icon-type"));
975 gtk_tree_store_set(sensors_applet->sensors,
976 &sensors_iter,
977 PATH_COLUMN, g_settings_get_string (settings, PATH"path"),
978 ID_COLUMN, settings_id,
979 LABEL_COLUMN, g_settings_get_string (settings, LABEL"label"),
980 INTERFACE_COLUMN, g_settings_get_string (settings, INTERFACE"interface"),
981 SENSOR_TYPE_COLUMN, g_settings_get_int (settings, SENSOR_TYPE"sensor-type"),
982 ENABLE_COLUMN, enable,
983 VISIBLE_COLUMN, TRUE(!(0)),
984 LOW_VALUE_COLUMN, g_settings_get_double (settings, LOW_VALUE"low-value"),
985 HIGH_VALUE_COLUMN, g_settings_get_double (settings, HIGH_VALUE"high-value"),
986 ALARM_ENABLE_COLUMN, g_settings_get_boolean (settings, ALARM_ENABLED"alarm-enabled"),
987 ALARM_TIMEOUT_COLUMN, g_settings_get_int (settings, ALARM_TIMEOUT"alarm-timeout"),
988 LOW_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, LOW_ALARM_COMMAND"low-alarm-command"),
989 HIGH_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, HIGH_ALARM_COMMAND"high-alarm-command"),
990 MULTIPLIER_COLUMN, g_settings_get_double (settings, MULTIPLIER"multiplier"),
991 OFFSET_COLUMN, g_settings_get_double (settings, OFFSET"offset"),
992 ICON_TYPE_COLUMN, g_settings_get_int (settings, ICON_TYPE"icon-type"),
993 ICON_PIXBUF_COLUMN, icon,
994 GRAPH_COLOR_COLUMN, g_settings_get_string (settings, GRAPH_COLOR"graph-color"),
995 -1);
996 g_free (settings_id);
997 } else {
998 icon = sensors_applet_load_icon(icon_type);
999 gtk_tree_store_set(sensors_applet->sensors,
1000 &sensors_iter,
1001 PATH_COLUMN, path,
1002 ID_COLUMN, id,
1003 LABEL_COLUMN, label,
1004 INTERFACE_COLUMN, interface,
1005 SENSOR_TYPE_COLUMN, type,
1006 ENABLE_COLUMN, enable,
1007 VISIBLE_COLUMN, TRUE(!(0)),
1008 LOW_VALUE_COLUMN, low_value,
1009 HIGH_VALUE_COLUMN, high_value,
1010 ALARM_ENABLE_COLUMN, alarm_enable,
1011 ALARM_TIMEOUT_COLUMN, alarm_timeout,
1012 LOW_ALARM_COMMAND_COLUMN, low_alarm_command,
1013 HIGH_ALARM_COMMAND_COLUMN, high_alarm_command,
1014 MULTIPLIER_COLUMN, multiplier,
1015 OFFSET_COLUMN, offset,
1016 ICON_TYPE_COLUMN, icon_type,
1017 ICON_PIXBUF_COLUMN, icon,
1018 GRAPH_COLOR_COLUMN, graph_color,
1019 -1);
1020 }
1021 g_object_unref (settings);
1022 g_debug("added sensor %s to tree", path);
1023
1024 /* remove reference to icon as tree now has ref */
1025 g_object_unref(icon);
1026
1027 /* create the active sensor */
1028 if (enable) {
1029 tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
1030 sensors_applet_sensor_enabled(sensors_applet, tree_path);
1031 gtk_tree_path_free(tree_path);
1032 }
1033 return TRUE(!(0));
1034}
1035
1036static ActiveSensor *sensors_applet_find_active_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1037 GtkTreePath *sensor_tree_path;
1038 GList *current_sensor;
1039
1040 for (current_sensor = sensors_applet->active_sensors; current_sensor != NULL((void*)0); current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
) {
1041 sensor_tree_path = gtk_tree_row_reference_get_path(((ActiveSensor *)(current_sensor->data))->sensor_row);
1042
1043 if (gtk_tree_path_compare(path, sensor_tree_path) == 0) {
1044 gtk_tree_path_free(sensor_tree_path);
1045 return ((ActiveSensor *)(current_sensor->data));
1046 }
1047 gtk_tree_path_free(sensor_tree_path);
1048 }
1049 return NULL((void*)0);
1050}
1051
1052/* path should be the full path to a file representing the sensor (eg
1053 * /dev/hda or /sys/devices/platform/i2c-0/0-0290/temp1_input) */
1054void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet) {
1055 /* update sensors since will need to update icons / graphs etc
1056 * if weren't displayed before */
1057 GList *list = NULL((void*)0);
1058 for (list = sensors_applet->active_sensors; list != NULL((void*)0); list = list->next) {
1059 ActiveSensor *as = (ActiveSensor *)list->data;
1060 as->updated = FALSE(0);
1061 }
1062 sensors_applet_update_active_sensors(sensors_applet);
1063 sensors_applet_pack_display(sensors_applet);
1064}
1065
1066void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
1067 GtkTreePath *path,
1068 NotifType notif_type) {
1069 ActiveSensor *active_sensor;
1070
1071 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1072 active_sensor_alarm_off(active_sensor, notif_type);
1073 }
1074}
1075
1076void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet, GtkTreePath *path) {
1077 sensors_applet_alarm_off(sensors_applet, path, LOW_ALARM);
1078 sensors_applet_alarm_off(sensors_applet, path, HIGH_ALARM);
1079}
1080
1081void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1082 ActiveSensor *active_sensor;
1083
1084 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_50
; if (sensors_applet) _g_boolean_var_50 = 1; else _g_boolean_var_50
= 0; _g_boolean_var_50; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1084, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1085 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_51
; if (path) _g_boolean_var_51 = 1; else _g_boolean_var_51 = 0
; _g_boolean_var_51; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1085, ((const char*) (__func__
)), "path"); } while (0)
;
1086
1087 active_sensor = active_sensor_new(sensors_applet, gtk_tree_row_reference_new(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), path));
1088 active_sensor_update(active_sensor, sensors_applet);
1089
1090 /* keep list sorted */
1091 sensors_applet->active_sensors = g_list_insert_sorted(sensors_applet->active_sensors,
1092 active_sensor,
1093 (GCompareFunc)active_sensor_compare);
1094
1095 sensors_applet_pack_display(sensors_applet);
1096}
1097
1098void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet) {
1099 sensors_applet->active_sensors = g_list_sort(sensors_applet->active_sensors, (GCompareFunc)active_sensor_compare);
1100
1101 sensors_applet_pack_display(sensors_applet);
1102}
1103
1104void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1105
1106 ActiveSensor *active_sensor;
1107
1108 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_52
; if (sensors_applet) _g_boolean_var_52 = 1; else _g_boolean_var_52
= 0; _g_boolean_var_52; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1108, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1109 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_53
; if (path) _g_boolean_var_53 = 1; else _g_boolean_var_53 = 0
; _g_boolean_var_53; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1109, ((const char*) (__func__
)), "path"); } while (0)
;
1110
1111 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1112 g_debug("Destroying active sensor...");
1113
1114 g_debug("-- removing from list...");
1115 sensors_applet->active_sensors = g_list_remove(sensors_applet->active_sensors, active_sensor);
1116 g_debug("-- repacking display....");
1117 sensors_applet_pack_display(sensors_applet);
1118
1119 active_sensor_destroy(active_sensor);
1120 }
1121}
1122
1123void sensors_applet_update_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1124 ActiveSensor *active_sensor;
1125
1126 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_54
; if (sensors_applet) _g_boolean_var_54 = 1; else _g_boolean_var_54
= 0; _g_boolean_var_54; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1126, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1127 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_55
; if (path) _g_boolean_var_55 = 1; else _g_boolean_var_55 = 0
; _g_boolean_var_55; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1127, ((const char*) (__func__
)), "path"); } while (0)
;
1128
1129 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1130 active_sensor_update(active_sensor, sensors_applet);
1131 }
1132}
1133
1134void sensors_applet_icon_changed(SensorsApplet *sensors_applet, GtkTreePath *path) {
1135 ActiveSensor *active_sensor;
1136
1137 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_56
; if (sensors_applet) _g_boolean_var_56 = 1; else _g_boolean_var_56
= 0; _g_boolean_var_56; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1137, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1138 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_57
; if (path) _g_boolean_var_57 = 1; else _g_boolean_var_57 = 0
; _g_boolean_var_57; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1138, ((const char*) (__func__
)), "path"); } while (0)
;
1139
1140 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1141 active_sensor_icon_changed(active_sensor, sensors_applet);
1142 }
1143}
1144
1145/* Cycle thru ActiveSensors and update them all */
1146gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet) {
1147 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_58
; if (sensors_applet) _g_boolean_var_58 = 1; else _g_boolean_var_58
= 0; _g_boolean_var_58; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1147, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1148
1149 if (sensors_applet->active_sensors) {
1150 g_list_foreach(sensors_applet->active_sensors,
1151 (GFunc)active_sensor_update,
1152 sensors_applet);
1153 return TRUE(!(0));
1154 }
1155 return FALSE(0);
1156}
1157
1158/* Cycle thru ActiveSensors and set new graph dimensions */
1159void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet) {
1160 gint dimensions[2];
1161 gint graph_size;
1162 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_59
; if (sensors_applet) _g_boolean_var_59 = 1; else _g_boolean_var_59
= 0; _g_boolean_var_59; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1162, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1163
1164 if (sensors_applet->active_sensors) {
1165
1166 graph_size = g_settings_get_int (sensors_applet->settings, GRAPH_SIZE"graph-size");
1167 if (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP ||
1168 mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN) {
1169
1170 /* is horizontal so set graph_size as width */
1171 dimensions[0] = graph_size;
1172 dimensions[1] = sensors_applet->size;
1173 } else {
1174 dimensions[0] = sensors_applet->size;
1175 dimensions[1] = graph_size;
1176 }
1177
1178 g_list_foreach(sensors_applet->active_sensors,
1179 (GFunc)active_sensor_update_graph_dimensions,
1180 &dimensions);
1181 }
1182
1183}
1184
1185gdouble sensors_applet_convert_temperature(gdouble value, TemperatureScale old, TemperatureScale new) {
1186
1187 switch (old) {
1188 case KELVIN:
1189 switch (new) {
1190 case CELSIUS:
1191 value = value - 273.0;
1192 break;
1193 case FAHRENHEIT:
1194 value = (9.0 * (value - 273) / 5.0) + 32.0;
1195 break;
1196 case KELVIN:
1197 break;
1198 }
1199 break;
1200
1201 case CELSIUS:
1202 switch (new) {
1203 case FAHRENHEIT:
1204 value = (9.0 * value / 5.0) + 32.0;
1205 break;
1206 case KELVIN:
1207 value = value + 273.0;
1208 break;
1209 case CELSIUS:
1210 break;
1211 }
1212 break;
1213
1214 case FAHRENHEIT:
1215 switch (new) {
1216 case CELSIUS:
1217 value = (5.0 * (value - 32.0) / 9.0);
1218 break;
1219 case KELVIN:
1220 value = (5.0 * (value - 32.0) / 9.0) + 273.0;
1221 break;
1222 case FAHRENHEIT:
1223 break;
1224 }
1225 break;
1226 }
1227 return value;
1228}
1229
1230void sensors_applet_init(SensorsApplet *sensors_applet) {
1231
1232 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_60
; if (sensors_applet) _g_boolean_var_60 = 1; else _g_boolean_var_60
= 0; _g_boolean_var_60; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1232, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1233 g_assert(sensors_applet->applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_61
; if (sensors_applet->applet) _g_boolean_var_61 = 1; else _g_boolean_var_61
= 0; _g_boolean_var_61; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1233, ((const char*) (
__func__)), "sensors_applet->applet"); } while (0)
;
1234
1235 GtkActionGroup *action_group;
1236 gchar *ui_path;
1237
1238 /* Have our background automatically painted. */
1239 mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(sensors_applet->applet), GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1240
1241 /* plugin functions are stored as name -> get_value_function pairs so
1242 * use standard string functions on hash table */
1243 sensors_applet->plugins = g_hash_table_new(g_str_hash, g_str_equal);
1244
1245 sensors_applet->required_plugins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL((void*)0));
1246
1247 /* initialise size */
1248 sensors_applet->size = DEFAULT_APPLET_SIZE24;
1249
1250 mate_panel_applet_set_flags(sensors_applet->applet, MATE_PANEL_APPLET_EXPAND_MINOR);
1251
1252 g_signal_connect(sensors_applet->applet, "destroy",g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1253 G_CALLBACK(destroy_cb),g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1254 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
;
1255
1256 /* init gsettings */
1257 sensors_applet->settings = mate_panel_applet_settings_new (sensors_applet->applet, "org.mate.sensors-applet");
1258
1259 /* set up builder for sorting verification */
1260 g_variant_builder_init (&gvb_sensors_hash_list, G_VARIANT_TYPE ("as")(g_variant_type_checked_ (("as"))));
1261
1262 /* set up / load sensors from the plugins */
1263 sensors_applet_plugins_load_all(sensors_applet);
1264
1265 /* set sorting hash array */
1266 GVariant *gv_temp = g_variant_builder_end (&gvb_sensors_hash_list);
1267 sensors_applet->sensors_hash_array = g_variant_dup_strv (gv_temp, NULL((void*)0));
1268 g_variant_unref (gv_temp);
1269
1270 /* sort sensors based on saved sorting */
1271 sensors_applet_settings_sort_sensors(sensors_applet);
1272
1273 /* free hash array */
1274 g_strfreev (sensors_applet->sensors_hash_array);
1275
1276 /* should have created sensors tree above, but if have not was because we couldn't find any sensors */
1277 if (NULL((void*)0) == sensors_applet->sensors) {
1278 GtkWidget *label;
1279 label = gtk_label_new(_("No sensors found!")dcgettext (((void*)0), "No sensors found!", 5));
1280 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), label);
1281 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1282 return;
1283 }
1284
1285 /* only do menu and signal connections if sensors are found */
1286 action_group = gtk_action_group_new ("Sensors Applet Actions");
1287 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE"mate-sensors-applet");
1288 gtk_action_group_add_actions (action_group,
1289 sensors_applet_menu_actions,
1290 G_N_ELEMENTS (sensors_applet_menu_actions)(sizeof (sensors_applet_menu_actions) / sizeof ((sensors_applet_menu_actions
)[0]))
,
1291 sensors_applet);
1292 ui_path = g_build_filename (UIDIR"/usr/local/share/mate-sensors-applet/ui", SENSORS_APPLET_MENU_FILE"SensorsApplet.xml", NULL((void*)0));
1293 mate_panel_applet_setup_menu_from_file (sensors_applet->applet, ui_path, action_group);
1294 g_free (ui_path);
1295 g_object_unref (action_group);
1296
1297 g_signal_connect(sensors_applet->applet, "style-set",g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1298 G_CALLBACK(style_set_cb),g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1299 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
;
1300
1301 g_signal_connect(G_OBJECT(sensors_applet->applet), "change_orient",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1302 G_CALLBACK(change_orient_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1303 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1304
1305 g_signal_connect(G_OBJECT(sensors_applet->applet), "size_allocate",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1306 G_CALLBACK(size_allocate_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1307 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1308
1309 g_signal_connect(G_OBJECT(sensors_applet->applet), "leave_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1310 G_CALLBACK(mouse_leave_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1311 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1312
1313 g_signal_connect(G_OBJECT(sensors_applet->applet), "enter_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1314 G_CALLBACK(mouse_enter_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1315 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1316
1317 sensors_applet_update_active_sensors(sensors_applet);
1318 sensors_applet_pack_display(sensors_applet);
1319
1320 sensors_applet->timeout_id = g_timeout_add_seconds(g_settings_get_int(sensors_applet->settings, TIMEOUT"timeout-delay") / 1000,
1321 (GSourceFunc)sensors_applet_update_active_sensors,
1322 sensors_applet);
1323 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1324}
1325
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-699f6d.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-699f6d.html new file mode 100644 index 0000000..ac53105 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-699f6d.html @@ -0,0 +1,2005 @@ + + + +sensors-applet.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:sensors-applet/sensors-applet.c
Warning:line 887, column 9
Value stored to 'not_empty_tree' 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 sensors-applet.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=none -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/sensors-applet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D UIDIR="/usr/local/share/mate-sensors-applet/ui" -D SENSORS_APPLET_PLUGIN_DIR="/usr/local/lib/mate-sensors-applet/plugins" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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/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 -I /usr/include/mate-panel-4.0/libmate-panel-applet -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 /usr/include/cairo -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libxml2 -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -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 -O2 -Wno-unused-parameter -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/sensors-applet -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c sensors-applet.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/** Contain the functions for operating on the SensorsApplet structure
21 * (represents the applet itself, and its associated variables.
22 */
23
24#ifdef HAVE_CONFIG_H1
25#include "config.h"
26#endif /* HAVE_CONFIG_H */
27
28#ifdef HAVE_UNISTD_H1
29#include <unistd.h>
30#endif /* HAVE_UNISTD_H */
31
32#include <glib/gi18n.h>
33#include <glib/gprintf.h>
34#include <gio/gio.h>
35#include "sensors-applet.h"
36#include "active-sensor.h"
37#include "sensors-applet-settings.h"
38#include "sensors-applet-plugins.h"
39
40#ifdef HAVE_LIBNOTIFY1
41#include "active-sensor-libnotify.h"
42#define DEFAULT_NOTIFY_TIMEOUT3000 3000
43#endif
44
45#include "prefs-dialog.h"
46#include "about-dialog.h"
47
48#define SENSORS_APPLET_MENU_FILE"SensorsApplet.xml" "SensorsApplet.xml"
49/* initially set as sensors_applet->size to ensure a real value is stored */
50#define DEFAULT_APPLET_SIZE24 24
51#define COLUMN_SPACING2 2
52#define ROW_SPACING1 1
53
54/* builder for sensor sorting verification */
55static GVariantBuilder gvb_sensors_hash_list;
56
57/* callbacks for panel menu */
58static void prefs_cb(GtkAction *action, gpointer *data) {
59
60 SensorsApplet *sensors_applet;
61 sensors_applet = (SensorsApplet *)data;
62
63 if (sensors_applet->prefs_dialog) {
64 gtk_window_present(GTK_WINDOW(sensors_applet->prefs_dialog->dialog)((((GtkWindow*) (void *) ((sensors_applet->prefs_dialog->
dialog)))))
);
65 return;
66 }
67 prefs_dialog_open(sensors_applet);
68}
69
70static void about_cb(GtkAction *action, gpointer data) {
71 SensorsApplet *sensors_applet;
72 sensors_applet = (SensorsApplet *)data;
73
74 about_dialog_open(sensors_applet);
75}
76
77static void help_cb(GtkAction *action, gpointer data) {
78
79 GError *error = NULL((void*)0);
80
81 gtk_show_uri_on_window(NULL((void*)0), "help:mate-sensors-applet",
82
83 gtk_get_current_event_time(),
84 &error);
85
86 if (error) {
87 g_debug("Could not open help document: %s ",error->message);
88 g_error_free(error);
89 }
90}
91
92static void destroy_cb(GtkWidget *widget, gpointer data) {
93 SensorsApplet *sensors_applet;
94 sensors_applet = (SensorsApplet *)data;
95
96 /* destroy dialogs, remove timeout and clear sensors tree and finally the applet */
97 if (sensors_applet->prefs_dialog != NULL((void*)0)) {
98 /* destroy's dialog too */
99 prefs_dialog_close(sensors_applet);
100 }
101
102 if (sensors_applet->timeout_id) {
103 g_source_remove(sensors_applet->timeout_id);
104 }
105
106 if (sensors_applet->settings) {
107 g_object_unref (sensors_applet->settings);
108 sensors_applet->settings = NULL((void*)0);
109 }
110
111 /* destroy all active sensors */
112 g_list_foreach(sensors_applet->active_sensors,
113 (GFunc)active_sensor_destroy,
114 NULL((void*)0));
115
116 if (sensors_applet->sensors != NULL((void*)0)) {
117 gtk_tree_store_clear(sensors_applet->sensors);
118 }
119
120 gtk_widget_destroy(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
121
122 g_free(sensors_applet);
123 return;
124}
125
126static void change_orient_cb (MatePanelApplet *applet,
127 MatePanelAppletOrient orient,
128 gpointer data) {
129
130 SensorsApplet *sensors_applet;
131 sensors_applet = (SensorsApplet *)data;
132
133 sensors_applet_display_layout_changed(sensors_applet);
134}
135
136static void size_allocate_cb(MatePanelApplet *applet,
137 GtkAllocation *allocation,
138 gpointer data) {
139
140 SensorsApplet *sensors_applet;
141 MatePanelAppletOrient orient;
142
143 sensors_applet = (SensorsApplet *)data;
144 orient = mate_panel_applet_get_orient(sensors_applet->applet);
145
146 if ((orient == MATE_PANEL_APPLET_ORIENT_LEFT) ||
147 (orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
148
149 if (sensors_applet->size == allocation->width)
150 return;
151 sensors_applet->size = allocation->width;
152 } else {
153 if (sensors_applet->size == allocation->height)
154 return;
155 sensors_applet->size = allocation->height;
156 }
157
158 /* update if new value */
159 sensors_applet_graph_size_changed(sensors_applet);
160 sensors_applet_display_layout_changed(sensors_applet);
161}
162
163static void style_set_cb(GtkWidget *widget, GtkStyle *old_style, gpointer data) {
164
165 /* update all icons in the sensors tree and update all active sensors */
166 GtkTreeIter interfaces_iter, sensors_iter;
167 gboolean not_end_of_interfaces = TRUE(!(0)), not_end_of_sensors = TRUE(!(0));
168 IconType icon_type;
169 gboolean enabled;
170 SensorsApplet *sensors_applet;
171 DisplayMode display_mode;
172
173 sensors_applet = (SensorsApplet *)data;
174
175 display_mode = g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
176 if (sensors_applet->sensors) {
177 for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
178 not_end_of_interfaces;
179 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
180
181 /* reset sensors sentinel */
182 not_end_of_sensors = TRUE(!(0));
183
184 for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
185 not_end_of_sensors;
186 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
187
188 GdkPixbuf *new_icon;
189
190 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))),
191 &sensors_iter,
192 ENABLE_COLUMN, &enabled,
193 ICON_TYPE_COLUMN, &icon_type,
194 -1);
195 /* update icons */
196 new_icon = sensors_applet_load_icon(icon_type);
197
198 gtk_tree_store_set(sensors_applet->sensors,
199 &sensors_iter,
200 ICON_PIXBUF_COLUMN, new_icon,
201 -1);
202 g_object_unref(new_icon);
203
204 /* update icons only if currently being displayed */
205 if (enabled &&
206 (display_mode == DISPLAY_ICON ||
207 display_mode == DISPLAY_ICON_WITH_VALUE)) {
208
209 GtkTreePath *path;
210
211 path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
212 sensors_applet_icon_changed(sensors_applet, path);
213 gtk_tree_path_free(path);
214 }
215 }
216 }
217 /* now update layout as size may have changed */
218 sensors_applet_display_layout_changed(sensors_applet);
219 }
220
221}
222
223static gboolean mouse_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
224{
225 SensorsApplet *sensor_applet = data;
226 sensor_applet->show_tooltip = TRUE(!(0));
227 sensors_applet_update_active_sensors(sensor_applet);
228 return TRUE(!(0));
229}
230
231static gboolean mouse_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
232{
233 SensorsApplet *sensor_applet = data;
234 sensor_applet->show_tooltip = FALSE(0);
235 return TRUE(!(0));
236}
237
238static const GtkActionEntry sensors_applet_menu_actions[] = {
239 { "Preferences", "document-properties", N_("_Preferences")("_Preferences"),
240 NULL((void*)0), NULL((void*)0),
241 G_CALLBACK(prefs_cb)((GCallback) (prefs_cb)) },
242 { "Help", "help-browser", N_("_Help")("_Help"),
243 NULL((void*)0), NULL((void*)0),
244 G_CALLBACK(help_cb)((GCallback) (help_cb)) },
245 { "About", "help-about", N_("_About")("_About"),
246 NULL((void*)0), NULL((void*)0),
247 G_CALLBACK(about_cb)((GCallback) (about_cb)) }
248};
249
250void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type) {
251#ifdef HAVE_LIBNOTIFY1
252
253 SensorsApplet *sensors_applet;
254 gchar *summary, *message;
255 gint timeout_msecs;
256 gchar *sensor_label;
257 gchar *sensor_path;
258 SensorType sensor_type;
259 TemperatureScale temp_scale;
260 GtkTreeIter iter;
261 GtkTreePath *path;
262 const gchar *unit_type = NULL((void*)0);
263 const gchar *unit_type_title = NULL((void*)0);
264 const gchar *relation = NULL((void*)0);
265 const gchar *limit_type = NULL((void*)0);
266 const gchar *units = NULL((void*)0);
267 gdouble limit_value;
268 gdouble seconds;
269 gboolean show_notification = TRUE(!(0));
270
271 sensors_applet = active_sensor->sensors_applet;
272
273 if (!g_settings_get_boolean (sensors_applet->settings, DISPLAY_NOTIFICATIONS"display-notifications")) {
274 g_debug("Wanted to display notification, but user has disabled them");
275 return;
276 }
277
278 path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
279 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter, path)) {
280
281 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter,
282 LABEL_COLUMN, &sensor_label,
283 PATH_COLUMN, &sensor_path,
284 SENSOR_TYPE_COLUMN, &sensor_type,
285 -1);
286 } else {
287 g_warning("Error getting data from tree for notification...");
288 gtk_tree_path_free(path);
289 return;
290 }
291
292 gtk_tree_path_free(path);
293
294 /* do different stuff for different notif types */
295 switch (notif_type) {
296 case LOW_ALARM: /* fall thru */
297 case HIGH_ALARM:
298 if (active_sensor->sensor_values[0] <= active_sensor->sensor_low_value && notif_type == LOW_ALARM) {
299
300 relation = _("is very low")dcgettext (((void*)0), "is very low", 5);
301 limit_type = _("lower limit")dcgettext (((void*)0), "lower limit", 5);
302 limit_value = active_sensor->sensor_low_value;
303 } else if (active_sensor->sensor_values[0] >= active_sensor->sensor_high_value && notif_type == HIGH_ALARM) {
304
305 /* assume high alarm condition */
306 relation = _("is very high")dcgettext (((void*)0), "is very high", 5);
307 limit_type = _("upper limit")dcgettext (((void*)0), "upper limit", 5);
308 limit_value = active_sensor->sensor_high_value;
309 } else {
310 g_warning("Alarm notify called when no alarm condition!");
311 g_free(sensor_path);
312 g_free(sensor_label);
313 return;
314 }
315
316 switch ((SensorType)sensor_type) {
317 case TEMP_SENSOR:
318 unit_type_title = _("Temperature")dcgettext (((void*)0), "Temperature", 5);
319 unit_type = _("temperature")dcgettext (((void*)0), "temperature", 5);
320 temp_scale = (TemperatureScale) g_settings_get_int (active_sensor->sensors_applet->settings, TEMPERATURE_SCALE"temperature-scale");
321
322 switch (temp_scale) {
323 case CELSIUS:
324 units = UNITS_CELSIUS"\302\260C";
325 break;
326 case FAHRENHEIT:
327 units = UNITS_FAHRENHEIT"\302\260F";
328 break;
329 case KELVIN:
330 units = UNITS_KELVIN"";
331 break;
332 default:
333 units = NULL((void*)0);
334 }
335 break;
336
337 case VOLTAGE_SENSOR:
338 unit_type_title = _("Voltage")dcgettext (((void*)0), "Voltage", 5);
339 unit_type = _("voltage")dcgettext (((void*)0), "voltage", 5);
340 units = UNITS_VOLTAGEdcgettext (((void*)0), "V", 5);
341 break;
342
343 case FAN_SENSOR:
344 unit_type_title = _("Fan Speed")dcgettext (((void*)0), "Fan Speed", 5);
345 unit_type = _("fan speed")dcgettext (((void*)0), "fan speed", 5);
346 units = UNITS_RPMdcgettext (((void*)0), "RPM", 5);
347 break;
348
349 case CURRENT_SENSOR:
350 unit_type_title = _("Current")dcgettext (((void*)0), "Current", 5);
351 unit_type = _("current")dcgettext (((void*)0), "current", 5);
352 units = UNITS_CURRENTdcgettext (((void*)0), "A", 5);
353 break;
354 }
355
356 timeout_msecs = (active_sensor->alarm_timeout ? MIN(DEFAULT_NOTIFY_TIMEOUT, (active_sensor->alarm_timeout * 1000))(((3000) < ((active_sensor->alarm_timeout * 1000))) ? (
3000) : ((active_sensor->alarm_timeout * 1000)))
: DEFAULT_NOTIFY_TIMEOUT3000);
357
358 summary = g_strdup_printf("%s %s %s", sensor_label, unit_type_title, _("Alarm")dcgettext (((void*)0), "Alarm", 5));
359 message = g_strdup_printf("%s %s %s (%s %2.0f%s)", sensor_label, unit_type, relation, limit_type, limit_value, units);
360 break;
361
362 case SENSOR_INTERFACE_ERROR:
363 /* get time since the last error */
364 seconds = difftime(time(NULL((void*)0)), active_sensor->ierror_ts);
365
366 /* if the last error happened less than 10 seconds ago, don't display this one
367 * this should prevent recurring popups for removed sensors, like USB-HDDs */
368 if (seconds < 11.0) {
369 show_notification = FALSE(0);
370 }
371
372 summary = g_strdup_printf(_("Error updating sensor %s")dcgettext (((void*)0), "Error updating sensor %s", 5), sensor_label);
373 message = g_strdup_printf(_("An error occurred while trying to update the value of the sensor %s located at %s.")dcgettext (((void*)0), "An error occurred while trying to update the value of the sensor %s located at %s."
, 5)
, sensor_label, sensor_path);
374 timeout_msecs = g_settings_get_int (active_sensor->sensors_applet->settings, TIMEOUT"timeout-delay");
375
376 /* update timestamp */
377 time(&(active_sensor->ierror_ts));
378 break;
379
380 default:
381 g_assert_not_reached()do { g_assertion_message_expr ("sensors-applet", "sensors-applet.c"
, 381, ((const char*) (__func__)), ((void*)0)); } while (0)
;
382 }
383
384 if (show_notification) {
385 active_sensor_libnotify_notify(active_sensor,
386 notif_type,
387 summary,
388 message,
389 "dialog-warning",
390 timeout_msecs);
391 }
392
393 g_free(sensor_path);
394 g_free(sensor_label);
395 g_free(summary);
396 g_free(message);
397#endif
398}
399
400void sensors_applet_notify_end(ActiveSensor *active_sensor, NotifType notif_type) {
401#ifdef HAVE_LIBNOTIFY1
402 active_sensor_libnotify_notify_end(active_sensor, notif_type);
403#endif
404}
405
406#ifdef HAVE_LIBNOTIFY1
407static void sensors_applet_notify_end_all_gfunc(ActiveSensor *active_sensor, gpointer data) {
408 active_sensor_libnotify_notify_end(active_sensor, LOW_ALARM);
409 active_sensor_libnotify_notify_end(active_sensor, HIGH_ALARM);
410}
411#endif
412
413void sensors_applet_notify_end_all(SensorsApplet *sensors_applet) {
414#ifdef HAVE_LIBNOTIFY1
415 g_list_foreach(sensors_applet->active_sensors, (GFunc)sensors_applet_notify_end_all_gfunc, NULL((void*)0));
416#endif
417}
418
419/* internal helper functions for updating display etc */
420
421/* should be called as a g_container_foreach at the start of
422 * pack_display if the grid already exists to remove but keep alive
423 * all children of the grid before repacking it */
424static void sensors_applet_pack_display_empty_grid_cb(GtkWidget *widget, gpointer data)
425{
426 GtkContainer *container;
427
428 container = GTK_CONTAINER(data)((((GtkContainer*) (void *) ((data)))));
429
430 /* ref then remove widget */
431 g_object_ref(widget)((__typeof__ (widget)) (g_object_ref) (widget));
432 gtk_container_remove(container, widget);
433}
434
435/* should be called as a g_container_foreach at the end of
436 * pack_display to unref any of the old children that we have readdded
437 * to the table to stop reference creep from the g_object_ref called
438 * on each child at the start of pack labels */
439static void sensors_applet_pack_display_cleanup_refs_cb(GtkWidget *widget, gpointer data) {
440
441 GList *old_children;
442
443 old_children = (GList *)data;
444 if (g_list_find(old_children, widget)) {
445 g_object_unref(widget);
446 }
447}
448
449static void sensors_applet_pack_display(SensorsApplet *sensors_applet) {
450 /* note the if () around each widget is to ensure we only
451 * operate on those that actually exist */
452 GtkLabel *no_sensors_enabled_label = NULL((void*)0);
453 gint num_active_sensors = 0, num_sensors_per_group = 0, rows, cols, i, j;
454 GList *old_grid_children = NULL((void*)0);
455
456 GList *current_sensor;
457
458 DisplayMode display_mode;
459 LayoutMode layout_mode;
460
461 gboolean horizontal;
462 gint label_width, icon_width, value_width;
463 gint label_height, icon_height, value_height;
464
465 GtkRequisition req;
466
467 ActiveSensor *first_sensor;
468
469 /* it is possible that there could be no active sensors so
470 * handle that case first - make sure we dont do a NULL
471 * pointer access first though */
472 if (sensors_applet->active_sensors == NULL((void*)0) || g_list_length(sensors_applet->active_sensors) == 0) {
473 g_debug("no active sensors to pack in grid");
474 no_sensors_enabled_label = g_object_new(GTK_TYPE_LABEL(gtk_label_get_type ()), "label", _("No sensors enabled!")dcgettext (((void*)0), "No sensors enabled!", 5), NULL((void*)0));
475
476 if (sensors_applet->grid == NULL((void*)0)) {
477 /* only need 1 row and 1 col */
478 sensors_applet->grid = gtk_grid_new();
479 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
480 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
481 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
482 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
483 /* add grid to applet */
484 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
485 } else {
486 /* destroy existing widgets - could be an
487 * existing version of no sensors label - okay
488 * to just add again though if destroy first */
489 g_debug("destroying any existing widgets in container");
490 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))), (GtkCallback)gtk_widget_destroy, NULL((void*)0));
491 }
492 g_debug("packing no sensors enabled label");
493 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
494 GTK_WIDGET(no_sensors_enabled_label)((((GtkWidget*) (void *) ((no_sensors_enabled_label))))),
495 0, 0, 1, 1);
496 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
497 return;
498 }
499 /* otherwise can acess active_sensors without any worries */
500 num_active_sensors = g_list_length(sensors_applet->active_sensors);
501
502 display_mode = (DisplayMode) g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
503 layout_mode = (LayoutMode) g_settings_get_int (sensors_applet->settings, LAYOUT_MODE"layout-mode");
504
505 horizontal = (((mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP) ||
506 (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN)));
507
508 /* figure out num rows / cols by how high / wide sensors
509 * labels / icons are and how much size we have to put them in */
510
511 /* get the first active sensor */
512 first_sensor = (ActiveSensor *)sensors_applet->active_sensors->data;
513
514 switch (display_mode) {
515 case DISPLAY_VALUE:
516 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
517 value_width = req.width + COLUMN_SPACING2;
518 value_height = req.height + ROW_SPACING1;
519
520 /* make sure all widths and heights are non zero,
521 * otherwise will get a divide by zero exception below
522 * - is a non critical error since can happen when
523 * elements first added to list, so simply return - is
524 * not a programming error */
525 if (value_width == 0 && value_height == 0) {
526 return;
527 }
528
529 num_sensors_per_group = (sensors_applet->size / (horizontal ? value_height : value_width));
530 break;
531
532 case DISPLAY_LABEL_WITH_VALUE:
533 /* even though we end up packing the event boxes into the
534 * panel, these dont give back request sizes, so need to ask
535 * widgets directly */
536 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
537
538 value_width = req.width + COLUMN_SPACING2;
539 value_height = req.height + ROW_SPACING1;
540
541 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->label)((((GtkWidget*) (void *) ((first_sensor->label))))), &req, NULL((void*)0));
542 label_width = req.width + COLUMN_SPACING2;
543 label_height = req.height + ROW_SPACING1;
544
545 /* make sure all widths and heights are non zero, otherwise
546 * will get a divide by zero exception below
547 * - is a non critical error since can happen when
548 * elements first added to list, so simply return - is
549 * not a programming error */
550 if (!(label_width && label_height && value_width && value_height)) {
551 return;
552 }
553
554 switch (layout_mode) {
555 case VALUE_BESIDE_LABEL:
556 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(label_height, value_height)(((label_height) > (value_height)) ? (label_height) : (value_height
))
: (label_width + value_width)));
557 break;
558 case VALUE_BELOW_LABEL:
559 num_sensors_per_group = (sensors_applet->size / (horizontal ? (label_height + value_height) : MAX(label_width, value_width)(((label_width) > (value_width)) ? (label_width) : (value_width
))
));
560 break;
561 }
562 break;
563
564 case DISPLAY_ICON_WITH_VALUE:
565 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
566 value_width = req.width + COLUMN_SPACING2;
567 value_height = req.height + ROW_SPACING1;
568
569 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
570 icon_width = req.width + COLUMN_SPACING2;
571 icon_height = req.height + ROW_SPACING1;
572
573 if (!(icon_width && icon_height && value_width && value_height)) {
574 return;
575 }
576
577 switch (layout_mode) {
578 case VALUE_BESIDE_LABEL:
579 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(icon_height, value_height)(((icon_height) > (value_height)) ? (icon_height) : (value_height
))
: (icon_width + value_width)));
580 break;
581
582 case VALUE_BELOW_LABEL:
583 num_sensors_per_group = (sensors_applet->size / (horizontal ? (icon_height + value_height) : MAX(icon_width, value_width)(((icon_width) > (value_width)) ? (icon_width) : (value_width
))
));
584 break;
585 }
586 break;
587
588 case DISPLAY_ICON:
589 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
590 icon_width = req.width + COLUMN_SPACING2;
591 icon_height = req.height + ROW_SPACING1;
592
593 if (!(icon_width && icon_height)) {
594 return;
595 }
596
597 num_sensors_per_group = (sensors_applet->size / (horizontal ? icon_height : icon_width));
598 break;
599
600 case DISPLAY_GRAPH:
601 /* only show graphs in a line like System Monitor applet */
602 num_sensors_per_group = 1;
603 break;
604 }
605
606 /* ensure always atleast 1 sensor per group */
607 if (num_sensors_per_group < 1) {
608 /* force a better layout */
609 if (horizontal && layout_mode == VALUE_BELOW_LABEL) {
610 layout_mode = VALUE_BESIDE_LABEL;
611 } else if (!horizontal && layout_mode == VALUE_BESIDE_LABEL) {
612 layout_mode = VALUE_BELOW_LABEL;
613 }
614 num_sensors_per_group = 1;
615 }
616
617 if (horizontal) {
618 /* if oriented horizontally, want as many
619 sensors per column as user has defined, then
620 enough columns to hold all the widgets */
621 rows = num_sensors_per_group;
622 cols = num_active_sensors / num_sensors_per_group;
623 while (rows * cols < num_active_sensors || cols == 0) {
624 cols++;
625 }
626
627 } else {
628 /* if oriented vertically, want as many
629 sensors per row as user has defined, then
630 enough rows to hold all the widgets*/
631 cols = num_sensors_per_group;
632 rows = num_active_sensors / num_sensors_per_group;
633 while (rows * cols < num_active_sensors || rows == 0) {
634 rows++;
635 }
636
637 }
638
639 /* if displaying labels / icons and values need to modify
640 number of rows / colums to accomodate this */
641 if (display_mode == DISPLAY_LABEL_WITH_VALUE || display_mode == DISPLAY_ICON_WITH_VALUE) {
642 if (layout_mode == VALUE_BESIDE_LABEL) {
643 /* to display labels next to values need twice as many columns */
644 cols *= 2;
645 } else {
646 /* to display labels above values, we need twice as many rows as without */
647 rows *= 2;
648 }
649 }
650
651 if (sensors_applet->grid == NULL((void*)0)) {
652 /* create grid and add to applet */
653 sensors_applet->grid = gtk_grid_new();
654 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
655 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
656 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
657 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
658 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
659 } else {
660 /* remove all children if grid already exists so we can start again */
661 /* save a list of the old children for later */
662 old_grid_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))));
663
664 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
665 sensors_applet_pack_display_empty_grid_cb,
666 sensors_applet->grid);
667 }
668 /* pack icons / labels and values into grid */
669 current_sensor = sensors_applet->active_sensors;
670
671 /* if showing labels / icons and values, need to pack labels / icons these first */
672 if (display_mode == DISPLAY_ICON_WITH_VALUE || display_mode == DISPLAY_LABEL_WITH_VALUE) {
673 /* loop through columns */
674 for (i = 0; current_sensor != NULL((void*)0) && i < cols; /* increments depends on how we lay them out - see below */) {
675
676 /* loop through rows in a column */
677 for (j = 0; current_sensor && j < rows; /* see bottom of for loop*/) {
678 /* attach label / icon at this point */
679 if (display_mode == DISPLAY_ICON_WITH_VALUE) {
680 if (((ActiveSensor *)(current_sensor->data))->icon) {
681 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
682 ((ActiveSensor *)(current_sensor->data))->icon,
683 i, j, 1, 1);
684 }
685 } else {
686 if (((ActiveSensor *)(current_sensor->data))->label) {
687 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
688 ((ActiveSensor *)(current_sensor->data))->label,
689 i, j, 1, 1);
690 }
691 }
692 /* now attach sensor value to either row below or column next to */
693 if (layout_mode == VALUE_BESIDE_LABEL) {
694 /* left align labels */
695 if (((ActiveSensor *)(current_sensor->data))->icon) {
696 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_START);
697 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
698 }
699 if (((ActiveSensor *)(current_sensor->data))->label) {
700 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0);
701 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
702 }
703 if (((ActiveSensor *)(current_sensor->data))->value) {
704 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_START);
705 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
706 }
707
708 /* place value next to label */
709 if (((ActiveSensor *)(current_sensor->data))->value) {
710 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
711 ((ActiveSensor *)(current_sensor->data))->value,
712 i + 1, j, 1, 1);
713 }
714 j++;
715 } else { /* place value below label */
716
717 /* center align labels */
718 if (((ActiveSensor *)(current_sensor->data))->icon) {
719 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
720 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
721 }
722 if (((ActiveSensor *)(current_sensor->data))->label) {
723 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
724 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
725 }
726 if (((ActiveSensor *)(current_sensor->data))->value) {
727 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
728 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
729 }
730
731 if (((ActiveSensor *)(current_sensor->data))->value) {
732 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
733 ((ActiveSensor *)(current_sensor->data))->value,
734 i, j + 1, 1, 1);
735 }
736 j += 2;
737 }
738 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
739 } /* end row loop */
740
741 /* now increment column index as needed */
742 if (layout_mode == VALUE_BESIDE_LABEL) { /* place value next to label */
743 i += 2;
744 } else {
745 i++;
746 }
747 } /* end column loop */
748
749 } else { /* not showing labels and icons with values, so just pack either only icons or values */
750 for (i = 0; current_sensor != NULL((void*)0) && i < cols; ++i) {
751 for (j = 0; current_sensor!= NULL((void*)0) && j < rows; ++j) {
752 if (display_mode == DISPLAY_VALUE) {
753 if (((ActiveSensor *)(current_sensor->data))->value) {
754 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
755 ((ActiveSensor *)(current_sensor->data))->value,
756 i, j, 1, 1);
757 }
758 } else if (display_mode == DISPLAY_ICON) {
759 if (((ActiveSensor *)(current_sensor->data))->value) {
760 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
761 ((ActiveSensor *)(current_sensor->data))->icon,
762 i, j, 1, 1);
763 }
764 } else if (display_mode == DISPLAY_GRAPH) {
765 if (((ActiveSensor *)(current_sensor->data))->graph) {
766 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
767 ((ActiveSensor *)(current_sensor->data))->graph_frame,
768 i, j, 1, 1);
769 }
770 }
771
772 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
773 }
774 }
775 }
776
777 if (old_grid_children != NULL((void*)0)) {
778 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
779 sensors_applet_pack_display_cleanup_refs_cb,
780 old_grid_children);
781 g_list_free(old_grid_children);
782 }
783 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
784
785}
786
787/* must unref when done with returned pixbuf */
788GdkPixbuf *sensors_applet_load_icon(IconType icon_type) {
789 GtkIconTheme *icon_theme;
790 GdkPixbuf *icon = NULL((void*)0);
791 GError *error = NULL((void*)0);
792
793 /* try to load the icon */
794
795 /* not allowed to unref or ref icon_theme once we have it */
796 icon_theme = gtk_icon_theme_get_default();
797 icon = gtk_icon_theme_load_icon(icon_theme,
798 stock_icons[icon_type],
799 DEFAULT_ICON_SIZE22,
800 GTK_ICON_LOOKUP_USE_BUILTIN,
801 &error);
802
803 if (error) {
804 g_warning ("Could not load icon: %s", error->message);
805 g_error_free(error);
806 error = NULL((void*)0);
807
808 /* try again with default icon */
809 icon = gtk_icon_theme_load_icon(icon_theme,
810 "image-missing",
811 DEFAULT_ICON_SIZE22,
812 GTK_ICON_LOOKUP_USE_BUILTIN,
813 &error);
814
815 if (error) {
816 /* this will quit sensors-applet but it is a pretty major error so may as well */
817 g_error("Could not load GTK_STOCK_MISSING_IMAGE - major error!!!: %s", error->message);
818 g_error_free(error);
819 error = NULL((void*)0);
820 }
821
822 }
823 return icon;
824}
825
826// MUST FREE STRINGS AFTER CALLING THIS FUNCTION!!
827gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet,
828 const gchar *path,
829 const gchar *id,
830 const gchar *label,
831 const gchar *interface,
832 SensorType type,
833 gboolean enable,
834 gdouble low_value,
835 gdouble high_value,
836 gboolean alarm_enable,
837 const gchar *low_alarm_command,
838 const gchar *high_alarm_command,
839 gint alarm_timeout,
840 gdouble multiplier,
841 gdouble offset,
842 IconType icon_type,
843 const gchar *graph_color) {
844
845 GtkTreeIter interfaces_iter, sensors_iter;
846 gboolean not_empty_tree;
847
848 gchar *node_interface;
849 gboolean not_end_of_interfaces = TRUE(!(0)), interface_exists = FALSE(0);
850 gboolean not_end_of_sensors = TRUE(!(0));
851 gchar *sensor_id;
852 gchar *sensor_path;
853 SensorType sensor_type;
854 GdkPixbuf *icon;
855 GtkTreePath *tree_path;
856
857 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_62
; if (sensors_applet) _g_boolean_var_62 = 1; else _g_boolean_var_62
= 0; _g_boolean_var_62; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 857, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
858
859 /* assume tree is not empty */
860 not_empty_tree = TRUE(!(0));
861
862 if (NULL((void*)0) == sensors_applet->sensors) {
863
864 sensors_applet->sensors = gtk_tree_store_new(N_COLUMNS,
865 G_TYPE_STRING((GType) ((16) << (2))), /* path */
866 G_TYPE_STRING((GType) ((16) << (2))), /* id */
867 G_TYPE_STRING((GType) ((16) << (2))), /* label */
868 G_TYPE_STRING((GType) ((16) << (2))), /* interface */
869 G_TYPE_UINT((GType) ((7) << (2))), /* sensor type */
870 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* enable */
871 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* visible */
872 G_TYPE_DOUBLE((GType) ((15) << (2))), /* low value */
873 G_TYPE_DOUBLE((GType) ((15) << (2))), /* high type */
874 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* alarm enable */
875 G_TYPE_STRING((GType) ((16) << (2))), /* low alarm command */
876 G_TYPE_STRING((GType) ((16) << (2))), /* high alarm command */
877 G_TYPE_UINT((GType) ((7) << (2))), /* alarm timeout */
878 G_TYPE_DOUBLE((GType) ((15) << (2))), /* multiplier */
879 G_TYPE_DOUBLE((GType) ((15) << (2))), /* offset */
880 G_TYPE_UINT((GType) ((7) << (2))), /* icon type */
881 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()), /* icon pixbuf */
882 G_TYPE_STRING((GType) ((16) << (2)))); /* graph color */
883
884 g_debug("Sensor tree created.");
885
886 /* we know tree is actually empty since we just created it */
887 not_empty_tree = FALSE(0);
Value stored to 'not_empty_tree' is never read
888 }
889
890 /* search sensor tree for the parent interface to place this sensor under */
891 for (not_empty_tree = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
892 not_empty_tree && not_end_of_interfaces && !interface_exists;
893 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
894
895 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter, INTERFACE_COLUMN, &node_interface, -1);
896 if (g_ascii_strcasecmp(interface, node_interface) == 0) {
897 /* found interface in tree */
898 interface_exists = TRUE(!(0));
899
900 /* now see if this actual sensor already exists within this interface - don't want to add duplicates */
901 /* see if have children */
902 for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
903 not_end_of_sensors;
904 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
905
906 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter,
907 PATH_COLUMN, &sensor_path,
908 ID_COLUMN, &sensor_id,
909 SENSOR_TYPE_COLUMN, &sensor_type,
910 -1);
911 if (g_ascii_strcasecmp(sensor_id, id) == 0 && g_ascii_strcasecmp(sensor_path, path) == 0 && sensor_type == type) {
912 /* sensor already exists so dont add a second time */
913 g_debug("sensor with path: %s, id: %s already exists in tree, not adding a second time", sensor_path, sensor_id);
914 g_free(sensor_id);
915 g_free(sensor_path);
916 g_free(node_interface);
917 return FALSE(0);
918 }
919 g_free(sensor_id);
920 g_free(sensor_path);
921 }
922 g_free(node_interface);
923 break;
924 }
925 g_free(node_interface);
926 }
927
928 if (!interface_exists) {
929 /* add to required plugins hash table so we ensure this
930 plugin stays loaded to make sure we have a get sensor
931 value function if possible */
932 g_hash_table_insert(sensors_applet->required_plugins,
933 g_strdup(interface)g_strdup_inline (interface),
934 GINT_TO_POINTER(TRUE)((gpointer) (glong) ((!(0)))));
935 g_debug("added interface %s to required plugins", interface);
936
937 /* wasn't able to find interface root node so create it */
938 gtk_tree_store_append(sensors_applet->sensors,
939 &interfaces_iter,
940 NULL((void*)0));
941
942 gtk_tree_store_set(sensors_applet->sensors,
943 &interfaces_iter,
944 ID_COLUMN, interface,
945 INTERFACE_COLUMN, interface,
946 VISIBLE_COLUMN, FALSE(0),
947 -1);
948 g_debug("Added sensor interface %s to tree", interface);
949 }
950
951 /* then add sensor as a child under interface node - ie assume
952 * we either found it or created it - the inteface node that is */
953
954 /* for now just add sensors all in a single list */
955 gtk_tree_store_append(sensors_applet->sensors, &sensors_iter, &interfaces_iter);
956
957 /* if sensor is already in settings, load values from there */
958 gchar *applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet);
959 gchar *gsuid = sensors_applet_settings_get_unique_id (interface, id, path);
960 gchar *settings_path = g_strdup_printf ("%s%s/", applet_path, gsuid);
961 GSettings *settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", settings_path);
962
963 /* add hash to temp sorting list */
964 g_variant_builder_add (&gvb_sensors_hash_list, "s", gsuid);
965
966 g_free (applet_path);
967 g_free (gsuid);
968 g_free (settings_path);
969
970 gchar *settings_id = g_settings_get_string (settings, ID"id");
971
972 if (settings_id != NULL((void*)0) && settings_id[0] != '\0') {
973 enable = g_settings_get_boolean (settings, ENABLED"enabled");
974 icon = sensors_applet_load_icon(g_settings_get_int (settings, ICON_TYPE"icon-type"));
975 gtk_tree_store_set(sensors_applet->sensors,
976 &sensors_iter,
977 PATH_COLUMN, g_settings_get_string (settings, PATH"path"),
978 ID_COLUMN, settings_id,
979 LABEL_COLUMN, g_settings_get_string (settings, LABEL"label"),
980 INTERFACE_COLUMN, g_settings_get_string (settings, INTERFACE"interface"),
981 SENSOR_TYPE_COLUMN, g_settings_get_int (settings, SENSOR_TYPE"sensor-type"),
982 ENABLE_COLUMN, enable,
983 VISIBLE_COLUMN, TRUE(!(0)),
984 LOW_VALUE_COLUMN, g_settings_get_double (settings, LOW_VALUE"low-value"),
985 HIGH_VALUE_COLUMN, g_settings_get_double (settings, HIGH_VALUE"high-value"),
986 ALARM_ENABLE_COLUMN, g_settings_get_boolean (settings, ALARM_ENABLED"alarm-enabled"),
987 ALARM_TIMEOUT_COLUMN, g_settings_get_int (settings, ALARM_TIMEOUT"alarm-timeout"),
988 LOW_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, LOW_ALARM_COMMAND"low-alarm-command"),
989 HIGH_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, HIGH_ALARM_COMMAND"high-alarm-command"),
990 MULTIPLIER_COLUMN, g_settings_get_double (settings, MULTIPLIER"multiplier"),
991 OFFSET_COLUMN, g_settings_get_double (settings, OFFSET"offset"),
992 ICON_TYPE_COLUMN, g_settings_get_int (settings, ICON_TYPE"icon-type"),
993 ICON_PIXBUF_COLUMN, icon,
994 GRAPH_COLOR_COLUMN, g_settings_get_string (settings, GRAPH_COLOR"graph-color"),
995 -1);
996 g_free (settings_id);
997 } else {
998 icon = sensors_applet_load_icon(icon_type);
999 gtk_tree_store_set(sensors_applet->sensors,
1000 &sensors_iter,
1001 PATH_COLUMN, path,
1002 ID_COLUMN, id,
1003 LABEL_COLUMN, label,
1004 INTERFACE_COLUMN, interface,
1005 SENSOR_TYPE_COLUMN, type,
1006 ENABLE_COLUMN, enable,
1007 VISIBLE_COLUMN, TRUE(!(0)),
1008 LOW_VALUE_COLUMN, low_value,
1009 HIGH_VALUE_COLUMN, high_value,
1010 ALARM_ENABLE_COLUMN, alarm_enable,
1011 ALARM_TIMEOUT_COLUMN, alarm_timeout,
1012 LOW_ALARM_COMMAND_COLUMN, low_alarm_command,
1013 HIGH_ALARM_COMMAND_COLUMN, high_alarm_command,
1014 MULTIPLIER_COLUMN, multiplier,
1015 OFFSET_COLUMN, offset,
1016 ICON_TYPE_COLUMN, icon_type,
1017 ICON_PIXBUF_COLUMN, icon,
1018 GRAPH_COLOR_COLUMN, graph_color,
1019 -1);
1020 }
1021 g_object_unref (settings);
1022 g_debug("added sensor %s to tree", path);
1023
1024 /* remove reference to icon as tree now has ref */
1025 g_object_unref(icon);
1026
1027 /* create the active sensor */
1028 if (enable) {
1029 tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
1030 sensors_applet_sensor_enabled(sensors_applet, tree_path);
1031 gtk_tree_path_free(tree_path);
1032 }
1033 return TRUE(!(0));
1034}
1035
1036static ActiveSensor *sensors_applet_find_active_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1037 GtkTreePath *sensor_tree_path;
1038 GList *current_sensor;
1039
1040 for (current_sensor = sensors_applet->active_sensors; current_sensor != NULL((void*)0); current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
) {
1041 sensor_tree_path = gtk_tree_row_reference_get_path(((ActiveSensor *)(current_sensor->data))->sensor_row);
1042
1043 if (gtk_tree_path_compare(path, sensor_tree_path) == 0) {
1044 gtk_tree_path_free(sensor_tree_path);
1045 return ((ActiveSensor *)(current_sensor->data));
1046 }
1047 gtk_tree_path_free(sensor_tree_path);
1048 }
1049 return NULL((void*)0);
1050}
1051
1052/* path should be the full path to a file representing the sensor (eg
1053 * /dev/hda or /sys/devices/platform/i2c-0/0-0290/temp1_input) */
1054void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet) {
1055 /* update sensors since will need to update icons / graphs etc
1056 * if weren't displayed before */
1057 GList *list = NULL((void*)0);
1058 for (list = sensors_applet->active_sensors; list != NULL((void*)0); list = list->next) {
1059 ActiveSensor *as = (ActiveSensor *)list->data;
1060 as->updated = FALSE(0);
1061 }
1062 sensors_applet_update_active_sensors(sensors_applet);
1063 sensors_applet_pack_display(sensors_applet);
1064}
1065
1066void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
1067 GtkTreePath *path,
1068 NotifType notif_type) {
1069 ActiveSensor *active_sensor;
1070
1071 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1072 active_sensor_alarm_off(active_sensor, notif_type);
1073 }
1074}
1075
1076void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet, GtkTreePath *path) {
1077 sensors_applet_alarm_off(sensors_applet, path, LOW_ALARM);
1078 sensors_applet_alarm_off(sensors_applet, path, HIGH_ALARM);
1079}
1080
1081void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1082 ActiveSensor *active_sensor;
1083
1084 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_63
; if (sensors_applet) _g_boolean_var_63 = 1; else _g_boolean_var_63
= 0; _g_boolean_var_63; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1084, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1085 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_64
; if (path) _g_boolean_var_64 = 1; else _g_boolean_var_64 = 0
; _g_boolean_var_64; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1085, ((const char*) (__func__
)), "path"); } while (0)
;
1086
1087 active_sensor = active_sensor_new(sensors_applet, gtk_tree_row_reference_new(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), path));
1088 active_sensor_update(active_sensor, sensors_applet);
1089
1090 /* keep list sorted */
1091 sensors_applet->active_sensors = g_list_insert_sorted(sensors_applet->active_sensors,
1092 active_sensor,
1093 (GCompareFunc)active_sensor_compare);
1094
1095 sensors_applet_pack_display(sensors_applet);
1096}
1097
1098void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet) {
1099 sensors_applet->active_sensors = g_list_sort(sensors_applet->active_sensors, (GCompareFunc)active_sensor_compare);
1100
1101 sensors_applet_pack_display(sensors_applet);
1102}
1103
1104void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1105
1106 ActiveSensor *active_sensor;
1107
1108 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_65
; if (sensors_applet) _g_boolean_var_65 = 1; else _g_boolean_var_65
= 0; _g_boolean_var_65; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1108, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1109 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_66
; if (path) _g_boolean_var_66 = 1; else _g_boolean_var_66 = 0
; _g_boolean_var_66; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1109, ((const char*) (__func__
)), "path"); } while (0)
;
1110
1111 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1112 g_debug("Destroying active sensor...");
1113
1114 g_debug("-- removing from list...");
1115 sensors_applet->active_sensors = g_list_remove(sensors_applet->active_sensors, active_sensor);
1116 g_debug("-- repacking display....");
1117 sensors_applet_pack_display(sensors_applet);
1118
1119 active_sensor_destroy(active_sensor);
1120 }
1121}
1122
1123void sensors_applet_update_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1124 ActiveSensor *active_sensor;
1125
1126 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_67
; if (sensors_applet) _g_boolean_var_67 = 1; else _g_boolean_var_67
= 0; _g_boolean_var_67; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1126, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1127 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_68
; if (path) _g_boolean_var_68 = 1; else _g_boolean_var_68 = 0
; _g_boolean_var_68; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1127, ((const char*) (__func__
)), "path"); } while (0)
;
1128
1129 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1130 active_sensor_update(active_sensor, sensors_applet);
1131 }
1132}
1133
1134void sensors_applet_icon_changed(SensorsApplet *sensors_applet, GtkTreePath *path) {
1135 ActiveSensor *active_sensor;
1136
1137 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_69
; if (sensors_applet) _g_boolean_var_69 = 1; else _g_boolean_var_69
= 0; _g_boolean_var_69; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1137, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1138 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_70
; if (path) _g_boolean_var_70 = 1; else _g_boolean_var_70 = 0
; _g_boolean_var_70; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1138, ((const char*) (__func__
)), "path"); } while (0)
;
1139
1140 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1141 active_sensor_icon_changed(active_sensor, sensors_applet);
1142 }
1143}
1144
1145/* Cycle thru ActiveSensors and update them all */
1146gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet) {
1147 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_71
; if (sensors_applet) _g_boolean_var_71 = 1; else _g_boolean_var_71
= 0; _g_boolean_var_71; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1147, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1148
1149 if (sensors_applet->active_sensors) {
1150 g_list_foreach(sensors_applet->active_sensors,
1151 (GFunc)active_sensor_update,
1152 sensors_applet);
1153 return TRUE(!(0));
1154 }
1155 return FALSE(0);
1156}
1157
1158/* Cycle thru ActiveSensors and set new graph dimensions */
1159void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet) {
1160 gint dimensions[2];
1161 gint graph_size;
1162 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_72
; if (sensors_applet) _g_boolean_var_72 = 1; else _g_boolean_var_72
= 0; _g_boolean_var_72; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1162, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1163
1164 if (sensors_applet->active_sensors) {
1165
1166 graph_size = g_settings_get_int (sensors_applet->settings, GRAPH_SIZE"graph-size");
1167 if (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP ||
1168 mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN) {
1169
1170 /* is horizontal so set graph_size as width */
1171 dimensions[0] = graph_size;
1172 dimensions[1] = sensors_applet->size;
1173 } else {
1174 dimensions[0] = sensors_applet->size;
1175 dimensions[1] = graph_size;
1176 }
1177
1178 g_list_foreach(sensors_applet->active_sensors,
1179 (GFunc)active_sensor_update_graph_dimensions,
1180 &dimensions);
1181 }
1182
1183}
1184
1185gdouble sensors_applet_convert_temperature(gdouble value, TemperatureScale old, TemperatureScale new) {
1186
1187 switch (old) {
1188 case KELVIN:
1189 switch (new) {
1190 case CELSIUS:
1191 value = value - 273.0;
1192 break;
1193 case FAHRENHEIT:
1194 value = (9.0 * (value - 273) / 5.0) + 32.0;
1195 break;
1196 case KELVIN:
1197 break;
1198 }
1199 break;
1200
1201 case CELSIUS:
1202 switch (new) {
1203 case FAHRENHEIT:
1204 value = (9.0 * value / 5.0) + 32.0;
1205 break;
1206 case KELVIN:
1207 value = value + 273.0;
1208 break;
1209 case CELSIUS:
1210 break;
1211 }
1212 break;
1213
1214 case FAHRENHEIT:
1215 switch (new) {
1216 case CELSIUS:
1217 value = (5.0 * (value - 32.0) / 9.0);
1218 break;
1219 case KELVIN:
1220 value = (5.0 * (value - 32.0) / 9.0) + 273.0;
1221 break;
1222 case FAHRENHEIT:
1223 break;
1224 }
1225 break;
1226 }
1227 return value;
1228}
1229
1230void sensors_applet_init(SensorsApplet *sensors_applet) {
1231
1232 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_73
; if (sensors_applet) _g_boolean_var_73 = 1; else _g_boolean_var_73
= 0; _g_boolean_var_73; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1232, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1233 g_assert(sensors_applet->applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_74
; if (sensors_applet->applet) _g_boolean_var_74 = 1; else _g_boolean_var_74
= 0; _g_boolean_var_74; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1233, ((const char*) (
__func__)), "sensors_applet->applet"); } while (0)
;
1234
1235 GtkActionGroup *action_group;
1236 gchar *ui_path;
1237
1238 /* Have our background automatically painted. */
1239 mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(sensors_applet->applet), GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1240
1241 /* plugin functions are stored as name -> get_value_function pairs so
1242 * use standard string functions on hash table */
1243 sensors_applet->plugins = g_hash_table_new(g_str_hash, g_str_equal);
1244
1245 sensors_applet->required_plugins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL((void*)0));
1246
1247 /* initialise size */
1248 sensors_applet->size = DEFAULT_APPLET_SIZE24;
1249
1250 mate_panel_applet_set_flags(sensors_applet->applet, MATE_PANEL_APPLET_EXPAND_MINOR);
1251
1252 g_signal_connect(sensors_applet->applet, "destroy",g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1253 G_CALLBACK(destroy_cb),g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1254 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
;
1255
1256 /* init gsettings */
1257 sensors_applet->settings = mate_panel_applet_settings_new (sensors_applet->applet, "org.mate.sensors-applet");
1258
1259 /* set up builder for sorting verification */
1260 g_variant_builder_init (&gvb_sensors_hash_list, G_VARIANT_TYPE ("as")(g_variant_type_checked_ (("as"))));
1261
1262 /* set up / load sensors from the plugins */
1263 sensors_applet_plugins_load_all(sensors_applet);
1264
1265 /* set sorting hash array */
1266 GVariant *gv_temp = g_variant_builder_end (&gvb_sensors_hash_list);
1267 sensors_applet->sensors_hash_array = g_variant_dup_strv (gv_temp, NULL((void*)0));
1268 g_variant_unref (gv_temp);
1269
1270 /* sort sensors based on saved sorting */
1271 sensors_applet_settings_sort_sensors(sensors_applet);
1272
1273 /* free hash array */
1274 g_strfreev (sensors_applet->sensors_hash_array);
1275
1276 /* should have created sensors tree above, but if have not was because we couldn't find any sensors */
1277 if (NULL((void*)0) == sensors_applet->sensors) {
1278 GtkWidget *label;
1279 label = gtk_label_new(_("No sensors found!")dcgettext (((void*)0), "No sensors found!", 5));
1280 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), label);
1281 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1282 return;
1283 }
1284
1285 /* only do menu and signal connections if sensors are found */
1286 action_group = gtk_action_group_new ("Sensors Applet Actions");
1287 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE"mate-sensors-applet");
1288 gtk_action_group_add_actions (action_group,
1289 sensors_applet_menu_actions,
1290 G_N_ELEMENTS (sensors_applet_menu_actions)(sizeof (sensors_applet_menu_actions) / sizeof ((sensors_applet_menu_actions
)[0]))
,
1291 sensors_applet);
1292 ui_path = g_build_filename (UIDIR"/usr/local/share/mate-sensors-applet/ui", SENSORS_APPLET_MENU_FILE"SensorsApplet.xml", NULL((void*)0));
1293 mate_panel_applet_setup_menu_from_file (sensors_applet->applet, ui_path, action_group);
1294 g_free (ui_path);
1295 g_object_unref (action_group);
1296
1297 g_signal_connect(sensors_applet->applet, "style-set",g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1298 G_CALLBACK(style_set_cb),g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1299 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
;
1300
1301 g_signal_connect(G_OBJECT(sensors_applet->applet), "change_orient",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1302 G_CALLBACK(change_orient_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1303 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1304
1305 g_signal_connect(G_OBJECT(sensors_applet->applet), "size_allocate",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1306 G_CALLBACK(size_allocate_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1307 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1308
1309 g_signal_connect(G_OBJECT(sensors_applet->applet), "leave_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1310 G_CALLBACK(mouse_leave_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1311 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1312
1313 g_signal_connect(G_OBJECT(sensors_applet->applet), "enter_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1314 G_CALLBACK(mouse_enter_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1315 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1316
1317 sensors_applet_update_active_sensors(sensors_applet);
1318 sensors_applet_pack_display(sensors_applet);
1319
1320 sensors_applet->timeout_id = g_timeout_add_seconds(g_settings_get_int(sensors_applet->settings, TIMEOUT"timeout-delay") / 1000,
1321 (GSourceFunc)sensors_applet_update_active_sensors,
1322 sensors_applet);
1323 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1324}
1325
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-782a54.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-782a54.html new file mode 100644 index 0000000..1c6d601 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-782a54.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 319, column 97
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_22
; if (info != ((void*)0)) _g_boolean_var_22 = 1; else _g_boolean_var_22
= 0; _g_boolean_var_22; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_23
; if (connection != ((void*)0)) _g_boolean_var_23 = 1; else _g_boolean_var_23
= 0; _g_boolean_var_23; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-e082ac.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-e082ac.html new file mode 100644 index 0000000..782b3f0 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-e082ac.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 318, column 102
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_20
; if (info != ((void*)0)) _g_boolean_var_20 = 1; else _g_boolean_var_20
= 0; _g_boolean_var_20; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_21
; if (connection != ((void*)0)) _g_boolean_var_21 = 1; else _g_boolean_var_21
= 0; _g_boolean_var_21; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-f0c410.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-f0c410.html new file mode 100644 index 0000000..46d89f6 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-f0c410.html @@ -0,0 +1,2042 @@ + + + +sensors-applet.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:sensors-applet/sensors-applet.c
Warning:line 529, column 59
Division by zero
+ +

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 sensors-applet.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=none -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/sensors-applet -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D UIDIR="/usr/local/share/mate-sensors-applet/ui" -D SENSORS_APPLET_PLUGIN_DIR="/usr/local/lib/mate-sensors-applet/plugins" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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/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 -I /usr/include/mate-panel-4.0/libmate-panel-applet -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 /usr/include/cairo -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/harfbuzz -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libxml2 -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -I /usr/include/sysprof-4 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -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 -O2 -Wno-unused-parameter -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/sensors-applet -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c sensors-applet.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
3 * Copyright (C) 2012-2021 MATE Developers
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/** Contain the functions for operating on the SensorsApplet structure
21 * (represents the applet itself, and its associated variables.
22 */
23
24#ifdef HAVE_CONFIG_H1
25#include "config.h"
26#endif /* HAVE_CONFIG_H */
27
28#ifdef HAVE_UNISTD_H1
29#include <unistd.h>
30#endif /* HAVE_UNISTD_H */
31
32#include <glib/gi18n.h>
33#include <glib/gprintf.h>
34#include <gio/gio.h>
35#include "sensors-applet.h"
36#include "active-sensor.h"
37#include "sensors-applet-settings.h"
38#include "sensors-applet-plugins.h"
39
40#ifdef HAVE_LIBNOTIFY1
41#include "active-sensor-libnotify.h"
42#define DEFAULT_NOTIFY_TIMEOUT3000 3000
43#endif
44
45#include "prefs-dialog.h"
46#include "about-dialog.h"
47
48#define SENSORS_APPLET_MENU_FILE"SensorsApplet.xml" "SensorsApplet.xml"
49/* initially set as sensors_applet->size to ensure a real value is stored */
50#define DEFAULT_APPLET_SIZE24 24
51#define COLUMN_SPACING2 2
52#define ROW_SPACING1 1
53
54/* builder for sensor sorting verification */
55static GVariantBuilder gvb_sensors_hash_list;
56
57/* callbacks for panel menu */
58static void prefs_cb(GtkAction *action, gpointer *data) {
59
60 SensorsApplet *sensors_applet;
61 sensors_applet = (SensorsApplet *)data;
62
63 if (sensors_applet->prefs_dialog) {
64 gtk_window_present(GTK_WINDOW(sensors_applet->prefs_dialog->dialog)((((GtkWindow*) (void *) ((sensors_applet->prefs_dialog->
dialog)))))
);
65 return;
66 }
67 prefs_dialog_open(sensors_applet);
68}
69
70static void about_cb(GtkAction *action, gpointer data) {
71 SensorsApplet *sensors_applet;
72 sensors_applet = (SensorsApplet *)data;
73
74 about_dialog_open(sensors_applet);
75}
76
77static void help_cb(GtkAction *action, gpointer data) {
78
79 GError *error = NULL((void*)0);
80
81 gtk_show_uri_on_window(NULL((void*)0), "help:mate-sensors-applet",
82
83 gtk_get_current_event_time(),
84 &error);
85
86 if (error) {
87 g_debug("Could not open help document: %s ",error->message);
88 g_error_free(error);
89 }
90}
91
92static void destroy_cb(GtkWidget *widget, gpointer data) {
93 SensorsApplet *sensors_applet;
94 sensors_applet = (SensorsApplet *)data;
95
96 /* destroy dialogs, remove timeout and clear sensors tree and finally the applet */
97 if (sensors_applet->prefs_dialog != NULL((void*)0)) {
98 /* destroy's dialog too */
99 prefs_dialog_close(sensors_applet);
100 }
101
102 if (sensors_applet->timeout_id) {
103 g_source_remove(sensors_applet->timeout_id);
104 }
105
106 if (sensors_applet->settings) {
107 g_object_unref (sensors_applet->settings);
108 sensors_applet->settings = NULL((void*)0);
109 }
110
111 /* destroy all active sensors */
112 g_list_foreach(sensors_applet->active_sensors,
113 (GFunc)active_sensor_destroy,
114 NULL((void*)0));
115
116 if (sensors_applet->sensors != NULL((void*)0)) {
117 gtk_tree_store_clear(sensors_applet->sensors);
118 }
119
120 gtk_widget_destroy(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
121
122 g_free(sensors_applet);
123 return;
124}
125
126static void change_orient_cb (MatePanelApplet *applet,
127 MatePanelAppletOrient orient,
128 gpointer data) {
129
130 SensorsApplet *sensors_applet;
131 sensors_applet = (SensorsApplet *)data;
132
133 sensors_applet_display_layout_changed(sensors_applet);
134}
135
136static void size_allocate_cb(MatePanelApplet *applet,
137 GtkAllocation *allocation,
138 gpointer data) {
139
140 SensorsApplet *sensors_applet;
141 MatePanelAppletOrient orient;
142
143 sensors_applet = (SensorsApplet *)data;
144 orient = mate_panel_applet_get_orient(sensors_applet->applet);
145
146 if ((orient == MATE_PANEL_APPLET_ORIENT_LEFT) ||
147 (orient == MATE_PANEL_APPLET_ORIENT_RIGHT)) {
148
149 if (sensors_applet->size == allocation->width)
150 return;
151 sensors_applet->size = allocation->width;
152 } else {
153 if (sensors_applet->size == allocation->height)
154 return;
155 sensors_applet->size = allocation->height;
156 }
157
158 /* update if new value */
159 sensors_applet_graph_size_changed(sensors_applet);
160 sensors_applet_display_layout_changed(sensors_applet);
161}
162
163static void style_set_cb(GtkWidget *widget, GtkStyle *old_style, gpointer data) {
164
165 /* update all icons in the sensors tree and update all active sensors */
166 GtkTreeIter interfaces_iter, sensors_iter;
167 gboolean not_end_of_interfaces = TRUE(!(0)), not_end_of_sensors = TRUE(!(0));
168 IconType icon_type;
169 gboolean enabled;
170 SensorsApplet *sensors_applet;
171 DisplayMode display_mode;
172
173 sensors_applet = (SensorsApplet *)data;
174
175 display_mode = g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
176 if (sensors_applet->sensors) {
177 for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
178 not_end_of_interfaces;
179 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
180
181 /* reset sensors sentinel */
182 not_end_of_sensors = TRUE(!(0));
183
184 for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
185 not_end_of_sensors;
186 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
187
188 GdkPixbuf *new_icon;
189
190 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))),
191 &sensors_iter,
192 ENABLE_COLUMN, &enabled,
193 ICON_TYPE_COLUMN, &icon_type,
194 -1);
195 /* update icons */
196 new_icon = sensors_applet_load_icon(icon_type);
197
198 gtk_tree_store_set(sensors_applet->sensors,
199 &sensors_iter,
200 ICON_PIXBUF_COLUMN, new_icon,
201 -1);
202 g_object_unref(new_icon);
203
204 /* update icons only if currently being displayed */
205 if (enabled &&
206 (display_mode == DISPLAY_ICON ||
207 display_mode == DISPLAY_ICON_WITH_VALUE)) {
208
209 GtkTreePath *path;
210
211 path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
212 sensors_applet_icon_changed(sensors_applet, path);
213 gtk_tree_path_free(path);
214 }
215 }
216 }
217 /* now update layout as size may have changed */
218 sensors_applet_display_layout_changed(sensors_applet);
219 }
220
221}
222
223static gboolean mouse_enter_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
224{
225 SensorsApplet *sensor_applet = data;
226 sensor_applet->show_tooltip = TRUE(!(0));
227 sensors_applet_update_active_sensors(sensor_applet);
228 return TRUE(!(0));
229}
230
231static gboolean mouse_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data)
232{
233 SensorsApplet *sensor_applet = data;
234 sensor_applet->show_tooltip = FALSE(0);
235 return TRUE(!(0));
236}
237
238static const GtkActionEntry sensors_applet_menu_actions[] = {
239 { "Preferences", "document-properties", N_("_Preferences")("_Preferences"),
240 NULL((void*)0), NULL((void*)0),
241 G_CALLBACK(prefs_cb)((GCallback) (prefs_cb)) },
242 { "Help", "help-browser", N_("_Help")("_Help"),
243 NULL((void*)0), NULL((void*)0),
244 G_CALLBACK(help_cb)((GCallback) (help_cb)) },
245 { "About", "help-about", N_("_About")("_About"),
246 NULL((void*)0), NULL((void*)0),
247 G_CALLBACK(about_cb)((GCallback) (about_cb)) }
248};
249
250void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type) {
251#ifdef HAVE_LIBNOTIFY1
252
253 SensorsApplet *sensors_applet;
254 gchar *summary, *message;
255 gint timeout_msecs;
256 gchar *sensor_label;
257 gchar *sensor_path;
258 SensorType sensor_type;
259 TemperatureScale temp_scale;
260 GtkTreeIter iter;
261 GtkTreePath *path;
262 const gchar *unit_type = NULL((void*)0);
263 const gchar *unit_type_title = NULL((void*)0);
264 const gchar *relation = NULL((void*)0);
265 const gchar *limit_type = NULL((void*)0);
266 const gchar *units = NULL((void*)0);
267 gdouble limit_value;
268 gdouble seconds;
269 gboolean show_notification = TRUE(!(0));
270
271 sensors_applet = active_sensor->sensors_applet;
272
273 if (!g_settings_get_boolean (sensors_applet->settings, DISPLAY_NOTIFICATIONS"display-notifications")) {
274 g_debug("Wanted to display notification, but user has disabled them");
275 return;
276 }
277
278 path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
279 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter, path)) {
280
281 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &iter,
282 LABEL_COLUMN, &sensor_label,
283 PATH_COLUMN, &sensor_path,
284 SENSOR_TYPE_COLUMN, &sensor_type,
285 -1);
286 } else {
287 g_warning("Error getting data from tree for notification...");
288 gtk_tree_path_free(path);
289 return;
290 }
291
292 gtk_tree_path_free(path);
293
294 /* do different stuff for different notif types */
295 switch (notif_type) {
296 case LOW_ALARM: /* fall thru */
297 case HIGH_ALARM:
298 if (active_sensor->sensor_values[0] <= active_sensor->sensor_low_value && notif_type == LOW_ALARM) {
299
300 relation = _("is very low")dcgettext (((void*)0), "is very low", 5);
301 limit_type = _("lower limit")dcgettext (((void*)0), "lower limit", 5);
302 limit_value = active_sensor->sensor_low_value;
303 } else if (active_sensor->sensor_values[0] >= active_sensor->sensor_high_value && notif_type == HIGH_ALARM) {
304
305 /* assume high alarm condition */
306 relation = _("is very high")dcgettext (((void*)0), "is very high", 5);
307 limit_type = _("upper limit")dcgettext (((void*)0), "upper limit", 5);
308 limit_value = active_sensor->sensor_high_value;
309 } else {
310 g_warning("Alarm notify called when no alarm condition!");
311 g_free(sensor_path);
312 g_free(sensor_label);
313 return;
314 }
315
316 switch ((SensorType)sensor_type) {
317 case TEMP_SENSOR:
318 unit_type_title = _("Temperature")dcgettext (((void*)0), "Temperature", 5);
319 unit_type = _("temperature")dcgettext (((void*)0), "temperature", 5);
320 temp_scale = (TemperatureScale) g_settings_get_int (active_sensor->sensors_applet->settings, TEMPERATURE_SCALE"temperature-scale");
321
322 switch (temp_scale) {
323 case CELSIUS:
324 units = UNITS_CELSIUS"\302\260C";
325 break;
326 case FAHRENHEIT:
327 units = UNITS_FAHRENHEIT"\302\260F";
328 break;
329 case KELVIN:
330 units = UNITS_KELVIN"";
331 break;
332 default:
333 units = NULL((void*)0);
334 }
335 break;
336
337 case VOLTAGE_SENSOR:
338 unit_type_title = _("Voltage")dcgettext (((void*)0), "Voltage", 5);
339 unit_type = _("voltage")dcgettext (((void*)0), "voltage", 5);
340 units = UNITS_VOLTAGEdcgettext (((void*)0), "V", 5);
341 break;
342
343 case FAN_SENSOR:
344 unit_type_title = _("Fan Speed")dcgettext (((void*)0), "Fan Speed", 5);
345 unit_type = _("fan speed")dcgettext (((void*)0), "fan speed", 5);
346 units = UNITS_RPMdcgettext (((void*)0), "RPM", 5);
347 break;
348
349 case CURRENT_SENSOR:
350 unit_type_title = _("Current")dcgettext (((void*)0), "Current", 5);
351 unit_type = _("current")dcgettext (((void*)0), "current", 5);
352 units = UNITS_CURRENTdcgettext (((void*)0), "A", 5);
353 break;
354 }
355
356 timeout_msecs = (active_sensor->alarm_timeout ? MIN(DEFAULT_NOTIFY_TIMEOUT, (active_sensor->alarm_timeout * 1000))(((3000) < ((active_sensor->alarm_timeout * 1000))) ? (
3000) : ((active_sensor->alarm_timeout * 1000)))
: DEFAULT_NOTIFY_TIMEOUT3000);
357
358 summary = g_strdup_printf("%s %s %s", sensor_label, unit_type_title, _("Alarm")dcgettext (((void*)0), "Alarm", 5));
359 message = g_strdup_printf("%s %s %s (%s %2.0f%s)", sensor_label, unit_type, relation, limit_type, limit_value, units);
360 break;
361
362 case SENSOR_INTERFACE_ERROR:
363 /* get time since the last error */
364 seconds = difftime(time(NULL((void*)0)), active_sensor->ierror_ts);
365
366 /* if the last error happened less than 10 seconds ago, don't display this one
367 * this should prevent recurring popups for removed sensors, like USB-HDDs */
368 if (seconds < 11.0) {
369 show_notification = FALSE(0);
370 }
371
372 summary = g_strdup_printf(_("Error updating sensor %s")dcgettext (((void*)0), "Error updating sensor %s", 5), sensor_label);
373 message = g_strdup_printf(_("An error occurred while trying to update the value of the sensor %s located at %s.")dcgettext (((void*)0), "An error occurred while trying to update the value of the sensor %s located at %s."
, 5)
, sensor_label, sensor_path);
374 timeout_msecs = g_settings_get_int (active_sensor->sensors_applet->settings, TIMEOUT"timeout-delay");
375
376 /* update timestamp */
377 time(&(active_sensor->ierror_ts));
378 break;
379
380 default:
381 g_assert_not_reached()do { g_assertion_message_expr ("sensors-applet", "sensors-applet.c"
, 381, ((const char*) (__func__)), ((void*)0)); } while (0)
;
382 }
383
384 if (show_notification) {
385 active_sensor_libnotify_notify(active_sensor,
386 notif_type,
387 summary,
388 message,
389 "dialog-warning",
390 timeout_msecs);
391 }
392
393 g_free(sensor_path);
394 g_free(sensor_label);
395 g_free(summary);
396 g_free(message);
397#endif
398}
399
400void sensors_applet_notify_end(ActiveSensor *active_sensor, NotifType notif_type) {
401#ifdef HAVE_LIBNOTIFY1
402 active_sensor_libnotify_notify_end(active_sensor, notif_type);
403#endif
404}
405
406#ifdef HAVE_LIBNOTIFY1
407static void sensors_applet_notify_end_all_gfunc(ActiveSensor *active_sensor, gpointer data) {
408 active_sensor_libnotify_notify_end(active_sensor, LOW_ALARM);
409 active_sensor_libnotify_notify_end(active_sensor, HIGH_ALARM);
410}
411#endif
412
413void sensors_applet_notify_end_all(SensorsApplet *sensors_applet) {
414#ifdef HAVE_LIBNOTIFY1
415 g_list_foreach(sensors_applet->active_sensors, (GFunc)sensors_applet_notify_end_all_gfunc, NULL((void*)0));
416#endif
417}
418
419/* internal helper functions for updating display etc */
420
421/* should be called as a g_container_foreach at the start of
422 * pack_display if the grid already exists to remove but keep alive
423 * all children of the grid before repacking it */
424static void sensors_applet_pack_display_empty_grid_cb(GtkWidget *widget, gpointer data)
425{
426 GtkContainer *container;
427
428 container = GTK_CONTAINER(data)((((GtkContainer*) (void *) ((data)))));
429
430 /* ref then remove widget */
431 g_object_ref(widget)((__typeof__ (widget)) (g_object_ref) (widget));
432 gtk_container_remove(container, widget);
433}
434
435/* should be called as a g_container_foreach at the end of
436 * pack_display to unref any of the old children that we have readdded
437 * to the table to stop reference creep from the g_object_ref called
438 * on each child at the start of pack labels */
439static void sensors_applet_pack_display_cleanup_refs_cb(GtkWidget *widget, gpointer data) {
440
441 GList *old_children;
442
443 old_children = (GList *)data;
444 if (g_list_find(old_children, widget)) {
445 g_object_unref(widget);
446 }
447}
448
449static void sensors_applet_pack_display(SensorsApplet *sensors_applet) {
450 /* note the if () around each widget is to ensure we only
451 * operate on those that actually exist */
452 GtkLabel *no_sensors_enabled_label = NULL((void*)0);
453 gint num_active_sensors = 0, num_sensors_per_group = 0, rows, cols, i, j;
454 GList *old_grid_children = NULL((void*)0);
455
456 GList *current_sensor;
457
458 DisplayMode display_mode;
459 LayoutMode layout_mode;
460
461 gboolean horizontal;
462 gint label_width, icon_width, value_width;
463 gint label_height, icon_height, value_height;
464
465 GtkRequisition req;
466
467 ActiveSensor *first_sensor;
468
469 /* it is possible that there could be no active sensors so
470 * handle that case first - make sure we dont do a NULL
471 * pointer access first though */
472 if (sensors_applet->active_sensors == NULL((void*)0) || g_list_length(sensors_applet->active_sensors) == 0) {
1
Assuming field 'active_sensors' is not equal to NULL
2
Assuming the condition is false
3
Taking false branch
473 g_debug("no active sensors to pack in grid");
474 no_sensors_enabled_label = g_object_new(GTK_TYPE_LABEL(gtk_label_get_type ()), "label", _("No sensors enabled!")dcgettext (((void*)0), "No sensors enabled!", 5), NULL((void*)0));
475
476 if (sensors_applet->grid == NULL((void*)0)) {
477 /* only need 1 row and 1 col */
478 sensors_applet->grid = gtk_grid_new();
479 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
480 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
481 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
482 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
483 /* add grid to applet */
484 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
485 } else {
486 /* destroy existing widgets - could be an
487 * existing version of no sensors label - okay
488 * to just add again though if destroy first */
489 g_debug("destroying any existing widgets in container");
490 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))), (GtkCallback)gtk_widget_destroy, NULL((void*)0));
491 }
492 g_debug("packing no sensors enabled label");
493 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
494 GTK_WIDGET(no_sensors_enabled_label)((((GtkWidget*) (void *) ((no_sensors_enabled_label))))),
495 0, 0, 1, 1);
496 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
497 return;
498 }
499 /* otherwise can acess active_sensors without any worries */
500 num_active_sensors = g_list_length(sensors_applet->active_sensors);
501
502 display_mode = (DisplayMode) g_settings_get_int (sensors_applet->settings, DISPLAY_MODE"display-mode");
503 layout_mode = (LayoutMode) g_settings_get_int (sensors_applet->settings, LAYOUT_MODE"layout-mode");
504
505 horizontal = (((mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP) ||
4
Assuming the condition is false
506 (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN)));
5
Assuming the condition is false
507
508 /* figure out num rows / cols by how high / wide sensors
509 * labels / icons are and how much size we have to put them in */
510
511 /* get the first active sensor */
512 first_sensor = (ActiveSensor *)sensors_applet->active_sensors->data;
513
514 switch (display_mode) {
6
Control jumps to 'case DISPLAY_VALUE:' at line 515
515 case DISPLAY_VALUE:
516 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
517 value_width = req.width + COLUMN_SPACING2;
7
Value assigned to 'value_width'
518 value_height = req.height + ROW_SPACING1;
519
520 /* make sure all widths and heights are non zero,
521 * otherwise will get a divide by zero exception below
522 * - is a non critical error since can happen when
523 * elements first added to list, so simply return - is
524 * not a programming error */
525 if (value_width == 0 && value_height == 0) {
8
Assuming 'value_width' is equal to 0
9
Assuming 'value_height' is not equal to 0
10
Taking false branch
526 return;
527 }
528
529 num_sensors_per_group = (sensors_applet->size / (horizontal
10.1
'horizontal' is 0
? value_height : value_width)
);
11
'?' condition is false
12
Division by zero
530 break;
531
532 case DISPLAY_LABEL_WITH_VALUE:
533 /* even though we end up packing the event boxes into the
534 * panel, these dont give back request sizes, so need to ask
535 * widgets directly */
536 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
537
538 value_width = req.width + COLUMN_SPACING2;
539 value_height = req.height + ROW_SPACING1;
540
541 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->label)((((GtkWidget*) (void *) ((first_sensor->label))))), &req, NULL((void*)0));
542 label_width = req.width + COLUMN_SPACING2;
543 label_height = req.height + ROW_SPACING1;
544
545 /* make sure all widths and heights are non zero, otherwise
546 * will get a divide by zero exception below
547 * - is a non critical error since can happen when
548 * elements first added to list, so simply return - is
549 * not a programming error */
550 if (!(label_width && label_height && value_width && value_height)) {
551 return;
552 }
553
554 switch (layout_mode) {
555 case VALUE_BESIDE_LABEL:
556 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(label_height, value_height)(((label_height) > (value_height)) ? (label_height) : (value_height
))
: (label_width + value_width)));
557 break;
558 case VALUE_BELOW_LABEL:
559 num_sensors_per_group = (sensors_applet->size / (horizontal ? (label_height + value_height) : MAX(label_width, value_width)(((label_width) > (value_width)) ? (label_width) : (value_width
))
));
560 break;
561 }
562 break;
563
564 case DISPLAY_ICON_WITH_VALUE:
565 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->value)((((GtkWidget*) (void *) ((first_sensor->value))))), &req, NULL((void*)0));
566 value_width = req.width + COLUMN_SPACING2;
567 value_height = req.height + ROW_SPACING1;
568
569 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
570 icon_width = req.width + COLUMN_SPACING2;
571 icon_height = req.height + ROW_SPACING1;
572
573 if (!(icon_width && icon_height && value_width && value_height)) {
574 return;
575 }
576
577 switch (layout_mode) {
578 case VALUE_BESIDE_LABEL:
579 num_sensors_per_group = (sensors_applet->size / (horizontal ? MAX(icon_height, value_height)(((icon_height) > (value_height)) ? (icon_height) : (value_height
))
: (icon_width + value_width)));
580 break;
581
582 case VALUE_BELOW_LABEL:
583 num_sensors_per_group = (sensors_applet->size / (horizontal ? (icon_height + value_height) : MAX(icon_width, value_width)(((icon_width) > (value_width)) ? (icon_width) : (value_width
))
));
584 break;
585 }
586 break;
587
588 case DISPLAY_ICON:
589 gtk_widget_get_preferred_size(GTK_WIDGET(first_sensor->icon)((((GtkWidget*) (void *) ((first_sensor->icon))))), &req, NULL((void*)0));
590 icon_width = req.width + COLUMN_SPACING2;
591 icon_height = req.height + ROW_SPACING1;
592
593 if (!(icon_width && icon_height)) {
594 return;
595 }
596
597 num_sensors_per_group = (sensors_applet->size / (horizontal ? icon_height : icon_width));
598 break;
599
600 case DISPLAY_GRAPH:
601 /* only show graphs in a line like System Monitor applet */
602 num_sensors_per_group = 1;
603 break;
604 }
605
606 /* ensure always atleast 1 sensor per group */
607 if (num_sensors_per_group < 1) {
608 /* force a better layout */
609 if (horizontal && layout_mode == VALUE_BELOW_LABEL) {
610 layout_mode = VALUE_BESIDE_LABEL;
611 } else if (!horizontal && layout_mode == VALUE_BESIDE_LABEL) {
612 layout_mode = VALUE_BELOW_LABEL;
613 }
614 num_sensors_per_group = 1;
615 }
616
617 if (horizontal) {
618 /* if oriented horizontally, want as many
619 sensors per column as user has defined, then
620 enough columns to hold all the widgets */
621 rows = num_sensors_per_group;
622 cols = num_active_sensors / num_sensors_per_group;
623 while (rows * cols < num_active_sensors || cols == 0) {
624 cols++;
625 }
626
627 } else {
628 /* if oriented vertically, want as many
629 sensors per row as user has defined, then
630 enough rows to hold all the widgets*/
631 cols = num_sensors_per_group;
632 rows = num_active_sensors / num_sensors_per_group;
633 while (rows * cols < num_active_sensors || rows == 0) {
634 rows++;
635 }
636
637 }
638
639 /* if displaying labels / icons and values need to modify
640 number of rows / colums to accomodate this */
641 if (display_mode == DISPLAY_LABEL_WITH_VALUE || display_mode == DISPLAY_ICON_WITH_VALUE) {
642 if (layout_mode == VALUE_BESIDE_LABEL) {
643 /* to display labels next to values need twice as many columns */
644 cols *= 2;
645 } else {
646 /* to display labels above values, we need twice as many rows as without */
647 rows *= 2;
648 }
649 }
650
651 if (sensors_applet->grid == NULL((void*)0)) {
652 /* create grid and add to applet */
653 sensors_applet->grid = gtk_grid_new();
654 gtk_grid_set_column_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), COLUMN_SPACING2);
655 gtk_grid_set_row_spacing(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))), ROW_SPACING1);
656 gtk_widget_set_halign(sensors_applet->grid, GTK_ALIGN_CENTER);
657 gtk_widget_set_valign(sensors_applet->grid, GTK_ALIGN_CENTER);
658 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), sensors_applet->grid);
659 } else {
660 /* remove all children if grid already exists so we can start again */
661 /* save a list of the old children for later */
662 old_grid_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))));
663
664 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
665 sensors_applet_pack_display_empty_grid_cb,
666 sensors_applet->grid);
667 }
668 /* pack icons / labels and values into grid */
669 current_sensor = sensors_applet->active_sensors;
670
671 /* if showing labels / icons and values, need to pack labels / icons these first */
672 if (display_mode == DISPLAY_ICON_WITH_VALUE || display_mode == DISPLAY_LABEL_WITH_VALUE) {
673 /* loop through columns */
674 for (i = 0; current_sensor != NULL((void*)0) && i < cols; /* increments depends on how we lay them out - see below */) {
675
676 /* loop through rows in a column */
677 for (j = 0; current_sensor && j < rows; /* see bottom of for loop*/) {
678 /* attach label / icon at this point */
679 if (display_mode == DISPLAY_ICON_WITH_VALUE) {
680 if (((ActiveSensor *)(current_sensor->data))->icon) {
681 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
682 ((ActiveSensor *)(current_sensor->data))->icon,
683 i, j, 1, 1);
684 }
685 } else {
686 if (((ActiveSensor *)(current_sensor->data))->label) {
687 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
688 ((ActiveSensor *)(current_sensor->data))->label,
689 i, j, 1, 1);
690 }
691 }
692 /* now attach sensor value to either row below or column next to */
693 if (layout_mode == VALUE_BESIDE_LABEL) {
694 /* left align labels */
695 if (((ActiveSensor *)(current_sensor->data))->icon) {
696 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_START);
697 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
698 }
699 if (((ActiveSensor *)(current_sensor->data))->label) {
700 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0);
701 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
702 }
703 if (((ActiveSensor *)(current_sensor->data))->value) {
704 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_START);
705 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
706 }
707
708 /* place value next to label */
709 if (((ActiveSensor *)(current_sensor->data))->value) {
710 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
711 ((ActiveSensor *)(current_sensor->data))->value,
712 i + 1, j, 1, 1);
713 }
714 j++;
715 } else { /* place value below label */
716
717 /* center align labels */
718 if (((ActiveSensor *)(current_sensor->data))->icon) {
719 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
720 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->icon, GTK_ALIGN_CENTER);
721 }
722 if (((ActiveSensor *)(current_sensor->data))->label) {
723 gtk_label_set_xalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
724 gtk_label_set_yalign (GTK_LABEL(((ActiveSensor *)(current_sensor->data))->label)((((GtkLabel*) (void *) ((((ActiveSensor *)(current_sensor->
data))->label)))))
, 0.5);
725 }
726 if (((ActiveSensor *)(current_sensor->data))->value) {
727 gtk_widget_set_halign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
728 gtk_widget_set_valign (((ActiveSensor *)(current_sensor->data))->value, GTK_ALIGN_CENTER);
729 }
730
731 if (((ActiveSensor *)(current_sensor->data))->value) {
732 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
733 ((ActiveSensor *)(current_sensor->data))->value,
734 i, j + 1, 1, 1);
735 }
736 j += 2;
737 }
738 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
739 } /* end row loop */
740
741 /* now increment column index as needed */
742 if (layout_mode == VALUE_BESIDE_LABEL) { /* place value next to label */
743 i += 2;
744 } else {
745 i++;
746 }
747 } /* end column loop */
748
749 } else { /* not showing labels and icons with values, so just pack either only icons or values */
750 for (i = 0; current_sensor != NULL((void*)0) && i < cols; ++i) {
751 for (j = 0; current_sensor!= NULL((void*)0) && j < rows; ++j) {
752 if (display_mode == DISPLAY_VALUE) {
753 if (((ActiveSensor *)(current_sensor->data))->value) {
754 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
755 ((ActiveSensor *)(current_sensor->data))->value,
756 i, j, 1, 1);
757 }
758 } else if (display_mode == DISPLAY_ICON) {
759 if (((ActiveSensor *)(current_sensor->data))->value) {
760 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
761 ((ActiveSensor *)(current_sensor->data))->icon,
762 i, j, 1, 1);
763 }
764 } else if (display_mode == DISPLAY_GRAPH) {
765 if (((ActiveSensor *)(current_sensor->data))->graph) {
766 gtk_grid_attach(GTK_GRID(sensors_applet->grid)((((GtkGrid*) (void *) ((sensors_applet->grid))))),
767 ((ActiveSensor *)(current_sensor->data))->graph_frame,
768 i, j, 1, 1);
769 }
770 }
771
772 current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
;
773 }
774 }
775 }
776
777 if (old_grid_children != NULL((void*)0)) {
778 gtk_container_foreach(GTK_CONTAINER(sensors_applet->grid)((((GtkContainer*) (void *) ((sensors_applet->grid))))),
779 sensors_applet_pack_display_cleanup_refs_cb,
780 old_grid_children);
781 g_list_free(old_grid_children);
782 }
783 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
784
785}
786
787/* must unref when done with returned pixbuf */
788GdkPixbuf *sensors_applet_load_icon(IconType icon_type) {
789 GtkIconTheme *icon_theme;
790 GdkPixbuf *icon = NULL((void*)0);
791 GError *error = NULL((void*)0);
792
793 /* try to load the icon */
794
795 /* not allowed to unref or ref icon_theme once we have it */
796 icon_theme = gtk_icon_theme_get_default();
797 icon = gtk_icon_theme_load_icon(icon_theme,
798 stock_icons[icon_type],
799 DEFAULT_ICON_SIZE22,
800 GTK_ICON_LOOKUP_USE_BUILTIN,
801 &error);
802
803 if (error) {
804 g_warning ("Could not load icon: %s", error->message);
805 g_error_free(error);
806 error = NULL((void*)0);
807
808 /* try again with default icon */
809 icon = gtk_icon_theme_load_icon(icon_theme,
810 "image-missing",
811 DEFAULT_ICON_SIZE22,
812 GTK_ICON_LOOKUP_USE_BUILTIN,
813 &error);
814
815 if (error) {
816 /* this will quit sensors-applet but it is a pretty major error so may as well */
817 g_error("Could not load GTK_STOCK_MISSING_IMAGE - major error!!!: %s", error->message);
818 g_error_free(error);
819 error = NULL((void*)0);
820 }
821
822 }
823 return icon;
824}
825
826// MUST FREE STRINGS AFTER CALLING THIS FUNCTION!!
827gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet,
828 const gchar *path,
829 const gchar *id,
830 const gchar *label,
831 const gchar *interface,
832 SensorType type,
833 gboolean enable,
834 gdouble low_value,
835 gdouble high_value,
836 gboolean alarm_enable,
837 const gchar *low_alarm_command,
838 const gchar *high_alarm_command,
839 gint alarm_timeout,
840 gdouble multiplier,
841 gdouble offset,
842 IconType icon_type,
843 const gchar *graph_color) {
844
845 GtkTreeIter interfaces_iter, sensors_iter;
846 gboolean not_empty_tree;
847
848 gchar *node_interface;
849 gboolean not_end_of_interfaces = TRUE(!(0)), interface_exists = FALSE(0);
850 gboolean not_end_of_sensors = TRUE(!(0));
851 gchar *sensor_id;
852 gchar *sensor_path;
853 SensorType sensor_type;
854 GdkPixbuf *icon;
855 GtkTreePath *tree_path;
856
857 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_36
; if (sensors_applet) _g_boolean_var_36 = 1; else _g_boolean_var_36
= 0; _g_boolean_var_36; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 857, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
858
859 /* assume tree is not empty */
860 not_empty_tree = TRUE(!(0));
861
862 if (NULL((void*)0) == sensors_applet->sensors) {
863
864 sensors_applet->sensors = gtk_tree_store_new(N_COLUMNS,
865 G_TYPE_STRING((GType) ((16) << (2))), /* path */
866 G_TYPE_STRING((GType) ((16) << (2))), /* id */
867 G_TYPE_STRING((GType) ((16) << (2))), /* label */
868 G_TYPE_STRING((GType) ((16) << (2))), /* interface */
869 G_TYPE_UINT((GType) ((7) << (2))), /* sensor type */
870 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* enable */
871 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* visible */
872 G_TYPE_DOUBLE((GType) ((15) << (2))), /* low value */
873 G_TYPE_DOUBLE((GType) ((15) << (2))), /* high type */
874 G_TYPE_BOOLEAN((GType) ((5) << (2))), /* alarm enable */
875 G_TYPE_STRING((GType) ((16) << (2))), /* low alarm command */
876 G_TYPE_STRING((GType) ((16) << (2))), /* high alarm command */
877 G_TYPE_UINT((GType) ((7) << (2))), /* alarm timeout */
878 G_TYPE_DOUBLE((GType) ((15) << (2))), /* multiplier */
879 G_TYPE_DOUBLE((GType) ((15) << (2))), /* offset */
880 G_TYPE_UINT((GType) ((7) << (2))), /* icon type */
881 GDK_TYPE_PIXBUF(gdk_pixbuf_get_type ()), /* icon pixbuf */
882 G_TYPE_STRING((GType) ((16) << (2)))); /* graph color */
883
884 g_debug("Sensor tree created.");
885
886 /* we know tree is actually empty since we just created it */
887 not_empty_tree = FALSE(0);
888 }
889
890 /* search sensor tree for the parent interface to place this sensor under */
891 for (not_empty_tree = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter);
892 not_empty_tree && not_end_of_interfaces && !interface_exists;
893 not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter)) {
894
895 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &interfaces_iter, INTERFACE_COLUMN, &node_interface, -1);
896 if (g_ascii_strcasecmp(interface, node_interface) == 0) {
897 /* found interface in tree */
898 interface_exists = TRUE(!(0));
899
900 /* now see if this actual sensor already exists within this interface - don't want to add duplicates */
901 /* see if have children */
902 for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter, &interfaces_iter);
903 not_end_of_sensors;
904 not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter)) {
905
906 gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter,
907 PATH_COLUMN, &sensor_path,
908 ID_COLUMN, &sensor_id,
909 SENSOR_TYPE_COLUMN, &sensor_type,
910 -1);
911 if (g_ascii_strcasecmp(sensor_id, id) == 0 && g_ascii_strcasecmp(sensor_path, path) == 0 && sensor_type == type) {
912 /* sensor already exists so dont add a second time */
913 g_debug("sensor with path: %s, id: %s already exists in tree, not adding a second time", sensor_path, sensor_id);
914 g_free(sensor_id);
915 g_free(sensor_path);
916 g_free(node_interface);
917 return FALSE(0);
918 }
919 g_free(sensor_id);
920 g_free(sensor_path);
921 }
922 g_free(node_interface);
923 break;
924 }
925 g_free(node_interface);
926 }
927
928 if (!interface_exists) {
929 /* add to required plugins hash table so we ensure this
930 plugin stays loaded to make sure we have a get sensor
931 value function if possible */
932 g_hash_table_insert(sensors_applet->required_plugins,
933 g_strdup(interface)g_strdup_inline (interface),
934 GINT_TO_POINTER(TRUE)((gpointer) (glong) ((!(0)))));
935 g_debug("added interface %s to required plugins", interface);
936
937 /* wasn't able to find interface root node so create it */
938 gtk_tree_store_append(sensors_applet->sensors,
939 &interfaces_iter,
940 NULL((void*)0));
941
942 gtk_tree_store_set(sensors_applet->sensors,
943 &interfaces_iter,
944 ID_COLUMN, interface,
945 INTERFACE_COLUMN, interface,
946 VISIBLE_COLUMN, FALSE(0),
947 -1);
948 g_debug("Added sensor interface %s to tree", interface);
949 }
950
951 /* then add sensor as a child under interface node - ie assume
952 * we either found it or created it - the inteface node that is */
953
954 /* for now just add sensors all in a single list */
955 gtk_tree_store_append(sensors_applet->sensors, &sensors_iter, &interfaces_iter);
956
957 /* if sensor is already in settings, load values from there */
958 gchar *applet_path = mate_panel_applet_get_preferences_path (sensors_applet->applet);
959 gchar *gsuid = sensors_applet_settings_get_unique_id (interface, id, path);
960 gchar *settings_path = g_strdup_printf ("%s%s/", applet_path, gsuid);
961 GSettings *settings = g_settings_new_with_path ("org.mate.sensors-applet.sensor", settings_path);
962
963 /* add hash to temp sorting list */
964 g_variant_builder_add (&gvb_sensors_hash_list, "s", gsuid);
965
966 g_free (applet_path);
967 g_free (gsuid);
968 g_free (settings_path);
969
970 gchar *settings_id = g_settings_get_string (settings, ID"id");
971
972 if (settings_id != NULL((void*)0) && settings_id[0] != '\0') {
973 enable = g_settings_get_boolean (settings, ENABLED"enabled");
974 icon = sensors_applet_load_icon(g_settings_get_int (settings, ICON_TYPE"icon-type"));
975 gtk_tree_store_set(sensors_applet->sensors,
976 &sensors_iter,
977 PATH_COLUMN, g_settings_get_string (settings, PATH"path"),
978 ID_COLUMN, settings_id,
979 LABEL_COLUMN, g_settings_get_string (settings, LABEL"label"),
980 INTERFACE_COLUMN, g_settings_get_string (settings, INTERFACE"interface"),
981 SENSOR_TYPE_COLUMN, g_settings_get_int (settings, SENSOR_TYPE"sensor-type"),
982 ENABLE_COLUMN, enable,
983 VISIBLE_COLUMN, TRUE(!(0)),
984 LOW_VALUE_COLUMN, g_settings_get_double (settings, LOW_VALUE"low-value"),
985 HIGH_VALUE_COLUMN, g_settings_get_double (settings, HIGH_VALUE"high-value"),
986 ALARM_ENABLE_COLUMN, g_settings_get_boolean (settings, ALARM_ENABLED"alarm-enabled"),
987 ALARM_TIMEOUT_COLUMN, g_settings_get_int (settings, ALARM_TIMEOUT"alarm-timeout"),
988 LOW_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, LOW_ALARM_COMMAND"low-alarm-command"),
989 HIGH_ALARM_COMMAND_COLUMN, g_settings_get_string (settings, HIGH_ALARM_COMMAND"high-alarm-command"),
990 MULTIPLIER_COLUMN, g_settings_get_double (settings, MULTIPLIER"multiplier"),
991 OFFSET_COLUMN, g_settings_get_double (settings, OFFSET"offset"),
992 ICON_TYPE_COLUMN, g_settings_get_int (settings, ICON_TYPE"icon-type"),
993 ICON_PIXBUF_COLUMN, icon,
994 GRAPH_COLOR_COLUMN, g_settings_get_string (settings, GRAPH_COLOR"graph-color"),
995 -1);
996 g_free (settings_id);
997 } else {
998 icon = sensors_applet_load_icon(icon_type);
999 gtk_tree_store_set(sensors_applet->sensors,
1000 &sensors_iter,
1001 PATH_COLUMN, path,
1002 ID_COLUMN, id,
1003 LABEL_COLUMN, label,
1004 INTERFACE_COLUMN, interface,
1005 SENSOR_TYPE_COLUMN, type,
1006 ENABLE_COLUMN, enable,
1007 VISIBLE_COLUMN, TRUE(!(0)),
1008 LOW_VALUE_COLUMN, low_value,
1009 HIGH_VALUE_COLUMN, high_value,
1010 ALARM_ENABLE_COLUMN, alarm_enable,
1011 ALARM_TIMEOUT_COLUMN, alarm_timeout,
1012 LOW_ALARM_COMMAND_COLUMN, low_alarm_command,
1013 HIGH_ALARM_COMMAND_COLUMN, high_alarm_command,
1014 MULTIPLIER_COLUMN, multiplier,
1015 OFFSET_COLUMN, offset,
1016 ICON_TYPE_COLUMN, icon_type,
1017 ICON_PIXBUF_COLUMN, icon,
1018 GRAPH_COLOR_COLUMN, graph_color,
1019 -1);
1020 }
1021 g_object_unref (settings);
1022 g_debug("added sensor %s to tree", path);
1023
1024 /* remove reference to icon as tree now has ref */
1025 g_object_unref(icon);
1026
1027 /* create the active sensor */
1028 if (enable) {
1029 tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), &sensors_iter);
1030 sensors_applet_sensor_enabled(sensors_applet, tree_path);
1031 gtk_tree_path_free(tree_path);
1032 }
1033 return TRUE(!(0));
1034}
1035
1036static ActiveSensor *sensors_applet_find_active_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1037 GtkTreePath *sensor_tree_path;
1038 GList *current_sensor;
1039
1040 for (current_sensor = sensors_applet->active_sensors; current_sensor != NULL((void*)0); current_sensor = g_list_next(current_sensor)((current_sensor) ? (((GList *)(current_sensor))->next) : (
(void*)0))
) {
1041 sensor_tree_path = gtk_tree_row_reference_get_path(((ActiveSensor *)(current_sensor->data))->sensor_row);
1042
1043 if (gtk_tree_path_compare(path, sensor_tree_path) == 0) {
1044 gtk_tree_path_free(sensor_tree_path);
1045 return ((ActiveSensor *)(current_sensor->data));
1046 }
1047 gtk_tree_path_free(sensor_tree_path);
1048 }
1049 return NULL((void*)0);
1050}
1051
1052/* path should be the full path to a file representing the sensor (eg
1053 * /dev/hda or /sys/devices/platform/i2c-0/0-0290/temp1_input) */
1054void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet) {
1055 /* update sensors since will need to update icons / graphs etc
1056 * if weren't displayed before */
1057 GList *list = NULL((void*)0);
1058 for (list = sensors_applet->active_sensors; list != NULL((void*)0); list = list->next) {
1059 ActiveSensor *as = (ActiveSensor *)list->data;
1060 as->updated = FALSE(0);
1061 }
1062 sensors_applet_update_active_sensors(sensors_applet);
1063 sensors_applet_pack_display(sensors_applet);
1064}
1065
1066void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
1067 GtkTreePath *path,
1068 NotifType notif_type) {
1069 ActiveSensor *active_sensor;
1070
1071 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1072 active_sensor_alarm_off(active_sensor, notif_type);
1073 }
1074}
1075
1076void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet, GtkTreePath *path) {
1077 sensors_applet_alarm_off(sensors_applet, path, LOW_ALARM);
1078 sensors_applet_alarm_off(sensors_applet, path, HIGH_ALARM);
1079}
1080
1081void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1082 ActiveSensor *active_sensor;
1083
1084 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_37
; if (sensors_applet) _g_boolean_var_37 = 1; else _g_boolean_var_37
= 0; _g_boolean_var_37; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1084, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1085 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_38
; if (path) _g_boolean_var_38 = 1; else _g_boolean_var_38 = 0
; _g_boolean_var_38; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1085, ((const char*) (__func__
)), "path"); } while (0)
;
1086
1087 active_sensor = active_sensor_new(sensors_applet, gtk_tree_row_reference_new(GTK_TREE_MODEL(sensors_applet->sensors)((((GtkTreeModel*) (void *) ((sensors_applet->sensors))))), path));
1088 active_sensor_update(active_sensor, sensors_applet);
1089
1090 /* keep list sorted */
1091 sensors_applet->active_sensors = g_list_insert_sorted(sensors_applet->active_sensors,
1092 active_sensor,
1093 (GCompareFunc)active_sensor_compare);
1094
1095 sensors_applet_pack_display(sensors_applet);
1096}
1097
1098void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet) {
1099 sensors_applet->active_sensors = g_list_sort(sensors_applet->active_sensors, (GCompareFunc)active_sensor_compare);
1100
1101 sensors_applet_pack_display(sensors_applet);
1102}
1103
1104void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet, GtkTreePath *path) {
1105
1106 ActiveSensor *active_sensor;
1107
1108 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_39
; if (sensors_applet) _g_boolean_var_39 = 1; else _g_boolean_var_39
= 0; _g_boolean_var_39; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1108, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1109 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_40
; if (path) _g_boolean_var_40 = 1; else _g_boolean_var_40 = 0
; _g_boolean_var_40; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1109, ((const char*) (__func__
)), "path"); } while (0)
;
1110
1111 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1112 g_debug("Destroying active sensor...");
1113
1114 g_debug("-- removing from list...");
1115 sensors_applet->active_sensors = g_list_remove(sensors_applet->active_sensors, active_sensor);
1116 g_debug("-- repacking display....");
1117 sensors_applet_pack_display(sensors_applet);
1118
1119 active_sensor_destroy(active_sensor);
1120 }
1121}
1122
1123void sensors_applet_update_sensor(SensorsApplet *sensors_applet, GtkTreePath *path) {
1124 ActiveSensor *active_sensor;
1125
1126 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_41
; if (sensors_applet) _g_boolean_var_41 = 1; else _g_boolean_var_41
= 0; _g_boolean_var_41; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1126, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1127 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_42
; if (path) _g_boolean_var_42 = 1; else _g_boolean_var_42 = 0
; _g_boolean_var_42; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1127, ((const char*) (__func__
)), "path"); } while (0)
;
1128
1129 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1130 active_sensor_update(active_sensor, sensors_applet);
1131 }
1132}
1133
1134void sensors_applet_icon_changed(SensorsApplet *sensors_applet, GtkTreePath *path) {
1135 ActiveSensor *active_sensor;
1136
1137 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_43
; if (sensors_applet) _g_boolean_var_43 = 1; else _g_boolean_var_43
= 0; _g_boolean_var_43; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1137, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1138 g_assert(path)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_44
; if (path) _g_boolean_var_44 = 1; else _g_boolean_var_44 = 0
; _g_boolean_var_44; }), 1)) ; else g_assertion_message_expr (
"sensors-applet", "sensors-applet.c", 1138, ((const char*) (__func__
)), "path"); } while (0)
;
1139
1140 if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet, path)) != NULL((void*)0)) {
1141 active_sensor_icon_changed(active_sensor, sensors_applet);
1142 }
1143}
1144
1145/* Cycle thru ActiveSensors and update them all */
1146gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet) {
1147 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_45
; if (sensors_applet) _g_boolean_var_45 = 1; else _g_boolean_var_45
= 0; _g_boolean_var_45; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1147, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1148
1149 if (sensors_applet->active_sensors) {
1150 g_list_foreach(sensors_applet->active_sensors,
1151 (GFunc)active_sensor_update,
1152 sensors_applet);
1153 return TRUE(!(0));
1154 }
1155 return FALSE(0);
1156}
1157
1158/* Cycle thru ActiveSensors and set new graph dimensions */
1159void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet) {
1160 gint dimensions[2];
1161 gint graph_size;
1162 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_46
; if (sensors_applet) _g_boolean_var_46 = 1; else _g_boolean_var_46
= 0; _g_boolean_var_46; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1162, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1163
1164 if (sensors_applet->active_sensors) {
1165
1166 graph_size = g_settings_get_int (sensors_applet->settings, GRAPH_SIZE"graph-size");
1167 if (mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_UP ||
1168 mate_panel_applet_get_orient(sensors_applet->applet) == MATE_PANEL_APPLET_ORIENT_DOWN) {
1169
1170 /* is horizontal so set graph_size as width */
1171 dimensions[0] = graph_size;
1172 dimensions[1] = sensors_applet->size;
1173 } else {
1174 dimensions[0] = sensors_applet->size;
1175 dimensions[1] = graph_size;
1176 }
1177
1178 g_list_foreach(sensors_applet->active_sensors,
1179 (GFunc)active_sensor_update_graph_dimensions,
1180 &dimensions);
1181 }
1182
1183}
1184
1185gdouble sensors_applet_convert_temperature(gdouble value, TemperatureScale old, TemperatureScale new) {
1186
1187 switch (old) {
1188 case KELVIN:
1189 switch (new) {
1190 case CELSIUS:
1191 value = value - 273.0;
1192 break;
1193 case FAHRENHEIT:
1194 value = (9.0 * (value - 273) / 5.0) + 32.0;
1195 break;
1196 case KELVIN:
1197 break;
1198 }
1199 break;
1200
1201 case CELSIUS:
1202 switch (new) {
1203 case FAHRENHEIT:
1204 value = (9.0 * value / 5.0) + 32.0;
1205 break;
1206 case KELVIN:
1207 value = value + 273.0;
1208 break;
1209 case CELSIUS:
1210 break;
1211 }
1212 break;
1213
1214 case FAHRENHEIT:
1215 switch (new) {
1216 case CELSIUS:
1217 value = (5.0 * (value - 32.0) / 9.0);
1218 break;
1219 case KELVIN:
1220 value = (5.0 * (value - 32.0) / 9.0) + 273.0;
1221 break;
1222 case FAHRENHEIT:
1223 break;
1224 }
1225 break;
1226 }
1227 return value;
1228}
1229
1230void sensors_applet_init(SensorsApplet *sensors_applet) {
1231
1232 g_assert(sensors_applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_47
; if (sensors_applet) _g_boolean_var_47 = 1; else _g_boolean_var_47
= 0; _g_boolean_var_47; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1232, ((const char*) (
__func__)), "sensors_applet"); } while (0)
;
1233 g_assert(sensors_applet->applet)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_48
; if (sensors_applet->applet) _g_boolean_var_48 = 1; else _g_boolean_var_48
= 0; _g_boolean_var_48; }), 1)) ; else g_assertion_message_expr
("sensors-applet", "sensors-applet.c", 1233, ((const char*) (
__func__)), "sensors_applet->applet"); } while (0)
;
1234
1235 GtkActionGroup *action_group;
1236 gchar *ui_path;
1237
1238 /* Have our background automatically painted. */
1239 mate_panel_applet_set_background_widget(MATE_PANEL_APPLET(sensors_applet->applet), GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1240
1241 /* plugin functions are stored as name -> get_value_function pairs so
1242 * use standard string functions on hash table */
1243 sensors_applet->plugins = g_hash_table_new(g_str_hash, g_str_equal);
1244
1245 sensors_applet->required_plugins = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL((void*)0));
1246
1247 /* initialise size */
1248 sensors_applet->size = DEFAULT_APPLET_SIZE24;
1249
1250 mate_panel_applet_set_flags(sensors_applet->applet, MATE_PANEL_APPLET_EXPAND_MINOR);
1251
1252 g_signal_connect(sensors_applet->applet, "destroy",g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1253 G_CALLBACK(destroy_cb),g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
1254 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("destroy"
), (((GCallback) (destroy_cb))), (sensors_applet), ((void*)0)
, (GConnectFlags) 0)
;
1255
1256 /* init gsettings */
1257 sensors_applet->settings = mate_panel_applet_settings_new (sensors_applet->applet, "org.mate.sensors-applet");
1258
1259 /* set up builder for sorting verification */
1260 g_variant_builder_init (&gvb_sensors_hash_list, G_VARIANT_TYPE ("as")(g_variant_type_checked_ (("as"))));
1261
1262 /* set up / load sensors from the plugins */
1263 sensors_applet_plugins_load_all(sensors_applet);
1264
1265 /* set sorting hash array */
1266 GVariant *gv_temp = g_variant_builder_end (&gvb_sensors_hash_list);
1267 sensors_applet->sensors_hash_array = g_variant_dup_strv (gv_temp, NULL((void*)0));
1268 g_variant_unref (gv_temp);
1269
1270 /* sort sensors based on saved sorting */
1271 sensors_applet_settings_sort_sensors(sensors_applet);
1272
1273 /* free hash array */
1274 g_strfreev (sensors_applet->sensors_hash_array);
1275
1276 /* should have created sensors tree above, but if have not was because we couldn't find any sensors */
1277 if (NULL((void*)0) == sensors_applet->sensors) {
1278 GtkWidget *label;
1279 label = gtk_label_new(_("No sensors found!")dcgettext (((void*)0), "No sensors found!", 5));
1280 gtk_container_add(GTK_CONTAINER(sensors_applet->applet)((((GtkContainer*) (void *) ((sensors_applet->applet))))), label);
1281 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1282 return;
1283 }
1284
1285 /* only do menu and signal connections if sensors are found */
1286 action_group = gtk_action_group_new ("Sensors Applet Actions");
1287 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE"mate-sensors-applet");
1288 gtk_action_group_add_actions (action_group,
1289 sensors_applet_menu_actions,
1290 G_N_ELEMENTS (sensors_applet_menu_actions)(sizeof (sensors_applet_menu_actions) / sizeof ((sensors_applet_menu_actions
)[0]))
,
1291 sensors_applet);
1292 ui_path = g_build_filename (UIDIR"/usr/local/share/mate-sensors-applet/ui", SENSORS_APPLET_MENU_FILE"SensorsApplet.xml", NULL((void*)0));
1293 mate_panel_applet_setup_menu_from_file (sensors_applet->applet, ui_path, action_group);
1294 g_free (ui_path);
1295 g_object_unref (action_group);
1296
1297 g_signal_connect(sensors_applet->applet, "style-set",g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1298 G_CALLBACK(style_set_cb),g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
1299 sensors_applet)g_signal_connect_data ((sensors_applet->applet), ("style-set"
), (((GCallback) (style_set_cb))), (sensors_applet), ((void*)
0), (GConnectFlags) 0)
;
1300
1301 g_signal_connect(G_OBJECT(sensors_applet->applet), "change_orient",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1302 G_CALLBACK(change_orient_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1303 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("change_orient"), (((GCallback) (change_orient_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1304
1305 g_signal_connect(G_OBJECT(sensors_applet->applet), "size_allocate",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1306 G_CALLBACK(size_allocate_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
1307 sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("size_allocate"), (((GCallback) (size_allocate_cb
))), (sensors_applet), ((void*)0), (GConnectFlags) 0)
;
1308
1309 g_signal_connect(G_OBJECT(sensors_applet->applet), "leave_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1310 G_CALLBACK(mouse_leave_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1311 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("leave_notify_event"), (((GCallback) (mouse_leave_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1312
1313 g_signal_connect(G_OBJECT(sensors_applet->applet), "enter_notify_event",g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1314 G_CALLBACK(mouse_enter_cb),g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
1315 (gpointer)sensors_applet)g_signal_connect_data ((((((GObject*) (void *) ((sensors_applet
->applet)))))), ("enter_notify_event"), (((GCallback) (mouse_enter_cb
))), ((gpointer)sensors_applet), ((void*)0), (GConnectFlags) 0
)
;
1316
1317 sensors_applet_update_active_sensors(sensors_applet);
1318 sensors_applet_pack_display(sensors_applet);
1319
1320 sensors_applet->timeout_id = g_timeout_add_seconds(g_settings_get_int(sensors_applet->settings, TIMEOUT"timeout-delay") / 1000,
1321 (GSourceFunc)sensors_applet_update_active_sensors,
1322 sensors_applet);
1323 gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet)((((GtkWidget*) (void *) ((sensors_applet->applet))))));
1324}
1325
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/report-f7fb7e.html b/2023-06-14-024037-6156-1@50207d611f25_master/report-f7fb7e.html new file mode 100644 index 0000000..13d6220 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/report-f7fb7e.html @@ -0,0 +1,1133 @@ + + + +udisks2-plugin.c + + + + + + + + + + + + + + + + + + + + + + + + + + +

Bug Summary

+ + + + +
File:plugins/udisks2/udisks2-plugin.c
Warning:line 296, column 84
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 udisks2-plugin.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=none -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/plugins/udisks2 -resource-dir /usr/lib64/clang/16 -D HAVE_CONFIG_H -I . -I ../../sensors-applet -D MATELOCALEDIR="/usr/local/share/locale/" -D G_LOG_DOMAIN="sensors-applet" -D PIXMAPS_DIR="/usr/local/share/pixmaps/mate-sensors-applet/" -D DATADIR="/usr/local/share" -D LIBDIR="/usr/local/lib" -D SYSCONFDIR="/usr/local/etc" -D PREFIX="/usr/local" -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 -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 -O2 -Wno-unused-parameter -fdebug-compilation-dir=/rootdir/plugins/udisks2 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -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-06-14-024037-6156-1 -x c udisks2-plugin.c +
+ + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1/*
2 * Copyright (C) 2017 info-cppsp <info@cppsp.de>
3 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.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/*
22Udisks2 plugin for the mate-sensors-applet
23
24written using the structure and code of the previous version
25from Pramod Dematagoda <pmd.lotr.gandalf@gmail.com>
26
27dbus-glib documentation
28https://dbus.freedesktop.org/doc/dbus-glib/
29GDBUS documentation
30https://developer.gnome.org/gio/stable/index.html
31
32*/
33
34#ifdef HAVE_CONFIG_H1
35#include "config.h"
36#endif /* HAVE_CONFIG_H */
37
38#include <stdio.h>
39#include <gio/gio.h>
40#include "udisks2-plugin.h"
41
42/* remove // from next line for syslog debug */
43//#define UD2PD 1
44
45#ifdef UD2PD
46#include <syslog.h>
47#endif
48
49#define UDISKS2_BUS_NAME"org.freedesktop.UDisks2" "org.freedesktop.UDisks2"
50#define UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager" "org.freedesktop.DBus.ObjectManager"
51#define UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive" "org.freedesktop.UDisks2.Drive"
52#define UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata" "org.freedesktop.UDisks2.Drive.Ata"
53
54#define UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties" "org.freedesktop.DBus.Properties"
55#define UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2" "/org/freedesktop/UDisks2"
56
57/* Info about a single sensor */
58typedef struct _DevInfo {
59 gchar *path;
60 gchar *id;
61 gdouble temp;
62 GDBusProxy *sensor_proxy; /* dbus object */
63 GError *error;
64} DevInfo;
65
66const gchar *plugin_name = "udisks2";
67
68/* a container for the devices found to have smart enabled */
69GHashTable *devices = NULL((void*)0);
70
71/* This is a global variable for convenience */
72GDBusConnection *connection = NULL((void*)0);
73
74static void update_device (DevInfo *info) {
75 GError *error = NULL((void*)0);
76 GVariant *tempgvar = NULL((void*)0);
77 GVariant *tempgvar2 = NULL((void*)0);
78 gdouble temp;
79
80 /* check valid input parameter */
81 g_return_if_fail (info != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_14
; if (info != ((void*)0)) _g_boolean_var_14 = 1; else _g_boolean_var_14
= 0; _g_boolean_var_14; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "info != NULL"
); return; } } while (0)
;
82
83 /* check connection too */
84 g_return_if_fail (connection != NULL)do { if ((__builtin_expect (__extension__ ({ int _g_boolean_var_15
; if (connection != ((void*)0)) _g_boolean_var_15 = 1; else _g_boolean_var_15
= 0; _g_boolean_var_15; }), 1))) { } else { g_return_if_fail_warning
("sensors-applet", ((const char*) (__func__)), "connection != NULL"
); return; } } while (0)
;
85
86 g_clear_error (&info->error);
87
88 /* check for sensor_proxy, which should exist at this point, make one if necessary and save it into DevInfo
89 * this is used to get the temp value the direct way */
90 if (NULL((void*)0) == info->sensor_proxy) {
91 info->sensor_proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
92 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
93 info->path,
94 UDISKS2_PROPERTIES_INTERFACE"org.freedesktop.DBus.Properties",
95 NULL((void*)0), &error);
96
97 /* check, just to be sure */
98 if (NULL((void*)0) == info->sensor_proxy) {
99
100#ifdef UD2PD
101syslog(LOG_ERR, "Failed to get drive temperature 1");
102#endif
103 g_debug ("Failed to get drive temperature 1: %s", error->message);
104 g_clear_error (&error);
105 return;
106 }
107 }
108
109/* note on timing:
110 * it seems to me that smart updates occur automatically every 10 minutes
111 * mate-sensor-applet has a default refresh of 2 seconds...
112 * it is possible to force a smart update with udisks2: SmartUpdate (IN a{sv} options); */
113
114 /* directly asking the device's DBus object for the temp */
115 tempgvar = g_dbus_proxy_call_sync (info->sensor_proxy, "Get",
116 g_variant_new ("(ss)",
117 UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata",
118 "SmartTemperature"), /* parameters */
119 G_DBUS_CALL_FLAGS_NONE, /* flags */
120 -1, /* timeout */
121 NULL((void*)0), /* cancellable */
122 &error);
123
124 if (NULL((void*)0) == tempgvar) {
125
126#ifdef UD2PD
127syslog(LOG_ERR, "Failed to get drive temperature 2");
128#endif
129 g_debug ("Failed to get drive temperature 2: %s", error->message);
130 g_clear_error (&error);
131 /* throw away proxy, maybe next time it will be better */
132 g_clear_object (&info->sensor_proxy)do { _Static_assert (sizeof *((&info->sensor_proxy)) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&info->sensor_proxy))) _pp = ((&info->sensor_proxy
)); __typeof__ (*((&info->sensor_proxy))) _ptr = *_pp;
*_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
133 return;
134
135 } else {
136
137#ifdef UD2PD
138syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(tempgvar, TRUE(!(0))));
139/* leaks memory! */
140//syslog(LOG_ERR, "tempgvar value: %s", g_variant_print(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0)), TRUE));
141#endif
142
143 /* tempgvar comes back as something along the lines of array(gvariant(tempasdouble))
144 * hence unpacking
145 * need to free up every param / return value, so can't do it like:
146 * temp = g_variant_get_double(g_variant_get_variant(g_variant_get_child_value(tempgvar, 0))); */
147 tempgvar2 = g_variant_get_child_value (tempgvar, 0);
148 g_variant_unref (tempgvar);
149 tempgvar = g_variant_get_variant (tempgvar2);
150 g_variant_unref (tempgvar2);
151 temp = g_variant_get_double (tempgvar);
152 g_variant_unref (tempgvar);
153
154 /* temp in K */
155 info->temp = temp - 273.15;
156
157#ifdef UD2PD
158syslog(LOG_ERR, "Refresh udisks2 device temp: '%f'\n", info->temp);
159#endif
160
161 }
162
163}
164
165/* in this function we would like to get a list of device (hdd/ssd) paths
166 * then with each path we get the temperature
167 * it is possible with udisks2 to get all the above information in one g_dbus_proxy_call_sync(), so that is how I did it
168 * maybe a better version would be to use GDBusObjectManager Server + Client ?? */
169static void udisks2_plugin_get_sensors (GList **sensors) {
170
171#ifdef UD2PD
172syslog(LOG_ERR, "fstart");
173#endif
174
175 GDBusProxy *proxy = NULL((void*)0);
176 GError *error = NULL((void*)0);
177
178 DevInfo *info;
179
180 /* This connection will be used for everything, including the obtaining of sensor data */
181 connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL((void*)0), &error);
182 if (NULL((void*)0) == connection) {
183
184#ifdef UD2PD
185syslog(LOG_ERR, "dbus conn fail");
186#endif
187
188 g_debug ("Failed to open connection to DBUS: %s", error->message);
189 g_clear_error (&error);
190 return;
191 }
192
193#ifdef UD2PD
194syslog(LOG_ERR, "dbus conn success");
195#endif
196
197 /* I use this proxy to get all info of all devices at once */
198 proxy = g_dbus_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE, NULL((void*)0),
199 UDISKS2_BUS_NAME"org.freedesktop.UDisks2",
200 UDISKS2_OBJECT_PATH"/org/freedesktop/UDisks2",
201 UDISKS2_INTERFACE_NAME"org.freedesktop.DBus.ObjectManager",
202 NULL((void*)0), &error);
203
204 if (NULL((void*)0) == proxy) {
205
206#ifdef UD2PD
207syslog(LOG_ERR, "dbus conn proxy fail");
208#endif
209 g_debug ("dbus conn proxy fail: %s", error->message);
210 g_clear_error (&error);
211 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
212 return;
213 }
214
215#ifdef UD2PD
216syslog(LOG_ERR, "dbus conn proxy success");
217#endif
218
219 /* The object paths of the disks are enumerated and placed in an array of object paths
220 * "GetManagedObjects" returns dict of (objectpath, (dict of (string [ie. if. name], dict of(string [ie. property name], variant [ie. prop. value])))) */
221
222 /* g_dbus_proxy_call_sync() returns NULL on error, GVariant * otherwise
223 * need second variable to prevent memory leak */
224 GVariant *managed_objects = NULL((void*)0);
225 GVariant *managed_objects2 = NULL((void*)0);
226
227 managed_objects2 = g_dbus_proxy_call_sync (proxy, "GetManagedObjects",
228 NULL((void*)0), /* parameters */
229 G_DBUS_CALL_FLAGS_NONE, /* flags */
230 -1, /* timeout */
231 NULL((void*)0), /* cancellable */
232 &error);
233
234 if (NULL((void*)0) == managed_objects2) {
235
236#ifdef UD2PD
237syslog(LOG_ERR, "Failed to enumerate disk devices");
238#endif
239
240 g_debug ("Failed to enumerate disk devices: %s", error->message);
241 g_clear_error (&error);
242 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
243 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
244 return;
245 }
246
247 /* the result dictionary is enclosed in an array, unpack */
248 managed_objects = g_variant_get_child_value (managed_objects2, 0);
249 g_variant_unref (managed_objects2);
250
251#ifdef UD2PD
252//syslog(LOG_ERR, "managed_objects type: %s", g_variant_print(managed_objects, TRUE));
253syslog(LOG_ERR, "success to enumerate disk devices");
254#endif
255
256 /* iterator for the result dictionary
257 * iterator code is based on the g_variant_iter_next() documentation
258 * iter is freed if the GVariant is, when using g_variant_iter_init() */
259 GVariantIter iter;
260 gchar *key = NULL((void*)0); /* object path (like '/org/freedesktop/UDisks2/drives/Samsung_SSD_840_EVO_250GB_*insert drive serial nr.*') */
261 GVariant *value = NULL((void*)0);
262
263#ifdef UD2PD
264/* log collection size */
265syslog(LOG_ERR, "iter init count: %d", (int) g_variant_iter_init (&iter, managed_objects));
266#else
267 g_variant_iter_init (&iter, managed_objects);
268#endif
269
270 /* "{sv}" is a GVariant format string
271 * {} dictionary of, s string, v GVariant
272 * changed to "{oa{sa{sv}}}" on error message 'the GVariant format string '{sv}' has a type of '{sv}' but the given value has a type of 'a{oa{sa{sv}}}''
273 * a is array, o is object path
274 * NOO!! the right format string is "{o@*}", which means get an object path into the 1st variable (key)
275 * and get 'everything else' (as a GVariant) into the 2nd variable (value)
276 * needs the & before the key and value params! */
277 while (g_variant_iter_next (&iter, "{o@*}", &key, &value)) {
278
279#ifdef UD2PD
280syslog(LOG_ERR, "in iter while loop");
281syslog(LOG_ERR, "key value: %s", key);
282//syslog(LOG_ERR, "value type: %s", g_variant_print(value, TRUE));
283#endif
284
285 /* level 2
286 * create a dictionary of value
287 * the two interface names that we are searching for are known and defined
288 * can't use GVariantDict, it only supports '{sv}' but the given value has a type of '{sa{sv}}'
289 * using general lookup */
290
291 GVariant *propdict = NULL((void*)0); /* drive data */
292 GVariant *propdict2 = NULL((void*)0); /* drive smart data */
293
294 /* make two dictionaries that contain the properties of the drive interfaces */
295 propdict = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE_NAME"org.freedesktop.UDisks2.Drive", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
296 propdict2 = g_variant_lookup_value (value, UDISKS2_DEVICE_INTERFACE2_NAME"org.freedesktop.UDisks2.Drive.Ata", G_VARIANT_TYPE_DICTIONARY((const GVariantType *) "a{?*}"));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
297
298 /* do we have the right ifname keys? */
299 if ((NULL((void*)0) != propdict) && (NULL((void*)0) != propdict2)) {
300
301#ifdef UD2PD
302syslog(LOG_ERR, "propdict type: %s", g_variant_print(propdict, TRUE(!(0))));
303syslog(LOG_ERR, "propdict2 type: %s", g_variant_print(propdict2, TRUE(!(0))));
304#endif
305
306 /* get data */
307 gchar *id = NULL((void*)0);
308 gchar *model = NULL((void*)0);
309
310 gboolean smartenabled;
311 gdouble temp;
312
313 /* NULL, bc we don't care about the length of the string
314 * typecast bc g_variant_get_string() returns const char* */
315 id = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Id", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
316 model = (gchar *) g_variant_get_string (g_variant_lookup_value (propdict, "Model", G_VARIANT_TYPE_STRING((const GVariantType *) "s")), NULL((void*)0));
317
318 smartenabled = g_variant_get_boolean (g_variant_lookup_value (propdict2, "SmartEnabled", G_VARIANT_TYPE_BOOLEAN((const GVariantType *) "b")));
319 temp = g_variant_get_double (g_variant_lookup_value (propdict2, "SmartTemperature", G_VARIANT_TYPE_DOUBLE((const GVariantType *) "d")));
320
321#ifdef UD2PD
322syslog(LOG_ERR, "Found udisks2 device id: '%s'\n", id);
323syslog(LOG_ERR, "Found udisks2 device model: '%s'\n", model);
324syslog(LOG_ERR, "Found udisks2 device smartenabled: '%d'\n", smartenabled);
325syslog(LOG_ERR, "Found udisks2 device temp: '%f'\n", temp);
326#endif
327
328 /* only go on if smart is enabled
329 * save data */
330 if (smartenabled) {
331
332 info = g_new0 (DevInfo, 1)(DevInfo *) (__extension__ ({ gsize __n = (gsize) (1); gsize __s
= sizeof (DevInfo); gpointer __p; if (__s == 1) __p = g_malloc0
(__n); else if (__builtin_constant_p (__n) && (__s ==
0 || __n <= (9223372036854775807L *2UL+1UL) / __s)) __p =
g_malloc0 (__n * __s); else __p = g_malloc0_n (__n, __s); __p
; }))
;
333 if (NULL((void*)0) == devices) {
334 devices = g_hash_table_new (g_str_hash, g_str_equal);
335 }
336
337 info->id = g_strdup (id)g_strdup_inline (id);
338 info->path = g_strdup (key)g_strdup_inline (key);
339
340 /* temp in K
341 * this could be left at 0.0, 2 seconds later it will be refreshed anyway */
342 info->temp = (gdouble) temp - 273.15;
343 g_hash_table_insert (devices, info->id, info);
344
345 /* Write the sensor data */
346 sensors_applet_plugin_add_sensor (sensors,
347 id,
348 "Disk Temperature",
349 model,
350 TEMP_SENSOR,
351 FALSE(0),
352 HDD_ICON,
353 DEFAULT_GRAPH_COLOR"#ff0000");
354
355 g_debug ("Added %s", id);
356
357#ifdef UD2PD
358syslog(LOG_ERR, "Added %s", id);
359#endif
360
361 } else {
362
363#ifdef UD2PD
364syslog(LOG_ERR, "No temp data for device: %s\n", key);
365#endif
366
367 g_debug ("No temp data for device: %s\n", key);
368 }
369
370#ifdef UD2PD
371syslog(LOG_ERR, "b4 free1");
372#endif
373
374 g_free (id);
375 g_free (model);
376
377 }
378
379#ifdef UD2PD
380syslog(LOG_ERR, "b4 free2");
381#endif
382
383 /* free propdict, propdict2
384 * g_variant_dict_unref() may not work a few times, gives error
385 * this one seems to do fine */
386 if (NULL((void*)0) != propdict) {g_variant_unref (propdict);}
387 if (NULL((void*)0) != propdict2) {g_variant_unref (propdict2);}
388
389#ifdef UD2PD
390syslog(LOG_ERR, "b4 free3");
391#endif
392
393 g_free (key);
394 g_variant_unref (value);
395
396 } /* end of while loop */
397
398 g_variant_unref (managed_objects);
399 g_clear_object (&proxy)do { _Static_assert (sizeof *((&proxy)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&proxy
))) _pp = ((&proxy)); __typeof__ (*((&proxy))) _ptr =
*_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); }
while (0)
;
400 if (NULL((void*)0) == devices) {
401 g_clear_object (&connection)do { _Static_assert (sizeof *((&connection)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&connection
))) _pp = ((&connection)); __typeof__ (*((&connection
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
402 }
403}
404
405/* this function is called every refresh cycle */
406static gdouble udisks2_plugin_get_sensor_value (const gchar *path,
407 const gchar *id,
408 SensorType type,
409 GError **error) {
410 DevInfo *info = NULL((void*)0);
411
412 /* get device stuct from data store */
413 info = (DevInfo *) g_hash_table_lookup (devices, path);
414 if (NULL((void*)0) == info) {
415 g_set_error (error, SENSORS_APPLET_PLUGIN_ERROR(sensors_applet_plugin_error_quark()), 0, "Error finding disk with path %s", path);
416 return 0.0;
417 }
418
419 if (info->error) {
420 *error = info->error;
421 info->error = NULL((void*)0);
422 return 0.0;
423 }
424
425 /* refresh device temp */
426 update_device (info);
427 return info->temp;
428}
429
430/* API functions */
431const gchar *sensors_applet_plugin_name (void) {
432 return plugin_name;
433}
434
435static GList *udisks2_plugin_init (void) {
436 GList *sensors = NULL((void*)0);
437
438 udisks2_plugin_get_sensors (&sensors);
439
440 return sensors;
441}
442
443GList *sensors_applet_plugin_init (void) {
444 return udisks2_plugin_init ();
445}
446
447gdouble sensors_applet_plugin_get_sensor_value (const gchar *path,
448 const gchar *id,
449 SensorType type,
450 GError **error) {
451
452 return udisks2_plugin_get_sensor_value (path, id, type, error);
453}
diff --git a/2023-06-14-024037-6156-1@50207d611f25_master/scanview.css b/2023-06-14-024037-6156-1@50207d611f25_master/scanview.css new file mode 100644 index 0000000..cf8a5a6 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/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-06-14-024037-6156-1@50207d611f25_master/sorttable.js b/2023-06-14-024037-6156-1@50207d611f25_master/sorttable.js new file mode 100644 index 0000000..32faa07 --- /dev/null +++ b/2023-06-14-024037-6156-1@50207d611f25_master/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("