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

device.c

Go to the documentation of this file.
00001 
00011 /* $Progeny: device.c 3839 2003-11-17 04:25:01Z dsp $
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.h>
00044 #include <discover-conf.h>
00045 #include <discover-xml.h>
00046 
00047 #include "device.h"
00048 #include "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                     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                     /* The version is no longer relevant for nested data
00147                      * elements.
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, **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 = _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);
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  * Data accessors
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     for (;
00394          data->prev;
00395          data = data->prev)
00396     ;
00397     for (;
00398          data->parent;
00399          data = data->parent)
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  * Device accessors
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  * Local variables:
00641  * c-file-style: "progeny"
00642  * indent-tabs-mode: nil
00643  * End:
00644  */
00645 /* vim: set cin fo=tcroq sw=4 et sts=4 tw=75: */

Generated on Sat Jan 31 14:39:17 2004 for discover by doxygen 1.3.4