~ubuntu-branches/ubuntu/wily/hwinfo/wily

« back to all changes in this revision

Viewing changes to src/hd/hal.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-11-03 07:28:15 UTC
  • mfrom: (1.2.1 upstream) (3.1.7 edgy)
  • Revision ID: james.westby@ubuntu.com-20061103072815-7g9d6kzk0xn54159
Add cpu.c-alpha_bogo patch, which fixes a FTBFS on alpha because of an
undefined variable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <ctype.h>
 
6
#include <fcntl.h>
 
7
#include <inttypes.h>
 
8
#include <errno.h>
 
9
#include <sys/stat.h>
 
10
#include <sys/types.h>
 
11
#include <sys/ioctl.h>
 
12
#include <sys/socket.h>
 
13
 
 
14
#ifndef DBUS_API_SUBJECT_TO_CHANGE
 
15
  #define DBUS_API_SUBJECT_TO_CHANGE 1
 
16
#endif
 
17
 
 
18
#include <dbus/dbus.h>
 
19
#include <hal/libhal.h>
 
20
 
 
21
#include "hd.h"
 
22
#include "hd_int.h"
 
23
#include "hal.h"
 
24
 
 
25
/**
 
26
 * @defgroup HALint Hardware abstraction (HAL) information
 
27
 * @ingroup  libhdInternals
 
28
 *
 
29
 * @{
 
30
 */
 
31
 
 
32
static void read_hal(hd_data_t *hd_data);
 
33
static void add_pci(hd_data_t *hd_data);
 
34
static void link_hal_tree(hd_data_t *hd_data);
 
35
 
 
36
static int hal_match_str(hal_prop_t *prop, const char *key, const char *val);
 
37
 
 
38
static int check_udi(const char *udi);
 
39
static FILE *hd_open_properties(const char *udi, const char *mode);
 
40
static char *skip_space(char *s);
 
41
static char *skip_non_eq_or_space(char *s);
 
42
static char *skip_nonquote(char *s);
 
43
static void parse_property(hal_prop_t *prop, char *str);
 
44
 
 
45
static void find_udi(hd_data_t *hd_data, hd_t *hd, int match);
 
46
 
 
47
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
48
 *
 
49
 * read hal data
 
50
 *
 
51
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
52
 */
 
53
 
 
54
void hd_scan_hal(hd_data_t *hd_data)
 
55
{
 
56
  if(!hd_probe_feature(hd_data, pr_hal)) return;
 
57
 
 
58
  hd_data->module = mod_hal;
 
59
 
 
60
  /* some clean-up */
 
61
  remove_hd_entries(hd_data);
 
62
  hd_data->hal = hd_free_hal_devices(hd_data->hal);
 
63
 
 
64
  PROGRESS(1, 0, "read hal data");
 
65
 
 
66
  read_hal(hd_data);
 
67
 
 
68
  if(!hd_data->hal) return;
 
69
 
 
70
  link_hal_tree(hd_data);
 
71
 
 
72
  PROGRESS(1, 0, "pci sysfs");
 
73
 
 
74
  hd_pci_read_data(hd_data);
 
75
 
 
76
  PROGRESS(2, 0, "pci devices");
 
77
 
 
78
  add_pci(hd_data);
 
79
 
 
80
}
 
81
 
 
82
 
 
83
void hd_scan_hal_basic(hd_data_t *hd_data)
 
84
{
 
85
  hd_data->module = mod_hal;
 
86
 
 
87
  /* some clean-up */
 
88
  hd_data->hal = hd_free_hal_devices(hd_data->hal);
 
89
 
 
90
  PROGRESS(1, 0, "read hal data");
 
91
 
 
92
  read_hal(hd_data);
 
93
}
 
94
 
 
95
 
 
96
void read_hal(hd_data_t *hd_data)
 
97
{
 
98
  DBusError error;
 
99
  DBusConnection *conn;
 
100
  LibHalContext *hal_ctx;
 
101
  LibHalPropertySet *props;
 
102
  LibHalPropertySetIterator it;
 
103
  char **device_names, **slist, *s;
 
104
  int i, num_devices, type;
 
105
  hal_device_t *dev;
 
106
  hal_prop_t *prop;
 
107
 
 
108
  dbus_error_init(&error);
 
109
 
 
110
  if(!(conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
 
111
    ADD2LOG("  hal: dbus_bus_get: %s: %s\n", error.name, error.message);
 
112
    return;
 
113
  }
 
114
 
 
115
  ADD2LOG("  hal: connected to: %s\n", dbus_bus_get_unique_name(conn));
 
116
 
 
117
  if(!(hal_ctx = libhal_ctx_new())) return;
 
118
 
 
119
  if(!libhal_ctx_set_dbus_connection(hal_ctx, conn)) return;
 
120
 
 
121
  if(!libhal_ctx_init(hal_ctx, &error)) {
 
122
    ADD2LOG("  hal: libhal_ctx_init: %s: %s\n", error.name, error.message);
 
123
    return;
 
124
  }
 
125
 
 
126
 
 
127
  dbus_error_init(&error);
 
128
 
 
129
  if((device_names = libhal_get_all_devices(hal_ctx, &num_devices, &error))) {
 
130
    ADD2LOG("----- hal device list -----\n");
 
131
    for(i = 0; i < num_devices; i++) {
 
132
      if(!(props = libhal_device_get_all_properties(hal_ctx, device_names[i], &error))) {
 
133
        ADD2LOG("  hal: %s: %s\n", error.name, error.message);
 
134
        dbus_error_init(&error);
 
135
        continue;
 
136
      }
 
137
 
 
138
      dev = new_mem(sizeof *dev);
 
139
      dev->udi = new_str(device_names[i]);
 
140
      dev->next = hd_data->hal;
 
141
      hd_data->hal = dev;
 
142
 
 
143
      ADD2LOG("  %d: udi = '%s'\n", i, dev->udi);
 
144
 
 
145
      for(libhal_psi_init(&it, props); libhal_psi_has_more(&it); libhal_psi_next(&it)) {
 
146
        type = libhal_psi_get_type(&it);
 
147
 
 
148
        prop = new_mem(sizeof *prop);
 
149
        prop->next = dev->prop;
 
150
        dev->prop = prop;
 
151
 
 
152
        switch(type) {
 
153
          case LIBHAL_PROPERTY_TYPE_STRING:
 
154
            prop->type = p_string;
 
155
            prop->key = new_str(libhal_psi_get_key(&it));
 
156
            prop->val.str = new_str(libhal_psi_get_string(&it));
 
157
            break;
 
158
 
 
159
          case LIBHAL_PROPERTY_TYPE_INT32:
 
160
            prop->type = p_int32;
 
161
            prop->key = new_str(libhal_psi_get_key(&it));
 
162
            prop->val.int32 = libhal_psi_get_int(&it);
 
163
            break;
 
164
 
 
165
          case LIBHAL_PROPERTY_TYPE_UINT64:
 
166
            prop->type = p_uint64;
 
167
            prop->key = new_str(libhal_psi_get_key(&it));
 
168
            prop->val.uint64 = libhal_psi_get_uint64(&it);
 
169
            break;
 
170
 
 
171
          case LIBHAL_PROPERTY_TYPE_DOUBLE:
 
172
            prop->type = p_double;
 
173
            prop->key = new_str(libhal_psi_get_key(&it));
 
174
            prop->val.d = libhal_psi_get_double(&it);
 
175
            break;
 
176
 
 
177
          case LIBHAL_PROPERTY_TYPE_BOOLEAN:
 
178
            prop->type = p_bool;
 
179
            prop->key = new_str(libhal_psi_get_key(&it));
 
180
            prop->val.b = libhal_psi_get_bool(&it);
 
181
            break;
 
182
 
 
183
          case LIBHAL_PROPERTY_TYPE_STRLIST:
 
184
            prop->type = p_list;
 
185
            prop->key = new_str(libhal_psi_get_key(&it));
 
186
            for(slist = libhal_psi_get_strlist(&it); *slist; slist++) {
 
187
              add_str_list(&prop->val.list, *slist);
 
188
            }
 
189
            break;
 
190
 
 
191
          default:
 
192
            prop->type = p_invalid;
 
193
        }
 
194
 
 
195
        if((s = hd_hal_print_prop(prop))) {
 
196
          ADD2LOG("  %s\n", s);
 
197
        }
 
198
      }
 
199
 
 
200
      libhal_free_property_set(props);
 
201
      if(i != num_devices - 1) ADD2LOG("\n");
 
202
 
 
203
    }
 
204
 
 
205
    ADD2LOG("----- hal device list end -----\n");
 
206
 
 
207
    libhal_free_string_array(device_names);
 
208
 
 
209
    dbus_error_free(&error);
 
210
  }
 
211
  else {
 
212
    ADD2LOG("  hal: empty device list\n");
 
213
  }
 
214
 
 
215
 
 
216
  libhal_ctx_shutdown(hal_ctx, &error);
 
217
 
 
218
  libhal_ctx_free(hal_ctx);
 
219
 
 
220
  dbus_connection_unref(conn);
 
221
 
 
222
  dbus_error_free(&error);
 
223
}
 
224
 
 
225
 
 
226
void link_hal_tree(hd_data_t *hd_data)
 
227
{
 
228
  hal_device_t *dev;
 
229
  hal_prop_t *prop;
 
230
 
 
231
  for(dev = hd_data->hal; dev; dev = dev->next) {
 
232
    prop = hal_get_str(dev->prop, "info.parent");
 
233
    if(prop) {
 
234
      dev->parent = hal_find_device(hd_data, prop->val.str);
 
235
    }
 
236
  }
 
237
}
 
238
 
 
239
 
 
240
hal_device_t *hal_find_device(hd_data_t *hd_data, char *udi)
 
241
{
 
242
  hal_device_t *dev;
 
243
 
 
244
  if(udi) {
 
245
    for(dev = hd_data->hal; dev; dev = dev->next) {
 
246
      if(!strcmp(dev->udi, udi)) return dev;
 
247
    }
 
248
  }
 
249
 
 
250
  return NULL;
 
251
}
 
252
 
 
253
 
 
254
void hal_invalidate(hal_prop_t *prop)
 
255
{
 
256
  if(prop->type == p_string) free_mem(prop->val.str);
 
257
  if(prop->type == p_list) free_str_list(prop->val.list);
 
258
  prop->type = p_invalid;
 
259
  memset(&prop->val, 0, sizeof prop->val);
 
260
}
 
261
 
 
262
 
 
263
void hal_invalidate_all(hal_prop_t *prop, const char *key)
 
264
{
 
265
  for(; (prop = hal_get_any(prop, key)); prop = prop->next) {
 
266
    hal_invalidate(prop);
 
267
  }
 
268
}
 
269
 
 
270
 
 
271
hal_prop_t *hal_get_any(hal_prop_t *prop, const char *key)
 
272
{
 
273
  for(; prop; prop = prop->next) {
 
274
    if(!strcmp(prop->key, key)) return prop;
 
275
  }
 
276
 
 
277
  return NULL;
 
278
}
 
279
 
 
280
 
 
281
hal_prop_t *hal_get_bool(hal_prop_t *prop, const char *key)
 
282
{
 
283
  for(; prop; prop = prop->next) {
 
284
    if(prop->type == p_bool && !strcmp(prop->key, key)) return prop;
 
285
  }
 
286
 
 
287
  return NULL;
 
288
}
 
289
 
 
290
 
 
291
hal_prop_t *hal_get_int32(hal_prop_t *prop, const char *key)
 
292
{
 
293
  for(; prop; prop = prop->next) {
 
294
    if(prop->type == p_int32 && !strcmp(prop->key, key)) return prop;
 
295
  }
 
296
 
 
297
  return NULL;
 
298
}
 
299
 
 
300
 
 
301
hal_prop_t *hal_get_str(hal_prop_t *prop, const char *key)
 
302
{
 
303
  for(; prop; prop = prop->next) {
 
304
    if(prop->type == p_string && !strcmp(prop->key, key)) return prop;
 
305
  }
 
306
 
 
307
  return NULL;
 
308
}
 
309
 
 
310
 
 
311
char *hal_get_useful_str(hal_prop_t *prop, const char *key)
 
312
{
 
313
  for(; prop; prop = prop->next) {
 
314
    if(prop->type == p_string && !strcmp(prop->key, key)) {
 
315
      if(prop->val.str && strncmp(prop->val.str, "Unknown", sizeof "Unknown" - 1)) return prop->val.str;
 
316
      break;
 
317
    }
 
318
  }
 
319
 
 
320
  return NULL;
 
321
}
 
322
 
 
323
 
 
324
int hal_match_str(hal_prop_t *prop, const char *key, const char *val)
 
325
{
 
326
  return val && (prop = hal_get_str(prop, key)) && !strcmp(prop->val.str, val);
 
327
}
 
328
 
 
329
 
 
330
hal_prop_t *hal_get_list(hal_prop_t *prop, const char *key)
 
331
{
 
332
  for(; prop; prop = prop->next) {
 
333
    if(prop->type == p_list && !strcmp(prop->key, key)) return prop;
 
334
  }
 
335
 
 
336
  return NULL;
 
337
}
 
338
 
 
339
 
 
340
void add_pci(hd_data_t *hd_data)
 
341
{
 
342
  hd_t *hd;
 
343
  hal_prop_t *prop;
 
344
  int i, j;
 
345
  char *s;
 
346
  hal_device_t *dev;
 
347
  pci_t *pci;
 
348
 
 
349
  for(dev = hd_data->hal ; dev; dev = dev->next) {
 
350
    if(dev->used) continue;
 
351
    if(!hal_match_str(dev->prop, "info.bus", "pci")) continue;
 
352
    dev->used = 1;
 
353
 
 
354
    hd = add_hd_entry(hd_data, __LINE__, 0);
 
355
 
 
356
    if((prop = hal_get_str(dev->prop, "linux.sysfs_path"))) hd->sysfs_id = new_str(hd_sysfs_id(prop->val.str));
 
357
 
 
358
    for(pci = hd_data->pci; pci; pci = pci->next) {
 
359
      if(!strcmp(hd_sysfs_id(pci->sysfs_id), hd->sysfs_id)) {
 
360
        hd->detail = new_mem(sizeof *hd->detail);
 
361
        hd->detail->type = hd_detail_pci;
 
362
        hd->detail->pci.data = pci;
 
363
 
 
364
        break;
 
365
      }
 
366
    }
 
367
 
 
368
    hd_pci_complete_data(hd);
 
369
 
 
370
    hd->udi = new_str(dev->udi);
 
371
    if(dev->parent) hd->parent_udi = new_str(dev->parent->udi);
 
372
 
 
373
    if((prop = hal_get_int32(dev->prop, "pci.device_protocol"))) hd->prog_if.id = prop->val.int32;
 
374
    if((prop = hal_get_int32(dev->prop, "pci.device_subclass"))) hd->sub_class.id = prop->val.int32;
 
375
    if((prop = hal_get_int32(dev->prop, "pci.device_class"))) hd->base_class.id = prop->val.int32;
 
376
 
 
377
    i = (prop = hal_get_int32(dev->prop, "pci.vendor_id")) ? prop->val.int32 : 0;
 
378
    j = (prop = hal_get_int32(dev->prop, "pci.product_id")) ? prop->val.int32 : 0;
 
379
 
 
380
    if(i || j) {
 
381
      hd->vendor.id = MAKE_ID(TAG_PCI, i);
 
382
      hd->device.id = MAKE_ID(TAG_PCI, j);
 
383
    }
 
384
 
 
385
    if((s = hal_get_useful_str(dev->prop, "pci.vendor"))) hd->vendor.name = new_str(s);
 
386
    if((s = hal_get_useful_str(dev->prop, "pci.product"))) hd->device.name = new_str(s);
 
387
 
 
388
    i = (prop = hal_get_int32(dev->prop, "pci.subsys_vendor_id")) ? prop->val.int32 : 0;
 
389
    j = (prop = hal_get_int32(dev->prop, "pci.subsys_product_id")) ? prop->val.int32 : 0;
 
390
 
 
391
    if(i || j) {
 
392
      hd->sub_vendor.id = MAKE_ID(TAG_PCI, i);
 
393
      hd->sub_device.id = MAKE_ID(TAG_PCI, j);
 
394
    }
 
395
 
 
396
    if((s = hal_get_useful_str(dev->prop, "pci.subsys_vendor"))) hd->sub_vendor.name = new_str(s);
 
397
    if((s = hal_get_useful_str(dev->prop, "pci.subsys_product"))) hd->sub_device.name = new_str(s);
 
398
 
 
399
    if((prop = hal_get_str(dev->prop, "linux.sysfs_path"))) hd->sysfs_id = new_str(hd_sysfs_id(prop->val.str));
 
400
 
 
401
    if((prop = hal_get_str(dev->prop, "info.linux.driver"))) add_str_list(&hd->drivers, prop->val.str);
 
402
 
 
403
    hd->hal_prop = dev->prop;
 
404
    dev->prop = NULL;
 
405
  }
 
406
 
 
407
  for(hd = hd_data->hd; hd; hd = hd->next) {
 
408
    if(
 
409
      !hd->detail ||
 
410
      hd->detail->type != hd_detail_pci ||
 
411
      !(pci = hd->detail->pci.data)
 
412
    ) continue;
 
413
 
 
414
    pci->next = NULL;
 
415
  }
 
416
 
 
417
  hd_data->pci = NULL;
 
418
}
 
419
 
 
420
 
 
421
char *hd_hal_print_prop(hal_prop_t *prop)
 
422
{
 
423
  static char *s = NULL;
 
424
  str_list_t *sl;
 
425
 
 
426
  switch(prop->type) {
 
427
    case p_string:
 
428
      str_printf(&s, 0, "%s = '%s'", prop->key, prop->val.str);
 
429
      break;
 
430
 
 
431
    case p_int32:
 
432
      str_printf(&s, 0, "%s = %d (0x%x)", prop->key, prop->val.int32, prop->val.int32);
 
433
      break;
 
434
 
 
435
    case p_uint64:
 
436
      str_printf(&s, 0, "%s = %"PRIu64"ull (0x%"PRIx64"ull)", prop->key, prop->val.uint64, prop->val.uint64);
 
437
      break;
 
438
 
 
439
    case p_double:
 
440
      str_printf(&s, 0, "%s = %#g", prop->key, prop->val.d);
 
441
      break;
 
442
 
 
443
    case p_bool:
 
444
      str_printf(&s, 0, "%s = %s", prop->key, prop->val.b ? "true" : "false");
 
445
      break;
 
446
 
 
447
    case p_list:
 
448
      str_printf(&s, 0, "%s = { ", prop->key);
 
449
      for(sl = prop->val.list; sl; sl = sl->next) {
 
450
        str_printf(&s, -1, "'%s'%s", sl->str, sl->next ? ", " : "");
 
451
      }
 
452
      str_printf(&s, -1, " }");
 
453
      break;
 
454
 
 
455
    case p_invalid:
 
456
      str_printf(&s, 0, "%s", prop->key);
 
457
      break;
 
458
  }
 
459
 
 
460
  return s;
 
461
}
 
462
 
 
463
 
 
464
/*
 
465
 * Ensure that udi is a sane path name.
 
466
 *
 
467
 * return:
 
468
 *   0/1: fail/ok
 
469
 */
 
470
int check_udi(const char *udi)
 
471
{
 
472
  if(
 
473
    !udi ||
 
474
    !strncmp(udi, "../", sizeof "../" - 1) ||
 
475
    strstr(udi, "/../") ||
 
476
    strstr(udi, "//")
 
477
  ) return 0;
 
478
 
 
479
  return 1;
 
480
}
 
481
 
 
482
 
 
483
int hd_write_properties(const char *udi, hal_prop_t *prop)
 
484
{
 
485
  FILE *f;
 
486
  char *s;
 
487
 
 
488
  f = hd_open_properties(udi, "w");
 
489
 
 
490
  if(!f) return 1;
 
491
 
 
492
  for(; prop; prop = prop->next) {
 
493
    if(prop->type == p_invalid) continue;
 
494
    s = hd_hal_print_prop(prop);
 
495
    if(s) fprintf(f, "%s\n", s);
 
496
  }
 
497
 
 
498
  fclose(f);
 
499
 
 
500
  return 0;
 
501
}
 
502
 
 
503
 
 
504
hal_prop_t *hd_read_properties(const char *udi)
 
505
{
 
506
  char *path = NULL;
 
507
  str_list_t *sl0, *sl;
 
508
  hal_prop_t *prop_list = NULL, *prop_list_e = NULL, prop, *p;
 
509
 
 
510
  if(!udi) return NULL;
 
511
 
 
512
  while(*udi == '/') udi++;
 
513
 
 
514
  if(!check_udi(udi)) return NULL;
 
515
 
 
516
  str_printf(&path, 0, "%s/%s", hd_get_hddb_path("udi"), udi);
 
517
 
 
518
  sl0 = read_file(path, 0, 0);
 
519
 
 
520
  free_mem(path);
 
521
 
 
522
  for(sl = sl0; sl; sl = sl->next) {
 
523
    parse_property(&prop, sl->str);
 
524
    if(prop.type != p_invalid) {
 
525
      p = new_mem(sizeof *p);
 
526
      *p = prop;
 
527
      if(prop_list) {
 
528
        prop_list_e->next = p;
 
529
        prop_list_e = prop_list_e->next;
 
530
      }
 
531
      else {
 
532
        prop_list = prop_list_e = p;
 
533
      }
 
534
    }
 
535
    else {
 
536
      prop.key = free_mem(prop.key);
 
537
    }
 
538
  }
 
539
 
 
540
  free_str_list(sl0);
 
541
 
 
542
  return prop_list;
 
543
}
 
544
 
 
545
 
 
546
FILE *hd_open_properties(const char *udi, const char *mode)
 
547
{
 
548
  str_list_t *path, *sl;
 
549
  struct stat sbuf;
 
550
  char *dir = NULL;
 
551
  int err, i;
 
552
  FILE *f = NULL;
 
553
 
 
554
  if(!udi) return f;
 
555
  while(*udi == '/') udi++;
 
556
 
 
557
  if(!check_udi(udi)) return f;
 
558
 
 
559
  path = hd_split('/', udi);
 
560
 
 
561
  if(!path) return f;
 
562
 
 
563
  dir = new_str(hd_get_hddb_path("udi"));
 
564
 
 
565
  for(err = 0, sl = path; sl->next; sl = sl->next) {
 
566
    str_printf(&dir, -1, "/%s", sl->str);
 
567
    i = lstat(dir, &sbuf);
 
568
    if(i == -1 && errno == ENOENT) {
 
569
      mkdir(dir, 0755);
 
570
      i = lstat(dir, &sbuf);
 
571
    }
 
572
    if(i || !S_ISDIR(sbuf.st_mode)) {
 
573
      err = 1;
 
574
      break;
 
575
    }
 
576
  }
 
577
 
 
578
  if(!err) {
 
579
    str_printf(&dir, -1, "/%s", sl->str);
 
580
    f = fopen(dir, mode);
 
581
  }
 
582
 
 
583
  free_mem(dir);
 
584
 
 
585
  return f;
 
586
}
 
587
 
 
588
 
 
589
char *skip_space(char *s)
 
590
{
 
591
  while(isspace(*s)) s++;
 
592
 
 
593
  return s;
 
594
}
 
595
 
 
596
 
 
597
char *skip_non_eq_or_space(char *s)
 
598
{
 
599
  while(*s && *s != '=' && !isspace(*s)) s++;
 
600
 
 
601
  return s;
 
602
}
 
603
 
 
604
 
 
605
char *skip_nonquote(char *s)
 
606
{
 
607
  while(*s && *s != '\'') s++;
 
608
 
 
609
  return s;
 
610
}
 
611
 
 
612
 
 
613
void parse_property(hal_prop_t *prop, char *str)
 
614
{
 
615
  char *s, *s1, *key, *s_val;
 
616
  int l;
 
617
 
 
618
  memset(prop, 0, sizeof *prop);
 
619
  prop->type = p_invalid;
 
620
 
 
621
  s = skip_space(str);
 
622
  s = skip_non_eq_or_space(key = s);
 
623
 
 
624
  *s++ = 0;
 
625
  if(!*key) return;
 
626
 
 
627
  s = skip_space(s);
 
628
  if(*s == '=') s++;
 
629
  s = skip_space(s);
 
630
 
 
631
  prop->key = new_str(key);
 
632
 
 
633
  if(!*s) return;
 
634
 
 
635
  if(*s == '\'') {
 
636
    s_val = s + 1;
 
637
    s = strrchr(s_val, '\'');
 
638
    *(s ?: s_val) = 0;
 
639
    prop->type = p_string;
 
640
    prop->val.str = strdup(s_val);
 
641
  }
 
642
  else if(*s == '{') {
 
643
    s_val = skip_space(s + 1);
 
644
    s1 = strrchr(s_val, '}');
 
645
    if(s1) *s1 = 0;
 
646
    prop->type = p_list;
 
647
    while(*s_val++ == '\'') {
 
648
      s = skip_nonquote(s_val);
 
649
      if(*s) *s++ = 0;
 
650
      add_str_list(&prop->val.list, s_val);
 
651
      s_val = skip_nonquote(s);
 
652
    }
 
653
  }
 
654
  else if(!strncmp(s, "true", 4)) {
 
655
    s += 4;
 
656
    prop->type = p_bool;
 
657
    prop->val.b = 1;
 
658
  }
 
659
  else if(!strncmp(s, "false", 5)) {
 
660
    s += 5;
 
661
    prop->type = p_bool;
 
662
    prop->val.b = 0;
 
663
  }
 
664
  else if(isdigit(*s) || *s == '+' || *s == '-' || *s == '.') {
 
665
    *skip_non_eq_or_space(s) = 0;
 
666
    if(strchr(s, '.')) {
 
667
      prop->type = p_double;
 
668
      prop->val.d = strtod(s, NULL);
 
669
    }
 
670
    else {
 
671
      l = strlen(s);
 
672
      if(l >= 2 && s[l - 2] == 'l' && s[l - 1] == 'l') {
 
673
        prop->type = p_uint64;
 
674
        s[l -= 2] = 0;
 
675
      }
 
676
      else {
 
677
        prop->type = p_int32;
 
678
      }
 
679
      if(l >= 1 && s[l - 1] == 'u') s[--l] = 0;
 
680
 
 
681
      if(prop->type == p_int32) {
 
682
        prop->val.int32 = strtol(s, NULL, 0);
 
683
      }
 
684
      else {
 
685
        prop->val.uint64 = strtoull(s, NULL, 0);
 
686
      }
 
687
    }
 
688
  }
 
689
}
 
690
 
 
691
 
 
692
void hd_scan_hal_assign_udi(hd_data_t *hd_data)
 
693
{
 
694
  hd_t *hd;
 
695
  int i;
 
696
 
 
697
  if(!hd_data->hal) return;
 
698
 
 
699
  PROGRESS(2, 0, "assign udi");
 
700
 
 
701
  for(i = 0; i < 3; i++) {
 
702
    for(hd = hd_data->hd; hd; hd = hd->next) find_udi(hd_data, hd, i);
 
703
  }
 
704
}
 
705
 
 
706
 
 
707
void find_udi(hd_data_t *hd_data, hd_t *hd, int match)
 
708
{
 
709
  hal_device_t *dev;
 
710
  char *h_sysfsid, *h_devname;
 
711
 
 
712
  if(hd->udi) return;
 
713
 
 
714
  dev = NULL;
 
715
 
 
716
  /* device file first, thanks to usb devices */
 
717
 
 
718
  /* based on device file */
 
719
  if(
 
720
    !dev &&
 
721
    (
 
722
      (match == 0 && hd->unix_dev_name) ||
 
723
      (match == 1 && hd->unix_dev_name2) ||
 
724
      (match == 2 && hd->unix_dev_names)
 
725
    )
 
726
  ) for(dev = hd_data->hal; dev; dev = dev->next) {
 
727
    h_devname = hal_get_useful_str(dev->prop, "linux.device_file");
 
728
    if(!h_devname) h_devname = hal_get_useful_str(dev->prop, "block.device");
 
729
    if(h_devname) {
 
730
      if(match == 0 && hd->unix_dev_name && !strcmp(hd->unix_dev_name, h_devname)) break;
 
731
      if(match == 1 && hd->unix_dev_name2 && !strcmp(hd->unix_dev_name2, h_devname)) break;
 
732
      if(match == 2 && search_str_list(hd->unix_dev_names, h_devname)) break;
 
733
    }
 
734
  }
 
735
 
 
736
  /* based on sysfs id, only once for match == 0 */
 
737
  if(!dev && !match && hd->sysfs_id) for(dev = hd_data->hal; dev; dev = dev->next) {
 
738
    h_sysfsid = hd_sysfs_id(hal_get_useful_str(dev->prop, "linux.sysfs_path"));
 
739
    if(h_sysfsid && !strcmp(hd->sysfs_id, h_sysfsid)) break;
 
740
  }
 
741
 
 
742
  if(dev) {
 
743
    hd->udi = new_str(dev->udi);
 
744
    hd->hal_prop = dev->prop;
 
745
    dev->prop = NULL;
 
746
  }
 
747
}
 
748
 
 
749
/** @} */
 
750