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>
70 STATE_LOCATION, /* 3 */
71 STATE_CHECKSUM, /* 4 */
72 STATE_TIMESTAMP, /* 5 */
73 STATE_OPENCHECKSUM, /* 6 */
84 /* !! must be sorted by first column !! */
85 static struct stateswitch stateswitches[] = {
86 { STATE_START, "repomd", STATE_REPOMD, 0 },
87 { STATE_REPOMD, "data", STATE_DATA, 0 },
88 { STATE_DATA, "location", STATE_LOCATION, 0 },
89 { STATE_DATA, "checksum", STATE_CHECKSUM, 1 },
90 { STATE_DATA, "timestamp", STATE_TIMESTAMP, 1 },
91 { STATE_DATA, "open-checksum", STATE_OPENCHECKSUM, 1 },
96 * split l into m parts, store to sp[]
101 split_comma(char *l, char **sp, int m)
113 while (*l && !(*l == ','))
135 struct stateswitch *swtab[NUMSTATES];
136 enum state sbtab[NUMSTATES];
144 static inline const char *
145 find_attr(const char *txt, const char **atts)
147 for (; *atts; atts += 2)
149 if (!strcmp(*atts, txt))
157 startElement(void *userData, const char *name, const char **atts)
159 struct parsedata *pd = userData;
160 /*Pool *pool = pd->pool;*/
161 struct stateswitch *sw;
162 const char *expirestr = 0;
166 fprintf(stderr, "start: [%d]%s\n", pd->state, name);
168 if (pd->depth != pd->statedepth)
175 for (sw = pd->swtab[pd->state]; sw->from == pd->state; sw++) /* find name in statetable */
176 if (!strcmp(sw->ename, name))
179 if (sw->from != pd->state)
182 fprintf(stderr, "into unknown: [%d]%s (from: %d)\n", sw->to, name, sw->from);
188 pd->docontent = sw->docontent;
189 pd->statedepth = pd->depth;
195 case STATE_START: break;
202 expirestr = (char*) find_attr("expire", atts);
203 if ( expirestr != NULL )
204 expire = atoi(expirestr);
207 /* save the timestamp in the non solvable number 1 */
208 repo_set_num(pd->repo, -1, REPOSITORY_EXPIRE, expire);
211 updstr = find_attr("updates", atts);
212 if ( updstr != NULL )
214 value = strdup(updstr);
215 fvalue = value; /* save the first */
221 int words = split_comma(value, sp, 2);
225 repo_add_poolstr_array(pd->repo, -1, REPOSITORY_UPDATES, sp[0]);
235 case STATE_DATA: break;
236 case STATE_LOCATION: break;
237 case STATE_CHECKSUM: break;
238 case STATE_TIMESTAMP: break;
239 case STATE_OPENCHECKSUM: break;
240 case NUMSTATES: break;
247 endElement(void *userData, const char *name)
249 struct parsedata *pd = userData;
250 /* Pool *pool = pd->pool; */
254 fprintf(stderr, "end: %s\n", name);
256 if (pd->depth != pd->statedepth)
260 fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth);
269 case STATE_START: break;
270 case STATE_REPOMD: break;
271 case STATE_DATA: break;
272 case STATE_LOCATION: break;
273 case STATE_CHECKSUM: break;
274 case STATE_OPENCHECKSUM: break;
275 case STATE_TIMESTAMP:
277 * we want to look for the newer timestamp
278 * of all resources to save it as the time
279 * the metadata was generated
281 timestamp = atoi(pd->content);
282 /** if the timestamp is invalid or just 0 ignore it */
283 if ( timestamp == 0 )
285 if ( timestamp > pd->timestamp )
287 pd->timestamp = timestamp;
288 /* save the timestamp in the non solvable number 1 */
289 repo_set_num(pd->repo, -1, REPOSITORY_TIMESTAMP, pd->timestamp);
292 case NUMSTATES: break;
297 pd->state = pd->sbtab[pd->state];
305 characterData(void *userData, const XML_Char *s, int len)
307 struct parsedata *pd = userData;
310 if (!pd->docontent) {
312 char *dup = strndup( s, len );
313 fprintf(stderr, "Content: [%d]'%s'\n", pd->state, dup );
318 l = pd->lcontent + len + 1;
319 if (l > pd->acontent)
321 pd->content = realloc(pd->content, l + 256);
322 pd->acontent = l + 256;
324 c = pd->content + pd->lcontent;
331 #define BUFF_SIZE 8192
334 repo_add_repomdxml(Repo *repo, FILE *fp, int flags)
336 Pool *pool = repo->pool;
342 struct stateswitch *sw;
344 memset(&pd, 0, sizeof(pd));
345 for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++)
347 if (!pd.swtab[sw->from])
348 pd.swtab[sw->from] = sw;
349 pd.sbtab[sw->to] = sw->from;
353 pd.data = repo_add_repodata(pd.repo, 0);
355 pd.content = malloc(256);
358 XML_Parser parser = XML_ParserCreate(NULL);
359 XML_SetUserData(parser, &pd);
360 XML_SetElementHandler(parser, startElement, endElement);
361 XML_SetCharacterDataHandler(parser, characterData);
364 l = fread(buf, 1, sizeof(buf), fp);
365 if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
367 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));
373 XML_ParserFree(parser);
376 repodata_internalize(pd.data);