convert remaining locations to use istream instead of bstream

cute-signatures
Timo Teräs 2020-01-11 09:16:38 +02:00
parent 6da3e8eb15
commit 7caa217731
8 changed files with 161 additions and 156 deletions

View File

@ -110,13 +110,28 @@ static inline void apk_istream_close(struct apk_istream *is)
is->ops->close(is);
}
#define APK_MPART_DATA 1 /* data processed so far */
#define APK_MPART_BOUNDARY 2 /* final part of data, before boundary */
#define APK_MPART_END 3 /* signals end of stream */
typedef int (*apk_multipart_cb)(void *ctx, int part, apk_blob_t data);
struct apk_istream *apk_istream_gunzip_mpart(struct apk_istream *,
apk_multipart_cb cb, void *ctx);
static inline struct apk_istream *apk_istream_gunzip(struct apk_istream *is)
{
return apk_istream_gunzip_mpart(is, NULL, NULL);
}
struct apk_segment_istream {
struct apk_istream is;
struct apk_istream *pis;
size_t bytes_left;
time_t mtime;
};
void apk_istream_segment(struct apk_segment_istream *sis, struct apk_istream *is, size_t len, time_t mtime);
struct apk_istream *apk_istream_segment(struct apk_segment_istream *sis, struct apk_istream *is, size_t len, time_t mtime);
struct apk_istream *apk_istream_tee(struct apk_istream *from, int atfd, const char *to, int copy_meta,
apk_progress_cb cb, void *cb_ctx);
#define APK_BSTREAM_SINGLE_READ 0x0001
#define APK_BSTREAM_EOF 0x0002
@ -141,19 +156,6 @@ struct apk_ostream {
const struct apk_ostream_ops *ops;
};
#define APK_MPART_DATA 1 /* data processed so far */
#define APK_MPART_BOUNDARY 2 /* final part of data, before boundary */
#define APK_MPART_END 3 /* signals end of stream */
typedef int (*apk_multipart_cb)(void *ctx, int part, apk_blob_t data);
struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *,
apk_multipart_cb cb, void *ctx);
static inline struct apk_istream *apk_bstream_gunzip(struct apk_bstream *bs)
{
return apk_bstream_gunzip_mpart(bs, NULL, NULL);
}
struct apk_ostream *apk_ostream_gzip(struct apk_ostream *);
struct apk_ostream *apk_ostream_counter(off_t *);
@ -162,8 +164,6 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
struct apk_bstream *apk_bstream_from_file(int atfd, const char *file);
struct apk_bstream *apk_bstream_from_fd(int fd);
struct apk_bstream *apk_bstream_from_fd_url_if_modified(int atfd, const char *url, time_t since);
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to, int copy_meta,
apk_progress_cb cb, void *cb_ctx);
static inline struct apk_bstream *apk_bstream_from_url(const char *url)
{

View File

@ -619,7 +619,6 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
{
struct stat st = {0};
struct apk_istream *is;
struct apk_bstream *bs;
struct apk_sign_ctx sctx;
char url[PATH_MAX];
char tmpcacheitem[128], *cacheitem = &tmpcacheitem[tmpprefix.len];
@ -650,9 +649,9 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
if (verify != APK_SIGN_NONE) {
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
bs = apk_bstream_from_url_if_modified(url, st.st_mtime);
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, !autoupdate, cb, cb_ctx);
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
is = apk_istream_from_url_if_modified(url, st.st_mtime);
is = apk_istream_tee(is, db->cache_fd, tmpcacheitem, !autoupdate, cb, cb_ctx);
is = apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &sctx);
if (!IS_ERR_OR_NULL(is))
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, &db->id_cache);
else
@ -2176,22 +2175,21 @@ static int load_apkindex(void *sctx, const struct apk_file_info *fi,
return 0;
}
static int load_index(struct apk_database *db, struct apk_bstream *bs,
static int load_index(struct apk_database *db, struct apk_istream *is,
int targz, int repo)
{
int r = 0;
if (IS_ERR_OR_NULL(bs)) return bs ? PTR_ERR(bs) : -EINVAL;
if (IS_ERR_OR_NULL(is)) return is ? PTR_ERR(is) : -EINVAL;
if (targz) {
struct apk_istream *is;
struct apkindex_ctx ctx;
ctx.db = db;
ctx.repo = repo;
ctx.found = 0;
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
is = apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx);
r = apk_tar_parse(is, load_apkindex, &ctx, &db->id_cache);
apk_istream_close(is);
apk_sign_ctx_free(&ctx.sctx);
@ -2199,7 +2197,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
if (r >= 0 && ctx.found == 0)
r = -ENOMSG;
} else {
apk_db_index_read(db, apk_bstream_gunzip(bs), repo);
apk_db_index_read(db, apk_istream_gunzip(is), repo);
}
return r;
}
@ -2211,13 +2209,12 @@ int apk_db_index_read_file(struct apk_database *db, const char *file, int repo)
if (strstr(file, ".tar.gz") == NULL && strstr(file, ".gz") != NULL)
targz = 0;
return load_index(db, apk_bstream_from_file(AT_FDCWD, file), targz, repo);
return load_index(db, apk_istream_from_file(AT_FDCWD, file), targz, repo);
}
int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
{
struct apk_database *db = _db.db;
struct apk_bstream *bs = NULL;
struct apk_repository *repo;
apk_blob_t brepo, btag;
int repo_num, r, targz = 1, tag_id = 0;
@ -2273,11 +2270,7 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
r = apk_repo_format_real_url(db, repo, NULL, buf, sizeof(buf));
}
if (r == 0) {
bs = apk_bstream_from_fd_url(db->cache_fd, buf);
if (!IS_ERR_OR_NULL(bs))
r = load_index(db, bs, targz, repo_num);
else
r = PTR_ERR(bs);
r = load_index(db, apk_istream_from_fd_url(db->cache_fd, buf), targz, repo_num);
}
if (r != 0) {
@ -2760,8 +2753,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
char **script_args)
{
struct install_ctx ctx;
struct apk_bstream *bs = NULL, *cache_bs;
struct apk_istream *tar;
struct apk_istream *is = NULL, *cache_is, *tar;
struct apk_repository *repo;
struct apk_package *pkg = ipkg->pkg;
char file[PATH_MAX];
@ -2789,9 +2781,9 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (!apk_db_cache_active(db))
need_copy = FALSE;
bs = apk_bstream_from_fd_url(filefd, file);
if (IS_ERR_OR_NULL(bs)) {
r = PTR_ERR(bs);
is = apk_istream_from_fd_url(filefd, file);
if (IS_ERR_OR_NULL(is)) {
r = PTR_ERR(is);
if (r == -ENOENT && pkg->filename == NULL)
r = -EAPKSTALEINDEX;
goto err_msg;
@ -2800,9 +2792,9 @@ static int apk_db_unpack_pkg(struct apk_database *db,
apk_blob_t b = APK_BLOB_BUF(tmpcacheitem);
apk_blob_push_blob(&b, tmpprefix);
apk_pkg_format_cache_pkg(b, pkg);
cache_bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, 1, NULL, NULL);
if (!IS_ERR_OR_NULL(cache_bs))
bs = cache_bs;
cache_is = apk_istream_tee(is, db->cache_fd, tmpcacheitem, 1, NULL, NULL);
if (!IS_ERR_OR_NULL(cache_is))
is = cache_is;
else
apk_warning(PKG_VER_FMT": unable to cache: %s",
PKG_VER_PRINTF(pkg), apk_error_str(errno));
@ -2819,7 +2811,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
.cb_ctx = cb_ctx,
};
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &pkg->csum, db->keys_fd);
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
tar = apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, &ctx.sctx);
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, &db->id_cache);
apk_sign_ctx_free(&ctx.sctx);
apk_istream_close(tar);

View File

@ -20,7 +20,7 @@
struct apk_gzip_istream {
struct apk_istream is;
struct apk_bstream *bs;
struct apk_istream *zis;
z_stream zs;
apk_multipart_cb cb;
@ -32,7 +32,7 @@ struct apk_gzip_istream {
static void gzi_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
{
struct apk_gzip_istream *gis = container_of(is, struct apk_gzip_istream, is);
apk_bstream_get_meta(gis->bs, meta);
apk_istream_get_meta(gis->zis, meta);
}
static int gzi_boundary_change(struct apk_gzip_istream *gis)
@ -68,7 +68,7 @@ static ssize_t gzi_read(struct apk_istream *is, void *ptr, size_t size)
APK_BLOB_PTR_LEN(gis->cbprev,
(void *)gis->zs.next_in - gis->cbprev));
}
blob = apk_bstream_read(gis->bs, APK_BLOB_NULL);
blob = apk_istream_get_all(gis->zis);
gis->cbprev = blob.ptr;
gis->zs.avail_in = blob.len;
gis->zs.next_in = (void *) gis->cbprev;
@ -87,9 +87,8 @@ static ssize_t gzi_read(struct apk_istream *is, void *ptr, size_t size)
switch (r) {
case Z_STREAM_END:
/* Digest the inflated bytes */
if ((gis->bs->flags & APK_BSTREAM_EOF) &&
gis->zs.avail_in == 0)
gis->is.err = 1;
if (gis->zis->err && gis->zs.avail_in == 0)
gis->is.err = gis->zis->err;
if (gis->cb != NULL) {
gis->cbarg = APK_BLOB_PTR_LEN(gis->cbprev, (void *) gis->zs.next_in - gis->cbprev);
gis->cbprev = gis->zs.next_in;
@ -125,7 +124,7 @@ static void gzi_close(struct apk_istream *is)
struct apk_gzip_istream *gis = container_of(is, struct apk_gzip_istream, is);
inflateEnd(&gis->zs);
apk_bstream_close(gis->bs);
apk_istream_close(gis->zis);
free(gis);
}
@ -135,12 +134,11 @@ static const struct apk_istream_ops gunzip_istream_ops = {
.close = gzi_close,
};
struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
apk_multipart_cb cb, void *ctx)
struct apk_istream *apk_istream_gunzip_mpart(struct apk_istream *is, apk_multipart_cb cb, void *ctx)
{
struct apk_gzip_istream *gis;
if (IS_ERR_OR_NULL(bs)) return ERR_CAST(bs);
if (IS_ERR_OR_NULL(is)) return ERR_CAST(is);
gis = malloc(sizeof(*gis) + apk_io_bufsize);
if (!gis) goto err;
@ -149,7 +147,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
.is.ops = &gunzip_istream_ops,
.is.buf = (uint8_t*)(gis + 1),
.is.buf_size = apk_io_bufsize,
.bs = bs,
.zis = is,
.cb = cb,
.cbctx = ctx,
};
@ -161,7 +159,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
return &gis->is;
err:
apk_bstream_close(bs);
apk_istream_close(is);
return ERR_PTR(-ENOMEM);
}

197
src/io.c
View File

@ -226,7 +226,7 @@ static const struct apk_istream_ops segment_istream_ops = {
.close = segment_close,
};
void apk_istream_segment(struct apk_segment_istream *sis, struct apk_istream *is, size_t len, time_t mtime)
struct apk_istream *apk_istream_segment(struct apk_segment_istream *sis, struct apk_istream *is, size_t len, time_t mtime)
{
*sis = (struct apk_segment_istream) {
.is.ops = &segment_istream_ops,
@ -245,6 +245,114 @@ void apk_istream_segment(struct apk_segment_istream *sis, struct apk_istream *is
is->ptr = is->end = 0;
}
sis->bytes_left -= sis->is.end - sis->is.ptr;
return &sis->is;
}
struct apk_tee_istream {
struct apk_istream is;
struct apk_istream *inner_is;
int fd, copy_meta;
size_t size;
apk_progress_cb cb;
void *cb_ctx;
};
static void tee_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
{
struct apk_tee_istream *tee = container_of(is, struct apk_tee_istream, is);
apk_istream_get_meta(tee->inner_is, meta);
}
static ssize_t __tee_write(struct apk_tee_istream *tee, void *ptr, size_t size)
{
ssize_t w = write(tee->fd, ptr, size);
if (size != w) {
if (w < 0) return w;
return -ENOSPC;
}
tee->size += size;
if (tee->cb) tee->cb(tee->cb_ctx, tee->size);
return size;
}
static ssize_t tee_read(struct apk_istream *is, void *ptr, size_t size)
{
struct apk_tee_istream *tee = container_of(is, struct apk_tee_istream, is);
ssize_t r;
r = tee->inner_is->ops->read(tee->inner_is, ptr, size);
if (r <= 0) return r;
return __tee_write(tee, ptr, r);
}
static void tee_close(struct apk_istream *is)
{
struct apk_tee_istream *tee = container_of(is, struct apk_tee_istream, is);
struct apk_file_meta meta;
if (tee->copy_meta) {
apk_istream_get_meta(tee->inner_is, &meta);
apk_file_meta_to_fd(tee->fd, &meta);
}
apk_istream_close(tee->inner_is);
close(tee->fd);
free(tee);
}
static const struct apk_istream_ops tee_istream_ops = {
.get_meta = tee_get_meta,
.read = tee_read,
.close = tee_close,
};
struct apk_istream *apk_istream_tee(struct apk_istream *from, int atfd, const char *to, int copy_meta, apk_progress_cb cb, void *cb_ctx)
{
struct apk_tee_istream *tee;
int fd, r;
if (IS_ERR_OR_NULL(from)) return ERR_CAST(from);
fd = openat(atfd, to, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
r = -errno;
goto err_is;
}
tee = malloc(sizeof *tee);
if (!tee) {
r = -ENOMEM;
goto err_fd;
}
*tee = (struct apk_tee_istream) {
.is.ops = &tee_istream_ops,
.is.buf = from->buf,
.is.buf_size = from->buf_size,
.is.ptr = from->ptr,
.is.end = from->end,
.inner_is = from,
.fd = fd,
.copy_meta = copy_meta,
.cb = cb,
.cb_ctx = cb_ctx,
};
if (from->ptr != from->end) {
r = __tee_write(tee, from->ptr, from->end - from->ptr);
if (r < 0) goto err_free;
}
return &tee->is;
err_free:
free(tee);
err_fd:
close(fd);
err_is:
apk_istream_close(from);
return ERR_PTR(r);
}
struct apk_fd_istream {
@ -571,91 +679,6 @@ struct apk_bstream *apk_bstream_from_file(int atfd, const char *file)
}
struct apk_tee_bstream {
struct apk_bstream bs;
struct apk_bstream *inner_bs;
int fd, copy_meta;
size_t size;
apk_progress_cb cb;
void *cb_ctx;
};
static void tee_get_meta(struct apk_bstream *bs, struct apk_file_meta *meta)
{
struct apk_tee_bstream *tbs = container_of(bs, struct apk_tee_bstream, bs);
apk_bstream_get_meta(tbs->inner_bs, meta);
}
static apk_blob_t tee_read(struct apk_bstream *bs, apk_blob_t token)
{
struct apk_tee_bstream *tbs = container_of(bs, struct apk_tee_bstream, bs);
apk_blob_t blob;
blob = apk_bstream_read(tbs->inner_bs, token);
if (!APK_BLOB_IS_NULL(blob)) {
tbs->size += write(tbs->fd, blob.ptr, blob.len);
if (tbs->cb) tbs->cb(tbs->cb_ctx, tbs->size);
}
return blob;
}
static void tee_close(struct apk_bstream *bs)
{
struct apk_file_meta meta;
struct apk_tee_bstream *tbs = container_of(bs, struct apk_tee_bstream, bs);
if (tbs->copy_meta) {
apk_bstream_get_meta(tbs->inner_bs, &meta);
apk_file_meta_to_fd(tbs->fd, &meta);
}
apk_bstream_close(tbs->inner_bs);
close(tbs->fd);
free(tbs);
}
static const struct apk_bstream_ops tee_bstream_ops = {
.get_meta = tee_get_meta,
.read = tee_read,
.close = tee_close,
};
struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to, int copy_meta, apk_progress_cb cb, void *cb_ctx)
{
struct apk_tee_bstream *tbs;
int fd, r;
if (IS_ERR_OR_NULL(from)) return ERR_CAST(from);
fd = openat(atfd, to, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
r = errno;
apk_bstream_close(from);
return ERR_PTR(-r);
}
tbs = malloc(sizeof(struct apk_tee_bstream));
if (!tbs) {
r = errno;
close(fd);
apk_bstream_close(from);
return ERR_PTR(-r);
}
*tbs = (struct apk_tee_bstream) {
.bs.ops = &tee_bstream_ops,
.inner_bs = from,
.fd = fd,
.copy_meta = copy_meta,
.cb = cb,
.cb_ctx = cb_ctx,
};
return &tbs->bs;
}
apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
{
void *ptr;
@ -911,7 +934,7 @@ int apk_dir_foreach_file(int dirfd, apk_dir_file_cb cb, void *ctx)
struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file)
{
return apk_bstream_gunzip(apk_bstream_from_file(atfd, file));
return apk_istream_gunzip(apk_istream_from_file(atfd, file));
}
struct apk_fd_ostream {

View File

@ -91,7 +91,7 @@ static void process_file(struct apk_database *db, const char *match)
struct manifest_file_ctx ctx = {match, &sctx};
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, match),
is = apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, match),
apk_sign_ctx_mpart_cb, &sctx);
if (IS_ERR_OR_NULL(is)) {

View File

@ -904,8 +904,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
{
struct read_info_ctx ctx;
struct apk_file_info fi;
struct apk_bstream *bs;
struct apk_istream *tar;
struct apk_istream *is, *tar;
int r;
r = apk_fileinfo_get(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi);
@ -918,16 +917,16 @@ int apk_pkg_read(struct apk_database *db, const char *file,
r = -ENOMEM;
if (ctx.pkg == NULL)
goto err;
bs = apk_bstream_from_file(AT_FDCWD, file);
if (IS_ERR_OR_NULL(bs)) {
r = PTR_ERR(bs) ?: -EIO;
is = apk_istream_from_file(AT_FDCWD, file);
if (IS_ERR_OR_NULL(is)) {
r = PTR_ERR(is) ?: -EIO;
goto err;
}
ctx.db = db;
ctx.pkg->size = fi.size;
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx);
tar = apk_istream_gunzip_mpart(is, apk_sign_ctx_mpart_cb, sctx);
r = apk_tar_parse(tar, read_info_entry, &ctx, &db->id_cache);
apk_istream_close(tar);
if (r < 0 && r != -ECANCELED)

View File

@ -152,12 +152,5 @@ struct apk_istream *apk_istream_from_fd_url_if_modified(int atfd, const char *ur
struct apk_istream *apk_istream_from_url_gz(const char *file)
{
return apk_bstream_gunzip(apk_bstream_from_url(file));
}
struct apk_bstream *apk_bstream_from_fd_url_if_modified(int atfd, const char *url, time_t since)
{
if (apk_url_local_file(url) != NULL)
return apk_bstream_from_file(atfd, apk_url_local_file(url));
return apk_bstream_from_istream(apk_istream_fetch(url, since));
return apk_istream_gunzip(apk_istream_from_url(file));
}

View File

@ -26,7 +26,7 @@ static int verify_main(void *ctx, struct apk_database *db, struct apk_string_arr
foreach_array_item(parg, args) {
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
is = apk_bstream_gunzip_mpart(apk_bstream_from_file(AT_FDCWD, *parg),
is = apk_istream_gunzip_mpart(apk_istream_from_file(AT_FDCWD, *parg),
apk_sign_ctx_mpart_cb, &sctx);
if (IS_ERR_OR_NULL(is)) {
if (apk_verbosity >= 1)