remove libfmd_snmp and smnp-notify
[unleashed.git] / usr / src / cmd / hal / addons / network-devices / addon-network-discovery.c
blobca323b4387ba95b31d0db0287e23e7e607212744
1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
5 * Licensed under the Academic Free License version 2.1
6 */
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <fcntl.h>
18 #include <sys/dkio.h>
19 #include <sys/stat.h>
20 #include <priv.h>
21 #include <glib.h>
23 #include <dbus/dbus-glib-lowlevel.h>
24 #include <libhal.h>
26 #include "../../hald/logger.h"
28 #include "network-discovery.h"
29 #include "printer.h"
31 #define DBUS_INTERFACE "org.freedesktop.Hal.Device.NetworkDiscovery"
32 #define NP(x) (x?x:"NULL")
33 #define STRDUP(x) (x?strdup(x):NULL)
35 typedef struct {
36 LibHalContext *ctx;
37 gboolean enabled;
38 char *parent;
39 char *community;
40 char *network;
41 } nds_snmp_cbdata_t;
43 static nds_snmp_cbdata_t *snmp_cb_data = NULL;
45 static int
46 nds_snmp_scan(LibHalContext *ctx, char *parent, char *community, char *network)
48 time_t start;
50 HAL_DEBUG(("nds_snmp_scan(0x%8.8x, %s, %s, %s)",
51 ctx, NP(parent), NP(community), NP(network)));
52 HAL_DEBUG(("NetworkDiscovery snmp scan initated"));
54 /* scan for devices */
55 time(&start);
56 if (network == NULL) {
57 GList *elem, *list = broadcast_addresses();
59 for (elem = list; elem != NULL; elem = g_list_next(elem)) {
60 scan_for_devices_using_snmp(ctx, parent, community,
61 (char *)elem->data);
62 free(elem->data);
64 g_list_free(list);
65 } else
66 scan_for_devices_using_snmp(ctx, parent, community, network);
68 /* remove devices that haven't been seen since before this scan */
69 scan_for_stale_devices(ctx, start);
71 HAL_DEBUG(("NetworkDiscovery snmp scan completed"));
73 return (0);
76 static gboolean
77 nds_snmp_scan_cb(gpointer data)
79 nds_snmp_cbdata_t *args = data;
81 if (args->enabled == FALSE) {
82 free(args->parent);
83 free(args->community);
84 free(args->network);
85 free(args);
86 return (FALSE);
89 nds_snmp_scan(args->ctx, args->parent, args->community, args->network);
91 return (TRUE);
94 static int
95 nds_EnablePrinterScanningViaSNMP(LibHalContext *ctx, char *parent, int interval,
96 char *community, char *network)
98 HAL_DEBUG(("NetworkDiscovery.EnablePrinterScanningViaSNMP(0x%8.8x, %s, %d, %s, %s)",
99 ctx, NP(parent), interval, NP(community), NP(network)));
101 /* are we already discoverying network devices ? */
102 if (snmp_cb_data != NULL) {
103 snmp_cb_data->enabled = FALSE; /* cancel it */
106 /* setup for network device discovery */
107 if ((snmp_cb_data = calloc(1, sizeof (*snmp_cb_data))) != NULL) {
108 snmp_cb_data->ctx = ctx;
109 snmp_cb_data->enabled = TRUE;
110 snmp_cb_data->parent = STRDUP(parent);
111 snmp_cb_data->community = STRDUP(community);
112 snmp_cb_data->network = STRDUP(network);
114 /* prime the pump with an initial scan */
115 nds_snmp_scan(ctx, parent, community, network);
117 /* add a regular network scan */
118 g_timeout_add(interval * 1000, nds_snmp_scan_cb, snmp_cb_data);
121 return (0);
124 static int
125 nds_DisablePrinterScanningViaSNMP(LibHalContext *ctx)
127 HAL_DEBUG(("NetworkDiscovery.DisablePrinterScanningViaSNMP(0x%8.8x)", ctx));
129 if (snmp_cb_data != NULL)
130 snmp_cb_data->enabled = FALSE;
131 snmp_cb_data = NULL;
133 return (0);
136 static int
137 nds_ScanForPrintersViaSNMP(LibHalContext *ctx, char *parent, char *community,
138 char *network)
140 time_t start, stop;
142 HAL_DEBUG(("NetworkDiscovery.ScanForPrintersViaSNMP(0x%8.8x, %s, %s, %s)",
143 ctx, NP(parent), NP(community), NP(network)));
145 return (nds_snmp_scan(ctx, parent, community, network));
148 static DBusHandlerResult
149 nds_filter_function(DBusConnection *connection, DBusMessage *message,
150 void *user_data)
152 LibHalContext *ctx = user_data;
153 DBusMessage *reply;
154 DBusError error;
155 const char *member = dbus_message_get_member(message);
156 const char *path = dbus_message_get_path(message);
157 int rc = -1;
159 dbus_error_init(&error);
161 HAL_DEBUG(("DBus message: %s, %s ", member, path));
163 if (dbus_message_is_method_call(message,
164 DBUS_INTERFACE, "EnablePrinterScanningViaSNMP")) {
165 int interval = -1;
166 char *udi = getenv("UDI");
167 char *community = "public";
168 char *network = "0.0.0.0";
170 dbus_message_get_args(message, &error,
171 DBUS_TYPE_INT32, &interval,
172 DBUS_TYPE_STRING, &community,
173 DBUS_TYPE_STRING, &network,
174 DBUS_TYPE_INVALID);
176 if (strcmp(network, "0.0.0.0") == 0)
177 network = NULL;
179 rc = nds_EnablePrinterScanningViaSNMP(ctx, udi, interval,
180 community, network);
181 } else if (dbus_message_is_method_call(message,
182 DBUS_INTERFACE, "ScanForPrintersViaSNMP")) {
183 int interval = -1;
184 char *udi = getenv("UDI");
185 char *community = "public";
186 char *network = "0.0.0.0";
188 dbus_message_get_args(message, &error,
189 DBUS_TYPE_STRING, &community,
190 DBUS_TYPE_STRING, &network,
191 DBUS_TYPE_INVALID);
193 if (strcmp(network, "0.0.0.0") == 0)
194 network = NULL;
196 rc = nds_ScanForPrintersViaSNMP(ctx, udi, community, network);
197 } else if (dbus_message_is_method_call(message,
198 DBUS_INTERFACE, "DisablePrinterScanningViaSNMP")) {
199 rc = nds_DisablePrinterScanningViaSNMP(ctx);
200 } else {
201 /* bypass not-handled messages */
202 HAL_WARNING(("Unknown DBus message: %s, %s ", member, path));
203 return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
206 if (dbus_error_is_set(&error))
207 dbus_error_free(&error);
209 if ((reply = dbus_message_new_method_return(message)) == NULL) {
210 HAL_WARNING(("Could not allocate memory for the DBus reply"));
211 return (FALSE);
214 dbus_message_append_args(reply, DBUS_TYPE_INT32, &rc,
215 DBUS_TYPE_INVALID);
217 if (!dbus_connection_send(connection, reply, NULL)) {
218 HAL_WARNING(("Could not sent reply"));
220 dbus_connection_flush(connection);
221 dbus_message_unref(reply);
223 return (DBUS_HANDLER_RESULT_HANDLED);
226 static int
227 nds_claim_interface(LibHalContext *ctx, char *udi, DBusError *error)
229 DBusConnection *connection;
230 char *interface_xml =
231 "<method name=\"EnablePrinterScanningViaSNMP\">\n"
232 " <arg name=\"interval\" direction=\"in\" type=\"i\"/>\n"
233 " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
234 " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
235 " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
236 "</method>\n"
237 "<method name=\"DisablePrinterScanningViaSNMP\">\n"
238 " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
239 "</method>\n"
240 "<method name=\"ScanForPrintersViaSNMP\">\n"
241 " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
242 " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
243 " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
244 "</method>\n";
246 HAL_DEBUG(("nds_claim_interface(0x%8.8x, %s, 0x%8.8x): %s",
247 ctx, udi, error, DBUS_INTERFACE));
249 if ((connection = libhal_ctx_get_dbus_connection(ctx)) == NULL) {
250 HAL_WARNING(("Could not get DBus connection"));
251 return (-1);
254 if (libhal_device_claim_interface(ctx, udi,
255 DBUS_INTERFACE, interface_xml, error) == 0) {
256 HAL_WARNING(("Could not claim interface: %s", error->message));
257 return (-1);
260 dbus_connection_setup_with_g_main(connection, NULL);
261 dbus_connection_add_filter(connection, nds_filter_function, ctx, NULL);
262 dbus_connection_set_exit_on_disconnect(connection, 0);
264 return (0);
267 static void
268 drop_privileges()
270 priv_set_t *pPrivSet = NULL;
271 priv_set_t *lPrivSet = NULL;
274 * Start with the 'basic' privilege set and then remove any
275 * of the 'basic' privileges that will not be needed.
277 if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
278 return;
281 /* Clear privileges we will not need from the 'basic' set */
282 (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
283 (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
284 (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
285 (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
286 (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
288 /* Set the permitted privilege set. */
289 if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
290 return;
293 /* Clear the limit set. */
294 if ((lPrivSet = priv_allocset()) == NULL) {
295 return;
298 priv_emptyset(lPrivSet);
300 if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
301 return;
304 priv_freeset(lPrivSet);
309 main(int argc, char **argv)
311 LibHalContext *ctx = NULL;
312 DBusError error;
313 GMainLoop *loop = g_main_loop_new(NULL, FALSE);
314 char *udi;
316 if ((udi = getenv("UDI")) == NULL) {
317 return (0);
320 drop_privileges();
322 setup_logger();
324 dbus_error_init(&error);
326 if ((ctx = libhal_ctx_init_direct(&error)) == NULL) {
327 return (0);
330 if (!libhal_device_addon_is_ready(ctx, udi, &error)) {
331 return (0);
334 if (nds_claim_interface(ctx, udi, &error) != 0) {
335 return (0);
338 g_main_loop_run(loop);
340 /* NOTREACHED */