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
29typedef struct {
30	LibHalContext *ctx;
31	time_t timestamp;
32} removal_args_t;
33
34static GHashTable *seen = NULL;
35
36static gboolean
37device_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
72void
73scan_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
85gboolean
86device_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