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

url-xml.c

Go to the documentation of this file.
00001 
00010 /* $Progeny: url-xml.c 3839 2003-11-17 04:25:01Z dsp $
00011  *
00012  * AUTHOR: John R. Daily <jdaily@progeny.com>
00013  *
00014  * Copyright 2002 Progeny Linux Systems, Inc.
00015  * Copyright 2002 Hewlett-Packard Company
00016  *
00017  * Permission is hereby granted, free of charge, to any person obtaining a
00018  * copy of this software and associated documentation files (the "Software"),
00019  * to deal in the Software without restriction, including without limitation
00020  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00021  * and/or sell copies of the Software, and to permit persons to whom the
00022  * Software is furnished to do so, subject to the following conditions:
00023  *
00024  * The above copyright notice and this permission notice shall be included in
00025  * all copies or substantial portions of the Software.
00026  *
00027  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00028  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00029  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00030  * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00031  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00032  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00033  * DEALINGS IN THE SOFTWARE.
00034  */
00035 
00036 #include <config.h>
00037 
00038 #include <assert.h>
00039 #include <string.h>
00040 
00041 #include <expat.h>
00042 
00043 #include <discover.h>
00044 #include <discover-conf.h>
00045 #include <discover-xml.h>
00046 
00047 #include "load-url.h"
00048 #include "url-xml.h"
00049 #include "utils.h"
00050 
00052 enum state { START, DISCOVER_DATA };
00053 struct context {
00054     enum state state;
00055 
00056     discover_xml_url_t *urls;
00057     int unknown_level; /* How deep are we into unknown XML tags? */
00058 };
00059 
00060 static discover_xml_url_t *xml_urls = NULL;
00061 static discover_xml_url_t *data_urls[BUS_COUNT][3];
00062 
00063 static char *known_url_elements[] = {
00064     "location",
00065     "discover-data",
00066     NULL
00067 };
00068 
00069 
00070 static bool
00071 unknown_url_element(const XML_Char * const tag)
00072 {
00073     int i;
00074     for (i = 0; known_url_elements[i] != NULL; i++) {
00075         if (strcmp(tag, known_url_elements[i]) == 0)
00076             return false;
00077     }
00078     return true;
00079 }
00080 
00081 static void
00082 add_location(struct context *context, const XML_Char *attrs[])
00083 {
00084     discover_xml_url_t *new;
00085     int i;
00086 
00087     assert(context != NULL);
00088     assert(attrs != NULL);
00089 
00090     new = discover_xml_url_new();
00091 
00092     for (i = 0; attrs[i]; i += 2) {
00093         if (strcmp(attrs[i], "url") == 0) {
00094             new->url = _discover_xstrdup(attrs[i + 1]);
00095         } else if (strcmp(attrs[i], "bus") == 0) {
00096             new->bus = _discover_xstrdup(attrs[i + 1]);
00097         } else if (strcmp(attrs[i], "type") == 0) {
00098             new->type = _discover_xstrdup(attrs[i + 1]);
00099         }
00100     }
00101 
00102     if (context->urls) {
00103         if (context->urls->last) {
00104             context->urls->last->next = new;
00105         } else {
00106             context->urls->next = new;
00107         }
00108         context->urls->last = new;
00109     } else {
00110         context->urls = new;
00111         context->urls->next = context->urls->last = NULL;
00112     }
00113 }
00114 
00115 static void
00116 start_element(void *ctx, const XML_Char *name, const XML_Char *attrs[])
00117 {
00118     struct context *context = ctx;
00119 
00120     assert(context != NULL);
00121     assert(name != NULL);
00122 
00123     if (unknown_url_element(name)) {
00124         context->unknown_level++;
00125         return;
00126     }
00127 
00128     if (context->unknown_level > 0) {
00129         return;
00130     }
00131 
00132     switch (context->state) {
00133     case START:
00134         if (strcmp(name, "discover-data") == 0) {
00135             context->state = DISCOVER_DATA;
00136         }
00137         break;
00138 
00139     case DISCOVER_DATA:
00140         if (strcmp(name, "location") == 0) {
00141             add_location(context, attrs);
00142         }
00143         break;
00144     }
00145 }
00146 
00147 static void
00148 end_element(void *ctx, const XML_Char *name)
00149 {
00150     struct context *context = ctx;
00151 
00152     assert(context != NULL);
00153     assert(name != NULL);
00154 
00155     if (unknown_url_element(name)) {
00156         context->unknown_level--;
00157         return;
00158     }
00159 
00160     if (context->unknown_level > 0) {
00161         return;
00162     }
00163 
00164     /*
00165      * We don't have any end tags to worry about, but if we did, they
00166      * would be handled here.
00167      */
00168 }
00169 
00181 discover_xml_url_t *
00182 discover_xml_get_urls(discover_error_t *status)
00183 {
00184     discover_xml_url_t *urls, *i;
00185     XML_Parser parser;
00186     struct context context;
00187     int loaded_urls = 0;
00188 
00189     assert(status != NULL);
00190 
00191     status->code = 0;
00192 
00193     if (!xml_urls) {
00194         context.state = START;
00195         context.urls = NULL;
00196         context.unknown_level = 0;
00197 
00198         urls = discover_conf_get_urls(status);
00199         if (status->code != 0) {
00200             return NULL;
00201         }
00202 
00203         for (i = urls;
00204              i;
00205              i = i->next) {
00206             parser = XML_ParserCreate(NULL);
00207             XML_SetElementHandler(parser, start_element, end_element);
00208             XML_SetUserData(parser, &context);
00209 
00210             if (_discover_load_url(i->url, parser)) {
00211                 loaded_urls++;
00212             }
00213 
00214         }
00215 
00216         if (loaded_urls == 0) {
00217             discover_xml_url_free(context.urls);
00218             XML_ParserFree(parser);
00219             status->code = DISCOVER_EIO;
00220             return NULL;
00221         }
00222 
00223         if (!XML_Parse(parser, "", 0, 1)) {
00224             status->code = DISCOVER_EXML;
00225         }
00226 
00227         XML_ParserFree(parser);
00228         xml_urls = context.urls;
00229 
00230         /* This must be done here because there could be bogus status left
00231          * over from the XML_Parse check above.  (We assume something good
00232          * happened by this point.)
00233          */
00234         status->code = 0;
00235     }
00236 
00237     return xml_urls;
00238 }
00239 
00243 void
00244 discover_xml_free_urls(void)
00245 {
00246     if (xml_urls) {
00247         discover_xml_url_free(xml_urls);
00248         xml_urls = NULL;
00249     }
00250 }
00251 
00260 discover_xml_url_t *
00261 discover_xml_get_data_urls(discover_bus_t bus, discover_filetype_t filetype,
00262                            discover_error_t *status)
00263 {
00264     discover_xml_url_t *urls, *i, *new;
00265     char *busname = discover_conf_get_bus_name(bus);
00266     char *filetypename = discover_conf_get_filetype_name(filetype);
00267 
00268     assert(status != NULL);
00269     assert(busname != NULL);
00270 
00271     status->code = 0;
00272 
00273     if (!data_urls[bus][filetype]) {
00274         urls = discover_xml_get_urls(status);
00275         if (status->code != 0) {
00276             return NULL;
00277         }
00278 
00279         status->code = DISCOVER_EDATANOTFOUND;
00280         for (i = urls;
00281              i;
00282              i = i->next) {
00283             if (strcmp(i->bus, busname) == 0
00284                 && strcmp(i->type, filetypename) == 0) {
00285 
00286                 status->code = 0;
00287 
00288                 new = discover_xml_url_new();
00289                 discover_xml_url_copy(i, new);
00290 
00291                 if (data_urls[bus][filetype]) {
00292                     data_urls[bus][filetype]->last->next = new;
00293                     data_urls[bus][filetype]->last = new;
00294                 } else {
00295                     data_urls[bus][filetype] = new;
00296                     data_urls[bus][filetype]->last = new;
00297                     data_urls[bus][filetype]->next = NULL;
00298                 }
00299             }
00300         }
00301     }
00302 
00303     return data_urls[bus][filetype];
00304 }
00305 
00309 void
00310 discover_xml_free_data_urls(void)
00311 {
00312     int b, f;
00313 
00314     for(b = 0; b < BUS_COUNT; b++) {
00315         for(f = 0; f < 3; f++) {
00316             discover_xml_url_free(data_urls[b][f]);
00317             data_urls[b][f] = NULL;
00318         }
00319     }
00320 }
00321 
00325 discover_xml_url_t *
00326 discover_xml_url_new(void)
00327 {
00328     discover_xml_url_t *new;
00329 
00330     new = _discover_xmalloc(sizeof(discover_xml_url_t));
00331 
00332     new->url = NULL;
00333     new->bus = NULL;
00334     new->type = NULL;
00335     new->label = NULL;
00336     new->next = NULL;
00337     new->last = NULL;
00338 
00339     return new;
00340 }
00341 
00348 void
00349 discover_xml_url_copy(discover_xml_url_t *src,
00350                       discover_xml_url_t *dst)
00351 {
00352     assert(src != NULL);
00353     assert(dst != NULL);
00354 
00355     if (src->url) {
00356         dst->url = _discover_xstrdup(src->url);
00357     }
00358 
00359     if (src->bus) {
00360         dst->bus = _discover_xstrdup(src->bus);
00361     }
00362 
00363     if (src->type) {
00364         dst->type = _discover_xstrdup(src->type);
00365     }
00366 
00367     if (src->label) {
00368         dst->label = _discover_xstrdup(src->label);
00369     }
00370 }
00371 
00375 char *
00376 discover_xml_url_get_url(discover_xml_url_t *url)
00377 {
00378     assert(url != NULL);
00379 
00380     return url->url;
00381 }
00382 
00386 char *
00387 discover_xml_url_get_label(discover_xml_url_t *url)
00388 {
00389     assert(url != NULL);
00390 
00391     return url->label;
00392 }
00393 
00397 char *
00398 discover_xml_url_get_bus(discover_xml_url_t *url)
00399 {
00400     assert(url != NULL);
00401 
00402     return url->bus;
00403 }
00404 
00408 char *
00409 discover_xml_url_get_type(discover_xml_url_t *url)
00410 {
00411     assert(url != NULL);
00412 
00413     return url->type;
00414 }
00415 
00419 discover_xml_url_t *
00420 discover_xml_url_get_next(discover_xml_url_t *url)
00421 {
00422     assert(url != NULL);
00423 
00424     return url->next;
00425 }
00426 
00430 discover_xml_url_t *
00431 discover_xml_url_get_last(discover_xml_url_t *url)
00432 {
00433     assert(url != NULL);
00434 
00435     return url->last;
00436 }
00437 
00443 void
00444 discover_xml_url_free(discover_xml_url_t *urls)
00445 {
00446     discover_xml_url_t *url, *last;
00447 
00448     last = NULL;
00449 
00450     for (url = urls;
00451          url;
00452          url = url->next) {
00453         if (url->url) {
00454             free(url->url);
00455         }
00456 
00457         if (url->bus) {
00458             free(url->bus);
00459         }
00460 
00461         if (url->type) {
00462             free(url->type);
00463         }
00464 
00465         if (url->label) {
00466             free(url->label);
00467         }
00468 
00469         if (last) {
00470             free(last);
00471         }
00472         last = url;
00473     }
00474 
00475     if (last) {
00476         free(last);
00477     }
00478 }
00479 

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