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 
00036 
00037 #include "config.h"
00038 
00039 #include <sys/types.h>
00040 
00041 #include <assert.h>
00042 #include <limits.h>
00043 #include <stdio.h>
00044 #include <string.h>
00045 
00046 #include <expat.h>
00047 
00048 #include <discover/discover.h>
00049 #include <discover/discover-xml.h>
00050 
00051 #include <discover/load-url.h>
00052 #include <discover/utils.h>
00053 
00055 struct discover_xml_vendor {
00056     char *id;
00057     char *name;
00058     discover_xml_vendor_t *next;
00059 };
00060 
00061 static discover_xml_vendor_t *vendors[BUS_COUNT];
00062 
00064 struct context {
00065     discover_xml_vendor_t **vlist;
00066 
00067     int unknown_level; 
00068 };
00069 
00070 static char *known_vendor_elements[] = {
00071     "vendor",
00072     "vendor_list",
00073     NULL
00074 };
00075 
00076 
00077 static bool
00078 unknown_vendor_element(const XML_Char * const tag)
00079 {
00080     int i;
00081     for (i = 0; known_vendor_elements[i] != NULL; i++) {
00082         if (strcmp(tag, known_vendor_elements[i]) == 0)
00083             return false;
00084     }
00085     return true;
00086 }
00087 
00088 static void
00089 start_element(void *ctx, const XML_Char *name, const XML_Char *attrs[])
00090 {
00091     struct context *context = ctx;
00092     int i;
00093     char *vid, *vname;
00094     discover_xml_vendor_t *next, **vlist;
00095 
00096     assert(context != NULL);
00097     assert(name != NULL);
00098     assert(attrs != NULL);
00099 
00100     if (unknown_vendor_element(name)) {
00101         context->unknown_level++;
00102         return;
00103     }
00104 
00105     if (context->unknown_level > 0) {
00106         return;
00107     }
00108 
00109     if (strcmp(name, "vendor") == 0) {
00110         vid = vname = NULL;
00111         for (i = 0; attrs[i]; i += 2) {
00112             if (strcmp(attrs[i], "id") == 0) {
00113                 vid = (char *) attrs[i + 1];
00114             } else if (strcmp(attrs[i], "name") == 0) {
00115                 vname = (char *) attrs[i + 1];
00116             }
00117         }
00118 
00119         assert(vid != NULL);
00120         assert(vname != NULL);
00121 
00122         vlist = context->vlist;
00123         next = *vlist;
00124         *vlist = discover_xml_vendor_new();
00125         (*vlist)->id = _discover_xstrdup(vid);
00126         (*vlist)->name = _discover_xstrdup(vname);
00127         (*vlist)->next = next;
00128     }
00129 }
00130 
00131 static void
00132 end_element(void *ctx, const XML_Char *name)
00133 {
00134     struct context *context = ctx;
00135 
00136     assert(context != NULL);
00137     assert(name != NULL);
00138 
00139     if (unknown_vendor_element(name)) {
00140         context->unknown_level--;
00141         return;
00142     }
00143 
00144     if (context->unknown_level > 0) {
00145         return;
00146     }
00147 
00148     
00149 
00150 
00151 
00152 }
00153 
00166 
00167 
00168 
00169 
00170 
00171 
00172 void
00173 discover_xml_merge_vendor_url(discover_xml_vendor_t **vlist,
00174                               char *url, discover_error_t *status)
00175 {
00176     XML_Parser parser;
00177     struct context context;
00178 
00179     assert(url != NULL);
00180     assert(status != NULL);
00181 
00182     status->code = 0;
00183 
00184     context.vlist = vlist;
00185     context.unknown_level = 0;
00186 
00187     parser = XML_ParserCreate(NULL);
00188     XML_SetElementHandler(parser, start_element, end_element);
00189     XML_SetUserData(parser, &context);
00190 
00191     if (!_discover_load_url(url, parser)) {
00192         XML_ParserFree(parser);
00193         status->code = DISCOVER_EIO;
00194         return;
00195     }
00196 
00197     if (!XML_Parse(parser, "", 0, 1)) {
00198         XML_ParserFree(parser);
00199         status->code = DISCOVER_EXML;
00200         return;
00201     }
00202 
00203     XML_ParserFree(parser);
00204 
00205     return;
00206 }
00207 
00214 discover_xml_vendor_t *
00215 discover_xml_get_vendors(discover_bus_t bus, discover_error_t *status)
00216 {
00217     discover_xml_url_t *urls, *i;
00218     char *url;
00219 
00220     assert(status != NULL);
00221 
00222     status->code = 0;
00223 
00224     if (!vendors[bus]) {
00225         urls = discover_xml_get_data_urls(bus, VENDOR_TYPE, status);
00226         if (status->code != 0) {
00227             return NULL;
00228         }
00229 
00230         for (i = urls;
00231              i;
00232              i = discover_xml_url_get_next(i)) {
00233             url = discover_xml_url_get_url(i);
00234             discover_xml_merge_vendor_url(&(vendors[bus]), url, status);
00235             if (status->code != 0) {
00236                 return NULL;
00237             }
00238         }
00239     }
00240 
00241     return vendors[bus];
00242 }
00243 
00247 void
00248 discover_xml_free_vendors(void)
00249 {
00250     int i;
00251     for (i = 0; i < BUS_COUNT; i++) {
00252         discover_xml_vendor_free(vendors[i]);
00253         vendors[i] = NULL;
00254     }
00255 }
00256 
00263 char *
00264 discover_xml_vendor_id2name(discover_xml_vendor_t *vendors, char *id)
00265 {
00266     discover_xml_vendor_t *vendor;
00267     char *name;
00268 
00269     assert(vendors != NULL);
00270     assert(id != NULL);
00271 
00272     name = NULL;
00273 
00274     for (vendor = vendors;
00275          vendor;
00276          vendor = vendor->next) {
00277         if (strcmp(id, vendor->id) == 0) {
00278             name = vendor->name;
00279             break;
00280         }
00281     }
00282 
00283     return name;
00284 }
00285 
00289 char *
00290 discover_xml_vendor_get_id(discover_xml_vendor_t *vendor)
00291 {
00292     assert(vendor != NULL);
00293 
00294     return vendor->id;
00295 }
00296 
00300 char *
00301 discover_xml_vendor_get_name(discover_xml_vendor_t *vendor)
00302 {
00303     assert(vendor != NULL);
00304 
00305     return vendor->name;
00306 }
00307 
00311 discover_xml_vendor_t *
00312 discover_xml_vendor_get_next(discover_xml_vendor_t *vendor)
00313 {
00314     assert(vendor != NULL);
00315 
00316     return vendor->next;
00317 }
00318 
00322 discover_xml_vendor_t *
00323 discover_xml_vendor_new(void)
00324 {
00325     discover_xml_vendor_t *new;
00326 
00327     new = _discover_xmalloc(sizeof(discover_xml_vendor_t));
00328 
00329     new->id = NULL;
00330     new->name = NULL;
00331     new->next = NULL;
00332 
00333     return new;
00334 }
00335 
00341 void
00342 discover_xml_vendor_free(discover_xml_vendor_t *vendors)
00343 {
00344     discover_xml_vendor_t *vendor, *last;
00345 
00346     last = NULL;
00347 
00348     for (vendor = vendors;
00349          vendor;
00350          vendor = vendor->next) {
00351         if (vendor->id) {
00352             free(vendor->id);
00353         }
00354 
00355         if (vendor->name) {
00356             free(vendor->name);
00357         }
00358 
00359         if (last) {
00360             free(last);
00361         }
00362         last = vendor;
00363     }
00364 
00365     if (last) {
00366         free(last);
00367     }
00368 }
00369 
00372 
00373 
00374 
00375 
00376 
00377 
00378