| File: | cafe-disk-image-mounter/src/main.c |
| Warning: | line 233, column 43 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | |
| 33 | static gboolean have_ctk = FALSE(0); |
| 34 | static UDisksClient *udisks_client = NULL((void*)0); |
| 35 | static GMainLoop *main_loop = NULL((void*)0); |
| 36 | |
| 37 | /* ---------------------------------------------------------------------------------------------------- */ |
| 38 | |
| 39 | static void |
| 40 | show_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 | |
| 74 | static gboolean opt_writable = FALSE(0); |
| 75 | |
| 76 | static 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) */ |
| 85 | static 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 | |
| 109 | static GSList * |
| 110 | do_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 | |
| 148 | int |
| 149 | main (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 (); |
| 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); |
This statement is never executed | |
| 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 | } |