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