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