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