...
 
Commits (33)
......@@ -4,7 +4,7 @@
-include config.mk
PACKAGE := apk-tools
VERSION := 2.7.1
VERSION := 2.7.6
##
# Default directories
......@@ -41,3 +41,7 @@ check test: FORCE
static:
$(Q)$(MAKE) STATIC=y
tag: check
git commit . -m "apk-tools-$(VERSION)"
git tag -s v$(VERSION) -m "apk-tools-$(VERSION)"
......@@ -217,6 +217,13 @@ static int option_parse_commit(void *ctx, struct apk_db_options *dbopts, int opt
case 0x113:
apk_flags |= APK_NO_SCRIPTS;
break;
case 0x117:
apk_flags |= APK_NO_COMMIT_HOOKS;
break;
case 0x118:
dbopts->open_flags |= APK_OPENF_CREATE;
apk_flags |= APK_FORCE | APK_NO_COMMIT_HOOKS;
break;
default:
return -ENOTSUP;
}
......@@ -228,6 +235,9 @@ static const struct apk_option options_commit[] = {
{ 0x102, "clean-protected", "Do not create .apk-new files in configuration dirs" },
{ 0x111, "overlay-from-stdin", "Read list of overlay files from stdin" },
{ 0x113, "no-scripts", "Do not execute any scripts" },
{ 0x117, "no-commit-hooks", "Skip pre/post hook scripts (but not other scripts)" },
{ 0x118, "initramfs-diskless-boot",
"Enables options for diskeless initramfs boot (e.g. skip hooks)" },
};
const struct apk_option_group optgroup_commit = {
......@@ -548,7 +558,7 @@ int main(int argc, char **argv)
struct apk_bstream *bs = apk_bstream_from_file(AT_FDCWD, test_installed_db);
if (!IS_ERR_OR_NULL(bs)) {
apk_db_index_read(&db, bs, -1);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
for (i = 0; i < test_repos->num; i++) {
......@@ -576,7 +586,7 @@ int main(int argc, char **argv)
}
apk_db_index_read(&db, bs, repo);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
if (repo != -2) {
if (!(apk_flags & APK_NO_NETWORK))
db.available_repos |= BIT(repo);
......@@ -602,5 +612,8 @@ err:
free(ctx);
fetchConnectionCacheClose();
if (r < 0) r = 250;
if (r > 99) r = 99;
return r;
}
......@@ -28,7 +28,8 @@ int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae,
int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *suffix, struct apk_istream *is,
const char *extract_name, const char *hardlink_name,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx);
#endif
......@@ -77,6 +77,7 @@ extern char **apk_argv;
#define APK_OVERLAY_FROM_STDIN 0x2000
#define APK_NO_SCRIPTS 0x4000
#define APK_NO_CACHE 0x8000
#define APK_NO_COMMIT_HOOKS 0x00010000
/* default architecture for APK packages. */
#if defined(__x86_64__)
......
......@@ -54,27 +54,39 @@ struct apk_file_info {
struct apk_xattr_array *xattrs;
};
struct apk_istream {
struct apk_istream_ops {
void (*get_meta)(void *stream, struct apk_file_meta *meta);
ssize_t (*read)(void *stream, void *ptr, size_t size);
void (*close)(void *stream);
};
struct apk_istream {
const struct apk_istream_ops *ops;
};
#define APK_BSTREAM_SINGLE_READ 0x0001
#define APK_BSTREAM_EOF 0x0002
struct apk_bstream {
unsigned int flags;
struct apk_bstream_ops {
void (*get_meta)(void *stream, struct apk_file_meta *meta);
apk_blob_t (*read)(void *stream, apk_blob_t token);
void (*close)(void *stream, size_t *size);
};
struct apk_ostream {
struct apk_bstream {
unsigned int flags;
const struct apk_bstream_ops *ops;
};
struct apk_ostream_ops {
ssize_t (*write)(void *stream, const void *buf, size_t size);
int (*close)(void *stream);
};
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 */
......@@ -96,11 +108,11 @@ struct apk_istream *apk_istream_from_file(int atfd, const char *file);
struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file);
struct apk_istream *apk_istream_from_fd_url_if_modified(int atfd, const char *url, time_t since);
struct apk_istream *apk_istream_from_url_gz(const char *url);
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
ssize_t apk_istream_skip(struct apk_istream *istream, size_t size);
#define APK_SPLICE_ALL 0xffffffff
size_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx);
ssize_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx);
static inline struct apk_istream *apk_istream_from_fd(int fd)
{
......@@ -118,6 +130,18 @@ static inline struct apk_istream *apk_istream_from_url_if_modified(const char *u
{
return apk_istream_from_fd_url_if_modified(AT_FDCWD, url, since);
}
static inline void apk_istream_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
{
is->ops->get_meta(is, meta);
}
static inline ssize_t apk_istream_read(struct apk_istream *is, void *ptr, size_t size)
{
return is->ops->read(is, ptr, size);
}
static inline void apk_istream_close(struct apk_istream *is)
{
is->ops->close(is);
}
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int));
......@@ -143,11 +167,31 @@ static inline struct apk_bstream *apk_bstream_from_url_if_modified(const char *u
{
return apk_bstream_from_fd_url_if_modified(AT_FDCWD, url, since);
}
static inline void apk_bstream_get_meta(struct apk_bstream *bs, struct apk_file_meta *meta)
{
bs->ops->get_meta(bs, meta);
}
static inline apk_blob_t apk_bstream_read(struct apk_bstream *bs, apk_blob_t token)
{
return bs->ops->read(bs, token);
}
static inline void apk_bstream_close(struct apk_bstream *bs, size_t *size)
{
bs->ops->close(bs, size);
}
struct apk_ostream *apk_ostream_to_fd(int fd);
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, const char *tmpfile, mode_t mode);
struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, const char *tmpfile, mode_t mode);
size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string);
static inline ssize_t apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size)
{
return os->ops->write(os, buf, size);
}
static inline int apk_ostream_close(struct apk_ostream *os)
{
return os->ops->close(os);
}
apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
apk_blob_t apk_blob_from_file(int atfd, const char *file);
......
......@@ -41,6 +41,7 @@ struct apk_solver_name_state {
unsigned no_iif : 1;
unsigned has_options : 1;
unsigned reverse_deps_done : 1;
unsigned has_virtual_provides : 1;
};
struct apk_solver_package_state {
......
......@@ -59,7 +59,7 @@ struct apk_tar_digest_info {
#define GET_OCTAL(s) get_octal(s, sizeof(s))
#define PUT_OCTAL(s,v) put_octal(s, sizeof(s), v)
static int get_octal(char *s, size_t l)
static unsigned int get_octal(char *s, size_t l)
{
apk_blob_t b = APK_BLOB_PTR_LEN(s, l);
return apk_blob_pull_uint(&b, 8);
......@@ -108,7 +108,7 @@ static ssize_t tar_entry_read(void *stream, void *ptr, size_t size)
if (size == 0)
return 0;
r = teis->tar_is->read(teis->tar_is, ptr, size);
r = apk_istream_read(teis->tar_is, ptr, size);
if (r <= 0) {
/* If inner stream returned zero (end-of-stream), we
* are getting short read, because tar header indicated
......@@ -133,7 +133,13 @@ static void tar_entry_close(void *stream)
{
}
static int blob_realloc(apk_blob_t *b, int newsize)
static const struct apk_istream_ops tar_istream_ops = {
.get_meta = tar_entry_get_meta,
.read = tar_entry_read,
.close = tar_entry_close,
};
static int blob_realloc(apk_blob_t *b, size_t newsize)
{
char *tmp;
if (b->len >= newsize) return 0;
......@@ -153,8 +159,9 @@ static void handle_extended_header(struct apk_file_info *fi, apk_blob_t hdr)
unsigned int len = apk_blob_pull_uint(&hdr, 10);
apk_blob_pull_char(&hdr, ' ');
if (!apk_blob_split(hdr, APK_BLOB_STR("="), &name, &hdr)) break;
if (len < hdr.ptr - start + 1) break;
len -= hdr.ptr - start + 1;
if (len < 0 || hdr.len < len) break;
if (hdr.len < len) break;
value = APK_BLOB_PTR_LEN(hdr.ptr, len);
hdr = APK_BLOB_PTR_LEN(hdr.ptr+len, hdr.len-len);
apk_blob_pull_char(&hdr, '\n');
......@@ -191,9 +198,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
{
struct apk_file_info entry;
struct apk_tar_entry_istream teis = {
.is.get_meta = tar_entry_get_meta,
.is.read = tar_entry_read,
.is.close = tar_entry_close,
.is.ops = &tar_istream_ops,
.tar_is = is,
};
struct tar_header buf;
......@@ -202,11 +207,13 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
int end = 0, r;
size_t toskip, paxlen = 0;
apk_blob_t pax = APK_BLOB_NULL, longname = APK_BLOB_NULL;
char filename[sizeof buf.name + sizeof buf.prefix + 2];
odi = (struct apk_tar_digest_info *) &buf.linkname[3];
EVP_MD_CTX_init(&teis.mdctx);
memset(&entry, 0, sizeof(entry));
while ((r = is->read(is, &buf, 512)) == 512) {
entry.name = buf.name;
while ((r = apk_istream_read(is, &buf, 512)) == 512) {
offset += 512;
if (buf.name[0] == '\0') {
if (end) break;
......@@ -220,19 +227,27 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
.gid = apk_resolve_gid(idc, buf.gname, GET_OCTAL(buf.gid)),
.mode = GET_OCTAL(buf.mode) & 07777,
.mtime = GET_OCTAL(buf.mtime),
.name = entry.name ?: buf.name,
.name = entry.name,
.uname = buf.uname,
.gname = buf.gname,
.device = makedev(GET_OCTAL(buf.devmajor),
GET_OCTAL(buf.devminor)),
.xattrs = entry.xattrs,
};
if (buf.prefix[0] && buf.typeflag != 'x' && buf.typeflag != 'g') {
snprintf(filename, sizeof filename, "%.*s/%.*s",
(int) sizeof buf.prefix, buf.prefix,
(int) sizeof buf.name, buf.name);
entry.name = filename;
}
buf.mode[0] = 0; /* to nul terminate 100-byte buf.name */
buf.magic[0] = 0; /* to nul terminate 100-byte buf.linkname */
teis.csum = NULL;
teis.mtime = entry.mtime;
apk_xattr_array_resize(&entry.xattrs, 0);
if (entry.size >= SSIZE_MAX-512) goto err;
if (paxlen) {
handle_extended_header(&entry, APK_BLOB_PTR_LEN(pax.ptr, paxlen));
apk_fileinfo_hash_xattr(&entry);
......@@ -240,9 +255,10 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
switch (buf.typeflag) {
case 'L': /* GNU long name extension */
if (blob_realloc(&longname, entry.size+1)) goto err_nomem;
if ((r = blob_realloc(&longname, entry.size+1)) != 0 ||
(r = apk_istream_read(is, longname.ptr, entry.size)) != entry.size)
goto err;
entry.name = longname.ptr;
is->read(is, entry.name, entry.size);
entry.name[entry.size] = 0;
offset += entry.size;
entry.size = 0;
......@@ -284,19 +300,29 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
case '5': /* directory */
entry.mode |= S_IFDIR;
break;
case '6': /* fifo */
entry.mode |= S_IFIFO;
break;
case 'g': /* global pax header */
break;
case 'x': /* file specific pax header */
paxlen = entry.size;
entry.size = 0;
if (blob_realloc(&pax, (paxlen + 511) & -512)) goto err_nomem;
is->read(is, pax.ptr, paxlen);
if ((r = blob_realloc(&pax, (paxlen + 511) & -512)) != 0 ||
(r = apk_istream_read(is, pax.ptr, paxlen)) != paxlen)
goto err;
offset += paxlen;
break;
default:
break;
}
if (strnlen(entry.name, PATH_MAX) >= PATH_MAX-10 ||
(entry.link_target && strnlen(entry.link_target, PATH_MAX) >= PATH_MAX-10)) {
r = -ENAMETOOLONG;
goto err;
}
teis.bytes_left = entry.size;
if (entry.mode & S_IFMT) {
/* callback parser function */
......@@ -316,31 +342,29 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
if ((offset + toskip) & 511)
toskip += 512 - ((offset + toskip) & 511);
offset += toskip;
if (toskip != 0)
is->read(is, NULL, toskip);
if (toskip != 0) {
if ((r = apk_istream_read(is, NULL, toskip)) != toskip)
goto err;
}
}
/* Read remaining end-of-archive records, to ensure we read all of
* the file. The underlying istream is likely doing checksumming. */
if (r == 512) {
while ((r = is->read(is, &buf, 512)) == 512) {
while ((r = apk_istream_read(is, &buf, 512)) == 512) {
if (buf.name[0] != 0) break;
}
}
/* Check that there was no partial (or non-zero) record */
if (r > 0) r = -EBADMSG;
if (r == 0) goto ok;
err:
/* Check that there was no partial (or non-zero) record */
if (r >= 0) r = -EBADMSG;
ok:
EVP_MD_CTX_cleanup(&teis.mdctx);
free(pax.ptr);
free(longname.ptr);
apk_fileinfo_free(&entry);
return r;
err_nomem:
r = -ENOMEM;
goto err;
}
int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae,
......@@ -379,15 +403,15 @@ int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae,
put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum);
}
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
if (ae == NULL) {
/* End-of-archive is two empty headers */
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
} else if (data != NULL) {
if (os->write(os, data, ae->size) != ae->size)
if (apk_ostream_write(os, data, ae->size) != ae->size)
return -1;
if (apk_tar_write_padding(os, ae) != 0)
return -1;
......@@ -403,30 +427,22 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
pad = 512 - (ae->size & 511);
if (pad != 512 &&
os->write(os, padding, pad) != pad)
apk_ostream_write(os, padding, pad) != pad)
return -1;
return 0;
}
int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
const char *suffix, struct apk_istream *is,
const char *extract_name, const char *link_target,
struct apk_istream *is,
apk_progress_cb cb, void *cb_ctx)
{
struct apk_xattr *xattr;
char *fn = ae->name;
const char *fn = extract_name ?: ae->name;
int fd, r = -1, atflags = 0, ret = 0;
if (suffix != NULL) {
fn = alloca(PATH_MAX);
snprintf(fn, PATH_MAX, "%s%s", ae->name, suffix);
}
if ((!S_ISDIR(ae->mode) && !S_ISREG(ae->mode)) ||
(ae->link_target != NULL)) {
/* non-standard entries need to be deleted first */
unlinkat(atfd, fn, 0);
}
if (unlinkat(atfd, fn, 0) != 0 && errno != ENOENT) return -errno;
switch (ae->mode & S_IFMT) {
case S_IFDIR:
......@@ -436,7 +452,7 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
break;
case S_IFREG:
if (ae->link_target == NULL) {
int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC;
int flags = O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC | O_EXCL;
fd = openat(atfd, fn, flags, ae->mode & 07777);
if (fd < 0) {
......@@ -447,26 +463,19 @@ int apk_archive_entry_extract(int atfd, const struct apk_file_info *ae,
if (r != ae->size) ret = r < 0 ? r : -ENOSPC;
close(fd);
} else {
char *link_target = ae->link_target;
if (suffix != NULL) {
link_target = alloca(PATH_MAX);
snprintf(link_target, PATH_MAX, "%s%s",
ae->link_target, suffix);
}
r = linkat(atfd, link_target, atfd, fn, 0);
r = linkat(atfd, link_target ?: ae->link_target, atfd, fn, 0);
if (r < 0) ret = -errno;
}
break;
case S_IFLNK:
r = symlinkat(ae->link_target, atfd, fn);
r = symlinkat(link_target ?: ae->link_target, atfd, fn);
if (r < 0) ret = -errno;
atflags |= AT_SYMLINK_NOFOLLOW;
break;
case S_IFSOCK:
case S_IFBLK:
case S_IFCHR:
case S_IFIFO:
r = mknodat(atfd, fn, ae->mode & 07777, ae->device);
r = mknodat(atfd, fn, ae->mode, ae->device);
if (r < 0) ret = -errno;
break;
}
......
......@@ -232,10 +232,14 @@ static int run_commit_hook(void *ctx, int dirfd, const char *file)
struct apk_database *db = hook->db;
char fn[PATH_MAX], *argv[] = { fn, (char *) commit_hook_str[hook->type], NULL };
if ((apk_flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0)
return 0;
if (file[0] == '.') return 0;
if ((apk_flags & (APK_NO_SCRIPTS | APK_SIMULATE)) != 0) return 0;
snprintf(fn, sizeof(fn), "etc/apk/commit_hooks.d" "/%s", file);
if ((apk_flags & APK_NO_COMMIT_HOOKS) != 0) {
apk_message("Skipping: %s %s", fn, commit_hook_str[hook->type]);
return 0;
}
if (apk_verbosity >= 2) apk_message("Executing: %s %s", fn, commit_hook_str[hook->type]);
if (apk_db_run_script(db, fn, argv) < 0 && hook->type == PRE_COMMIT_HOOK)
......@@ -279,7 +283,7 @@ int apk_solver_commit_changeset(struct apk_database *db,
size_diff -= change->old_pkg->installed_size / 1024;
}
size_unit = 'K';
if (abs(size_diff) > 10000) {
if (labs(size_diff) > 10000) {
size_diff /= 1024;
size_unit = 'M';
}
......@@ -350,7 +354,8 @@ all_done:
if (!db->performing_self_upgrade) {
if (errors)
snprintf(buf, sizeof(buf), "%d errors;", errors);
snprintf(buf, sizeof(buf), "%d error%s;", errors,
errors > 1 ? "s" : "");
else
strcpy(buf, "OK:");
if (apk_verbosity > 1) {
......@@ -455,7 +460,8 @@ static void print_conflicts(struct print_state *ps, struct apk_package *pkg)
if (d->version == &apk_null_blob &&
p->version == &apk_null_blob)
continue;
if (once && p->pkg == pkg) {
if (once && p->pkg == pkg &&
p->version == d->version) {
once = 0;
continue;
}
......
This diff is collapsed.
......@@ -178,11 +178,11 @@ static int fetch_package(apk_hash_item item, void *pctx)
r = apk_istream_splice(is, fd, pkg->size, progress_cb, ctx);
if (fd != STDOUT_FILENO) {
struct apk_file_meta meta;
is->get_meta(is, &meta);
apk_istream_get_meta(is, &meta);
apk_file_meta_to_fd(fd, &meta);
close(fd);
}
is->close(is);
apk_istream_close(is);
if (r != pkg->size) {
unlinkat(ctx->outdir_fd, filename, 0);
......@@ -242,12 +242,15 @@ static void mark_name_recursive(struct apk_database *db, const char *match, stru
apk_dependency_array_init(&world);
*apk_dependency_array_add(&world) = dep;
r = apk_solver_solve(db, 0, world, &changeset);
apk_dependency_array_free(&world);
if (r == 0) {
foreach_array_item(change, changeset.changes)
mark_package(ctx, change->new_pkg);
} else
} else {
mark_error(ctx, match, name);
if (apk_verbosity > 1)
apk_solver_print_errors(db, &changeset, world);
}
apk_dependency_array_free(&world);
apk_change_array_free(&changeset.changes);
}
......
......@@ -67,6 +67,7 @@ static const struct apk_option_group optgroup_applet = {
static int mark_recalculate(apk_hash_item item, void *ctx)
{
struct apk_db_dir *dir = (struct apk_db_dir *) item;
if (dir->refs == 0) return 0;
dir->update_permissions = 1;
return 0;
}
......
......@@ -34,7 +34,17 @@ static void gzi_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
gis->bs->get_meta(gis->bs, meta);
apk_bstream_get_meta(gis->bs, meta);
}
static int gzi_boundary_change(struct apk_gzip_istream *gis)
{
int r;
r = gis->cb(gis->cbctx, gis->err ? APK_MPART_END : APK_MPART_BOUNDARY, gis->cbarg);
if (r > 0) r = -ECANCELED;
if (r != 0) gis->err = r;
return r;
}
static ssize_t gzi_read(void *stream, void *ptr, size_t size)
......@@ -57,15 +67,8 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
while (gis->zs.avail_out != 0 && gis->err == 0) {
if (!APK_BLOB_IS_NULL(gis->cbarg)) {
r = gis->cb(gis->cbctx,
gis->err ? APK_MPART_END : APK_MPART_BOUNDARY,
gis->cbarg);
if (r > 0)
r = -ECANCELED;
if (r != 0) {
gis->err = r;
if (gzi_boundary_change(gis))
goto ret;
}
gis->cbarg = APK_BLOB_NULL;
}
if (gis->zs.avail_in == 0) {
......@@ -77,7 +80,7 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
APK_BLOB_PTR_LEN(gis->cbprev,
(void *)gis->zs.next_in - gis->cbprev));
}
blob = gis->bs->read(gis->bs, APK_BLOB_NULL);
blob = apk_bstream_read(gis->bs, APK_BLOB_NULL);
gis->cbprev = blob.ptr;
gis->zs.avail_in = blob.len;
gis->zs.next_in = (void *) gis->cbprev;
......@@ -86,14 +89,8 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
goto ret;
} else if (gis->zs.avail_in == 0) {
gis->err = 1;
if (gis->cb != NULL) {
r = gis->cb(gis->cbctx, APK_MPART_END,
APK_BLOB_NULL);
if (r > 0)
r = -ECANCELED;
if (r != 0)
gis->err = r;
}
gis->cbarg = APK_BLOB_NULL;
gzi_boundary_change(gis);
goto ret;
}
}
......@@ -115,11 +112,7 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
* For boundaries it should be postponed to not
* be called until next gzip read is started. */
if (gis->err) {
r = gis->cb(gis->cbctx,
gis->err ? APK_MPART_END : APK_MPART_BOUNDARY,
gis->cbarg);
if (r > 0)
r = -ECANCELED;
gzi_boundary_change(gis);
goto ret;
}
inflateEnd(&gis->zs);
......@@ -147,10 +140,16 @@ static void gzi_close(void *stream)
container_of(stream, struct apk_gzip_istream, is);
inflateEnd(&gis->zs);
gis->bs->close(gis->bs, NULL);
apk_bstream_close(gis->bs, NULL);
free(gis);
}
static const struct apk_istream_ops gunzip_istream_ops = {
.get_meta = gzi_get_meta,
.read = gzi_read,
.close = gzi_close,
};
struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
apk_multipart_cb cb, void *ctx)
{
......@@ -162,9 +161,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
if (!gis) goto err;
*gis = (struct apk_gzip_istream) {
.is.get_meta = gzi_get_meta,
.is.read = gzi_read,
.is.close = gzi_close,
.is.ops = &gunzip_istream_ops,
.bs = bs,
.cb = cb,
.cbctx = ctx,
......@@ -177,7 +174,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
return &gis->is;
err:
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
return ERR_PTR(-ENOMEM);
}
......@@ -203,7 +200,7 @@ static ssize_t gzo_write(void *stream, const void *ptr, size_t size)
return -EIO;
have = sizeof(buffer) - gos->zs.avail_out;
if (have != 0) {
r = gos->output->write(gos->output, buffer, have);
r = apk_ostream_write(gos->output, buffer, have);
if (r != have)
return -EIO;
}
......@@ -224,10 +221,10 @@ static int gzo_close(void *stream)
gos->zs.next_out = buffer;
r = deflate(&gos->zs, Z_FINISH);
have = sizeof(buffer) - gos->zs.avail_out;
if (gos->output->write(gos->output, buffer, have) != have)
if (apk_ostream_write(gos->output, buffer, have) != have)
rc = -EIO;
} while (r == Z_OK);
r = gos->output->close(gos->output);
r = apk_ostream_close(gos->output);
if (r != 0)
rc = r;
......@@ -237,6 +234,11 @@ static int gzo_close(void *stream)
return rc;
}
static const struct apk_ostream_ops gzip_ostream_ops = {
.write = gzo_write,
.close = gzo_close,
};
struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
{
struct apk_gzip_ostream *gos;
......@@ -247,8 +249,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
if (gos == NULL) goto err;
*gos = (struct apk_gzip_ostream) {
.os.write = gzo_write,
.os.close = gzo_close,
.os.ops = &gzip_ostream_ops,
.output = output,
};
......@@ -260,7 +261,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
return &gos->os;
err:
output->close(output);
apk_ostream_close(output);
return ERR_PTR(-ENOMEM);
}
......@@ -192,9 +192,9 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
errors++;
} else {
newpkgs++;
if (ictx->rewrite_arch != NULL)
pkg->arch = ictx->rewrite_arch;
}
if (ictx->rewrite_arch != NULL)
pkg->arch = ictx->rewrite_arch;
apk_sign_ctx_free(&sctx);
}
}
......@@ -215,7 +215,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
fi.name = "APKINDEX";
counter = apk_ostream_counter(&fi.size);
r = apk_db_index_write(db, counter);
counter->close(counter);
apk_ostream_close(counter);
if (r >= 0) {
os = apk_ostream_gzip(os);
......@@ -237,7 +237,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
} else {
r = apk_db_index_write(db, os);
}
os->close(os);
apk_ostream_close(os);
if (r < 0) {
apk_error("Index generation failed: %s", apk_error_str(r));
......@@ -249,7 +249,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
if (counts.unsatisfied != 0)
apk_warning("Total of %d unsatisfiable package "
"names. Your repository maybe broken.",
"names. Your repository may be broken.",
counts.unsatisfied);
apk_message("Index has %d packages (of which %d are new)",
total, newpkgs);
......
......@@ -140,8 +140,8 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
os = apk_ostream_to_fd(STDOUT_FILENO);
if (!IS_ERR_OR_NULL(os)) {
apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1));
os->write(os, "\n", 1);
os->close(os);
apk_ostream_write(os, "\n", 1);
apk_ostream_close(os);
}
}
apk_dependency_array_free(&deps);
......@@ -472,7 +472,7 @@ static const struct apk_option_group optgroup_applet = {
static struct apk_applet apk_info = {
.name = "info",
.help = "Give detailed information about PACKAGEs or repositores",
.help = "Give detailed information about PACKAGEs or repositories",
.arguments = "PACKAGE...",
.open_flags = APK_OPENF_READ,
.context_size = sizeof(struct info_ctx),
......
......@@ -21,6 +21,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/xattr.h>
#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
......@@ -110,6 +111,12 @@ static void fdi_close(void *stream)
free(fis);
}
static const struct apk_istream_ops fd_istream_ops = {
.get_meta = fdi_get_meta,
.read = fdi_read,
.close = fdi_close,
};
struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int))
{
struct apk_fd_istream *fis;
......@@ -123,9 +130,7 @@ struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_s
}
*fis = (struct apk_fd_istream) {
.is.get_meta = fdi_get_meta,
.is.read = fdi_read,
.is.close = fdi_close,
.is.ops = &fd_istream_ops,
.fd = fd,
.pid = pid,
.translate_status = translate_status,
......@@ -144,32 +149,29 @@ struct apk_istream *apk_istream_from_file(int atfd, const char *file)
return apk_istream_from_fd(fd);
}
size_t apk_istream_skip(struct apk_istream *is, size_t size)
ssize_t apk_istream_skip(struct apk_istream *is, size_t size)
{
unsigned char buf[2048];
size_t done = 0, r, togo;
size_t done = 0, togo;
ssize_t r;
while (done < size) {
togo = size - done;
if (togo > sizeof(buf))
togo = sizeof(buf);
r = is->read(is, buf, togo);
if (r < 0)
return r;
togo = MIN(size - done, sizeof buf);
r = apk_istream_read(is, buf, togo);
if (r <= 0) return r ?: -EIO;
done += r;
if (r != togo)
break;
}
return done;
}
size_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx)
ssize_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx)
{
static void *splice_buffer = NULL;
struct apk_istream *is = (struct apk_istream *) stream;
unsigned char *buf, *mmapbase = MAP_FAILED;
size_t bufsz, done = 0, r, togo;
size_t bufsz, done = 0, togo;
ssize_t r;
bufsz = size;
if (size > 128 * 1024) {
......@@ -181,32 +183,29 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
else if (r == EBADF || r == EFBIG || r == ENOSPC || r == EIO)
return -r;
}
if (bufsz > 2*1024*1024)
bufsz = 2*1024*1024;
bufsz = MIN(bufsz, 2*1024*1024);
buf = mmapbase;
}
if (mmapbase == MAP_FAILED) {
if (splice_buffer == NULL)
splice_buffer = malloc(256*1024);
if (!splice_buffer) splice_buffer = malloc(256*1024);
buf = splice_buffer;
if (buf == NULL)
return -ENOMEM;
if (bufsz > 256*1024)
bufsz = 256*1024;
if (!buf) return -ENOMEM;
bufsz = MIN(bufsz, 256*1024);
}
while (done < size) {
if (cb != NULL)
cb(cb_ctx, done);
togo = size - done;
if (togo > bufsz)
togo = bufsz;
r = is->read(is, buf, togo);
if (r < 0)
goto err;
if (r == 0)
if (cb != NULL) cb(cb_ctx, done);
togo = MIN(size - done, bufsz);
r = apk_istream_read(is, buf, togo);
if (r <= 0) {
if (r) goto err;
if (size != APK_SPLICE_ALL && done != size) {
r = -EBADMSG;
goto err;
}
break;
}
if (mmapbase == MAP_FAILED) {
if (write(fd, buf, r) != r) {
......@@ -218,8 +217,6 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
buf += r;
done += r;
if (r != togo)
break;
}
r = done;
err:
......@@ -240,7 +237,7 @@ static void is_bs_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_istream_bstream *isbs =
container_of(stream, struct apk_istream_bstream, bs);
return isbs->is->get_meta(isbs->is, meta);
return apk_istream_get_meta(isbs->is, meta);
}
static apk_blob_t is_bs_read(void *stream, apk_blob_t token)
......@@ -268,8 +265,8 @@ static apk_blob_t is_bs_read(void *stream, apk_blob_t token)
if (isbs->left.len != 0)
memmove(isbs->buffer, isbs->left.ptr, isbs->left.len);
isbs->left.ptr = isbs->buffer;
size = isbs->is->read(isbs->is, isbs->buffer + isbs->left.len,
sizeof(isbs->buffer) - isbs->left.len);
size = apk_istream_read(isbs->is, isbs->buffer + isbs->left.len,
sizeof(isbs->buffer) - isbs->left.len);
if (size > 0) {
isbs->size += size;
isbs->left.len += size;
......@@ -306,10 +303,16 @@ static void is_bs_close(void *stream, size_t *size)
if (size != NULL)
*size = isbs->size;
isbs->is->close(isbs->is);
apk_istream_close(isbs->is);
free(isbs);
}
static const struct apk_bstream_ops is_bstream_ops = {
.get_meta = is_bs_get_meta,
.read = is_bs_read,
.close = is_bs_close,
};
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream)
{
struct apk_istream_bstream *isbs;
......@@ -320,9 +323,7 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream)
if (isbs == NULL) return ERR_PTR(-ENOMEM);
isbs->bs = (struct apk_bstream) {
.get_meta = is_bs_get_meta,
.read = is_bs_read,
.close = is_bs_close,
.ops = &is_bstream_ops,
};
isbs->is = istream;
isbs->left = APK_BLOB_PTR_LEN(isbs->buffer, 0),
......@@ -376,6 +377,12 @@ static void mmap_close(void *stream, size_t *size)
free(mbs);
}
static const struct apk_bstream_ops mmap_bstream_ops = {
.get_meta = mmap_get_meta,
.read = mmap_read,
.close = mmap_close,
};
static struct apk_bstream *apk_mmap_bstream_from_fd(int fd)
{
struct apk_mmap_bstream *mbs;
......@@ -395,9 +402,7 @@ static struct apk_bstream *apk_mmap_bstream_from_fd(int fd)
mbs->bs = (struct apk_bstream) {
.flags = APK_BSTREAM_SINGLE_READ,
.get_meta = mmap_get_meta,
.read = mmap_read,
.close = mmap_close,
.ops = &mmap_bstream_ops,
};
mbs->fd = fd;
mbs->size = st.st_size;
......@@ -446,7 +451,7 @@ static void tee_get_meta(void *stream, struct apk_file_meta *meta)
{
struct apk_tee_bstream *tbs =
container_of(stream, struct apk_tee_bstream, bs);
tbs->inner_bs->get_meta(tbs->inner_bs, meta);
apk_bstream_get_meta(tbs->inner_bs, meta);
}
static apk_blob_t tee_read(void *stream, apk_blob_t token)
......@@ -455,11 +460,10 @@ static apk_blob_t tee_read(void *stream, apk_blob_t token)
container_of(stream, struct apk_tee_bstream, bs);
apk_blob_t blob;
blob = tbs->inner_bs->read(tbs->inner_bs, token);
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);
if (tbs->cb) tbs->cb(tbs->cb_ctx, tbs->size);
}
return blob;
......@@ -472,16 +476,21 @@ static void tee_close(void *stream, size_t *size)
container_of(stream, struct apk_tee_bstream, bs);
/* copy info */
tbs->inner_bs->get_meta(tbs->inner_bs, &meta);
apk_bstream_get_meta(tbs->inner_bs, &meta);
apk_file_meta_to_fd(tbs->fd, &meta);
tbs->inner_bs->close(tbs->inner_bs, NULL);
if (size != NULL)
*size = tbs->size;
apk_bstream_close(tbs->inner_bs, NULL);
if (size != NULL) *size = tbs->size;
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, apk_progress_cb cb, void *cb_ctx)
{
struct apk_tee_bstream *tbs;
......@@ -493,7 +502,7 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd < 0) {
r = errno;
from->close(from, NULL);
apk_bstream_close(from, NULL);
return ERR_PTR(-r);
}
......@@ -501,14 +510,12 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
if (!tbs) {
r = errno;
close(fd);
from->close(from, NULL);
apk_bstream_close(from, NULL);
return ERR_PTR(-r);
}
tbs->bs = (struct apk_bstream) {
.get_meta = tee_get_meta,
.read = tee_read,
.close = tee_close,
.ops = &tee_bstream_ops,
};
tbs->inner_bs = from;
tbs->fd = fd;
......@@ -522,13 +529,13 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch
apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
{
void *ptr;
size_t rsize;
ssize_t rsize;
ptr = malloc(size);
if (ptr == NULL)
return APK_BLOB_NULL;
rsize = is->read(is, ptr, size);
rsize = apk_istream_read(is, ptr, size);
if (rsize < 0) {
free(ptr);
return APK_BLOB_NULL;
......@@ -720,12 +727,12 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
EVP_DigestInit(&mdctx, apk_checksum_evp(checksum));
if (bs->flags & APK_BSTREAM_SINGLE_READ)
EVP_MD_CTX_set_flags(&mdctx, EVP_MD_CTX_FLAG_ONESHOT);
while (!APK_BLOB_IS_NULL(blob = bs->read(bs, APK_BLOB_NULL)))
while (!APK_BLOB_IS_NULL(blob = apk_bstream_read(bs, APK_BLOB_NULL)))
EVP_DigestUpdate(&mdctx, (void*) blob.ptr, blob.len);
fi->csum.type = EVP_MD_CTX_size(&mdctx);
EVP_DigestFinal(&mdctx, fi->csum.data, NULL);
bs->close(bs, NULL);
apk_bstream_close(bs, NULL);
}
}
......@@ -865,6 +872,11 @@ static int fdo_close(void *stream)
return rc;
}
static const struct apk_ostream_ops fd_ostream_ops = {
.write = fdo_write,
.close = fdo_close,
};
struct apk_ostream *apk_ostream_to_fd(int fd)
{
struct apk_fd_ostream *fos;
......@@ -878,8 +890,7 @@ struct apk_ostream *apk_ostream_to_fd(int fd)
}
*fos = (struct apk_fd_ostream) {
.os.write = fdo_write,
.os.close = fdo_close,
.os.ops = &fd_ostream_ops,
.fd = fd,
};
......@@ -935,6 +946,11 @@ static int co_close(void *stream)
return 0;
}
static const struct apk_ostream_ops counter_ostream_ops = {
.write = co_write,
.close = co_close,
};
struct apk_ostream *apk_ostream_counter(off_t *counter)
{
struct apk_counter_ostream *cos;
......@@ -944,8 +960,7 @@ struct apk_ostream *apk_ostream_counter(off_t *counter)
return NULL;
*cos = (struct apk_counter_ostream) {
.os.write = co_write,
.os.close = co_close,
.os.ops = &counter_ostream_ops,
.counter = counter,
};
......@@ -957,7 +972,7 @@ size_t apk_ostream_write_string(struct apk_ostream *os, const char *string)
size_t len;
len = strlen(string);
if (os->write(os, string, len) != len)
if (apk_ostream_write(os, string, len) != len)
return -1;
return len;
......
......@@ -428,7 +428,7 @@ int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps, s
blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob);
if (APK_BLOB_IS_NULL(blob) ||
os->write(os, blob.ptr, blob.len) != blob.len)
apk_ostream_write(os, blob.ptr, blob.len) != blob.len)
return -1;
n += blob.len;
......@@ -470,13 +470,7 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
ctx->md = EVP_md_null();
break;
case APK_SIGN_VERIFY_IDENTITY:
if (identity->type == APK_CHECKSUM_MD5) {
ctx->md = EVP_md5();
ctx->control_started = 1;
ctx->data_started = 1;
} else {
ctx->md = EVP_sha1();
}
ctx->md = EVP_sha1();
memcpy(&ctx->identity, identity, sizeof(ctx->identity));
break;
case APK_SIGN_GENERATE:
......@@ -546,6 +540,9 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
* style .PKGINFO */
if (ctx->has_data_checksum)
return -ENOMSG;
/* Error out early if identity part is missing */
if (ctx->action == APK_SIGN_VERIFY_IDENTITY)
return -EKEYREJECTED;
ctx->data_started = 1;
ctx->control_started = 1;
r = check_signing_key_trust(ctx);
......@@ -924,7 +921,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx);
r = apk_tar_parse(tar, read_info_entry, &ctx, FALSE, &db->id_cache);
tar->close(tar);
apk_istream_close(tar);
if (r < 0 && r != -ECANCELED)
goto err;
if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) {
......@@ -973,7 +970,7 @@ int apk_ipkg_add_script(struct apk_installed_package *ipkg,
return -1;
ptr = malloc(size);
r = is->read(is, ptr, size);
r = apk_istream_read(is, ptr, size);
if (r < 0) {
free(ptr);
return r;
......@@ -1012,21 +1009,24 @@ void apk_ipkg_run_script(struct apk_installed_package *ipkg,
if (fd < 0) {
mkdirat(root_fd, "var/cache/misc", 0755);
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
if (fd < 0)
goto error;
if (fd < 0) goto err_log;
}
if (write(fd, ipkg->script[type].ptr, ipkg->script[type].len) < 0) {
close(fd);
goto error;
goto err_log;
}
close(fd);
if (apk_db_run_script(db, fn, argv) < 0)
ipkg->broken_script = 1;
return;
error:
goto err;
goto cleanup;
err_log:
apk_error("%s: failed to execute: %s", &fn[15], apk_error_str(errno));
err:
ipkg->broken_script = 1;
cleanup:
unlinkat(root_fd, fn, 0);
}
static int parse_index_line(void *ctx, apk_blob_t line)
......@@ -1067,17 +1067,10 @@ static int write_depends(struct apk_ostream *os, const char *field,
{
int r;
if (deps->num == 0)
return 0;
if (os->write(os, field, 2) != 2)
return -1;
r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1));
if (r < 0)
return r;
if (os->write(os, "\n", 1) != 1)
return -1;
if (deps->num == 0) return 0;
if (apk_ostream_write(os, field, 2) != 2) return -1;
if ((r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1))) < 0) return r;
if (apk_ostream_write(os, "\n", 1) != 1) return -1;
return 0;
}
......@@ -1132,7 +1125,7 @@ int apk_pkg_write_index_entry(struct apk_package *info,
}
bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf);
if (os->write(os, bbuf.ptr, bbuf.len) != bbuf.len ||
if (apk_ostream_write(os, bbuf.ptr, bbuf.len) != bbuf.len ||
write_depends(os, "D:", info->depends) ||
write_depends(os, "p:", info->provides) ||
write_depends(os, "i:", info->install_if))
......
......@@ -184,55 +184,57 @@ static void discover_name(struct apk_solver_state *ss, struct apk_name *name)
name->ss.no_iif = 1;
foreach_array_item(p, name->providers) {
struct apk_package *pkg = p->pkg;
if (pkg->ss.seen)
continue;
if (!pkg->ss.seen) {
pkg->ss.seen = 1;
pkg->ss.pinning_allowed = APK_DEFAULT_PINNING_MASK;
pkg->ss.pinning_preferred = APK_DEFAULT_PINNING_MASK;
pkg->ss.pkg_available =
(pkg->filename != NULL) ||
(pkg->repos & db->available_repos & ~BIT(APK_REPOSITORY_CACHED));
/* Package is in 'cached' repository if filename is provided,
* or it's a 'virtual' package with install_size zero */
pkg->ss.pkg_selectable =
(pkg->repos & db->available_repos) ||
pkg->cached_non_repository ||
pkg->ipkg;
/* Prune install_if packages that are no longer available,
* currently works only if SOLVERF_AVAILABLE is set in the
* global solver flags. */
pkg->ss.iif_failed =
(pkg->install_if->num == 0) ||
((ss->solver_flags_inherit & APK_SOLVERF_AVAILABLE) &&
!pkg->ss.pkg_available);
repos = get_pkg_repos(db, pkg);
pkg->ss.tag_preferred =
(pkg->filename != NULL) ||
(pkg->installed_size == 0) ||
(repos & ss->default_repos);
pkg->ss.tag_ok =
pkg->ss.tag_preferred ||
pkg->cached_non_repository ||
pkg->ipkg;
pkg->ss.seen = 1;
pkg->ss.pinning_allowed = APK_DEFAULT_PINNING_MASK;
pkg->ss.pinning_preferred = APK_DEFAULT_PINNING_MASK;
pkg->ss.pkg_available =
(pkg->filename != NULL) ||
(pkg->repos & db->available_repos & ~BIT(APK_REPOSITORY_CACHED));
/* Package is in 'cached' repository if filename is provided,
* or it's a 'virtual' package with install_size zero */
pkg->ss.pkg_selectable =
(pkg->repos & db->available_repos) ||
pkg->cached_non_repository ||
pkg->ipkg;
/* Prune install_if packages that are no longer available,
* currently works only if SOLVERF_AVAILABLE is set in the
* global solver flags. */
pkg->ss.iif_failed =
(pkg->install_if->num == 0) ||
((ss->solver_flags_inherit & APK_SOLVERF_AVAILABLE) &&
!pkg->ss.pkg_available);
name->ss.no_iif &= pkg->ss.iif_failed;
foreach_array_item(dep, pkg->depends) {
discover_name(ss, dep->name);
pkg->ss.max_dep_chain = max(pkg->ss.max_dep_chain,
dep->name->ss.max_dep_chain+1);
}
repos = get_pkg_repos(db, pkg);
pkg->ss.tag_preferred =
(pkg->filename != NULL) ||
(pkg->installed_size == 0) ||
(repos & ss->default_repos);
pkg->ss.tag_ok =
pkg->ss.tag_preferred ||
pkg->cached_non_repository ||
pkg->ipkg;
foreach_array_item(dep, pkg->depends) {
discover_name(ss, dep->name);
pkg->ss.max_dep_chain = max(pkg->ss.max_dep_chain,
dep->name->ss.max_dep_chain+1);
dbg_printf("discover " PKG_VER_FMT ": tag_ok=%d, tag_pref=%d max_dep_chain=%d selectable=%d\n",
PKG_VER_PRINTF(pkg),
pkg->ss.tag_ok,
pkg->ss.tag_preferred,
pkg->ss.max_dep_chain,
pkg->ss.pkg_selectable);
}
name->ss.no_iif &= pkg->ss.iif_failed;
name->ss.max_dep_chain = max(name->ss.max_dep_chain, pkg->ss.max_dep_chain);
dbg_printf("discover " PKG_VER_FMT ": tag_ok=%d, tag_pref=%d max_dep_chain=%d selectable=%d\n",
PKG_VER_PRINTF(pkg),
pkg->ss.tag_ok,
pkg->ss.tag_preferred,
pkg->ss.max_dep_chain,
pkg->ss.pkg_selectable);
dbg_printf("discover %s: max_dep_chain=%d no_iif=%d\n",
name->name, name->ss.max_dep_chain, name->ss.no_iif);
}
foreach_array_item(pname0, name->rinstall_if)
discover_name(ss, *pname0);
......@@ -302,7 +304,7 @@ static void apply_constraint(struct apk_solver_state *ss, struct apk_package *pp
}
}
static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *name, struct apk_name *must_provide)
static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *name,