#include "pool.h"
#include "repo.h"
-#include "repo_updateinfoxml.h"
-
-//#define DUMPOUT 0
+#include "chksum.h"
+#include "repo_repomdxml.h"
/*
<repomd>
STATE_CHECKSUM,
STATE_TIMESTAMP,
STATE_OPENCHECKSUM,
+ STATE_SIZE,
NUMSTATES
};
{ STATE_DATA, "location", STATE_LOCATION, 0 },
{ STATE_DATA, "checksum", STATE_CHECKSUM, 1 },
{ STATE_DATA, "timestamp", STATE_TIMESTAMP, 1 },
- { STATE_DATA, "open-checksum", STATE_OPENCHECKSUM, 1 },
+ { STATE_DATA, "open-checksum", STATE_OPENCHECKSUM, 1 },
+ { STATE_DATA, "size", STATE_SIZE, 1 },
{ NUMSTATES }
};
struct parsedata {
+ int ret;
int depth;
enum state state;
int statedepth;
/* repo data handle */
Id rdhandle;
- const char *tmpattr;
+ Id chksumtype;
};
/*
switch(pd->state)
{
- case STATE_START: break;
case STATE_REPOMD:
{
const char *updstr;
updstr = find_attr("updates", atts);
if (updstr)
{
- char *value = strdup(updstr);
+ char *value = solv_strdup(updstr);
char *fvalue = value; /* save the first */
while (value)
{
if (*p)
*p++ = 0;
if (*value)
- repo_add_poolstr_array(pd->repo, SOLVID_META, REPOSITORY_UPDATES, value);
+ repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_UPDATES, value);
value = p;
}
free(fvalue);
}
- break;
- }
- case STATE_SUSEINFO: break;
- case STATE_EXPIRE: break;
- case STATE_KEYWORDS: break;
- case STATE_KEYWORD: break;
- case STATE_CONTENT: break;
- case STATE_REVISION: break;
+ break;
+ }
case STATE_DISTRO:
{
/* this is extra metadata about the product this repository
const char *href = find_attr("href", atts);
if (href)
repodata_set_str(pd->data, pd->rdhandle, REPOSITORY_REPOMD_LOCATION, href);
+ break;
}
case STATE_CHECKSUM:
case STATE_OPENCHECKSUM:
- pd->tmpattr= find_attr("type", atts);
- break;
+ {
+ const char *type= find_attr("type", atts);
+ pd->chksumtype = type && *type ? solv_chksum_str2type(type) : 0;
+ if (!pd->chksumtype)
+ pd->ret = pool_error(pd->pool, -1, "line %d: unknown checksum type: %s", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), type ? type : "NULL");
+ break;
+ }
default:
break;
}
pd->statedepth--;
switch (pd->state)
{
- case STATE_START: break;
case STATE_REPOMD:
if (pd->timestamp > 0)
repodata_set_num(pd->data, SOLVID_META, REPOSITORY_TIMESTAMP, pd->timestamp);
repodata_add_flexarray(pd->data, SOLVID_META, REPOSITORY_REPOMD, pd->rdhandle);
pd->rdhandle = 0;
break;
- case STATE_LOCATION: break;
case STATE_CHECKSUM:
case STATE_OPENCHECKSUM:
- {
- int l;
- Id type;
- if (!strcasecmp(pd->tmpattr, "sha") || !strcasecmp(pd->tmpattr, "sha1"))
- l = SIZEOF_SHA1 * 2, type = REPOKEY_TYPE_SHA1;
- else if (!strcasecmp(pd->tmpattr, "sha256"))
- l = SIZEOF_SHA256 * 2, type = REPOKEY_TYPE_SHA256;
- else if (!strcasecmp(pd->tmpattr, "md5"))
- l = SIZEOF_MD5 * 2, type = REPOKEY_TYPE_MD5;
- else
- {
- fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
- exit(1);
- }
- if (strlen(pd->content) != l)
- {
- fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr);
- exit(1);
- }
- repodata_set_checksum(pd->data, pd->rdhandle, pd->state == STATE_CHECKSUM ? REPOSITORY_REPOMD_CHECKSUM : REPOSITORY_REPOMD_OPENCHECKSUM, type, pd->content);
- break;
- }
+ if (!pd->chksumtype)
+ break;
+ if (strlen(pd->content) != 2 * solv_chksum_len(pd->chksumtype))
+ pd->ret = pool_error(pd->pool, -1, "line %d: invalid checksum length for %s", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), solv_chksum_type2str(pd->chksumtype));
+ else
+ repodata_set_checksum(pd->data, pd->rdhandle, pd->state == STATE_CHECKSUM ? REPOSITORY_REPOMD_CHECKSUM : REPOSITORY_REPOMD_OPENCHECKSUM, pd->chksumtype, pd->content);
+ break;
case STATE_TIMESTAMP:
{
/* repomd.xml content and suseinfo.xml keywords are equivalent */
case STATE_CONTENT:
case STATE_KEYWORD:
- if (pd->content)
+ if (*pd->content)
repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_KEYWORDS, pd->content);
break;
case STATE_REVISION:
- if (pd->content)
- repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_REVISION, pd->content);
+ if (*pd->content)
+ repodata_set_str(pd->data, SOLVID_META, REPOSITORY_REVISION, pd->content);
break;
case STATE_DISTRO:
/* distro tag is used in repomd.xml to say the product this repo is
made for */
- if (pd->content)
+ if (*pd->content)
repodata_set_str(pd->data, pd->rphandle, REPOSITORY_PRODUCT_LABEL, pd->content);
repodata_add_flexarray(pd->data, SOLVID_META, REPOSITORY_DISTROS, pd->rphandle);
break;
case STATE_UPDATES:
- /* distro tag is used in suseinfo.xml to say the repo updates a product
+ /* updates tag is used in suseinfo.xml to say the repo updates a product
however it s not yet a tag standarized for repomd.xml */
- if (pd->content)
+ if (*pd->content)
repodata_set_str(pd->data, pd->ruhandle, REPOSITORY_PRODUCT_LABEL, pd->content);
repodata_add_flexarray(pd->data, SOLVID_META, REPOSITORY_UPDATES, pd->ruhandle);
break;
case STATE_REPO:
- if (pd->content)
+ if (*pd->content)
repodata_add_poolstr_array(pd->data, SOLVID_META, REPOSITORY_REPOID, pd->content);
break;
- case STATE_SUSEINFO: break;
- case STATE_KEYWORDS: break;
- case NUMSTATES: break;
+ case STATE_SIZE:
+ if (*pd->content)
+ repodata_set_num(pd->data, pd->rdhandle, REPOSITORY_REPOMD_SIZE, strtoull(pd->content, 0, 10));
+ break;
default:
break;
}
#define BUFF_SIZE 8192
-void
+int
repo_add_repomdxml(Repo *repo, FILE *fp, int flags)
{
Pool *pool = repo->pool;
char buf[BUFF_SIZE];
int i, l;
struct stateswitch *sw;
+ XML_Parser parser;
data = repo_add_repodata(repo, 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);
pd.parser = &parser;
XML_SetElementHandler(parser, startElement, endElement);
l = fread(buf, 1, sizeof(buf), fp);
if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR)
{
- pool_debug(pool, SAT_FATAL, "repo_repomdxml: %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_repomdxml: %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;
repodata_internalize(data);
free(pd.content);
+ return pd.ret;
}
/* EOF */