Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

device.c

Go to the documentation of this file.
00001 
00011 /* $Progeny$
00012  *
00013  * Copyright 2001, 2002 Progeny Linux Systems, Inc.
00014  * Copyright 2002 Hewlett-Packard Company
00015  *
00016  * Permission is hereby granted, free of charge, to any person obtaining a
00017  * copy of this software and associated documentation files (the "Software"),
00018  * to deal in the Software without restriction, including without limitation
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00020  * and/or sell copies of the Software, and to permit persons to whom the
00021  * Software is furnished to do so, subject to the following conditions:
00022  *
00023  * The above copyright notice and this permission notice shall be included in
00024  * all copies or substantial portions of the Software.
00025  *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00029  * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00030  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00031  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00032  * DEALINGS IN THE SOFTWARE.
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                 /* This is a device about which we know nothing. */
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                     /* The version is no longer relevant for nested data
00151                      * elements.
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  * Data accessors
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     for (;
00398          data->prev;
00399          data = data->prev)
00400     ;
00401     for (;
00402          data->parent;
00403          data = data->parent)
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  * Device accessors
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  * Local variables:
00645  * c-file-style: "progeny"
00646  * indent-tabs-mode: nil
00647  * End:
00648  */
00649 /* vim: set cin fo=tcroq sw=4 et sts=4 tw=75: */

Generated on Fri Aug 11 16:43:43 2006 for discover by  doxygen 1.4.2