1 /*
2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 *
5 * Licensed under the Academic Free License version 2.1
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <string.h>
12
13 #include <libhal.h>
14 #include <logger.h>
15
16 #include <glib.h>
17
18 #include "network-discovery.h"
19
20 /*
21 * The interfaces in this file comprise a means of keeping track of devices
22 * that we have already seen and those that have gone missing. This allows
23 * us to quickly determine if we need to probe the device and quickly search
24 * for devices that are no longer available.
25 */
26
27 typedef struct {
28 LibHalContext *ctx;
29 time_t timestamp;
30 } removal_args_t;
31
32 static GHashTable *seen = NULL;
33
34 static gboolean
device_remove_if_stale(gpointer key,gpointer value,gpointer user_data)35 device_remove_if_stale(gpointer key, gpointer value, gpointer user_data)
36 {
37 gboolean result = FALSE;
38 removal_args_t *args = user_data;
39 char *name = key;
40 time_t *val = value;
41
42 HAL_DEBUG(("test stale: %s (%d > %d)", name, args->timestamp, *val));
43 if (args->timestamp > *val) {
44 DBusError error;
45 char **udi = NULL;
46 int num = 0;
47
48 dbus_error_init(&error);
49 udi = libhal_manager_find_device_string_match(args->ctx,
50 "network_device.address", name,
51 &num, &error);
52
53 if (udi != NULL) {
54 int i;
55
56 for (i = 0; i < num; i++) {
57 libhal_remove_device(args->ctx, udi[i], &error);
58 HAL_DEBUG(("remove: %s (%s)", name, udi[i]));
59 }
60 libhal_free_string_array(udi);
61 result = TRUE;
62 }
63 if (dbus_error_is_set(&error))
64 dbus_error_free(&error);
65 }
66
67 return (result);
68 }
69
70 void
scan_for_stale_devices(LibHalContext * ctx,time_t timestamp)71 scan_for_stale_devices(LibHalContext *ctx, time_t timestamp)
72 {
73 if (seen != NULL) {
74 removal_args_t args[1];
75
76 args->ctx = ctx;
77 args->timestamp = timestamp;
78
79 g_hash_table_foreach_remove(seen, device_remove_if_stale, args);
80 }
81 }
82
83 gboolean
device_seen(char * name)84 device_seen(char *name)
85 {
86 gboolean result;
87 char *key;
88 time_t *val;
89
90 if (seen == NULL)
91 seen = g_hash_table_new_full(g_str_hash, g_str_equal,
92 free, free);
93
94 result = g_hash_table_lookup_extended(seen, name,
95 (gpointer)&key, (gpointer)&val);
96
97 if ((result == FALSE) && ((val = calloc(1, sizeof (*val))) != NULL)) {
98 g_hash_table_insert(seen, strdup(name), val);
99 }
100 (void) time(val);
101 HAL_DEBUG(("seen: %s (%d)", name, *val));
102
103 return (result);
104 }
105