4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs/*
97191cec6312a1c3a1b70c5f4a543c415c59edf7Xiaolin Zhang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Use is subject to license terms.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs *
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Licensed under the Academic Free License version 2.1
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#ifdef HAVE_CONFIG_H
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <config.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#endif
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <unistd.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <string.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <stdlib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <fcntl.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/dkio.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <sys/stat.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <priv.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <glib.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <dbus/dbus-glib-lowlevel.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include <libhal.h>
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "../../hald/logger.h"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "network-discovery.h"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#include "printer.h"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#define DBUS_INTERFACE "org.freedesktop.Hal.Device.NetworkDiscovery"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#define NP(x) (x?x:"NULL")
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs#define STRDUP(x) (x?strdup(x):NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobstypedef struct {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs LibHalContext *ctx;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs gboolean enabled;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *parent;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *community;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *network;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs} nds_snmp_cbdata_t;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic nds_snmp_cbdata_t *snmp_cb_data = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_snmp_scan(LibHalContext *ctx, char *parent, char *community, char *network)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time_t start;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("nds_snmp_scan(0x%8.8x, %s, %s, %s)",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ctx, NP(parent), NP(community), NP(network)));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("NetworkDiscovery snmp scan initated"));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* scan for devices */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time(&start);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (network == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs GList *elem, *list = broadcast_addresses();
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs for (elem = list; elem != NULL; elem = g_list_next(elem)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs scan_for_devices_using_snmp(ctx, parent, community,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (char *)elem->data);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(elem->data);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs g_list_free(list);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs scan_for_devices_using_snmp(ctx, parent, community, network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* remove devices that haven't been seen since before this scan */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs scan_for_stale_devices(ctx, start);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("NetworkDiscovery snmp scan completed"));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic gboolean
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_snmp_scan_cb(gpointer data)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs nds_snmp_cbdata_t *args = data;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (args->enabled == FALSE) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (args->parent) free(args->parent);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (args->community) free(args->community);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (args->network) free(args->network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs free(args);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (FALSE);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs nds_snmp_scan(args->ctx, args->parent, args->community, args->network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (TRUE);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_EnablePrinterScanningViaSNMP(LibHalContext *ctx, char *parent, int interval,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *community, char *network)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("NetworkDiscovery.EnablePrinterScanningViaSNMP(0x%8.8x, %s, %d, %s, %s)",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ctx, NP(parent), interval, NP(community), NP(network)));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* are we already discoverying network devices ? */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (snmp_cb_data != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->enabled = FALSE; /* cancel it */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* setup for network device discovery */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((snmp_cb_data = calloc(1, sizeof (*snmp_cb_data))) != NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->ctx = ctx;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->enabled = TRUE;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->parent = STRDUP(parent);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->community = STRDUP(community);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->network = STRDUP(network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* prime the pump with an initial scan */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs nds_snmp_scan(ctx, parent, community, network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* add a regular network scan */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs g_timeout_add(interval * 1000, nds_snmp_scan_cb, snmp_cb_data);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_DisablePrinterScanningViaSNMP(LibHalContext *ctx)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("NetworkDiscovery.DisablePrinterScanningViaSNMP(0x%8.8x)", ctx));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (snmp_cb_data != NULL)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data->enabled = FALSE;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs snmp_cb_data = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_ScanForPrintersViaSNMP(LibHalContext *ctx, char *parent, char *community,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *network)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs time_t start, stop;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("NetworkDiscovery.ScanForPrintersViaSNMP(0x%8.8x, %s, %s, %s)",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ctx, NP(parent), NP(community), NP(network)));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (nds_snmp_scan(ctx, parent, community, network));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic DBusHandlerResult
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_filter_function(DBusConnection *connection, DBusMessage *message,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs void *user_data)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs LibHalContext *ctx = user_data;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusMessage *reply;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusError error;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs const char *member = dbus_message_get_member(message);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs const char *path = dbus_message_get_path(message);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int rc = -1;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_init(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("DBus message: %s, %s ", member, path));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (dbus_message_is_method_call(message,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_INTERFACE, "EnablePrinterScanningViaSNMP")) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int interval = -1;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *udi = getenv("UDI");
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *community = "public";
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *network = "0.0.0.0";
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_message_get_args(message, &error,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_INT32, &interval,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_STRING, &community,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_STRING, &network,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_INVALID);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (strcmp(network, "0.0.0.0") == 0)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs network = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = nds_EnablePrinterScanningViaSNMP(ctx, udi, interval,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs community, network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else if (dbus_message_is_method_call(message,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_INTERFACE, "ScanForPrintersViaSNMP")) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs int interval = -1;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *udi = getenv("UDI");
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *community = "public";
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *network = "0.0.0.0";
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_message_get_args(message, &error,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_STRING, &community,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_STRING, &network,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_INVALID);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (strcmp(network, "0.0.0.0") == 0)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs network = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = nds_ScanForPrintersViaSNMP(ctx, udi, community, network);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs } else if (dbus_message_is_method_call(message,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_INTERFACE, "DisablePrinterScanningViaSNMP")) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs rc = nds_DisablePrinterScanningViaSNMP(ctx);
97191cec6312a1c3a1b70c5f4a543c415c59edf7Xiaolin Zhang - Sun Microsystems - Beijing China } else {
97191cec6312a1c3a1b70c5f4a543c415c59edf7Xiaolin Zhang - Sun Microsystems - Beijing China /* bypass not-handled messages */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("Unknown DBus message: %s, %s ", member, path));
97191cec6312a1c3a1b70c5f4a543c415c59edf7Xiaolin Zhang - Sun Microsystems - Beijing China return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
97191cec6312a1c3a1b70c5f4a543c415c59edf7Xiaolin Zhang - Sun Microsystems - Beijing China }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (dbus_error_is_set(&error))
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_free(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((reply = dbus_message_new_method_return(message)) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("Could not allocate memory for the DBus reply"));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (FALSE);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_message_append_args(reply, DBUS_TYPE_INT32, &rc,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_TYPE_INVALID);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (!dbus_connection_send(connection, reply, NULL)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("Could not sent reply"));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_connection_flush(connection);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_message_unref(reply);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (DBUS_HANDLER_RESULT_HANDLED);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic int
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsnds_claim_interface(LibHalContext *ctx, char *udi, DBusError *error)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusConnection *connection;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *interface_xml =
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "<method name=\"EnablePrinterScanningViaSNMP\">\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"interval\" direction=\"in\" type=\"i\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "</method>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "<method name=\"DisablePrinterScanningViaSNMP\">\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "</method>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "<method name=\"ScanForPrintersViaSNMP\">\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"community\" direction=\"in\" type=\"s\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"network\" direction=\"in\" type=\"s\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs "</method>\n";
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_DEBUG(("nds_claim_interface(0x%8.8x, %s, 0x%8.8x): %s",
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs ctx, udi, error, DBUS_INTERFACE));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((connection = libhal_ctx_get_dbus_connection(ctx)) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("Could not get DBus connection"));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (-1);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (libhal_device_claim_interface(ctx, udi,
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBUS_INTERFACE, interface_xml, error) == 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs HAL_WARNING(("Could not claim interface: %s", error->message));
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (-1);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_connection_setup_with_g_main(connection, NULL);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_connection_add_filter(connection, nds_filter_function, ctx, NULL);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_connection_set_exit_on_disconnect(connection, 0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsstatic void
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsdrop_privileges()
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs priv_set_t *pPrivSet = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs priv_set_t *lPrivSet = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /*
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * Start with the 'basic' privilege set and then remove any
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs * of the 'basic' privileges that will not be needed.
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* Clear privileges we will not need from the 'basic' set */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* Set the permitted privilege set. */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* Clear the limit set. */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((lPrivSet = priv_allocset()) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs priv_emptyset(lPrivSet);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs priv_freeset(lPrivSet);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsint
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobsmain(int argc, char **argv)
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs{
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs LibHalContext *ctx = NULL;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs DBusError error;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs GMainLoop *loop = g_main_loop_new(NULL, FALSE);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs char *udi;
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((udi = getenv("UDI")) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs drop_privileges();
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs setup_logger();
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs dbus_error_init(&error);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if ((ctx = libhal_ctx_init_direct(&error)) == NULL) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (!libhal_device_addon_is_ready(ctx, udi, &error)) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs if (nds_claim_interface(ctx, udi, &error) != 0) {
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs return (0);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs }
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs g_main_loop_run(loop);
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs /* NOTREACHED */
4e9cfc9a015e8ca7d41f7d018c74dc8a692305b3jacobs}