xbps_repo_open: switch to archive_read_data_block() and misc tweaks.

This commit is contained in:
Juan RP 2013-12-12 00:18:08 +01:00
parent 711f2ea7f5
commit 865dffde58

View File

@ -48,51 +48,57 @@ xbps_repo_path(struct xbps_handle *xhp, const char *url)
} }
static xbps_dictionary_t static xbps_dictionary_t
repo_get_dict(struct xbps_repo *repo, const char *fname) repo_get_dict(struct xbps_repo *repo)
{ {
xbps_dictionary_t d; xbps_dictionary_t d = NULL;
struct archive_entry *entry; struct archive_entry *entry;
void *buf; char *adata = NULL;
size_t buflen; const void *buf;
ssize_t nbytes = -1; off_t offset;
size_t size;
int rv; int rv;
assert(repo); rv = archive_read_next_header(repo->ar, &entry);
assert(fname); if (rv != ARCHIVE_OK) {
xbps_dbg_printf(repo->xhp,
if (repo->ar == NULL) "%s: read_next_header %s\n", repo->uri,
archive_error_string(repo->ar));
return NULL; return NULL;
}
for (;;) { for (;;) {
rv = archive_read_next_header(repo->ar, &entry); rv = archive_read_data_block(repo->ar, &buf, &size, &offset);
if (rv == ARCHIVE_EOF || rv == ARCHIVE_FATAL) if (rv == ARCHIVE_EOF)
break; break;
else if (rv == ARCHIVE_RETRY) if (rv != ARCHIVE_OK) {
continue; xbps_dbg_printf(repo->xhp,
"%s: read_data_block %s\n", repo->uri,
if (strcmp(archive_entry_pathname(entry), fname) == 0) { archive_error_string(repo->ar));
buflen = (size_t)archive_entry_size(entry); return NULL;
buf = malloc(buflen); }
assert(buf); if (adata == NULL) {
nbytes = archive_read_data(repo->ar, buf, buflen); adata = malloc(size);
if ((size_t)nbytes != buflen) { } else {
free(buf); adata = realloc(adata, sizeof(size) * offset);
if (adata == NULL) {
free(adata);
return NULL; return NULL;
} }
d = xbps_dictionary_internalize(buf);
free(buf);
return d;
} }
archive_read_data_skip(repo->ar); memcpy(adata+offset, buf, size);
} }
return NULL; if (adata != NULL) {
d = xbps_dictionary_internalize(adata);
free(adata);
}
return d;
} }
struct xbps_repo * struct xbps_repo *
xbps_repo_open(struct xbps_handle *xhp, const char *url) xbps_repo_open(struct xbps_handle *xhp, const char *url)
{ {
xbps_dictionary_t meta; xbps_dictionary_t meta;
struct xbps_repo *repo; struct archive *ar = NULL;
struct xbps_repo *repo = NULL;
struct stat st; struct stat st;
const char *arch; const char *arch;
char *repofile; char *repofile;
@ -120,34 +126,35 @@ xbps_repo_open(struct xbps_handle *xhp, const char *url)
repofile = xbps_repo_path(xhp, url); repofile = xbps_repo_path(xhp, url);
} }
if (stat(repofile, &st) == -1) {
xbps_dbg_printf(xhp, "[repo] `%s' stat repodata %s\n",
repofile, strerror(errno));
free(repofile);
return NULL;
}
ar = archive_read_new();
archive_read_support_compression_gzip(ar);
archive_read_support_format_tar(ar);
if (archive_read_open_filename(ar, repofile, st.st_blksize) == ARCHIVE_FATAL) {
xbps_dbg_printf(xhp,
"[repo] `%s' failed to open repodata archive %s\n",
repofile, strerror(archive_errno(repo->ar)));
archive_read_free(ar);
free(repo);
repo = NULL;
goto out;
}
repo = calloc(1, sizeof(struct xbps_repo)); repo = calloc(1, sizeof(struct xbps_repo));
assert(repo); assert(repo);
repo->ar = ar;
repo->xhp = xhp; repo->xhp = xhp;
repo->uri = url; repo->uri = url;
repo->ar = archive_read_new();
repo->is_remote = is_remote; repo->is_remote = is_remote;
archive_read_support_compression_gzip(repo->ar);
archive_read_support_format_tar(repo->ar);
if (stat(repofile, &st) == -1) { if ((repo->idx = repo_get_dict(repo)) == NULL) {
xbps_dbg_printf(xhp, "[repo] `%s' missing repodata %s: %s\n",
url, repofile, strerror(errno));
archive_read_finish(repo->ar);
free(repo);
repo = NULL;
goto out;
}
if (archive_read_open_filename(repo->ar, repofile, st.st_blksize) == ARCHIVE_FATAL) {
xbps_dbg_printf(xhp,
"[repo] `%s' failed to open repodata archive %s: %s\n",
url, repofile, strerror(archive_errno(repo->ar)));
archive_read_finish(repo->ar);
free(repo);
repo = NULL;
goto out;
}
if ((repo->idx = repo_get_dict(repo, XBPS_REPOIDX)) == NULL) {
xbps_dbg_printf(xhp, xbps_dbg_printf(xhp,
"[repo] `%s' failed to internalize index on archive %s: %s\n", "[repo] `%s' failed to internalize index on archive %s: %s\n",
url, repofile, strerror(archive_errno(repo->ar))); url, repofile, strerror(archive_errno(repo->ar)));
@ -156,7 +163,7 @@ xbps_repo_open(struct xbps_handle *xhp, const char *url)
repo = NULL; repo = NULL;
goto out; goto out;
} }
if ((meta = repo_get_dict(repo, XBPS_REPOIDX_META))) { if ((meta = repo_get_dict(repo))) {
repo->is_signed = true; repo->is_signed = true;
repo->signature = xbps_dictionary_get(meta, "signature"); repo->signature = xbps_dictionary_get(meta, "signature");
xbps_dictionary_get_cstring_nocopy(meta, "signature-by", &repo->signedby); xbps_dictionary_get_cstring_nocopy(meta, "signature-by", &repo->signedby);
@ -173,7 +180,8 @@ out:
void void
xbps_repo_open_idxfiles(struct xbps_repo *repo) xbps_repo_open_idxfiles(struct xbps_repo *repo)
{ {
repo->idxfiles = repo_get_dict(repo, XBPS_REPOIDX_FILES); assert(repo);
repo->idxfiles = repo_get_dict(repo);
} }
void HIDDEN void HIDDEN