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