gboolean battery_update(LibHalContext *ctx, const char *udi, int fd) { acpi_bst_t bst; DBusError error; HAL_DEBUG(("battery_update() enter")); dbus_error_init(&error); libhal_device_set_property_string(ctx, udi, "info.product", "Battery Bay", &error); my_dbus_error_free(&error); libhal_device_set_property_string(ctx, udi, "info.category", "battery", &error); bzero(&bst, sizeof (bst)); if (ioctl(fd, BATT_IOC_STATUS, &bst) < 0) { if (errno == ENXIO) { my_dbus_error_free(&error); libhal_device_set_property_bool(ctx, udi, "battery.present", FALSE, &error); } else { my_dbus_error_free(&error); return (FALSE); } } else { my_dbus_error_free(&error); libhal_device_set_property_bool(ctx, udi, "battery.present", TRUE, &error); } my_dbus_error_free(&error); if (!libhal_device_get_property_bool(ctx, udi, "battery.present", &error)) { HAL_DEBUG(("battery_update(): battery is NOT present")); battery_remove(ctx, udi); } else { HAL_DEBUG(("battery_update(): battery is present")); my_dbus_error_free(&error); libhal_device_set_property_string(ctx, udi, "battery.type", "primary", &error); my_dbus_error_free(&error); libhal_device_add_capability(ctx, udi, "battery", &error); my_dbus_error_free(&error); if (libhal_device_get_property_type(ctx, udi, "battery.vendor", &error) == LIBHAL_PROPERTY_TYPE_INVALID) { battery_static_update(ctx, udi, fd); } battery_dynamic_update(ctx, udi, fd); } my_dbus_error_free(&error); HAL_DEBUG(("battery_update() exit")); return (TRUE); }
static gboolean hal_backend_set_control_path (ItdbBackend *itdb_backend, const char *control_path) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.model.control_path", control_path, NULL); return TRUE; }
static gboolean hal_backend_set_name (ItdbBackend *itdb_backend, const char *name) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, "info.desktop.name", name, NULL); return TRUE; }
static gboolean hal_backend_set_firewire_id (ItdbBackend *itdb_backend, const char *fwid) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.firewire_id", fwid, NULL); return TRUE; }
static gboolean hal_backend_set_serial_number (ItdbBackend *itdb_backend, const char *serial_number) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.serial_number", serial_number, NULL); return TRUE; }
static gboolean hal_backend_set_firmware_version (ItdbBackend *itdb_backend, const char *firmware_version) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.firmware_version", firmware_version, NULL); return TRUE; }
static gboolean hal_backend_set_model_name (ItdbBackend *itdb_backend, const char *model_name) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.model.device_class", model_name, NULL); return TRUE; }
static gboolean hal_backend_set_color (ItdbBackend *itdb_backend, const char *color_name) { HalBackend *backend = (HalBackend *)itdb_backend; libhal_device_set_property_string (backend->ctx, backend->udi, LIBGPOD_HAL_NS"ipod.model.shell_color", color_name, NULL); return TRUE; }
static void copykeyval (char *key, char *compat_key) { char *value; value = libhal_device_get_property_string (hfp_ctx, hfp_udi, key, NULL); if (value != NULL) { hfp_info ("Copying %s -> %s", key, compat_key); libhal_device_set_property_string (hfp_ctx, hfp_udi, compat_key, value, NULL); } }
/** * setstr: * @buf: The non tabbed prefixed, null terminated string * @str: The strings to compare with e.g. "Vendor:" * @prop: The HAL property to set * * Return TRUE is found, FALSE otherwise. * * Finds the start of a null terminated string and sets HAL property if valid. */ static int setstr (char *buf, char *str, char *prop) { DBusError error; char *value; if (strbegin (buf, str)) { dbus_error_init (&error); value = buf + strlen (str) + 1; if (strcmp (value, "Not Specified") == 0) goto out; libhal_device_set_property_string (hfp_ctx, hfp_udi, prop, value, &hfp_error); LIBHAL_FREE_DBUS_ERROR (&hfp_error); hfp_info ("Setting %s='%s'", prop, value); return TRUE; } out: return FALSE; }
/** * setstr: * @buf: The non tabbed prefixed, null terminated string * @str: The strings to compare with e.g. "Vendor:" * @prop: The HAL property to set * * Returns: TRUE is found, FALSE otherwise. * * Finds the start of a null terminated string and sets HAL * property if valid. */ static int setstr (char *buf, char *str, char *prop) { DBusError error; char *value; if (str == NULL) goto out; if (strbegin (buf, str)) { dbus_error_init (&error); value = buf + strlen (str) + 1; if (strcmp (value, "Not Specified") == 0) goto out; if (!libhal_device_set_property_string (ctx, udi, prop, value, &error)) dbus_error_init (&error); HAL_DEBUG (("Setting %s='%s'", prop, value)); return TRUE; } out: return FALSE; }
/* returns: whether the state changed */ static gboolean poll_for_media_force (void) { int fd; int got_media; int old_media_status; got_media = FALSE; old_media_status = media_status; if (is_cdrom) { int drive; fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL); if (fd < 0 && errno == EBUSY) { /* this means the disc is mounted or some other app, * like a cd burner, has already opened O_EXCL */ /* HOWEVER, when starting hald, a disc may be * mounted; so check /etc/mtab to see if it * actually is mounted. If it is we retry to open * without O_EXCL */ if (!is_mounted (device_file)) { if (!is_locked_via_o_excl) { is_locked_via_o_excl = TRUE; update_proc_title (); } else { is_locked_via_o_excl = TRUE; } goto skip_check; } fd = open (device_file, O_RDONLY | O_NONBLOCK); } if (fd < 0) { HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); goto skip_check; } if (is_locked_via_o_excl) { is_locked_via_o_excl = FALSE; update_proc_title (); } /* Check if a disc is in the drive * * @todo Use MMC-2 API if applicable */ drive = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); switch (drive) { case CDS_NO_INFO: case CDS_NO_DISC: case CDS_TRAY_OPEN: case CDS_DRIVE_NOT_READY: break; case CDS_DISC_OK: /* some CD-ROMs report CDS_DISK_OK even with an open * tray; if media check has the same value two times in * a row then this seems to be the case and we must not * report that there is a media in it. */ if (support_media_changed && ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT) && ioctl (fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT)) { } else { got_media = TRUE; } break; case -1: HAL_ERROR (("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno))); break; default: break; } /* check if eject button was pressed */ if (got_media) { unsigned char cdb[10] = { 0x4a, 1, 0, 0, 16, 0, 0, 0, 8, 0}; unsigned char buffer[8]; struct sg_io_hdr sg_h; int retval; memset(buffer, 0, sizeof(buffer)); memset(&sg_h, 0, sizeof(struct sg_io_hdr)); sg_h.interface_id = 'S'; sg_h.cmd_len = sizeof(cdb); sg_h.dxfer_direction = SG_DXFER_FROM_DEV; sg_h.dxfer_len = sizeof(buffer); sg_h.dxferp = buffer; sg_h.cmdp = cdb; sg_h.timeout = 5000; retval = ioctl(fd, SG_IO, &sg_h); if (retval == 0 && sg_h.status == 0 && (buffer[4] & 0x0f) == 0x01) { DBusError error; /* emit signal from drive device object */ dbus_error_init (&error); libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error); LIBHAL_FREE_DBUS_ERROR (&error); } } close (fd); } else { fd = open (device_file, O_RDONLY); if (fd < 0 && errno == ENOMEDIUM) { got_media = FALSE; } else if (fd >= 0) { got_media = TRUE; close (fd); } else { HAL_ERROR (("open failed for %s: %s", device_file, strerror (errno))); goto skip_check; } } /* set correct state on startup, this avoid endless loops if there was a media in the device on startup */ if (media_status == MEDIA_STATUS_UNKNOWN) { if (got_media) media_status = MEDIA_STATUS_NO_MEDIA; else media_status = MEDIA_STATUS_GOT_MEDIA; } switch (media_status) { case MEDIA_STATUS_GOT_MEDIA: if (!got_media) { DBusError error; HAL_DEBUG (("Media removal detected on %s", device_file)); libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL); libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL); /* attempt to unmount all childs */ unmount_childs (ctx, udi); /* could have a fs on the main block device; do a rescan to remove it */ dbus_error_init (&error); libhal_device_rescan (ctx, udi, &error); LIBHAL_FREE_DBUS_ERROR (&error); /* have to this to trigger appropriate hotplug events */ fd = open (device_file, O_RDONLY | O_NONBLOCK); if (fd >= 0) { ioctl (fd, BLKRRPART); close (fd); } } break; case MEDIA_STATUS_NO_MEDIA: if (got_media) { DBusError error; HAL_DEBUG (("Media insertion detected on %s", device_file)); /* our probe will trigger the appropriate hotplug events */ libhal_device_set_property_bool ( ctx, udi, "storage.removable.media_available", TRUE, NULL); /* could have a fs on the main block device; do a rescan to add it */ dbus_error_init (&error); libhal_device_rescan (ctx, udi, &error); LIBHAL_FREE_DBUS_ERROR (&error); } break; case MEDIA_STATUS_UNKNOWN: default: break; } /* update our current status */ if (got_media) media_status = MEDIA_STATUS_GOT_MEDIA; else media_status = MEDIA_STATUS_NO_MEDIA; /*HAL_DEBUG (("polling %s; got media=%d", device_file, got_media));*/ skip_check: return old_media_status != media_status; }
int main (int argc, char **argv) { char *device_file; int fd = -1; int report_id; report_desc_t report_desc; struct hid_data *data; hid_item_t item; boolean is_keyboard = FALSE; boolean is_keypad = FALSE; boolean is_mouse = FALSE; boolean is_joystick = FALSE; if (! hfp_init(argc, argv)) goto end; device_file = getenv("HAL_PROP_HIDDEV_DEVICE"); if (! device_file) goto end; fd = open(device_file, O_RDONLY); if (fd < 0) goto end; /* give a meaningful process title for ps(1) */ setproctitle("%s", device_file); #ifdef HAVE_LIBUSB20 report_id = hid_get_report_id(fd); if (report_id == -1) #else if (ioctl(fd, USB_GET_REPORT_ID, &report_id) < 0) #endif goto end; hid_init(NULL); report_desc = hid_get_report_desc(fd); if (! report_desc) goto end; for (data = hid_start_parse(report_desc, ~0, report_id); hid_get_item(data, &item);) if (item.kind == hid_collection) { if (item.collection == HID_COLLECTION_APPLICATION) { const char *page; char *full_page; int i; page = hid_usage_page(HID_PAGE(item.usage)); full_page = hfp_strdup_printf("%s Page", page); for (i = 0; full_page[i] != 0; i++) if (full_page[i] == '_') full_page[i] = ' '; libhal_device_property_strlist_append(hfp_ctx, hfp_udi, "hiddev.application_pages", full_page, &hfp_error); hfp_free(full_page); } switch (item.usage) { case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE): is_mouse = TRUE; break; case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK): case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD): is_joystick = TRUE; break; case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD): is_keyboard = TRUE; break; case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYPAD): is_keypad = TRUE; break; } } hid_end_parse(data); hid_dispose_report_desc(report_desc); if (is_keyboard || is_mouse || is_joystick || is_keypad) { libhal_device_add_capability(hfp_ctx, hfp_udi, "input", &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input", &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", device_file, &hfp_error); } if (is_keyboard) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keyboard", &hfp_error); if (is_keypad) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keypad", &hfp_error); if (is_keyboard || is_keypad) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keys", &hfp_error); if (is_mouse) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.mouse", &hfp_error); if (is_joystick) libhal_device_add_capability(hfp_ctx, hfp_udi, "input.joystick", &hfp_error); end: return 0; }
int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop) { DBusError error; lh_prop_t *p; char *udi2 = NULL, *udi3 = NULL, **s; LibHalPropertyType old_type; dbus_error_init(&error); for(p = prop; p; p = p->next) { if (!strcmp(p->key, "udi") && p->type == LIBHAL_PROPERTY_TYPE_STRING) { udi2 = p->v.str_value; continue; } old_type = libhal_device_get_property_type(hal_ctx, nd->real_udi, p->key, &error); dbus_error_init(&error); if (old_type != LIBHAL_PROPERTY_TYPE_INVALID && ( p->type != old_type || p->type == LIBHAL_PROPERTY_TYPE_STRLIST)) { if (!libhal_device_remove_property(hal_ctx, nd->real_udi, p->key, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 41; } } switch (p->type) { case LIBHAL_PROPERTY_TYPE_INVALID: break; case LIBHAL_PROPERTY_TYPE_BOOLEAN: if (!libhal_device_set_property_bool(hal_ctx, nd->real_udi, p->key, p->v.bool_value, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } break; case LIBHAL_PROPERTY_TYPE_INT32: if (!libhal_device_set_property_int(hal_ctx, nd->real_udi, p->key, p->v.int_value, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } break; case LIBHAL_PROPERTY_TYPE_UINT64: if (!libhal_device_set_property_uint64(hal_ctx, nd->real_udi, p->key, p->v.uint64_value, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } break; case LIBHAL_PROPERTY_TYPE_DOUBLE: if (!libhal_device_set_property_double(hal_ctx, nd->real_udi, p->key, p->v.double_value, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } break; case LIBHAL_PROPERTY_TYPE_STRING: if (!strcmp(p->key, "info.udi")) udi3 = p->v.str_value; if (!libhal_device_set_property_string(hal_ctx, nd->real_udi, p->key, p->v.str_value, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } break; case LIBHAL_PROPERTY_TYPE_STRLIST: for(s = p->v.strlist_value; *s; s++) { if (!libhal_device_property_strlist_append(hal_ctx, nd->real_udi, p->key, *s, &error)) { fprintf(stderr, "%s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 42; } } break; } } if (udi2) udi3 = NULL; if (udi3) udi2 = udi3; if (udi2 && !nd->udi) nd->udi = strdup(udi2); return 0; }
int main (int argc, char *argv[]) { DBusError err; int retval = 0; hal_set_proc_title_init (argc, argv); setup_logger (); device_udi = getenv ("UDI"); HAL_DEBUG (("device:[%s]", device_udi)); if (device_udi == NULL) { HAL_ERROR (("No device specified")); return -2; } dbus_error_init (&err); if ((halctx = libhal_ctx_init_direct (&err)) == NULL) { HAL_ERROR (("Cannot connect to hald")); retval = -3; goto out; } /* update_properties */ libhal_device_set_property_bool (halctx, device_udi, "battery.present", TRUE, &err); LIBHAL_FREE_DBUS_ERROR (&err); if (!libhal_device_property_exists (halctx, device_udi, "battery.is_rechargeable", &err)) { LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_set_property_bool (halctx, device_udi, "battery.is_rechargeable", FALSE, &err); } LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_set_property_int (halctx, device_udi, "battery.charge_level.design", 7, &err); LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_set_property_int (halctx, device_udi, "battery.charge_level.last_full", 7, &err); LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_set_property_string (halctx, device_udi, "info.category", "battery", &err); LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_set_property_string (halctx, device_udi, "battery.command_interface", "csr", &err); /* monitor change */ libhal_ctx_set_device_property_modified (halctx, property_modified); /* Initial fillup */ dev_props = property_cache_item_get (device_udi); HAL_ERROR (("** Initial fillup done")); /* init usb */ usb_init (); /* do coldplug */ check_all_batteries (NULL); /* only add capability when initial charge_level key has been set */ LIBHAL_FREE_DBUS_ERROR (&err); libhal_device_add_capability (halctx, device_udi, "battery", &err); LIBHAL_FREE_DBUS_ERROR (&err); if (!libhal_device_addon_is_ready (halctx, device_udi, &err)) { retval = -4; goto out; } hal_set_proc_title ("hald-addon-usb-csr: listening on '%s'", libhal_device_get_property_string(halctx, device_udi, "info.product", &err)); main_loop = g_main_loop_new (NULL, FALSE); #ifdef HAVE_GLIB_2_14 g_timeout_add_seconds (TIMEOUT, check_all_batteries, NULL); #else g_timeout_add (1000L * TIMEOUT, check_all_batteries, NULL); #endif g_main_loop_run (main_loop); return 0; out: HAL_DEBUG (("An error occured, exiting cleanly")); LIBHAL_FREE_DBUS_ERROR (&err); if (halctx != NULL) { libhal_ctx_shutdown (halctx, &err); LIBHAL_FREE_DBUS_ERROR (&err); libhal_ctx_free (halctx); } return retval; }
/** * main: * @argc: Number of arguments given to program * @argv: Arguments given to program * * Returns: Return code * * Main entry point */ int main (int argc, char *argv[]) { dbus_bool_t rc = 0; char *udi = NULL; char *key = NULL; char *str_value = NULL; dbus_int32_t int_value = 0; dbus_uint64_t uint64_value = 0; double double_value = 0.0f; dbus_bool_t bool_value = TRUE; dbus_bool_t remove = FALSE; dbus_bool_t is_version = FALSE; int type = PROP_INVALID; DBusError error; dbus_bool_t direct = FALSE; if (argc <= 1) { usage (argc, argv); return 1; } while (1) { int c; int option_index = 0; const char *opt; static struct option long_options[] = { {"udi", 1, NULL, 0}, {"key", 1, NULL, 0}, {"int", 1, NULL, 0}, {"uint64", 1, NULL, 0}, {"string", 1, NULL, 0}, {"double", 1, NULL, 0}, {"bool", 1, NULL, 0}, {"strlist-pre", 1, NULL, 0}, {"strlist-post", 1, NULL, 0}, {"strlist-rem", 1, NULL, 0}, {"direct", 0, NULL, 0}, {"remove", 0, NULL, 0}, {"version", 0, NULL, 0}, {"help", 0, NULL, 0}, {NULL, 0, NULL, 0} }; c = getopt_long (argc, argv, "", long_options, &option_index); if (c == -1) break; switch (c) { case 0: opt = long_options[option_index].name; if (strcmp (opt, "help") == 0) { usage (argc, argv); return 0; } else if (strcmp (opt, "key") == 0) { key = strdup (optarg); } else if (strcmp (opt, "string") == 0) { str_value = strdup (optarg); type = PROP_STRING; } else if (strcmp (opt, "int") == 0) { int_value = strtol (optarg, NULL, 0); type = PROP_INT; } else if (strcmp (opt, "uint64") == 0) { uint64_value = strtoull (optarg, NULL, 0); type = PROP_UINT64; } else if (strcmp (opt, "double") == 0) { double_value = (double) atof (optarg); type = PROP_DOUBLE; } else if (strcmp (opt, "bool") == 0) { if (strcmp (optarg, "true") == 0) bool_value = TRUE; else if (strcmp (optarg, "false") == 0) bool_value = FALSE; else { usage (argc, argv); return 1; } type = PROP_BOOL; } else if (strcmp (opt, "strlist-pre") == 0) { str_value = strdup (optarg); type = PROP_STRLIST_PRE; } else if (strcmp (opt, "strlist-post") == 0) { str_value = strdup (optarg); type = PROP_STRLIST_POST; } else if (strcmp (opt, "strlist-rem") == 0) { str_value = strdup (optarg); type = PROP_STRLIST_REM; } else if (strcmp (opt, "remove") == 0) { remove = TRUE; } else if (strcmp (opt, "direct") == 0) { direct = TRUE; } else if (strcmp (opt, "udi") == 0) { udi = strdup (optarg); } else if (strcmp (opt, "version") == 0) { is_version = TRUE; } break; default: usage (argc, argv); return 1; break; } } if (is_version) { printf ("hal-set-property " PACKAGE_VERSION "\n"); return 0; } /* must have at least one, but not neither or both */ if ((remove && type != PROP_INVALID) || ((!remove) && type == PROP_INVALID)) { usage (argc, argv); return 1; } fprintf (stderr, "\n"); dbus_error_init (&error); if (direct) { if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) { fprintf (stderr, "error: libhal_ctx_init_direct\n"); LIBHAL_FREE_DBUS_ERROR (&error); return 1; } } else { if ((hal_ctx = libhal_ctx_new ()) == NULL) { fprintf (stderr, "error: libhal_ctx_new\n"); return 1; } if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) { fprintf (stderr, "error: libhal_ctx_set_dbus_connection: %s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 1; } if (!libhal_ctx_init (hal_ctx, &error)) { if (dbus_error_is_set(&error)) { fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message); dbus_error_free (&error); } fprintf (stderr, "Could not initialise connection to hald.\n" "Normally this means the HAL daemon (hald) is not running or not ready.\n"); return 1; } } if (remove) { rc = libhal_device_remove_property (hal_ctx, udi, key, &error); if (!rc) { fprintf (stderr, "error: libhal_device_remove_property: %s: %s\n", error.name, error.message); LIBHAL_FREE_DBUS_ERROR (&error); return 1; } } else { switch (type) { case PROP_STRING: rc = libhal_device_set_property_string (hal_ctx, udi, key, str_value, &error); break; case PROP_INT: rc = libhal_device_set_property_int (hal_ctx, udi, key, int_value, &error); break; case PROP_UINT64: rc = libhal_device_set_property_uint64 (hal_ctx, udi, key, uint64_value, &error); break; case PROP_DOUBLE: rc = libhal_device_set_property_double (hal_ctx, udi, key, double_value, &error); break; case PROP_BOOL: rc = libhal_device_set_property_bool (hal_ctx, udi, key, bool_value, &error); break; case PROP_STRLIST_PRE: rc = libhal_device_property_strlist_prepend (hal_ctx, udi, key, str_value, &error); break; case PROP_STRLIST_POST: rc = libhal_device_property_strlist_append (hal_ctx, udi, key, str_value, &error); break; case PROP_STRLIST_REM: rc = libhal_device_property_strlist_remove (hal_ctx, udi, key, str_value, &error); break; } if (!rc) { fprintf (stderr, "error: libhal_device_set_property: %s: %s\n", error.name, error.message); dbus_error_free (&error); return 1; } } return rc ? 0 : 1; }
int main (int argc, char **argv) { char *device_file; char *parent_udi; char *grandparent_udi; char *parent_drive_type; int fd = -1; struct volume_id *vid = NULL; int ret = 1; gboolean has_children; gboolean is_swap; gboolean is_cdrom; gboolean is_partition = FALSE; gboolean has_audio = FALSE; gboolean has_data = FALSE; gboolean is_blank = FALSE; const char *usage; char *label; unsigned int sector_size = 0; off_t media_size = 0; if (! hfp_init(argc, argv)) goto end; device_file = getenv("HAL_PROP_BLOCK_DEVICE"); if (! device_file) goto end; parent_udi = getenv("HAL_PROP_INFO_PARENT"); if (! parent_udi) goto end; /* give a meaningful process title for ps(1) */ setproctitle("%s", device_file); has_children = hfp_getenv_bool("HF_HAS_CHILDREN"); is_swap = hfp_getenv_bool("HF_IS_SWAP"); fd = open(device_file, O_RDONLY); if (fd < 0) goto end; parent_drive_type = libhal_device_get_property_string(hfp_ctx, parent_udi, "storage.drive_type", &hfp_error); dbus_error_free(&hfp_error); grandparent_udi = libhal_device_get_property_string(hfp_ctx, parent_udi, "info.parent", &hfp_error); dbus_error_free(&hfp_error); is_cdrom = parent_drive_type && ! strcmp(parent_drive_type, "cdrom"); g_free(parent_drive_type); if (is_cdrom) { hf_probe_volume_get_disc_info(fd, &has_audio, &has_data); is_blank = (! has_audio && ! has_data); } ioctl(fd, DIOCGMEDIASIZE, &media_size); /* * We only check for filesystems if the volume has no children, * otherwise volume_id might find a filesystem in what is actually * the first child partition of the volume. * * If hald (which has looked at the partition type) reports that it * is a swap partition, we probe it nevertheless in case the * partition type is incorrect. */ if (! has_children && ! (is_cdrom && ! has_data)) { vid = volume_id_open_fd(fd); if (vid) { if (volume_id_probe_all(vid, 0, media_size) == 0) has_data = TRUE; else { volume_id_close(vid); vid = NULL; } } } if (! has_children && ! is_swap && ! has_audio && ! has_data && ! is_blank) goto end; libhal_device_add_capability(hfp_ctx, hfp_udi, "volume", &hfp_error); if (is_cdrom) { HFPCDROM *cdrom; int type; guint64 capacity; libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume.disc", &hfp_error); libhal_device_add_capability(hfp_ctx, hfp_udi, "volume.disc", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_audio", has_audio, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.has_data", has_data, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_vcd", FALSE, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_svcd", FALSE, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_videodvd", FALSE, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_appendable", FALSE, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_blank", is_blank, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", FALSE, &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "unknown", &hfp_error); /* the following code was adapted from linux's probe-volume.c */ cdrom = hfp_cdrom_new_from_fd(fd, device_file, grandparent_udi); if (cdrom) { type = get_disc_type(cdrom); if (type != -1) switch (type) { case 0x08: /* CD-ROM */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rom", &hfp_error); break; case 0x09: /* CD-R */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_r", &hfp_error); break; case 0x0a: /* CD-RW */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "cd_rw", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x10: /* DVD-ROM */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rom", &hfp_error); break; case 0x11: /* DVD-R Sequential */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_r", &hfp_error); break; case 0x12: /* DVD-RAM */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_ram", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x13: /* DVD-RW Restricted Overwrite */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x14: /* DVD-RW Sequential */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_rw", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x1A: /* DVD+RW */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_rw", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x1B: /* DVD+R */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r", &hfp_error); break; case 0x2B: /* DVD+R Double Layer */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "dvd_plus_r_dl", &hfp_error); break; case 0x40: /* BD-ROM */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_rom", &hfp_error); break; case 0x41: /* BD-R Sequential */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error); break; case 0x42: /* BD-R Random */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_r", &hfp_error); break; case 0x43: /* BD-RE */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "bd_re", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; case 0x50: /* HD DVD-ROM */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rom", &hfp_error); break; case 0x51: /* HD DVD-R */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_r", &hfp_error); break; case 0x52: /* HD DVD-Rewritable */ libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.disc.type", "hddvd_rw", &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); break; } if (get_disc_capacity_for_type(cdrom, type, &capacity) == 0) libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.disc.capacity", capacity, &hfp_error); /* * linux's probe-volume.c: "on some hardware the get_disc_type * call fails, so we use this as a backup". */ if (disc_is_rewritable(cdrom)) libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.disc.is_rewritable", TRUE, &hfp_error); if (disc_is_appendable(cdrom)) libhal_device_set_property_bool (hfp_ctx, hfp_udi, "volume.disc.is_appendable", TRUE, &hfp_error); hfp_cdrom_free(cdrom); } if (has_data && vid && (! strcmp(vid->type, "iso9660") || ! strcmp(vid->type, "udf"))) hf_probe_volume_advanced_disc_detect(fd); } else { libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "volume", &hfp_error); if (libhal_device_query_capability(hfp_ctx, parent_udi, "storage", &hfp_error)) { char *geom_class; char *type; char *scheme; int number; guint64 mediasize; guint64 offset; geom_class = getenv("HF_VOLUME_GEOM_CLASS"); if (geom_class) { if (hf_probe_volume_get_partition_info(geom_class, device_file, &number, &type, &scheme, &mediasize, &offset)) { is_partition = TRUE; libhal_device_set_property_int(hfp_ctx, hfp_udi, "volume.partition.number", number, &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.scheme", scheme, &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.type", type, &hfp_error); /* FIXME We need to fill in the supported partition flags. */ libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.media_size", mediasize, &hfp_error); libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.partition.start", offset, &hfp_error); if (! strcmp(scheme, "gpt")) libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.uuid", type, &hfp_error); if (! strcmp(scheme, "gpt") || ! strcmp(scheme, "apm")) libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.partition.label", "", &hfp_error); g_free(type); g_free(scheme); } } } else dbus_error_free(&hfp_error); } libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_disc", is_cdrom, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.is_partition", is_partition, &hfp_error); libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", has_children || is_swap, &hfp_error); #ifdef HAVE_LIBUFS if (vid && ! strcmp (vid->type, "ufs")) { struct uufsd ufsdisk; if (ufs_disk_fillout(&ufsdisk, device_file) == 0) { char ufsid[64]; char **ufs_devs = NULL; int num_udis; int i; snprintf(ufsid, sizeof(ufsid), "%08x%08x", ufsdisk.d_fs.fs_id[0], ufsdisk.d_fs.fs_id[1]); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.freebsd.ufsid", ufsid, &hfp_error); dbus_error_free(&hfp_error); ufs_devs = libhal_manager_find_device_string_match(hfp_ctx, "volume.freebsd.ufsid", ufsid, &num_udis, &hfp_error); dbus_error_free(&hfp_error); for (i = 0; i < num_udis; i++) { if (ufs_devs[i] != NULL && strcmp(ufs_devs[i], hfp_udi)) { gboolean mounted; mounted = libhal_device_get_property_bool(hfp_ctx, ufs_devs[i], "volume.is_mounted", &hfp_error); dbus_error_free(&hfp_error); if (mounted) { libhal_device_set_property_bool(hfp_ctx, hfp_udi, "volume.ignore", TRUE, &hfp_error); dbus_error_free(&hfp_error); break; } } } if (ufs_devs) libhal_free_string_array(ufs_devs); ufs_disk_close(&ufsdisk); } } #endif /* HAVE_LIBUFS */ if (has_children) usage = "partitiontable"; else if (is_swap) usage = "other"; else switch (vid ? vid->usage_id : (enum volume_id_usage) -1) { case VOLUME_ID_FILESYSTEM: usage = "filesystem"; break; case VOLUME_ID_DISKLABEL: usage = "disklabel"; break; case VOLUME_ID_OTHER: usage = "other"; break; case VOLUME_ID_RAID: usage = "raid"; break; case VOLUME_ID_CRYPTO: usage = "crypto"; break; case VOLUME_ID_UNUSED: usage = "unused"; break; default: usage = "unknown"; break; } libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsusage", usage, &hfp_error); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fstype", vid ? vid->type: "", &hfp_error); if (vid && *vid->type_version) libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.fsversion", vid->type_version, &hfp_error); label = hf_probe_volume_get_label(vid); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.label", label ? label : "", &hfp_error); g_free(label); libhal_device_set_property_string(hfp_ctx, hfp_udi, "volume.uuid", vid ? vid->uuid : "", &hfp_error); ioctl(fd, DIOCGSECTORSIZE, §or_size); if (sector_size != 0) libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.block_size", sector_size, &hfp_error); if (media_size != 0) libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.size", media_size, &hfp_error); if (sector_size != 0 && media_size != 0) libhal_device_set_property_uint64(hfp_ctx, hfp_udi, "volume.num_blocks", media_size / sector_size, &hfp_error); ret = 0; /* is a volume */ end: return ret; }
int main (int argc, char *argv[]) { int fd, rfd; int ret; char *udi; char *device_file, *raw_device_file; char *devpath, *rdevpath; boolean_t is_dos; int dos_num; LibHalContext *ctx = NULL; DBusError error; DBusConnection *conn; char *parent_udi; char *storage_device; char *is_disc_str; int fdc; dbus_bool_t is_disc = FALSE; dbus_bool_t is_floppy = FALSE; unsigned int block_size; dbus_uint64_t vol_size; dbus_bool_t has_data = TRUE; /* probe for fs by default */ dbus_bool_t has_audio = FALSE; char *partition_scheme = NULL; dbus_uint64_t partition_start = 0; int partition_number = 0; struct vtoc vtoc; dk_gpt_t *gpt; struct dk_minfo mi; int i, dos_cnt; fstyp_handle_t fstyp_handle; int systid, relsect, numsect; off_t probe_offset = 0; int num_volumes; char **volumes; dbus_uint64_t v_start; const char *fstype; nvlist_t *fsattr; fd = rfd = -1; ret = 1; if ((udi = getenv ("UDI")) == NULL) { goto out; } if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL) { goto out; } if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL) { goto out; } if (!dos_to_dev(device_file, &rdevpath, &dos_num)) { rdevpath = raw_device_file; } if (!(is_dos = dos_to_dev(device_file, &devpath, &dos_num))) { devpath = device_file; } if ((parent_udi = getenv ("HAL_PROP_INFO_PARENT")) == NULL) { goto out; } if ((storage_device = getenv ("HAL_PROP_BLOCK_STORAGE_DEVICE")) == NULL) { goto out; } is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC"); if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0) { is_disc = TRUE; } else { is_disc = FALSE; } drop_privileges (); setup_logger (); dbus_error_init (&error); if ((ctx = libhal_ctx_init_direct (&error)) == NULL) goto out; HAL_DEBUG (("Doing probe-volume for %s\n", device_file)); fd = open (devpath, O_RDONLY | O_NONBLOCK); if (fd < 0) { goto out; } rfd = open (rdevpath, O_RDONLY | O_NONBLOCK); if (rfd < 0) { goto out; } /* if it's a floppy with no media, bail out */ if (ioctl(rfd, FDGETCHANGE, &fdc) == 0) { is_floppy = TRUE; if (fdc & FDGC_CURRENT) { goto out; } } /* block size and total size */ if (ioctl(rfd, DKIOCGMEDIAINFO, &mi) != -1) { block_size = mi.dki_lbsize; vol_size = mi.dki_capacity * block_size; } else if (errno == ENXIO) { /* driver supports ioctl, but media is not available */ goto out; } else { /* driver does not support ioctl, e.g. lofi */ block_size = 512; vol_size = 0; } libhal_device_set_property_int (ctx, udi, "volume.block_size", block_size, &error); my_dbus_error_free (&error); libhal_device_set_property_uint64 (ctx, udi, "volume.size", vol_size, &error); my_dbus_error_free (&error); if (is_disc) { if (!probe_disc (rfd, ctx, udi, &has_data, &has_audio)) { HAL_DEBUG (("probe_disc failed, skipping fstyp")); goto out; } /* with audio present, create volume even if fs probing fails */ if (has_audio) { ret = 0; } } if (!has_data) { goto skip_fs; } /* don't support partitioned floppy */ if (is_floppy) { goto skip_part; } /* * first get partitioning info */ if (is_dos) { /* for a dos drive find partition offset */ if (!find_dos_drive(fd, dos_num, &relsect, &numsect, &systid)) { goto out; } partition_scheme = "mbr"; partition_start = (dbus_uint64_t)relsect * 512; partition_number = dos_num; probe_offset = (off_t)relsect * 512; } else { if ((partition_number = read_vtoc(rfd, &vtoc)) >= 0) { if (!vtoc_one_slice_entire_disk(&vtoc)) { partition_scheme = "smi"; if (partition_number < vtoc.v_nparts) { if (vtoc.v_part[partition_number].p_size == 0) { HAL_DEBUG (("zero size partition")); } partition_start = vtoc.v_part[partition_number].p_start * block_size; } } } else if ((partition_number = efi_alloc_and_read(rfd, &gpt)) >= 0) { partition_scheme = "gpt"; if (partition_number < gpt->efi_nparts) { if (gpt->efi_parts[partition_number].p_size == 0) { HAL_DEBUG (("zero size partition")); } partition_start = gpt->efi_parts[partition_number].p_start * block_size; } efi_free(gpt); } probe_offset = 0; } if (partition_scheme != NULL) { libhal_device_set_property_string (ctx, udi, "volume.partition.scheme", partition_scheme, &error); my_dbus_error_free (&error); libhal_device_set_property_int (ctx, udi, "volume.partition.number", partition_number, &error); my_dbus_error_free (&error); libhal_device_set_property_uint64 (ctx, udi, "volume.partition.start", partition_start, &error); my_dbus_error_free (&error); libhal_device_set_property_bool (ctx, udi, "volume.is_partition", TRUE, &error); my_dbus_error_free (&error); } else { libhal_device_set_property_bool (ctx, udi, "volume.is_partition", FALSE, &error); my_dbus_error_free (&error); } /* * ignore duplicate partitions */ if ((volumes = libhal_manager_find_device_string_match ( ctx, "block.storage_device", storage_device, &num_volumes, &error)) != NULL) { my_dbus_error_free (&error); for (i = 0; i < num_volumes; i++) { if (strcmp (udi, volumes[i]) == 0) { continue; /* skip self */ } v_start = libhal_device_get_property_uint64 (ctx, volumes[i], "volume.partition.start", &error); if (dbus_error_is_set(&error)) { dbus_error_free(&error); continue; } if (v_start == partition_start) { HAL_DEBUG (("duplicate partition")); goto out; } } libhal_free_string_array (volumes); } skip_part: /* * now determine fs type * * XXX We could get better performance from block device, * but for now we use raw device because: * * - fstyp_udfs has a bug that it only works on raw * * - sd has a bug that causes extremely slow reads * and incorrect probing of hybrid audio/data media */ if (fstyp_init(rfd, probe_offset, NULL, &fstyp_handle) != 0) { HAL_DEBUG (("fstyp_init failed")); goto out; } if ((fstyp_ident(fstyp_handle, NULL, &fstype) != 0) || (fstyp_get_attr(fstyp_handle, &fsattr) != 0)) { HAL_DEBUG (("fstyp ident or get_attr failed")); fstyp_fini(fstyp_handle); goto out; } set_fstyp_properties (ctx, udi, fstype, fsattr); if (strcmp (fstype, "hsfs") == 0) { hsfs_contents (fd, probe_offset, ctx, udi); } fstyp_fini(fstyp_handle); skip_fs: ret = 0; out: if (fd >= 0) close (fd); if (rfd >= 0) close (rfd); if (ctx != NULL) { my_dbus_error_free (&error); libhal_ctx_shutdown (ctx, &error); libhal_ctx_free (ctx); } return ret; }
int add_network_printer(LibHalContext *ctx, char *base, char *hostaddr, char *device, char *community) { DBusError error; int rc = -1; char udi[128]; char *tmp_udi = NULL; static char *parent = NULL; char *manufacturer = NULL, *model = NULL, *description = NULL, *uri = NULL, *sn, *serial; sn = serial = pseudo_serialno_from_addr(hostaddr); if (parent == NULL) parent = getenv("UDI"); dbus_error_init(&error); network_device_name_to_udi(udi, sizeof (udi), base, serial, NULL); if (libhal_device_exists(ctx, udi, &error) == TRUE) goto out; if ((tmp_udi = libhal_new_device(ctx, &error)) == NULL) goto out; snmp_printer_info(hostaddr, community, &manufacturer, &model, &description, &serial, NULL, &uri); libhal_device_set_property_string(ctx, tmp_udi, "info.parent", parent, &error); libhal_device_set_property_string(ctx, tmp_udi, "info.category", "printer", &error); libhal_device_property_strlist_append(ctx, tmp_udi, "info.capabilities", "printer", &error); libhal_device_property_strlist_append(ctx, tmp_udi, "info.capabilities", "network_device", &error); libhal_device_set_property_string(ctx, tmp_udi, "network_device.address", hostaddr, &error); if ((community != NULL) && (strcasecmp(community, "public") != 0)) libhal_device_set_property_string(ctx, tmp_udi, "network_device.snmp_community", community, &error); if ((uri != NULL) || (device != NULL)) libhal_device_set_property_string(ctx, tmp_udi, "printer.device", (uri ? uri : device), &error); if (serial != NULL) libhal_device_set_property_string(ctx, tmp_udi, "printer.serial", serial, &error); if (manufacturer != NULL) libhal_device_set_property_string(ctx, tmp_udi, "printer.vendor", manufacturer, &error); if (model != NULL) libhal_device_set_property_string(ctx, tmp_udi, "printer.product", model, &error); if (description != NULL) libhal_device_set_property_string(ctx, tmp_udi, "printer.description", description, &error); /* commit the changes to the new UDI */ rc = libhal_device_commit_to_gdl(ctx, tmp_udi, udi, &error); out: HAL_DEBUG(("result: %s (%s): %s, %s, %s, %s, %s", hostaddr, udi, NP(manufacturer), NP(model), NP(description), NP(serial), NP(uri))); if (tmp_udi != NULL) free(tmp_udi); if (manufacturer != NULL) free(manufacturer); if (model != NULL) free(model); if (description != NULL) free(description); if (uri != NULL) free(uri); if (sn != NULL) free(sn); if (dbus_error_is_set(&error)) { HAL_WARNING(("%s: %s", error.name, error.message)); dbus_error_free(&error); } HAL_DEBUG(("add: %s (%s)", hostaddr, udi)); return (rc); }