~ubuntu-core-dev/update-notifier/ubuntu

« back to all changes in this revision

Viewing changes to src/gdu.c

  • Committer: Lionel Le Folgoc
  • Date: 2011-02-13 12:39:35 UTC
  • Revision ID: mrpouit@ubuntu.com-20110213123935-hc46lt2c32z8z8qb
Tags: 0.110.3ubuntu2
releasing version 0.110.3ubuntu2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
1
2
#ifdef HAVE_CONFIG_H
2
3
#include "config.h"
3
4
#endif
 
5
#ifdef HAVE_GDU
 
6
#include <glib.h>
 
7
#include <glib-object.h>
4
8
 
5
 
#include <glib.h>
6
9
#include <sys/types.h>
7
10
#include <sys/wait.h>
8
11
 
9
 
 
10
12
#include "update-notifier.h"
11
 
#include "hal.h"
 
13
#define GDU_API_IS_SUBJECT_TO_CHANGE
 
14
#include <gdu/gdu.h>
 
15
#include "gdu.h"
12
16
 
13
17
#define CDROM_CHECKER PACKAGE_LIB_DIR"/update-notifier/apt-cdrom-check"
14
18
 
35
39
   CD_WITH_APTONCD   
36
40
};
37
41
 
38
 
static LibHalContext *hal_ctx;
39
 
static DBusConnection *dbus_connection;
40
 
 
41
 
void distro_cd_detected(UpgradeNotifier *un, int cdtype, char *mount_point)
 
42
void distro_cd_detected(UpgradeNotifier *un, 
 
43
                        int cdtype, 
 
44
                        const char *mount_point)
42
45
{
43
46
   GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
44
47
                                              GTK_MESSAGE_QUESTION, 
47
50
   gchar *title, *markup;
48
51
   switch(cdtype) {
49
52
   case CD_WITH_PACKAGES:
50
 
      title = _("Software packages volume detected");
 
53
      title = _("Software Packages Volume Detected");
51
54
      markup = _("<span weight=\"bold\" size=\"larger\">"
52
55
            "A volume with software packages has "
53
56
            "been detected.</span>\n\n"
56
59
      gtk_dialog_add_buttons(GTK_DIALOG(dialog), 
57
60
                             GTK_STOCK_CANCEL,
58
61
                             GTK_RESPONSE_REJECT,
59
 
                             _("Start package manager"), 
 
62
                             _("Start Package Manager"), 
60
63
                             RES_START_PM,
61
64
                             NULL);
62
65
      gtk_dialog_set_default_response (GTK_DIALOG(dialog), RES_START_PM);
127
130
      break;
128
131
   case RES_DIST_UPGRADER:
129
132
      argv[0] = "/usr/lib/update-notifier/cddistupgrader";
130
 
      argv[1] = mount_point;
 
133
      argv[1] = (gchar *)mount_point;
131
134
      argv[2] = NULL;
132
135
      g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL);
133
136
      break;
143
146
   gtk_widget_destroy (dialog);
144
147
}
145
148
 
146
 
/** Invoked by GLib in response to a D-BUS disconnect event.
147
 
 *
148
 
 * @param  data                 Context pointer
149
 
 */
150
 
static gboolean
151
 
up_reconnect_to_hal (gpointer data __attribute__((__unused__)))
152
 
{
153
 
        static unsigned int retries = 0;
154
 
 
155
 
        g_message ("Trying a reconnect ...");
156
 
        hal_ctx = up_do_hal_init ();
157
 
        if (hal_ctx != NULL) {
158
 
                g_message ("Reconnected OK.");
159
 
                retries = 0;
160
 
                return FALSE;
161
 
        } else if (dbus_connection) { 
162
 
           dbus_connection_unref (dbus_connection);
163
 
           dbus_connection = NULL;
164
 
        }
165
 
 
166
 
        /* Retry later if it failed. */
167
 
        if (retries++ < 6000)
168
 
                return TRUE;
169
 
 
170
 
        /* Too many retries; clean up and bail. */
171
 
        g_warning ("gvm_reconnect_to_hal: no reconnection after 6000 retries, "
172
 
                   "exiting\n");
173
 
 
174
 
        /* Too many retries; clean up and bail. */
175
 
        gtk_main_quit ();
176
 
        return FALSE;
177
 
}
178
 
 
179
 
static DBusHandlerResult
180
 
up_do_filter_dbus_msg (DBusConnection *connection __attribute__((__unused__)),
181
 
                        DBusMessage *message,
182
 
                        void *user_data __attribute__((__unused__)))
183
 
{
184
 
        DBusError error;
185
 
 
186
 
        if (dbus_message_is_signal (message,
187
 
                                    DBUS_INTERFACE_LOCAL,
188
 
                                    "Disconnected")) {
189
 
                g_timeout_add(1000, up_reconnect_to_hal, NULL);
190
 
                libhal_ctx_shutdown (hal_ctx, &error);
191
 
                libhal_ctx_free (hal_ctx);
192
 
                hal_ctx = NULL;
193
 
                dbus_connection_unref (dbus_connection);
194
 
                dbus_connection = NULL;
195
 
                return DBUS_HANDLER_RESULT_HANDLED;
196
 
        }
197
 
        else
198
 
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
199
 
}
200
 
 
201
 
static dbus_bool_t
202
 
hal_mainloop_integration (LibHalContext *ctx, 
203
 
                           DBusError *error)
204
 
                          
205
 
{
206
 
 
207
 
        dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, error);
208
 
 
209
 
        if (dbus_error_is_set (error))
210
 
                return FALSE;
211
 
 
212
 
        dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
213
 
 
214
 
        dbus_connection_setup_with_g_main (dbus_connection, NULL);
215
 
        dbus_connection_add_filter (dbus_connection, up_do_filter_dbus_msg, 
216
 
                                    NULL, NULL);
217
 
        
218
 
        libhal_ctx_set_dbus_connection (ctx, dbus_connection);
219
 
        
220
 
        return TRUE;
221
 
}
222
 
 
223
 
/** callback when a property of a device changes. 
224
 
 *
225
 
 *  @param  udi                 Unique Device Id
226
 
 *  @param  key                 Name of the property that has changed
227
 
 *  @param  is_removed          Property removed
228
 
 *  @param  is_added            Property added
229
 
 */
230
 
void 
231
 
hal_property_modified(LibHalContext *ctx, const char *udi, const char *key,
232
 
                      dbus_bool_t is_removed, dbus_bool_t is_added)
233
 
{
234
 
   //g_print("hal_device_changed(): %s\n",key);
235
 
 
236
 
   /* we are only interessted in mount events from the cdrom*/
237
 
   if (g_strcasecmp (key, "volume.is_mounted") != 0)
238
 
      return;
239
 
   if(!libhal_device_get_property_bool(ctx, udi, key, NULL))
240
 
      return;
241
 
 
242
 
   up_check_device_for_packages (ctx, udi);
243
 
}
244
 
 
245
 
/** check if the given udi contains package files
246
 
 *
247
 
 *  @param  udi                 Unique Device Id
248
 
 */
249
 
void 
250
 
up_check_device_for_packages (LibHalContext *ctx, const char *udi)
251
 
{
252
 
   gchar *mount_point, *storage_device, *media_type;
253
 
 
254
 
   storage_device = libhal_device_get_property_string (ctx, udi,
255
 
                                                    "block.storage_device",
256
 
                                                             NULL);
257
 
   if (!storage_device) {
258
 
      g_warning("cannot get storage_device\n");
259
 
      return;
260
 
   }
261
 
   media_type = libhal_device_get_property_string (ctx, storage_device, 
262
 
                                                   "storage.drive_type",
263
 
                                                   NULL);
264
 
   if(!media_type) {
265
 
      g_warning("cannot get storage.drive_type\n");
266
 
      return;
267
 
   }
268
 
   if (g_ascii_strcasecmp(media_type, "cdrom") != 0) {
269
 
      //g_warning("no cdrom: %s\n",media_type);
270
 
      return;
271
 
   }
272
 
      
273
 
   mount_point = libhal_device_get_property_string (ctx, udi, 
274
 
                                                    "volume.mount_point",
275
 
                                                    NULL);
276
 
   //g_print("mounted: %s on %s\n", udi, mount_point);
 
149
void 
 
150
up_check_mount_point_for_packages (const char *mount_point, gpointer data)
 
151
{
 
152
   if (!mount_point)
 
153
      return;
277
154
 
278
155
   char *ubuntu_dir = g_strdup_printf("%s/ubuntu",mount_point);
279
156
   char *aptoncd_file = g_strdup_printf("%s/aptoncd.info",mount_point);
303
180
   //g_print("retval: %i \n", WEXITSTATUS(retval));
304
181
   int cdtype = WEXITSTATUS(retval);
305
182
   if(cdtype > 0) {
306
 
     distro_cd_detected(libhal_ctx_get_user_data(ctx), cdtype, mount_point);
 
183
      distro_cd_detected(data, cdtype, mount_point);
307
184
   }
308
185
 
309
186
   g_free(cmd);
310
187
}
311
188
 
312
 
gboolean
313
 
up_check_mounted_devices (gpointer data)
314
 
{
315
 
   LibHalContext *hal_ctx;
316
 
   gchar **devices;
317
 
   int nr, i;
318
 
 
319
 
   hal_ctx = data;
320
 
 
321
 
   devices = libhal_get_all_devices (hal_ctx, &nr, NULL);
322
 
   /* Now go over the devices and check for CDROMs
323
 
    */
324
 
   for(i=0; i<nr; i++) {
325
 
      if(libhal_device_get_property_bool (hal_ctx, devices[i], "volume.is_mounted", NULL))
326
 
         up_check_device_for_packages (hal_ctx, devices[i]);
327
 
   }
 
189
void 
 
190
up_device_changed (GduPool *pool, GduDevice *device, gpointer data)
 
191
{
 
192
   //g_print("up_device_changed %s\n", gdu_device_get_device_file (device));
 
193
 
 
194
   // check if that is a removable device
 
195
   if (!gdu_device_is_removable(device))
 
196
      return;
 
197
 
 
198
   // we only care about the first mount point
 
199
   const gchar *p = gdu_device_get_mount_path (device);
 
200
   //g_print("checking mount point %s\n", p);
 
201
   up_check_mount_point_for_packages (p, data);
 
202
}
 
203
 
 
204
 
 
205
void
 
206
up_check_mounted_devices (GduPool *pool, gpointer data)
 
207
{
 
208
   GList *devices = gdu_pool_get_devices (pool);
328
209
   
329
 
   libhal_free_string_array (devices);
330
 
   return FALSE;
331
 
}
332
 
 
333
 
/** Internal UP initialization function
334
 
 *
335
 
 * @functions                   The LibHalFunctions to register as callbacks.
336
 
 * @return                      The LibHalContext of the HAL connection or
337
 
 *                              NULL on error.
338
 
 */
339
 
LibHalContext *
340
 
up_do_hal_init ()
341
 
{
342
 
        DBusError error;
343
 
        char **devices;
344
 
        int nr;
345
 
 
346
 
        hal_ctx = libhal_ctx_new ();
347
 
        if (!hal_ctx) {
348
 
                g_warning ("failed to initialize HAL!\n");
349
 
                return NULL;
350
 
        }
351
 
 
352
 
        dbus_error_init (&error);
353
 
        if (!hal_mainloop_integration (hal_ctx, &error)) {
354
 
                g_warning ("hal_initialize failed: %s\n", error.message);
355
 
                dbus_error_free (&error);
356
 
                return NULL;
357
 
        }
358
 
 
359
 
        libhal_ctx_set_device_property_modified (hal_ctx,
360
 
                                                 hal_property_modified);
361
 
 
362
 
        if (!libhal_device_property_watch_all (hal_ctx, &error)) {
363
 
                g_warning ("failed to watch all HAL properties!: %s\n", error.message);
364
 
                libhal_ctx_shutdown (hal_ctx, &error);
365
 
                return NULL;
366
 
        }
367
 
 
368
 
        if (!libhal_ctx_init (hal_ctx, &error)) {
369
 
                g_warning ("hal_initialize failed: %s\n", error.message);
370
 
                dbus_error_free (&error);
371
 
                libhal_ctx_free (hal_ctx);
372
 
                return NULL;
373
 
        }
374
 
 
375
 
        /*
376
 
         * Do something to ping the HAL daemon - the above functions will
377
 
         * succeed even if hald is not running, so long as DBUS is.  But we
378
 
         * want to exit silently if hald is not running, to behave on
379
 
         * pre-2.6 systems.
380
 
         */
381
 
        devices = libhal_get_all_devices (hal_ctx, &nr, &error);
382
 
        if (!devices) {
383
 
                g_warning ("seems that HAL is not running\n");
384
 
                libhal_ctx_shutdown (hal_ctx, &error);
385
 
                if (dbus_error_is_set (&error))
386
 
                        dbus_error_free (&error);
387
 
                libhal_ctx_free (hal_ctx);
388
 
                return NULL;
389
 
        }
390
 
        libhal_free_string_array (devices);
391
 
        
392
 
        // check for already mounted media for new package CDs
393
 
        // (after a small delay)
394
 
        g_timeout_add (5000, up_check_mounted_devices, hal_ctx);
395
 
 
396
 
        return hal_ctx;
397
 
}
 
210
   while(devices != NULL) {
 
211
      up_device_changed (pool, devices->data, data);
 
212
      devices = g_list_next(devices);
 
213
   }
 
214
   g_list_free(devices);
 
215
}
 
216
 
 
217
gboolean
 
218
up_do_hal_init (UpgradeNotifier *un)
 
219
{
 
220
   GduPool *pool = gdu_pool_new ();
 
221
   if (pool == NULL)
 
222
      return FALSE;
 
223
 
 
224
   g_signal_connect (pool, "device_changed", (GCallback)up_device_changed, un);
 
225
   // now check what devices we have
 
226
   up_check_mounted_devices(pool, un);
 
227
 
 
228
   return TRUE;
 
229
}
 
230
 
 
231
 
 
232
#else
 
233
#include <glib.h>
 
234
 
 
235
#include "update-notifier.h"
 
236
 
 
237
gboolean
 
238
up_do_hal_init (UpgradeNotifier *un)
 
239
{
 
240
    g_warning("Detection and monitoring of CD-ROMs disabled.");
 
241
    return FALSE;
 
242
}
 
243
#endif // HAVE_GUDEV