00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "config.h"
00036
00037 #include <sys/types.h>
00038
00039 #include <assert.h>
00040 #include <stdbool.h>
00041 #include <string.h>
00042
00043 #include <discover/discover.h>
00044 #include <discover/discover-conf.h>
00045 #include <discover/discover-xml.h>
00046
00047 #include <discover/device.h>
00048 #include <discover/utils.h>
00049
00062 discover_device_t *
00063 discover_device_find(char *discover_class, discover_error_t *status)
00064 {
00065 discover_device_t *result, *device, *last, *new_device;
00066 discover_xml_busclass_t *busclasses;
00067 discover_bus_map_t *busmap;
00068 int i;
00069
00070 assert(discover_class);
00071
00072 result = last = NULL;
00073
00074 busmap = discover_conf_get_full_bus_map(status);
00075 if (status->code != 0) {
00076 return NULL;
00077 }
00078
00079 for (i = 0; busmap[i].name; i++) {
00080 if (!busmap[i].scan_default) {
00081 continue;
00082 }
00083
00084 busclasses = discover_xml_get_busclasses(i, status);
00085 if (status->code != 0) {
00086 return result;
00087 }
00088 for (device = discover_get_devices(i, status);
00089 device;
00090 device = discover_device_get_next(device)) {
00091 if (!device->busclass) {
00092
00093 continue;
00094 }
00095 if (discover_xml_busclass_cmp(device->busclass, discover_class,
00096 busclasses) == 0) {
00097 new_device = discover_device_new();
00098 discover_device_copy(device, new_device);
00099 new_device->next = NULL;
00100
00101 if (last) {
00102 for (; last->next; last = last->next)
00103 ;
00104 last->next = new_device;
00105 last = new_device;
00106 } else {
00107 result = last = new_device;
00108 }
00109 }
00110 else {
00111 }
00112 }
00113
00114 if (status->code != 0) {
00115 return result;
00116 }
00117 }
00118
00119 if (result) {
00120 status->code = DISCOVER_SUCCESS;
00121 } else {
00122 char *message = _discover_xmalloc(100);
00123 snprintf(message, 100, "Device \"%s\" not found",
00124 discover_class);
00125 status->code = DISCOVER_EDEVICENOTFOUND;
00126 status->create_message(&status, message);
00127 }
00128
00129 return result;
00130 }
00131
00132 static discover_data_t *
00133 scan_data_list(discover_data_t *node, char *discover_class, char **version,
00134 discover_error_t *status)
00135 {
00136 discover_data_t *result = NULL;
00137 int cmp;
00138
00139 for ( ; node != NULL; node = node->next) {
00140 if (strcmp(node->discover_class, discover_class) == 0) {
00141 if (*version && node->version) {
00142 cmp = discover_xml_version_cmp(node->version,
00143 *version, status);
00144
00145 if (status->code != 0) {
00146 return result;
00147 }
00148 if (cmp) {
00149 result = node;
00150
00151
00152
00153 *version = NULL;
00154 break;
00155 }
00156 } else {
00157 result = node;
00158 break;
00159 }
00160 }
00161 }
00162 return result;
00163 }
00164
00165
00166 static discover_data_t *
00167 get_data(discover_device_t *device, char *discover_class, char **version,
00168 discover_error_t *status)
00169 {
00170 assert(device != NULL);
00171 assert(discover_class != NULL);
00172
00173 return scan_data_list(device->data, discover_class, version, status);
00174 }
00175
00176 static discover_data_t *
00177 get_child_data(discover_data_t *data, char *discover_class, char **version,
00178 discover_error_t *status)
00179 {
00180 assert(data != NULL);
00181 assert(discover_class != NULL);
00182
00183 return scan_data_list(data->child, discover_class, version, status);
00184 }
00185
00207 char *
00208 discover_device_get_data(discover_device_t *device, char *discover_class,
00209 char *version, discover_error_t *status)
00210 {
00211 discover_data_t *data;
00212 char *result, *tmp, *tmp_orig, **argv, *block;
00213 size_t argv_len;
00214 int i;
00215
00216 assert(device != NULL);
00217 assert(discover_class != NULL);
00218 assert(status != NULL);
00219
00220 status->code = 0;
00221
00222 data = NULL;
00223 result = NULL;
00224 tmp_orig = tmp = _discover_xstrdup(discover_class);
00225 argv = NULL;
00226 argv_len = 0;
00227
00228 while ((block = strsep(&tmp, "/"))) {
00229 argv_len++;
00230 argv = _discover_xrealloc(argv, sizeof(char *) * argv_len);
00231 argv[argv_len - 1] = block;
00232 }
00233
00234
00235 while(!data && device) {
00236 data = get_data(device, argv[0], &version, status);
00237
00238 if (data) {
00239 for (i = 1; i < argv_len; i++) {
00240 data = get_child_data(data, argv[i], &version, status);
00241 if (status->code != 0) {
00242 goto out;
00243 }
00244 if (!data) {
00245 break;
00246 }
00247 }
00248 }
00249
00250 device = device->extra;
00251 }
00252
00253 if (data) {
00254 result = data->text;
00255 }
00256
00257 out:
00258
00259 free(tmp_orig);
00260 free(argv);
00261
00262 return result;
00263 }
00264
00271 void
00272 discover_device_copy(discover_device_t *src, discover_device_t *dst)
00273 {
00274 assert(src != NULL);
00275 assert(dst != NULL);
00276
00277 if (src->busclass) {
00278 dst->busclass = _discover_xstrdup(src->busclass);
00279 }
00280
00281 if (src->model_id) {
00282 dst->model_id = _discover_xstrdup(src->model_id);
00283 }
00284
00285 if (src->model_name) {
00286 dst->model_name = _discover_xstrdup(src->model_name);
00287 }
00288
00289 if (src->vendor_id) {
00290 dst->vendor_id = _discover_xstrdup(src->vendor_id);
00291 }
00292
00293 if (src->vendor_name) {
00294 dst->vendor_name = _discover_xstrdup(src->vendor_name);
00295 }
00296
00297 dst->busclasses = src->busclasses;
00298 dst->vendors = src->vendors;
00299 dst->data = src->data;
00300 dst->extra = src->extra;
00301 dst->next = src->next;
00302 }
00303
00304
00305
00306
00307
00311 char *
00312 discover_data_get_class(discover_data_t *data)
00313 {
00314 assert(data != NULL);
00315
00316 return data->discover_class;
00317 }
00318
00322 char *
00323 discover_data_get_text(discover_data_t *data)
00324 {
00325 assert(data != NULL);
00326
00327 return data->text;
00328 }
00329
00333 discover_data_t *
00334 discover_data_get_parent(discover_data_t *data)
00335 {
00336 assert(data != NULL);
00337
00338 return data->parent;
00339 }
00340
00344 discover_data_t *
00345 discover_data_get_child(discover_data_t *data)
00346 {
00347 assert(data != NULL);
00348
00349 return data->child;
00350 }
00351
00355 discover_data_t *
00356 discover_data_get_next(discover_data_t *data)
00357 {
00358 assert(data != NULL);
00359
00360 return data->next;
00361 }
00362
00366 discover_data_t *
00367 discover_data_get_prev(discover_data_t *data)
00368 {
00369 assert(data != NULL);
00370
00371 return data->prev;
00372 }
00373
00377 discover_data_t *
00378 discover_data_get_first(discover_data_t *data)
00379 {
00380 int i = 1;
00381
00382 if (data == NULL) {
00383 return NULL;
00384 }
00385
00386 while(i) {
00387 if(data->prev) {
00388 data = data->prev;
00389 } else if(data->parent) {
00390 data = data->parent;
00391 } else {
00392 i = 0;
00393 }
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 return data;
00407 }
00408
00412 discover_data_t *
00413 discover_data_new(void)
00414 {
00415 discover_data_t *new;
00416
00417 new = _discover_xmalloc(sizeof(discover_data_t));
00418
00419 new->discover_class = NULL;
00420 new->version = NULL;
00421 new->text = NULL;
00422 new->parent = NULL;
00423 new->child = NULL;
00424 new->next = NULL;
00425 new->prev = NULL;
00426
00427 return new;
00428 }
00429
00439 void
00440 discover_data_free(discover_data_t *data_tree)
00441 {
00442 discover_data_t *data, *last;
00443
00444 last = NULL;
00445
00446 if (data_tree) {
00447 for (data = data_tree->next;
00448 data;
00449 data = data->next) {
00450 discover_data_free(data);
00451
00452 if (last) {
00453 free(last);
00454 }
00455 last = data;
00456 }
00457
00458 if (last) {
00459 free(last);
00460 }
00461
00462 if (data_tree->child) {
00463 discover_data_free(data_tree->child);
00464 free(data_tree->child);
00465 }
00466
00467 if (data_tree->discover_class) {
00468 free(data_tree->discover_class);
00469 }
00470
00471 if (data_tree->version) {
00472 free(data_tree->version);
00473 }
00474
00475 if (data_tree->text) {
00476 free(data_tree->text);
00477 }
00478 }
00479 }
00480
00481
00482
00483
00484
00488 char *
00489 discover_device_get_busclass(discover_device_t *device)
00490 {
00491 assert(device != NULL);
00492
00493 return device->busclass;
00494 }
00495
00499 char *
00500 discover_device_get_model_id(discover_device_t *device)
00501 {
00502 assert(device != NULL);
00503
00504 return device->model_id;
00505 }
00506
00510 char *
00511 discover_device_get_model_name(discover_device_t *device)
00512 {
00513 assert(device != NULL);
00514
00515 return device->model_name;
00516 }
00517
00521 char *
00522 discover_device_get_vendor_id(discover_device_t *device)
00523 {
00524 assert(device != NULL);
00525
00526 return device->vendor_id;
00527 }
00528
00532 char *
00533 discover_device_get_vendor_name(discover_device_t *device)
00534 {
00535 assert(device != NULL);
00536
00537 return device->vendor_name;
00538 }
00539
00543 discover_data_t *
00544 discover_device_get_data_struct(discover_device_t *device)
00545 {
00546 assert(device != NULL);
00547
00548 return device->data;
00549 }
00550
00554 discover_device_t *
00555 discover_device_get_next(discover_device_t *device)
00556 {
00557 assert(device != NULL);
00558
00559 return device->next;
00560 }
00561
00565 discover_device_t *
00566 discover_device_new(void)
00567 {
00568 discover_device_t *new;
00569
00570 new = _discover_xmalloc(sizeof(discover_device_t));
00571
00572 new->busclass = NULL;
00573 new->model_id = NULL;
00574 new->model_name = NULL;
00575 new->vendor_id = NULL;
00576 new->vendor_name = NULL;
00577 new->busclasses = NULL;
00578 new->vendors = NULL;
00579 new->data = NULL;
00580 new->next = NULL;
00581 new->extra = NULL;
00582
00583 return new;
00584 }
00585
00595 void
00596 discover_device_free(discover_device_t *devices, int free_data)
00597 {
00598 discover_device_t *device, *last;
00599
00600 last = NULL;
00601
00602 for (device = devices;
00603 device;
00604 device = device->next) {
00605 if (device->busclass) {
00606 free(device->busclass);
00607 }
00608
00609 if (device->model_id) {
00610 free(device->model_id);
00611 }
00612
00613 if (device->model_name) {
00614 free(device->model_name);
00615 }
00616
00617 if (device->vendor_id) {
00618 free(device->vendor_id);
00619 }
00620
00621 if (device->vendor_name) {
00622 free(device->vendor_name);
00623 }
00624
00625 if (free_data && device->data) {
00626 discover_data_free(device->data);
00627 free(device->data);
00628 }
00629
00630 if (last) {
00631 free(last);
00632 }
00633 last = device;
00634 }
00635
00636 if (last) {
00637 free(last);
00638 }
00639 }
00640
00643
00644
00645
00646
00647
00648
00649