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 last->next = new_device;
00103 last = new_device;
00104 } else {
00105 result = last = new_device;
00106 }
00107 }
00108 }
00109
00110 if (status->code != 0) {
00111 return result;
00112 }
00113 }
00114
00115 if (result) {
00116 status->code = DISCOVER_SUCCESS;
00117 } else {
00118 char *message = _discover_xmalloc(100);
00119 snprintf(message, 100, "Device \"%s\" not found",
00120 discover_class);
00121 status->code = DISCOVER_EDEVICENOTFOUND;
00122 status->create_message(&status, message);
00123 }
00124
00125 return result;
00126 }
00127
00128 static discover_data_t *
00129 scan_data_list(discover_data_t *node, char *discover_class, char **version,
00130 discover_error_t *status)
00131 {
00132 discover_data_t *result = NULL;
00133 int cmp;
00134
00135 for ( ; node != NULL; node = node->next) {
00136 if (strcmp(node->discover_class, discover_class) == 0) {
00137 if (*version && node->version) {
00138 cmp = discover_xml_version_cmp(node->version,
00139 *version, status);
00140
00141 if (status->code != 0) {
00142 return result;
00143 }
00144 if (cmp) {
00145 result = node;
00146
00147
00148
00149 *version = NULL;
00150 break;
00151 }
00152 } else {
00153 result = node;
00154 break;
00155 }
00156 }
00157 }
00158 return result;
00159 }
00160
00161
00162 static discover_data_t *
00163 get_data(discover_device_t *device, char *discover_class, char **version,
00164 discover_error_t *status)
00165 {
00166 assert(device != NULL);
00167 assert(discover_class != NULL);
00168
00169 return scan_data_list(device->data, discover_class, version, status);
00170 }
00171
00172 static discover_data_t *
00173 get_child_data(discover_data_t *data, char *discover_class, char **version,
00174 discover_error_t *status)
00175 {
00176 assert(data != NULL);
00177 assert(discover_class != NULL);
00178
00179 return scan_data_list(data->child, discover_class, version, status);
00180 }
00181
00203 char *
00204 discover_device_get_data(discover_device_t *device, char *discover_class,
00205 char *version, discover_error_t *status)
00206 {
00207 discover_data_t *data;
00208 char *result, *tmp, *tmp_orig, **argv, *block;
00209 size_t argv_len;
00210 int i;
00211
00212 assert(device != NULL);
00213 assert(discover_class != NULL);
00214 assert(status != NULL);
00215
00216 status->code = 0;
00217
00218 data = NULL;
00219 result = NULL;
00220 tmp_orig = tmp = _discover_xstrdup(discover_class);
00221 argv = NULL;
00222 argv_len = 0;
00223
00224 while ((block = strsep(&tmp, "/"))) {
00225 argv_len++;
00226 argv = _discover_xrealloc(argv, sizeof(char *) * argv_len);
00227 argv[argv_len - 1] = block;
00228 }
00229
00230
00231 while(!data && device) {
00232 data = get_data(device, argv[0], &version, status);
00233
00234 if (data) {
00235 for (i = 1; i < argv_len; i++) {
00236 data = get_child_data(data, argv[i], &version, status);
00237 if (status->code != 0) {
00238 goto out;
00239 }
00240 if (!data) {
00241 break;
00242 }
00243 }
00244 }
00245
00246 device = device->extra;
00247 }
00248
00249 if (data) {
00250 result = data->text;
00251 }
00252
00253 out:
00254
00255 free(tmp_orig);
00256 free(argv);
00257
00258 return result;
00259 }
00260
00267 void
00268 discover_device_copy(discover_device_t *src, discover_device_t *dst)
00269 {
00270 assert(src != NULL);
00271 assert(dst != NULL);
00272
00273 if (src->busclass) {
00274 dst->busclass = _discover_xstrdup(src->busclass);
00275 }
00276
00277 if (src->model_id) {
00278 dst->model_id = _discover_xstrdup(src->model_id);
00279 }
00280
00281 if (src->model_name) {
00282 dst->model_name = _discover_xstrdup(src->model_name);
00283 }
00284
00285 if (src->vendor_id) {
00286 dst->vendor_id = _discover_xstrdup(src->vendor_id);
00287 }
00288
00289 if (src->vendor_name) {
00290 dst->vendor_name = _discover_xstrdup(src->vendor_name);
00291 }
00292
00293 dst->busclasses = src->busclasses;
00294 dst->vendors = src->vendors;
00295 dst->data = src->data;
00296 dst->extra = src->extra;
00297 dst->next = src->next;
00298 }
00299
00300
00301
00302
00303
00307 char *
00308 discover_data_get_class(discover_data_t *data)
00309 {
00310 assert(data != NULL);
00311
00312 return data->discover_class;
00313 }
00314
00318 char *
00319 discover_data_get_text(discover_data_t *data)
00320 {
00321 assert(data != NULL);
00322
00323 return data->text;
00324 }
00325
00329 discover_data_t *
00330 discover_data_get_parent(discover_data_t *data)
00331 {
00332 assert(data != NULL);
00333
00334 return data->parent;
00335 }
00336
00340 discover_data_t *
00341 discover_data_get_child(discover_data_t *data)
00342 {
00343 assert(data != NULL);
00344
00345 return data->child;
00346 }
00347
00351 discover_data_t *
00352 discover_data_get_next(discover_data_t *data)
00353 {
00354 assert(data != NULL);
00355
00356 return data->next;
00357 }
00358
00362 discover_data_t *
00363 discover_data_get_prev(discover_data_t *data)
00364 {
00365 assert(data != NULL);
00366
00367 return data->prev;
00368 }
00369
00373 discover_data_t *
00374 discover_data_get_first(discover_data_t *data)
00375 {
00376 int i = 1;
00377
00378 if (data == NULL) {
00379 return NULL;
00380 }
00381
00382 while(i) {
00383 if(data->prev) {
00384 data = data->prev;
00385 } else if(data->parent) {
00386 data = data->parent;
00387 } else {
00388 i = 0;
00389 }
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 return data;
00403 }
00404
00408 discover_data_t *
00409 discover_data_new(void)
00410 {
00411 discover_data_t *new;
00412
00413 new = _discover_xmalloc(sizeof(discover_data_t));
00414
00415 new->discover_class = NULL;
00416 new->version = NULL;
00417 new->text = NULL;
00418 new->parent = NULL;
00419 new->child = NULL;
00420 new->next = NULL;
00421 new->prev = NULL;
00422
00423 return new;
00424 }
00425
00435 void
00436 discover_data_free(discover_data_t *data_tree)
00437 {
00438 discover_data_t *data, *last;
00439
00440 last = NULL;
00441
00442 if (data_tree) {
00443 for (data = data_tree->next;
00444 data;
00445 data = data->next) {
00446 discover_data_free(data);
00447
00448 if (last) {
00449 free(last);
00450 }
00451 last = data;
00452 }
00453
00454 if (last) {
00455 free(last);
00456 }
00457
00458 if (data_tree->child) {
00459 discover_data_free(data_tree->child);
00460 free(data_tree->child);
00461 }
00462
00463 if (data_tree->discover_class) {
00464 free(data_tree->discover_class);
00465 }
00466
00467 if (data_tree->version) {
00468 free(data_tree->version);
00469 }
00470
00471 if (data_tree->text) {
00472 free(data_tree->text);
00473 }
00474 }
00475 }
00476
00477
00478
00479
00480
00484 char *
00485 discover_device_get_busclass(discover_device_t *device)
00486 {
00487 assert(device != NULL);
00488
00489 return device->busclass;
00490 }
00491
00495 char *
00496 discover_device_get_model_id(discover_device_t *device)
00497 {
00498 assert(device != NULL);
00499
00500 return device->model_id;
00501 }
00502
00506 char *
00507 discover_device_get_model_name(discover_device_t *device)
00508 {
00509 assert(device != NULL);
00510
00511 return device->model_name;
00512 }
00513
00517 char *
00518 discover_device_get_vendor_id(discover_device_t *device)
00519 {
00520 assert(device != NULL);
00521
00522 return device->vendor_id;
00523 }
00524
00528 char *
00529 discover_device_get_vendor_name(discover_device_t *device)
00530 {
00531 assert(device != NULL);
00532
00533 return device->vendor_name;
00534 }
00535
00539 discover_data_t *
00540 discover_device_get_data_struct(discover_device_t *device)
00541 {
00542 assert(device != NULL);
00543
00544 return device->data;
00545 }
00546
00550 discover_device_t *
00551 discover_device_get_next(discover_device_t *device)
00552 {
00553 assert(device != NULL);
00554
00555 return device->next;
00556 }
00557
00561 discover_device_t *
00562 discover_device_new(void)
00563 {
00564 discover_device_t *new;
00565
00566 new = _discover_xmalloc(sizeof(discover_device_t));
00567
00568 new->busclass = NULL;
00569 new->model_id = NULL;
00570 new->model_name = NULL;
00571 new->vendor_id = NULL;
00572 new->vendor_name = NULL;
00573 new->busclasses = NULL;
00574 new->vendors = NULL;
00575 new->data = NULL;
00576 new->next = NULL;
00577 new->extra = NULL;
00578
00579 return new;
00580 }
00581
00591 void
00592 discover_device_free(discover_device_t *devices, int free_data)
00593 {
00594 discover_device_t *device, *last;
00595
00596 last = NULL;
00597
00598 for (device = devices;
00599 device;
00600 device = device->next) {
00601 if (device->busclass) {
00602 free(device->busclass);
00603 }
00604
00605 if (device->model_id) {
00606 free(device->model_id);
00607 }
00608
00609 if (device->model_name) {
00610 free(device->model_name);
00611 }
00612
00613 if (device->vendor_id) {
00614 free(device->vendor_id);
00615 }
00616
00617 if (device->vendor_name) {
00618 free(device->vendor_name);
00619 }
00620
00621 if (free_data && device->data) {
00622 discover_data_free(device->data);
00623 free(device->data);
00624 }
00625
00626 if (last) {
00627 free(last);
00628 }
00629 last = device;
00630 }
00631
00632 if (last) {
00633 free(last);
00634 }
00635 }
00636
00639
00640
00641
00642
00643
00644
00645