2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
11 #include <sys/types.h>
21 #include "repo_updateinfoxml.h"
28 <location href="repodata/primary.xml.gz"/>
29 <checksum type="sha">e9162516fa25fec8d60caaf4682d2e49967786cc</checksum>
30 <timestamp>1215708444</timestamp>
31 <open-checksum type="sha">c796c48184cd5abc260e4ba929bdf01be14778a7</open-checksum>
33 <data type="filelists">
34 <location href="repodata/filelists.xml.gz"/>
35 <checksum type="sha">1c638295c49e9707c22810004ebb0799791fcf45</checksum>
36 <timestamp>1215708445</timestamp>
37 <open-checksum type="sha">54a40d5db3df0813b8acbe58cea616987eb9dc16</open-checksum>
40 <location href="repodata/other.xml.gz"/>
41 <checksum type="sha">a81ef39eaa70e56048f8351055119d8c82af2491</checksum>
42 <timestamp>1215708447</timestamp>
43 <open-checksum type="sha">4d1ee867c8864025575a2fb8fde3b85371d51978</open-checksum>
45 <data type="deltainfo">
46 <location href="repodata/deltainfo.xml.gz"/>
47 <checksum type="sha">5880cfa5187026a24a552d3c0650904a44908c28</checksum>
48 <timestamp>1215708447</timestamp>
49 <open-checksum type="sha">7c964a2c3b17df5bfdd962c3be952c9ca6978d8b</open-checksum>
51 <data type="updateinfo">
52 <location href="repodata/updateinfo.xml.gz"/>
53 <checksum type="sha">4097f7e25c7bb0770ae31b2471a9c8c077ee904b</checksum>
54 <timestamp>1215708447</timestamp>
55 <open-checksum type="sha">24f8252f3dd041e37e7c3feb2d57e02b4422d316</open-checksum>
57 <data type="diskusage">
58 <location href="repodata/diskusage.xml.gz"/>
59 <checksum type="sha">4097f7e25c7bb0770ae31b2471a9c8c077ee904b</checksum>
60 <timestamp>1215708447</timestamp>
61 <open-checksum type="sha">24f8252f3dd041e37e7c3feb2d57e02b4422d316</open-checksum>
65 support also extension suseinfo format
67 <expire>timestamp</expire>
87 /* normal repomd.xml */
104 /* !! must be sorted by first column !! */
105 static struct stateswitch stateswitches[] = {
107 { STATE_START, "repomd", STATE_REPOMD, 0 },
108 { STATE_START, "suseinfo", STATE_SUSEINFO, 0 },
109 { STATE_SUSEINFO, "expire", STATE_EXPIRE, 1 },
110 { STATE_SUSEINFO, "products", STATE_PRODUCTS, 0 },
111 { STATE_SUSEINFO, "keywords", STATE_KEYWORDS, 0 },
112 { STATE_PRODUCTS, "id", STATE_PRODUCT, 1 },
113 { STATE_KEYWORDS, "k", STATE_KEYWORD, 1 },
115 { STATE_REPOMD, "data", STATE_DATA, 0 },
116 { STATE_DATA, "location", STATE_LOCATION, 0 },
117 { STATE_DATA, "checksum", STATE_CHECKSUM, 1 },
118 { STATE_DATA, "timestamp", STATE_TIMESTAMP, 1 },
119 { STATE_DATA, "open-checksum", STATE_OPENCHECKSUM, 1 },
124 * split l into m parts, store to sp[]
125 * split at whitespace
129 split_comma(char *l, char **sp, int m)
141 while (*l && !(*l == ','))
163 struct stateswitch *swtab[NUMSTATES];
164 enum state sbtab[NUMSTATES];
172 static inline const char *
173 find_attr(const char *txt, const char **atts)
175 for (; *atts; atts += 2)
177 if (!strcmp(*atts, txt))
185 startElement(void *userData, const char *name, const char **atts)
187 struct parsedata *pd = userData;
188 /*Pool *pool = pd->pool;*/
189 struct stateswitch *sw;
192 fprintf(stderr, "start: [%d]%s\n", pd->state, name);
194 if (pd->depth != pd->statedepth)
201 if (!pd->swtab[pd->state])
203 for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) /* find name in statetable */
204 if (!strcmp(sw->ename, name))
207 if (sw->from != pd->state)
210 fprintf(stderr, "into unknown: %s (from: %d)\n", name, pd->state);
216 pd->docontent = sw->docontent;
217 pd->statedepth = pd->depth;
223 case STATE_START: break;
230 /* this should be OBSOLETE soon */
231 updstr = find_attr("updates", atts);
232 if ( updstr != NULL )
234 value = strdup(updstr);
235 fvalue = value; /* save the first */
241 int words = split_comma(value, sp, 2);
245 repo_add_poolstr_array(pd->repo, -1, REPOSITORY_UPDATES, sp[0]);
255 case STATE_SUSEINFO: break;
256 case STATE_EXPIRE: break;
257 case STATE_PRODUCTS: break;
258 case STATE_PRODUCT: break;
259 case STATE_KEYWORDS: break;
260 case STATE_KEYWORD: break;
261 case STATE_DATA: break;
262 case STATE_LOCATION: break;
263 case STATE_CHECKSUM: break;
264 case STATE_TIMESTAMP: break;
265 case STATE_OPENCHECKSUM: break;
266 case NUMSTATES: break;
273 endElement(void *userData, const char *name)
275 struct parsedata *pd = userData;
276 /* Pool *pool = pd->pool; */
280 fprintf(stderr, "end: %s\n", name);
282 if (pd->depth != pd->statedepth)
286 fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
295 case STATE_START: break;
297 /* save the timestamp in the non solvable number 1 */
298 if ( pd->timestamp > 0 )
299 repo_set_num(pd->repo, -1, REPOSITORY_TIMESTAMP, pd->timestamp);
301 case STATE_DATA: break;
302 case STATE_LOCATION: break;
303 case STATE_CHECKSUM: break;
304 case STATE_OPENCHECKSUM: break;
305 case STATE_TIMESTAMP:
308 * we want to look for the newer timestamp
309 * of all resources to save it as the time
310 * the metadata was generated
312 timestamp = atoi(pd->content);
313 /** if the timestamp is invalid or just 0 ignore it */
314 if ( timestamp == 0 )
316 if ( timestamp > pd->timestamp )
318 pd->timestamp = timestamp;
327 expire = atoi(pd->content);
330 /* save the timestamp in the non solvable number 1 */
331 repo_set_num(pd->repo, -1, REPOSITORY_EXPIRE, expire);
339 repo_add_poolstr_array(pd->repo, -1, REPOSITORY_PRODUCTS, pd->content);
345 repo_add_poolstr_array(pd->repo, -1, REPOSITORY_KEYWORDS, pd->content);
348 case STATE_SUSEINFO: break;
349 case STATE_PRODUCTS: break;
350 case STATE_KEYWORDS: break;
351 case NUMSTATES: break;
356 pd->state = pd->sbtab[pd->state];
364 characterData(void *userData, const XML_Char *s, int len)
366 struct parsedata *pd = userData;
369 if (!pd->docontent) {
371 char *dup = strndup( s, len );
372 fprintf(stderr, "Content: [%d]'%s'\n", pd->state, dup );
377 l = pd->lcontent + len + 1;
378 if (l > pd->acontent)
380 pd->content = realloc(pd->content, l + 256);
381 pd->acontent = l + 256;
383 c = pd->content + pd->lcontent;
390 #define BUFF_SIZE 8192
393 repo_add_repomdxml(Repo *repo, FILE *fp, int flags)
395 Pool *pool = repo->pool;
401 struct stateswitch *sw;
403 memset(&pd, 0, sizeof(pd));
404 for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
406 if (!pd.swtab[sw->from])
407 pd.swtab[sw->from] = sw;
408 pd.sbtab[sw->to] = sw->from;
412 pd.data = repo_add_repodata(pd.repo, 0);
414 pd.content = malloc(256);
417 XML_Parser parser = XML_ParserCreate(NULL);
418 XML_SetUserData(parser, &pd);
419 XML_SetElementHandler(parser, startElement, endElement);
420 XML_SetCharacterDataHandler(parser, characterData);
423 l = fread(buf, 1, sizeof(buf), fp);
424 if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
426 fprintf(stderr, "repo_repomdxml: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser));
432 XML_ParserFree(parser);
435 repodata_internalize(pd.data);