Bug Summary

File:cafe-disk-image-mounter/src/main.c
Warning:line 207, column 18
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/cafe-disk-image-mounter/src -fcoverage-compilation-dir=/rootdir/cafe-disk-image-mounter/src -resource-dir /usr/lib/llvm-21/lib/clang/21 -D HAVE_CONFIG_H -I . -I ../.. -I . -I . -D G_LOG_DOMAIN="cafe-disk-image-mounter" -D CAFELOCALEDIR="/usr/share/locale" -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/udisks2 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cairo -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/atk-1.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-03-12-092437-92740-1 -x c main.c
1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 *
3 * Copyright (C) 2012 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: David Zeuthen <davidz@redhat.com>
21 */
22
23#include "config.h"
24#include <glib/gi18n.h>
25
26#include <glib-unix1.h>
27#include <gio/gunixfdlist.h>
28
29#include <ctk/ctk.h>
30
31#include <udisks/udisks.h>
32
33static gboolean have_ctk = FALSE(0);
34static UDisksClient *udisks_client = NULL((void*)0);
35static GMainLoop *main_loop = NULL((void*)0);
36
37/* ---------------------------------------------------------------------------------------------------- */
38
39static void
40show_error (const gchar *format, ...)
41{
42 va_list var_args;
43 gchar *s;
44
45 va_start (var_args, format)__builtin_va_start(var_args, format);
46
47 s = g_strdup_vprintf (format, var_args);
48
49 if (have_ctk)
50 {
51 CtkWidget *dialog;
52 dialog = ctk_message_dialog_new_with_markup (NULL((void*)0),
53 CTK_DIALOG_MODAL,
54 CTK_MESSAGE_ERROR,
55 CTK_BUTTONS_CLOSE,
56 "<big><b>%s</b></big>",
57 _("An error occurred")gettext ("An error occurred"));
58 ctk_message_dialog_format_secondary_markup (CTK_MESSAGE_DIALOG (dialog)((((CtkMessageDialog*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((dialog)), ((ctk_message_dialog_get_type ())
)))))
, "%s", s);
59 ctk_window_set_title (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, _("CAFE Disk Image Mounter")gettext ("CAFE Disk Image Mounter"));
60 ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
);
61 ctk_widget_destroy (dialog);
62 }
63 else
64 {
65 g_printerr ("%s\n", s);
66 }
67
68 g_free (s);
69 va_end (var_args)__builtin_va_end(var_args);
70}
71
72/* ---------------------------------------------------------------------------------------------------- */
73
74static gboolean opt_writable = FALSE(0);
75
76static const GOptionEntry opt_entries[] =
77{
78 { "writable", 'w', 0, G_OPTION_ARG_NONE, &opt_writable, N_("Allow writing to the image")("Allow writing to the image"), NULL((void*)0)},
79 { NULL((void*)0) }
80};
81
82/* ---------------------------------------------------------------------------------------------------- */
83
84/* TODO: keep in sync with src/disks/gduutils.c (ideally in shared lib) */
85static void
86_gdu_utils_configure_file_chooser_for_disk_images (CtkFileChooser *file_chooser)
87{
88 CtkFileFilter *filter;
89 const gchar *folder;
90
91 /* Default to the "Documents" folder since that's where we save such images */
92 folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
93 if (folder != NULL((void*)0))
94 ctk_file_chooser_set_current_folder (file_chooser, folder);
95
96 /* TODO: define proper mime-types */
97 filter = ctk_file_filter_new ();
98 ctk_file_filter_set_name (filter, _("All Files")gettext ("All Files"));
99 ctk_file_filter_add_pattern (filter, "*");
100 ctk_file_chooser_add_filter (file_chooser, filter); /* adopts filter */
101 filter = ctk_file_filter_new ();
102 ctk_file_filter_set_name (filter, _("Disk Images (*.img, *.iso)")gettext ("Disk Images (*.img, *.iso)"));
103 ctk_file_filter_add_pattern (filter, "*.img");
104 ctk_file_filter_add_pattern (filter, "*.iso");
105 ctk_file_chooser_add_filter (file_chooser, filter); /* adopts filter */
106 ctk_file_chooser_set_filter (file_chooser, filter);
107}
108
109static GSList *
110do_filechooser (void)
111{
112 GSList *ret = NULL((void*)0);
113 CtkWidget *dialog;
114 CtkWidget *ro_checkbutton;
115
116 ret = NULL((void*)0);
117
118 dialog = ctk_file_chooser_dialog_new (_("Select Disk Image(s) to Mount")gettext ("Select Disk Image(s) to Mount"),
119 NULL((void*)0), /* parent window */
120 CTK_FILE_CHOOSER_ACTION_OPEN,
121 _("_Cancel")gettext ("_Cancel"), CTK_RESPONSE_CANCEL,
122 _("_Mount")gettext ("_Mount"), CTK_RESPONSE_ACCEPT,
123 NULL((void*)0));
124 _gdu_utils_configure_file_chooser_for_disk_images (CTK_FILE_CHOOSER (dialog)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_file_chooser_get_type ()))))))
);
125 ctk_file_chooser_set_local_only (CTK_FILE_CHOOSER (dialog)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_file_chooser_get_type ()))))))
, FALSE(0));
126
127 /* Add a RO check button that defaults to RO */
128 ro_checkbutton = ctk_check_button_new_with_mnemonic (_("Set up _read-only mount")gettext ("Set up _read-only mount"));
129 ctk_widget_set_tooltip_markup (ro_checkbutton, _("If checked, the mount will be read-only. This is useful if you don't want the underlying disk image to be modified")gettext ("If checked, the mount will be read-only. This is useful if you don't want the underlying disk image to be modified"
)
);
130 ctk_toggle_button_set_active (CTK_TOGGLE_BUTTON (ro_checkbutton)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ro_checkbutton)), ((ctk_toggle_button_get_type ()))))))
, !opt_writable);
131 ctk_file_chooser_set_select_multiple (CTK_FILE_CHOOSER (dialog)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_file_chooser_get_type ()))))))
, TRUE(!(0)));
132 ctk_file_chooser_set_extra_widget (CTK_FILE_CHOOSER (dialog)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_file_chooser_get_type ()))))))
, ro_checkbutton);
133
134 //ctk_widget_show_all (dialog);
135 if (ctk_dialog_run (CTK_DIALOG (dialog)((((CtkDialog*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_dialog_get_type ()))))))
) != CTK_RESPONSE_ACCEPT)
136 goto out;
137
138 ret = ctk_file_chooser_get_uris (CTK_FILE_CHOOSER (dialog)((((CtkFileChooser*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_file_chooser_get_type ()))))))
);
139 opt_writable = ! ctk_toggle_button_get_active (CTK_TOGGLE_BUTTON (ro_checkbutton)((((CtkToggleButton*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ro_checkbutton)), ((ctk_toggle_button_get_type ()))))))
);
140
141 out:
142 ctk_widget_destroy (dialog);
143 return ret;
144}
145
146/* ---------------------------------------------------------------------------------------------------- */
147
148int
149main (int argc, char *argv[])
150{
151 gint ret = 1;
152 GError *error = NULL((void*)0);
153 gchar *s = NULL((void*)0);
154 GOptionContext *o = NULL((void*)0);
155 gint n;
156 GSList *uris = NULL((void*)0);
157 GSList *l;
158
159 bindtextdomain (GETTEXT_PACKAGE"cafe-utils", CAFELOCALEDIR"/usr/share/locale");
160 bind_textdomain_codeset (GETTEXT_PACKAGE"cafe-utils", "UTF-8");
161 textdomain (GETTEXT_PACKAGE"cafe-utils");
162
163 have_ctk = ctk_init_check (&argc, &argv);
164
165 if (have_ctk)
166 ctk_window_set_default_icon_name ("drive-removable-media");
167
168 main_loop = g_main_loop_new (NULL((void*)0), FALSE(0));
169
170 udisks_client = udisks_client_new_sync (NULL((void*)0), &error);
171 if (udisks_client == NULL((void*)0))
172 {
173 g_printerr (_("Error connecting to udisks daemon: %s (%s, %d)")gettext ("Error connecting to udisks daemon: %s (%s, %d)"),
174 error->message, g_quark_to_string (error->domain), error->code);
175 g_error_free (error);
176 goto out;
177 }
178
179 o = g_option_context_new (NULL((void*)0));
180 g_option_context_set_help_enabled (o, FALSE(0));
181 g_option_context_set_summary (o, _("Attach and mount one or more disk image files.")gettext ("Attach and mount one or more disk image files."));
182 g_option_context_add_main_entries (o, opt_entries, GETTEXT_PACKAGE"cafe-utils");
183
184 if (!g_option_context_parse (o, &argc, &argv, NULL((void*)0)))
185 {
186 s = g_option_context_get_help (o, FALSE(0), NULL((void*)0));
187 g_printerr ("%s", s);
188 g_free (s);
189 goto out;
190 }
191
192 if (argc > 1)
193 {
194 for (n = 1; n < argc; n++)
195 uris = g_slist_prepend (uris, g_strdup (argv[n])g_strdup_inline (argv[n]));
196 uris = g_slist_reverse (uris);
197 }
198 else
199 {
200 if (!have_ctk)
201 {
202 show_error ("No files given and CTK+ not available");
203 goto out;
204 }
205 else
206 {
207 uris = do_filechooser ();
This statement is never executed
208 }
209 }
210
211 /* Files to attach are positional arguments */
212 for (l = uris; l != NULL((void*)0); l = l->next)
213 {
214 const gchar *uri;
215 gchar *filename;
216 GUnixFDList *fd_list = NULL((void*)0);
217 GVariantBuilder options_builder;
218 gint fd;
219 gchar *loop_object_path = NULL((void*)0);
220 GFile *file;
221
222 uri = l->data;
223 file = g_file_new_for_commandline_arg (uri);
224 filename = g_file_get_path (file);
225 g_object_unref (file);
226
227 if (filename == NULL((void*)0))
228 {
229 show_error (_("Cannot open `%s' - maybe the volume isn't mounted?")gettext ("Cannot open `%s' - maybe the volume isn't mounted?"
)
, uri);
230 goto done_with_image;
231 }
232
233 fd = open (filename, opt_writable ? O_RDWR02 : O_RDONLY00);
234 if (fd == -1)
235 {
236 show_error (_("Error opening `%s': %m")gettext ("Error opening `%s': %m"), filename);
237 goto done_with_image;
238 }
239
240 g_variant_builder_init (&options_builder, G_VARIANT_TYPE ("a{sv}")(g_variant_type_checked_ (("a{sv}"))));
241 if (!opt_writable)
242 g_variant_builder_add (&options_builder, "{sv}", "read-only", g_variant_new_boolean (TRUE(!(0))));
243
244 fd_list = g_unix_fd_list_new_from_array (&fd, 1); /* adopts the fd */
245
246 /* Set up the disk image... */
247 error = NULL((void*)0);
248 if (!udisks_manager_call_loop_setup_sync (udisks_client_get_manager (udisks_client),
249 g_variant_new_handle (0),
250 g_variant_builder_end (&options_builder),
251 fd_list,
252 &loop_object_path,
253 NULL((void*)0), /* out_fd_list */
254 NULL((void*)0), /* GCancellable */
255 &error))
256 {
257 show_error (_("Error attaching disk image: %s (%s, %d)")gettext ("Error attaching disk image: %s (%s, %d)"),
258 error->message, g_quark_to_string (error->domain), error->code);
259 g_clear_error (&error);
260 goto done_with_image;
261 }
262
263 /* Note that the desktop automounter is responsible for mounting,
264 * unlocking etc. partitions etc. inside the image...
265 */
266
267 done_with_image:
268
269 g_clear_object (&fd_list)do { _Static_assert (sizeof *((&fd_list)) == sizeof (gpointer
), "Expression evaluates to false"); __typeof__ (((&fd_list
))) _pp = ((&fd_list)); __typeof__ (*((&fd_list))) _ptr
= *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr)
; } while (0)
;
270 g_free (filename);
271 g_free (loop_object_path);
272
273 } /* for each image */
274
275 ret = 0;
276
277 out:
278 if (main_loop != NULL((void*)0))
279 g_main_loop_unref (main_loop);
280 g_slist_free_full (uris, g_free);
281 g_clear_object (&udisks_client)do { _Static_assert (sizeof *((&udisks_client)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&udisks_client))) _pp = ((&udisks_client)); __typeof__
(*((&udisks_client))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
282 return ret;
283}