1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * hal-device.c : add devices HAL 5*2912Sartem * 6*2912Sartem * Copyright (C) 2005 SuSE Linux Gmbh 7*2912Sartem * 8*2912Sartem * Authors: 9*2912Sartem * Steffen Winterfeldt <snwint@suse.de> 10*2912Sartem * 11*2912Sartem * Licensed under the Academic Free License version 2.1 12*2912Sartem * 13*2912Sartem * This program is free software; you can redistribute it and/or modify 14*2912Sartem * it under the terms of the GNU General Public License as published by 15*2912Sartem * the Free Software Foundation; either version 2 of the License, or 16*2912Sartem * (at your option) any later version. 17*2912Sartem * 18*2912Sartem * This program is distributed in the hope that it will be useful, 19*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 20*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21*2912Sartem * GNU General Public License for more details. 22*2912Sartem * 23*2912Sartem * You should have received a copy of the GNU General Public License 24*2912Sartem * along with this program; if not, write to the Free Software 25*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26*2912Sartem * 27*2912Sartem */ 28*2912Sartem 29*2912Sartem #define _GNU_SOURCE 30*2912Sartem 31*2912Sartem #ifdef HAVE_CONFIG_H 32*2912Sartem # include <config.h> 33*2912Sartem #endif 34*2912Sartem 35*2912Sartem #include <stdio.h> 36*2912Sartem #include <string.h> 37*2912Sartem #include <unistd.h> 38*2912Sartem #include <stdlib.h> 39*2912Sartem #include <ctype.h> 40*2912Sartem #include <inttypes.h> 41*2912Sartem #include <getopt.h> 42*2912Sartem 43*2912Sartem #ifndef DBUS_API_SUBJECT_TO_CHANGE 44*2912Sartem #define DBUS_API_SUBJECT_TO_CHANGE 1 45*2912Sartem #endif 46*2912Sartem 47*2912Sartem #include <dbus/dbus.h> 48*2912Sartem #include <libhal.h> 49*2912Sartem 50*2912Sartem typedef struct { 51*2912Sartem char *udi; 52*2912Sartem char *real_udi; 53*2912Sartem } new_dev_t; 54*2912Sartem 55*2912Sartem typedef struct lh_prop_s { 56*2912Sartem struct lh_prop_s *next; 57*2912Sartem LibHalPropertyType type; 58*2912Sartem char *key; 59*2912Sartem union { 60*2912Sartem char *str_value; 61*2912Sartem dbus_int32_t int_value; 62*2912Sartem dbus_uint64_t uint64_value; 63*2912Sartem double double_value; 64*2912Sartem dbus_bool_t bool_value; 65*2912Sartem char **strlist_value; 66*2912Sartem } v; 67*2912Sartem } lh_prop_t; 68*2912Sartem 69*2912Sartem 70*2912Sartem void help(void); 71*2912Sartem int dump_devices(LibHalContext *hal_ctx, char *arg); 72*2912Sartem int remove_udi(LibHalContext *hal_ctx, char *arg); 73*2912Sartem int add_udi(LibHalContext *hal_ctx, char *arg); 74*2912Sartem void process_property(LibHalContext *hal_ctx, char *buf, lh_prop_t **prop); 75*2912Sartem int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop); 76*2912Sartem lh_prop_t *free_properties(lh_prop_t *prop); 77*2912Sartem static char *skip_space(char *s); 78*2912Sartem static char *skip_non_eq_or_space(char *s); 79*2912Sartem static char *skip_number(char *s); 80*2912Sartem static char *skip_nonquote(char *s); 81*2912Sartem 82*2912Sartem 83*2912Sartem new_dev_t new_dev; 84*2912Sartem 85*2912Sartem struct { 86*2912Sartem unsigned remove:1; 87*2912Sartem unsigned add:1; 88*2912Sartem unsigned list:1; 89*2912Sartem char *udi; 90*2912Sartem } opt; 91*2912Sartem 92*2912Sartem struct option options[] = { 93*2912Sartem { "remove", 1, NULL, 'r' }, 94*2912Sartem { "add", 1, NULL, 'a' }, 95*2912Sartem { "help", 0, NULL, 'h' }, 96*2912Sartem { 0, 0, 0, 0 } 97*2912Sartem }; 98*2912Sartem 99*2912Sartem 100*2912Sartem int main(int argc, char **argv) 101*2912Sartem { 102*2912Sartem DBusError error; 103*2912Sartem DBusConnection *conn; 104*2912Sartem LibHalContext *hal_ctx; 105*2912Sartem int i, err; 106*2912Sartem 107*2912Sartem opterr = 0; 108*2912Sartem opt.list = 1; 109*2912Sartem 110*2912Sartem while ((i = getopt_long(argc, argv, "a:hr:", options, NULL)) != -1) { 111*2912Sartem switch (i) { 112*2912Sartem case 'a': 113*2912Sartem opt.add = 1; 114*2912Sartem opt.list = 0; 115*2912Sartem opt.udi = optarg; 116*2912Sartem break; 117*2912Sartem case 'r': 118*2912Sartem opt.remove = 1; 119*2912Sartem opt.list = 0; 120*2912Sartem opt.udi = optarg; 121*2912Sartem break; 122*2912Sartem case 'h': 123*2912Sartem help(); 124*2912Sartem return 0; 125*2912Sartem default: 126*2912Sartem help(); 127*2912Sartem return 1; 128*2912Sartem } 129*2912Sartem } 130*2912Sartem 131*2912Sartem dbus_error_init(&error); 132*2912Sartem 133*2912Sartem if (!(conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) { 134*2912Sartem fprintf(stderr, "error: dbus_bus_get: %s: %s\n", error.name, error.message); 135*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 136*2912Sartem return 2; 137*2912Sartem } 138*2912Sartem 139*2912Sartem /* fprintf(stderr, "connected to: %s\n", dbus_bus_get_unique_name(conn)); */ 140*2912Sartem if (!(hal_ctx = libhal_ctx_new())) return 3; 141*2912Sartem if (!libhal_ctx_set_dbus_connection(hal_ctx, conn)) return 4; 142*2912Sartem if (!libhal_ctx_init(hal_ctx, &error)) { 143*2912Sartem if (dbus_error_is_set(&error)) { 144*2912Sartem fprintf (stderr, "error: libhal_ctx_init: %s: %s\n", error.name, error.message); 145*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 146*2912Sartem } 147*2912Sartem fprintf (stderr, "Could not initialise connection to hald.\n" 148*2912Sartem "Normally this means the HAL daemon (hald) is not running or not ready.\n"); 149*2912Sartem return 5; 150*2912Sartem } 151*2912Sartem 152*2912Sartem err = 0; 153*2912Sartem if (opt.list) 154*2912Sartem err = dump_devices(hal_ctx, argv[optind]); 155*2912Sartem else if (opt.remove) 156*2912Sartem err = remove_udi(hal_ctx, opt.udi); 157*2912Sartem else if (opt.add) 158*2912Sartem err = add_udi(hal_ctx, opt.udi); 159*2912Sartem else 160*2912Sartem err = 6; 161*2912Sartem 162*2912Sartem libhal_ctx_shutdown(hal_ctx, &error); 163*2912Sartem libhal_ctx_free(hal_ctx); 164*2912Sartem dbus_connection_close(conn); 165*2912Sartem dbus_connection_unref(conn); 166*2912Sartem dbus_error_free(&error); 167*2912Sartem 168*2912Sartem return err; 169*2912Sartem } 170*2912Sartem 171*2912Sartem 172*2912Sartem void help() 173*2912Sartem { 174*2912Sartem fprintf(stderr, 175*2912Sartem "usage: hal-device [--help] [--add udi] [--remove udi] [udi]\n" 176*2912Sartem "Create, remove, or show HAL device. If no udi is given, shows all devices.\n" 177*2912Sartem "If udi doesn't start with a '/', '/org/freedesktop/Hal/devices/' is prepended.\n" 178*2912Sartem " -a, --add udi\t\tAdd new device.\n" 179*2912Sartem " \t\t\tReads property list in 'lshal' syntax from stdin.\n" 180*2912Sartem " -r, --remove udi\tRemove device.\n" 181*2912Sartem " -h, --help\t\tShow this text.\n" 182*2912Sartem ); 183*2912Sartem } 184*2912Sartem 185*2912Sartem 186*2912Sartem /* 187*2912Sartem * Dump all devices. 188*2912Sartem */ 189*2912Sartem int dump_devices(LibHalContext *hal_ctx, char *arg) 190*2912Sartem { 191*2912Sartem int i; 192*2912Sartem int num_devices; 193*2912Sartem char **device_names; 194*2912Sartem DBusError error; 195*2912Sartem char *udi = NULL; 196*2912Sartem 197*2912Sartem if (arg) { 198*2912Sartem if (*arg == '/') { 199*2912Sartem udi = arg; 200*2912Sartem } else { 201*2912Sartem #ifdef HAVE_ASPRINTF 202*2912Sartem asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg); 203*2912Sartem #else 204*2912Sartem udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg)); 205*2912Sartem sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg); 206*2912Sartem 207*2912Sartem #endif 208*2912Sartem } 209*2912Sartem } 210*2912Sartem 211*2912Sartem dbus_error_init(&error); 212*2912Sartem 213*2912Sartem if (!udi) { 214*2912Sartem if (!(device_names = libhal_get_all_devices(hal_ctx, &num_devices, &error))) { 215*2912Sartem fprintf(stderr, "Empty HAL device list.\n"); 216*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 217*2912Sartem return 31; 218*2912Sartem } 219*2912Sartem } else { 220*2912Sartem device_names = calloc(2, sizeof *device_names); 221*2912Sartem device_names[0] = strdup(udi); 222*2912Sartem num_devices = 1; 223*2912Sartem } 224*2912Sartem 225*2912Sartem for(i = 0; i < num_devices; i++) { 226*2912Sartem LibHalPropertySet *props; 227*2912Sartem LibHalPropertySetIterator it; 228*2912Sartem int type; 229*2912Sartem 230*2912Sartem if (!(props = libhal_device_get_all_properties(hal_ctx, device_names[i], &error))) { 231*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 232*2912Sartem dbus_error_init(&error); 233*2912Sartem continue; 234*2912Sartem } 235*2912Sartem 236*2912Sartem if (!udi) 237*2912Sartem printf("%d: ", i); 238*2912Sartem printf("udi = '%s'\n", device_names[i]); 239*2912Sartem 240*2912Sartem for(libhal_psi_init(&it, props); libhal_psi_has_more(&it); libhal_psi_next(&it)) { 241*2912Sartem type = libhal_psi_get_type(&it); 242*2912Sartem switch (type) { 243*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 244*2912Sartem printf(" %s = '%s' (string)\n", 245*2912Sartem libhal_psi_get_key(&it), 246*2912Sartem libhal_psi_get_string(&it) 247*2912Sartem ); 248*2912Sartem break; 249*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 250*2912Sartem printf(" %s = %d (0x%x) (int)\n", 251*2912Sartem libhal_psi_get_key(&it), 252*2912Sartem libhal_psi_get_int(&it), 253*2912Sartem libhal_psi_get_int(&it) 254*2912Sartem ); 255*2912Sartem break; 256*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 257*2912Sartem printf(" %s = %lld (0x%llx) (uint64)\n", 258*2912Sartem libhal_psi_get_key(&it), 259*2912Sartem (long long) libhal_psi_get_uint64(&it), 260*2912Sartem (long long) libhal_psi_get_uint64(&it) 261*2912Sartem ); 262*2912Sartem break; 263*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 264*2912Sartem printf(" %s = %g (double)\n", 265*2912Sartem libhal_psi_get_key(&it), 266*2912Sartem libhal_psi_get_double(&it) 267*2912Sartem ); 268*2912Sartem break; 269*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 270*2912Sartem printf(" %s = %s (bool)\n", 271*2912Sartem libhal_psi_get_key(&it), 272*2912Sartem libhal_psi_get_bool(&it) ? "true" : "false" 273*2912Sartem ); 274*2912Sartem break; 275*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 276*2912Sartem { 277*2912Sartem char **strlist; 278*2912Sartem 279*2912Sartem printf (" %s = { ", libhal_psi_get_key(&it)); 280*2912Sartem strlist = libhal_psi_get_strlist(&it); 281*2912Sartem while (*strlist) { 282*2912Sartem printf("'%s'%s", *strlist, strlist[1] ? ", " : ""); 283*2912Sartem strlist++; 284*2912Sartem } 285*2912Sartem printf(" } (string list)\n"); 286*2912Sartem } 287*2912Sartem break; 288*2912Sartem default: 289*2912Sartem printf("Unknown type %d = 0x%02x\n", type, type); 290*2912Sartem break; 291*2912Sartem } 292*2912Sartem } 293*2912Sartem 294*2912Sartem libhal_free_property_set(props); 295*2912Sartem printf("\n"); 296*2912Sartem } 297*2912Sartem 298*2912Sartem libhal_free_string_array(device_names); 299*2912Sartem dbus_error_free(&error); 300*2912Sartem 301*2912Sartem return 0; 302*2912Sartem } 303*2912Sartem 304*2912Sartem 305*2912Sartem int remove_udi(LibHalContext *hal_ctx, char *arg) 306*2912Sartem { 307*2912Sartem DBusError error; 308*2912Sartem char *udi; 309*2912Sartem 310*2912Sartem if (!arg) return 11; 311*2912Sartem 312*2912Sartem if (*arg == '/') { 313*2912Sartem udi = arg; 314*2912Sartem } else { 315*2912Sartem #ifdef HAVE_ASPRINTF 316*2912Sartem asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg); 317*2912Sartem #else 318*2912Sartem udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg)); 319*2912Sartem sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg); 320*2912Sartem #endif 321*2912Sartem 322*2912Sartem } 323*2912Sartem 324*2912Sartem dbus_error_init(&error); 325*2912Sartem 326*2912Sartem if (opt.remove) { 327*2912Sartem if (!libhal_remove_device(hal_ctx, udi, &error)) { 328*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 329*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 330*2912Sartem return 12; 331*2912Sartem } 332*2912Sartem 333*2912Sartem fprintf(stderr, "removed: %s\n", udi); 334*2912Sartem return 13; 335*2912Sartem } 336*2912Sartem 337*2912Sartem return 0; 338*2912Sartem } 339*2912Sartem 340*2912Sartem 341*2912Sartem int add_udi(LibHalContext *hal_ctx, char *arg) 342*2912Sartem { 343*2912Sartem DBusError error; 344*2912Sartem dbus_bool_t dev_exists = FALSE; 345*2912Sartem char *udi = NULL, buf[1024]; 346*2912Sartem lh_prop_t *prop; 347*2912Sartem int err; 348*2912Sartem 349*2912Sartem if (!arg) 350*2912Sartem return 21; 351*2912Sartem 352*2912Sartem if (*arg == '/') { 353*2912Sartem udi = arg; 354*2912Sartem } else { 355*2912Sartem #ifdef HAVE_ASPRINTF 356*2912Sartem asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg); 357*2912Sartem #else 358*2912Sartem udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg)); 359*2912Sartem sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg); 360*2912Sartem #endif 361*2912Sartem } 362*2912Sartem 363*2912Sartem if (udi) 364*2912Sartem new_dev.udi = strdup(udi); 365*2912Sartem 366*2912Sartem dbus_error_init(&error); 367*2912Sartem 368*2912Sartem if (udi) 369*2912Sartem dev_exists = libhal_device_exists(hal_ctx, udi, &error); 370*2912Sartem 371*2912Sartem if (dev_exists) { 372*2912Sartem new_dev.real_udi = strdup(new_dev.udi); 373*2912Sartem } else { 374*2912Sartem new_dev.real_udi = libhal_new_device(hal_ctx, &error); 375*2912Sartem 376*2912Sartem if (!new_dev.real_udi) { 377*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 378*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 379*2912Sartem free(new_dev.real_udi); 380*2912Sartem 381*2912Sartem return 22; 382*2912Sartem } 383*2912Sartem 384*2912Sartem printf("tmp udi: %s\n", new_dev.real_udi); 385*2912Sartem } 386*2912Sartem 387*2912Sartem prop = NULL; 388*2912Sartem 389*2912Sartem while (fgets(buf, sizeof buf, stdin)) { 390*2912Sartem process_property(hal_ctx, buf, &prop); 391*2912Sartem } 392*2912Sartem 393*2912Sartem err = add_properties(hal_ctx, &new_dev, prop); 394*2912Sartem 395*2912Sartem prop = free_properties(prop); 396*2912Sartem 397*2912Sartem if (!dev_exists) { 398*2912Sartem if (!libhal_device_commit_to_gdl(hal_ctx, new_dev.real_udi, new_dev.udi, &error)) { 399*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 400*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 401*2912Sartem free(new_dev.real_udi); 402*2912Sartem 403*2912Sartem err = err ? err : 23; 404*2912Sartem } 405*2912Sartem } 406*2912Sartem 407*2912Sartem printf("%s: %s\n", dev_exists ? "merged": "created", new_dev.udi); 408*2912Sartem 409*2912Sartem return err; 410*2912Sartem } 411*2912Sartem 412*2912Sartem 413*2912Sartem char *skip_space(char *s) 414*2912Sartem { 415*2912Sartem while (isspace(*s)) s++; 416*2912Sartem 417*2912Sartem return s; 418*2912Sartem } 419*2912Sartem 420*2912Sartem 421*2912Sartem char *skip_non_eq_or_space(char *s) 422*2912Sartem { 423*2912Sartem while (*s && *s != '=' && !isspace(*s)) 424*2912Sartem s++; 425*2912Sartem 426*2912Sartem return s; 427*2912Sartem } 428*2912Sartem 429*2912Sartem 430*2912Sartem char *skip_number(char *s) 431*2912Sartem { 432*2912Sartem while (*s == '-' || *s == '+' || *s == '.' || isdigit(*s)) 433*2912Sartem s++; 434*2912Sartem 435*2912Sartem return s; 436*2912Sartem } 437*2912Sartem 438*2912Sartem 439*2912Sartem char *skip_nonquote(char *s) 440*2912Sartem { 441*2912Sartem while (*s && *s != '\'') 442*2912Sartem s++; 443*2912Sartem 444*2912Sartem return s; 445*2912Sartem } 446*2912Sartem 447*2912Sartem 448*2912Sartem void process_property(LibHalContext *hal_ctx, char *buf, lh_prop_t **prop) 449*2912Sartem { 450*2912Sartem char *s, *s1; 451*2912Sartem char *key, *s_val = NULL; 452*2912Sartem lh_prop_t *p; 453*2912Sartem unsigned len; 454*2912Sartem int remove = 0; 455*2912Sartem 456*2912Sartem s = skip_space(buf); 457*2912Sartem 458*2912Sartem if (*s == '-') { 459*2912Sartem remove = 1; 460*2912Sartem s = skip_space(s + 1); 461*2912Sartem } 462*2912Sartem 463*2912Sartem if ((s1 = skip_number(s), s1 != s) && *s1 == ':') s = skip_space(s1 + 1); 464*2912Sartem 465*2912Sartem s = skip_non_eq_or_space(key = s); 466*2912Sartem *s++ = 0; 467*2912Sartem if (!*key) 468*2912Sartem return; 469*2912Sartem 470*2912Sartem if (*key == '#') 471*2912Sartem return; 472*2912Sartem 473*2912Sartem if (*s == '=') 474*2912Sartem s++; 475*2912Sartem s = skip_space(s); 476*2912Sartem 477*2912Sartem if (!*s) 478*2912Sartem remove = 1; 479*2912Sartem 480*2912Sartem p = calloc(1, sizeof *p); 481*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_INVALID; 482*2912Sartem p->key = strdup(key); 483*2912Sartem 484*2912Sartem if (remove) { 485*2912Sartem p->next = *prop; 486*2912Sartem *prop = p; 487*2912Sartem return; 488*2912Sartem } 489*2912Sartem 490*2912Sartem if (*s == '\'') { 491*2912Sartem s_val = s + 1; 492*2912Sartem s = strrchr(s_val, '\''); 493*2912Sartem *(s ? s : s_val) = 0; 494*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRING; 495*2912Sartem p->v.str_value = strdup(s_val); 496*2912Sartem } else if (*s == '{') { 497*2912Sartem s_val = s + 1; 498*2912Sartem s1 = strrchr(s_val, '}'); 499*2912Sartem if (s1) *s1 = 0; 500*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_STRLIST; 501*2912Sartem len = 0; 502*2912Sartem p->v.strlist_value = calloc(1, sizeof *p->v.strlist_value); 503*2912Sartem while (*s_val++ == '\'') { 504*2912Sartem s = skip_nonquote(s_val); 505*2912Sartem if (*s) *s++ = 0; 506*2912Sartem p->v.strlist_value = realloc(p->v.strlist_value, (len + 2) * sizeof *p->v.strlist_value); 507*2912Sartem p->v.strlist_value[len] = strdup(s_val); 508*2912Sartem p->v.strlist_value[++len] = NULL; 509*2912Sartem s_val = skip_nonquote(s); 510*2912Sartem } 511*2912Sartem } else if (!strncmp(s, "true", 4)) { 512*2912Sartem s += 4; 513*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN; 514*2912Sartem p->v.bool_value = TRUE; 515*2912Sartem } else if (!strncmp(s, "false", 5)) { 516*2912Sartem s += 5; 517*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_BOOLEAN; 518*2912Sartem p->v.bool_value = FALSE; 519*2912Sartem } else if ((s1 = skip_number(s)) != s) { 520*2912Sartem if (strstr(s1, "(int)")) { 521*2912Sartem *s1++ = 0; 522*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_INT32; 523*2912Sartem p->v.int_value = strtol(s, NULL, 10); 524*2912Sartem } else if (strstr(s1, "(uint64)")) { 525*2912Sartem *s1++ = 0; 526*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_UINT64; 527*2912Sartem p->v.uint64_value = strtoull(s, NULL, 10); 528*2912Sartem } else if (strstr(s1, "(double)")) { 529*2912Sartem p->type = LIBHAL_PROPERTY_TYPE_DOUBLE; 530*2912Sartem p->v.double_value = strtod(s, NULL); 531*2912Sartem } 532*2912Sartem 533*2912Sartem s = s1; 534*2912Sartem } 535*2912Sartem 536*2912Sartem if (p->type == LIBHAL_PROPERTY_TYPE_INVALID) { 537*2912Sartem free(p->key); 538*2912Sartem free(p); 539*2912Sartem } else { 540*2912Sartem p->next = *prop; 541*2912Sartem *prop = p; 542*2912Sartem } 543*2912Sartem } 544*2912Sartem 545*2912Sartem 546*2912Sartem int add_properties(LibHalContext *hal_ctx, new_dev_t *nd, lh_prop_t *prop) 547*2912Sartem { 548*2912Sartem DBusError error; 549*2912Sartem lh_prop_t *p; 550*2912Sartem char *udi2 = NULL, *udi3 = NULL, **s; 551*2912Sartem LibHalPropertyType old_type; 552*2912Sartem 553*2912Sartem dbus_error_init(&error); 554*2912Sartem 555*2912Sartem for(p = prop; p; p = p->next) { 556*2912Sartem if (!strcmp(p->key, "udi") && p->type == LIBHAL_PROPERTY_TYPE_STRING) { 557*2912Sartem udi2 = p->v.str_value; 558*2912Sartem continue; 559*2912Sartem } 560*2912Sartem 561*2912Sartem old_type = libhal_device_get_property_type(hal_ctx, nd->real_udi, p->key, &error); 562*2912Sartem dbus_error_init(&error); 563*2912Sartem 564*2912Sartem if (old_type != LIBHAL_PROPERTY_TYPE_INVALID && 565*2912Sartem ( p->type != old_type || p->type == LIBHAL_PROPERTY_TYPE_STRLIST)) { 566*2912Sartem if (!libhal_device_remove_property(hal_ctx, nd->real_udi, p->key, &error)) { 567*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 568*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 569*2912Sartem return 41; 570*2912Sartem } 571*2912Sartem } 572*2912Sartem 573*2912Sartem switch (p->type) { 574*2912Sartem case LIBHAL_PROPERTY_TYPE_INVALID: 575*2912Sartem break; 576*2912Sartem case LIBHAL_PROPERTY_TYPE_BOOLEAN: 577*2912Sartem if (!libhal_device_set_property_bool(hal_ctx, nd->real_udi, p->key, p->v.bool_value, &error)) { 578*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 579*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 580*2912Sartem return 42; 581*2912Sartem } 582*2912Sartem break; 583*2912Sartem case LIBHAL_PROPERTY_TYPE_INT32: 584*2912Sartem if (!libhal_device_set_property_int(hal_ctx, nd->real_udi, p->key, p->v.int_value, &error)) { 585*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 586*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 587*2912Sartem return 42; 588*2912Sartem } 589*2912Sartem break; 590*2912Sartem case LIBHAL_PROPERTY_TYPE_UINT64: 591*2912Sartem if (!libhal_device_set_property_uint64(hal_ctx, nd->real_udi, p->key, p->v.uint64_value, &error)) { 592*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 593*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 594*2912Sartem return 42; 595*2912Sartem } 596*2912Sartem break; 597*2912Sartem case LIBHAL_PROPERTY_TYPE_DOUBLE: 598*2912Sartem if (!libhal_device_set_property_double(hal_ctx, nd->real_udi, p->key, p->v.double_value, &error)) { 599*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 600*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 601*2912Sartem return 42; 602*2912Sartem } 603*2912Sartem break; 604*2912Sartem case LIBHAL_PROPERTY_TYPE_STRING: 605*2912Sartem if (!strcmp(p->key, "info.udi")) udi3 = p->v.str_value; 606*2912Sartem if (!libhal_device_set_property_string(hal_ctx, nd->real_udi, p->key, p->v.str_value, &error)) { 607*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 608*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 609*2912Sartem return 42; 610*2912Sartem } 611*2912Sartem break; 612*2912Sartem case LIBHAL_PROPERTY_TYPE_STRLIST: 613*2912Sartem for(s = p->v.strlist_value; *s; s++) { 614*2912Sartem if (!libhal_device_property_strlist_append(hal_ctx, nd->real_udi, p->key, *s, &error)) { 615*2912Sartem fprintf(stderr, "%s: %s\n", error.name, error.message); 616*2912Sartem LIBHAL_FREE_DBUS_ERROR (&error); 617*2912Sartem return 42; 618*2912Sartem } 619*2912Sartem } 620*2912Sartem break; 621*2912Sartem } 622*2912Sartem } 623*2912Sartem 624*2912Sartem if (udi2) udi3 = NULL; 625*2912Sartem if (udi3) udi2 = udi3; 626*2912Sartem 627*2912Sartem if (udi2 && !nd->udi) 628*2912Sartem nd->udi = strdup(udi2); 629*2912Sartem 630*2912Sartem return 0; 631*2912Sartem } 632*2912Sartem 633*2912Sartem 634*2912Sartem lh_prop_t *free_properties(lh_prop_t *prop) 635*2912Sartem { 636*2912Sartem lh_prop_t *next; 637*2912Sartem char **s; 638*2912Sartem 639*2912Sartem for(; prop; prop = next) { 640*2912Sartem next = prop->next; 641*2912Sartem 642*2912Sartem free(prop->key); 643*2912Sartem if (prop->type == LIBHAL_PROPERTY_TYPE_STRING) free(prop->v.str_value); 644*2912Sartem if (prop->type == LIBHAL_PROPERTY_TYPE_STRLIST && prop->v.strlist_value) { 645*2912Sartem for(s = prop->v.strlist_value; *s; ) free(*s++); 646*2912Sartem free(prop->v.strlist_value); 647*2912Sartem } 648*2912Sartem free(prop); 649*2912Sartem } 650*2912Sartem 651*2912Sartem return NULL; 652*2912Sartem } 653