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