X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=ext%2Frepo_updateinfoxml.c;h=6af74f220ff26b8ccd5aa82cd8e0458d80beb611;hb=27c054b4871ce52ea23347651c40e0922ea34e96;hp=c2bf69e5fc66c19a7aedb792720760fddc9226ed;hpb=9bbaf91bc428daef376f80a030909546e237b64d;p=platform%2Fupstream%2Flibsolv.git diff --git a/ext/repo_updateinfoxml.c b/ext/repo_updateinfoxml.c index c2bf69e..6af74f2 100644 --- a/ext/repo_updateinfoxml.c +++ b/ext/repo_updateinfoxml.c @@ -6,6 +6,7 @@ */ #define _GNU_SOURCE +#define _XOPEN_SOURCE /* glibc2 needs this */ #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include "pool.h" #include "repo.h" @@ -25,8 +27,11 @@ * * FEDORA-2007-4594 * imlib-1.9.15-6.fc8 + * Important * Fedora 8 + * Copyright 2007 Company Inc * + * * * * @@ -46,24 +51,27 @@ enum state { STATE_START, - STATE_UPDATES, /* 1 */ - STATE_UPDATE, /* 2 */ - STATE_ID, /* 3 */ - STATE_TITLE, /* 4 */ - STATE_RELEASE, /* 5 */ - STATE_ISSUED, /* 6 */ - STATE_MESSAGE, /* 7 */ - STATE_REFERENCES, /* 8 */ - STATE_REFERENCE, /* 9 */ - STATE_DESCRIPTION, /* 10 */ - STATE_PKGLIST, /* 11 */ - STATE_COLLECTION, /* 12 */ - STATE_NAME, /* 13 */ - STATE_PACKAGE, /* 14 */ - STATE_FILENAME, /* 15 */ - STATE_REBOOT, /* 16 */ - STATE_RESTART, /* 17 */ - STATE_RELOGIN, /* 18 */ + STATE_UPDATES, + STATE_UPDATE, + STATE_ID, + STATE_TITLE, + STATE_RELEASE, + STATE_ISSUED, + STATE_UPDATED, + STATE_MESSAGE, + STATE_REFERENCES, + STATE_REFERENCE, + STATE_DESCRIPTION, + STATE_PKGLIST, + STATE_COLLECTION, + STATE_NAME, + STATE_PACKAGE, + STATE_FILENAME, + STATE_REBOOT, + STATE_RESTART, + STATE_RELOGIN, + STATE_RIGHTS, + STATE_SEVERITY, NUMSTATES }; @@ -82,8 +90,11 @@ static struct stateswitch stateswitches[] = { { STATE_UPDATES, "update", STATE_UPDATE, 0 }, { STATE_UPDATE, "id", STATE_ID, 1 }, { STATE_UPDATE, "title", STATE_TITLE, 1 }, + { STATE_UPDATE, "severity", STATE_SEVERITY, 1 }, + { STATE_UPDATE, "rights", STATE_RIGHTS, 1 }, { STATE_UPDATE, "release", STATE_RELEASE, 1 }, - { STATE_UPDATE, "issued", STATE_ISSUED, 1 }, + { STATE_UPDATE, "issued", STATE_ISSUED, 0 }, + { STATE_UPDATE, "updated", STATE_UPDATED, 0 }, { STATE_UPDATE, "description", STATE_DESCRIPTION, 1 }, { STATE_UPDATE, "message", STATE_MESSAGE , 1 }, { STATE_UPDATE, "references", STATE_REFERENCES, 0 }, @@ -100,6 +111,7 @@ static struct stateswitch stateswitches[] = { }; struct parsedata { + int ret; int depth; enum state state; int statedepth; @@ -110,27 +122,41 @@ struct parsedata { Pool *pool; Repo *repo; Repodata *data; - unsigned int datanum; + Id handle; Solvable *solvable; + time_t buildtime; Id collhandle; + struct joindata jd; struct stateswitch *swtab[NUMSTATES]; enum state sbtab[NUMSTATES]; }; /* - * if we have seen a ... - * inside of ... - * - * - * If not, we must insert an empty filename to UPDATE_COLLECTION_FILENAME - * at in order to keep all UPDATE_COLLECTION_* arrays in sync + * Convert date strings ("1287746075" or "2010-10-22 13:14:35") + * to timestamp. */ +static time_t +datestr2timestamp(const char *date) +{ + const char *p; + struct tm tm; + + if (!date || !*date) + return 0; + for (p = date; *p >= '0' && *p <= '9'; p++) + ; + if (!*p) + return atoi(date); + memset(&tm, 0, sizeof(tm)); + if (!strptime(date, "%F%T", &tm)) + return 0; + return timegm(&tm); +} /* * create evr (as Id) from 'epoch', 'version' and 'release' attributes */ - static Id makeevr_atts(Pool *pool, struct parsedata *pd, const char **atts) { @@ -148,7 +174,7 @@ makeevr_atts(Pool *pool, struct parsedata *pd, const char **atts) else if (!strcmp(*atts, "release")) r = atts[1]; } - if (e && !strcmp(e, "0")) + if (e && (!*e || !strcmp(e, "0"))) e = 0; if (v && !e) { @@ -193,7 +219,7 @@ makeevr_atts(Pool *pool, struct parsedata *pd, const char **atts) #if 0 fprintf(stderr, "evr: %s\n", pd->content); #endif - return str2id(pool, pd->content, 1); + return pool_str2id(pool, pd->content, 1); } @@ -227,7 +253,6 @@ startElement(void *userData, const char *name, const char **atts) { #if 0 fprintf(stderr, "into unknown: %s (from: %d)\n", name, pd->state); - exit( 1 ); #endif return; } @@ -251,28 +276,25 @@ startElement(void *userData, const char *name, const char **atts) */ case STATE_UPDATE: { - const char *from = 0, *status = 0, *type = 0, *version = 0; + const char *from = 0, *type = 0, *version = 0; for (; *atts; atts += 2) { if (!strcmp(*atts, "from")) from = atts[1]; - else if (!strcmp(*atts, "status")) - status = atts[1]; else if (!strcmp(*atts, "type")) type = atts[1]; else if (!strcmp(*atts, "version")) version = atts[1]; } - - solvable = pd->solvable = pool_id2solvable(pool, repo_add_solvable(pd->repo)); - pd->datanum = pd->solvable - pool->solvables; - - solvable->vendor = str2id(pool, from, 1); - solvable->evr = str2id(pool, version, 1); + pd->handle = pd->solvable - pool->solvables; + + solvable->vendor = pool_str2id(pool, from, 1); + solvable->evr = pool_str2id(pool, version, 1); solvable->arch = ARCH_NOARCH; if (type) - repodata_set_str(pd->data, pd->datanum, SOLVABLE_PATCHCATEGORY, type); + repodata_set_str(pd->data, pd->handle, SOLVABLE_PATCHCATEGORY, type); + pd->buildtime = (time_t)0; } break; /* FEDORA-2007-4594 */ @@ -287,6 +309,7 @@ startElement(void *userData, const char *name, const char **atts) /* */ case STATE_ISSUED: + case STATE_UPDATED: { const char *date = 0; for (; *atts; atts += 2) @@ -296,13 +319,9 @@ startElement(void *userData, const char *name, const char **atts) } if (date) { - if (strlen(date) == strspn(date, "0123456789")) - repodata_set_num(pd->data, pd->datanum, SOLVABLE_BUILDTIME, atoi(date)); - else - { - /* FIXME: must convert to interger! */ - repodata_set_str(pd->data, pd->datanum, SOLVABLE_BUILDTIME, date); - } + time_t t = datestr2timestamp(date); + if (t && t > pd->buildtime) + pd->buildtime = t; } } break; @@ -316,7 +335,7 @@ startElement(void *userData, const char *name, const char **atts) case STATE_REFERENCE: { const char *href = 0, *id = 0, *title = 0, *type = 0; - Id handle; + Id refhandle; for (; *atts; atts += 2) { if (!strcmp(*atts, "href")) @@ -328,16 +347,16 @@ startElement(void *userData, const char *name, const char **atts) else if (!strcmp(*atts, "type")) type = atts[1]; } - handle = repodata_new_handle(pd->data); + refhandle = repodata_new_handle(pd->data); if (href) - repodata_set_str(pd->data, handle, UPDATE_REFERENCE_HREF, href); + repodata_set_str(pd->data, refhandle, UPDATE_REFERENCE_HREF, href); if (id) - repodata_set_str(pd->data, handle, UPDATE_REFERENCE_ID, id); + repodata_set_str(pd->data, refhandle, UPDATE_REFERENCE_ID, id); if (title) - repodata_set_str(pd->data, handle, UPDATE_REFERENCE_TITLE, title); + repodata_set_str(pd->data, refhandle, UPDATE_REFERENCE_TITLE, title); if (type) - repodata_set_poolstr(pd->data, handle, UPDATE_REFERENCE_TYPE, type); - repodata_add_flexarray(pd->data, pd->datanum, UPDATE_REFERENCE, handle); + repodata_set_poolstr(pd->data, refhandle, UPDATE_REFERENCE_TYPE, type); + repodata_add_flexarray(pd->data, pd->handle, UPDATE_REFERENCE, refhandle); } break; /* This update ... */ @@ -351,19 +370,19 @@ startElement(void *userData, const char *name, const char **atts) /* Fedora 8 */ + /* Fedora 8 */ case STATE_NAME: break; /* - * + * * * -> patch.conflicts: {name} < {version}.{release} */ case STATE_PACKAGE: { - const char *arch = 0, *name = 0, *src = 0; + const char *arch = 0, *name = 0; Id evr = makeevr_atts(pool, pd, atts); /* parse "epoch", "version", "release" */ Id n, a = 0; Id rel_id; @@ -374,30 +393,28 @@ startElement(void *userData, const char *name, const char **atts) arch = atts[1]; else if (!strcmp(*atts, "name")) name = atts[1]; - else if (!strcmp(*atts, "src")) - src = atts[1]; } /* generated Id for name */ - n = str2id(pool, name, 1); + n = pool_str2id(pool, name, 1); rel_id = n; if (arch) { /* generate Id for arch and combine with name */ - a = str2id(pool, arch, 1); - rel_id = rel2id(pool, n, a, REL_ARCH, 1); + a = pool_str2id(pool, arch, 1); + rel_id = pool_rel2id(pool, n, a, REL_ARCH, 1); } - rel_id = rel2id(pool, rel_id, evr, REL_LT, 1); - + rel_id = pool_rel2id(pool, rel_id, evr, REL_LT, 1); solvable->conflicts = repo_addid_dep(pd->repo, solvable->conflicts, rel_id, 0); /* who needs the collection anyway? */ pd->collhandle = repodata_new_handle(pd->data); repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_NAME, n); repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_EVR, evr); - repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_ARCH, a); + if (a) + repodata_set_id(pd->data, pd->collhandle, UPDATE_COLLECTION_ARCH, a); break; } - /* libntlm-0.4.2-1.fc8.x86_64.rpm */ + /* libntlm-0.4.2-1.fc8.x86_64.rpm */ /* libntlm-0.4.2-1.fc8.x86_64.rpm */ case STATE_FILENAME: break; @@ -446,16 +463,27 @@ endElement(void *userData, const char *name) case STATE_UPDATES: break; case STATE_UPDATE: - s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + if (pd->buildtime) + { + repodata_set_num(pd->data, pd->handle, SOLVABLE_BUILDTIME, pd->buildtime); + pd->buildtime = (time_t)0; + } break; case STATE_ID: - s->name = str2id(pool, join2("patch", ":", pd->content), 1); + s->name = pool_str2id(pool, join2(&pd->jd, "patch", ":", pd->content), 1); break; /* imlib-1.9.15-6.fc8 */ case STATE_TITLE: while (pd->lcontent > 0 && pd->content[pd->lcontent - 1] == '\n') pd->content[--pd->lcontent] = 0; - repodata_set_str(pd->data, pd->datanum, SOLVABLE_SUMMARY, pd->content); + repodata_set_str(pd->data, pd->handle, SOLVABLE_SUMMARY, pd->content); + break; + case STATE_SEVERITY: + repodata_set_poolstr(pd->data, pd->handle, UPDATE_SEVERITY, pd->content); + break; + case STATE_RIGHTS: + repodata_set_poolstr(pd->data, pd->handle, UPDATE_RIGHTS, pd->content); break; /* * Fedora 8 @@ -472,13 +500,13 @@ endElement(void *userData, const char *name) * This update ... */ case STATE_DESCRIPTION: - repodata_set_str(pd->data, pd->datanum, SOLVABLE_DESCRIPTION, pd->content); - break; + repodata_set_str(pd->data, pd->handle, SOLVABLE_DESCRIPTION, pd->content); + break; /* * Warning! ... */ case STATE_MESSAGE: - repodata_set_str(pd->data, pd->datanum, UPDATE_MESSAGE, pd->content); + repodata_set_str(pd->data, pd->handle, UPDATE_MESSAGE, pd->content); break; case STATE_PKGLIST: break; @@ -487,10 +515,10 @@ endElement(void *userData, const char *name) case STATE_NAME: break; case STATE_PACKAGE: - repodata_add_flexarray(pd->data, pd->datanum, UPDATE_COLLECTION, pd->collhandle); + repodata_add_flexarray(pd->data, pd->handle, UPDATE_COLLECTION, pd->collhandle); pd->collhandle = 0; break; - /* libntlm-0.4.2-1.fc8.x86_64.rpm */ + /* libntlm-0.4.2-1.fc8.x86_64.rpm */ /* libntlm-0.4.2-1.fc8.x86_64.rpm */ case STATE_FILENAME: repodata_set_str(pd->data, pd->collhandle, UPDATE_COLLECTION_FILENAME, pd->content); @@ -500,7 +528,7 @@ endElement(void *userData, const char *name) if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1') { /* FIXME: this is per-package, the global flag should be computed at runtime */ - repodata_set_void(pd->data, pd->datanum, UPDATE_REBOOT); + repodata_set_void(pd->data, pd->handle, UPDATE_REBOOT); repodata_set_void(pd->data, pd->collhandle, UPDATE_REBOOT); } break; @@ -509,7 +537,7 @@ endElement(void *userData, const char *name) if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1') { /* FIXME: this is per-package, the global flag should be computed at runtime */ - repodata_set_void(pd->data, pd->datanum, UPDATE_RESTART); + repodata_set_void(pd->data, pd->handle, UPDATE_RESTART); repodata_set_void(pd->data, pd->collhandle, UPDATE_RESTART); } break; @@ -518,7 +546,7 @@ endElement(void *userData, const char *name) if (pd->content[0] == 'T' || pd->content[0] == 't'|| pd->content[0] == '1') { /* FIXME: this is per-package, the global flag should be computed at runtime */ - repodata_set_void(pd->data, pd->datanum, UPDATE_RELOGIN); + repodata_set_void(pd->data, pd->handle, UPDATE_RELOGIN); repodata_set_void(pd->data, pd->collhandle, UPDATE_RELOGIN); } break; @@ -561,7 +589,7 @@ characterData(void *userData, const XML_Char *s, int len) #define BUFF_SIZE 8192 -void +int repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) { Pool *pool = repo->pool; @@ -570,6 +598,7 @@ repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) int i, l; struct stateswitch *sw; Repodata *data; + XML_Parser parser; data = repo_add_repodata(repo, flags); @@ -587,7 +616,7 @@ repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) pd.content = malloc(256); pd.acontent = 256; pd.lcontent = 0; - XML_Parser parser = XML_ParserCreate(NULL); + parser = XML_ParserCreate(NULL); XML_SetUserData(parser, &pd); XML_SetElementHandler(parser, startElement, endElement); XML_SetCharacterDataHandler(parser, characterData); @@ -596,18 +625,18 @@ repo_add_updateinfoxml(Repo *repo, FILE *fp, int flags) l = fread(buf, 1, sizeof(buf), fp); if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR) { - pool_debug(pool, SAT_FATAL, "repo_updateinfoxml: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser)); - exit(1); + pd.ret = pool_error(pool, -1, "repo_updateinfoxml: %s at line %u:%u", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser)); + break; } if (l == 0) break; } XML_ParserFree(parser); free(pd.content); - join_freemem(); + join_freemem(&pd.jd); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); + return pd.ret; } -/* EOF */