...
 
Commits (14)
##
# Building apk-tools
-include config.mk
PACKAGE := apk-tools
VERSION := 2.0.7
VERSION := 2.0.10
##
# Default directories
......
......@@ -103,9 +103,11 @@ struct apk_database {
char *root;
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
unsigned name_id, num_repos;
const char *cache_dir;
int permanent;
unsigned int local_repos;
const char *cache_dir, *arch;
unsigned int local_repos, bad_repos;
int permanent : 1;
int compat_newfeatures : 1;
int compat_notinstallable : 1;
struct apk_dependency_array *world;
struct apk_string_array *protected_paths;
......@@ -179,7 +181,7 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
int apk_db_cache_active(struct apk_database *db);
void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo, int ver);
int apk_cache_download(struct apk_database *db, const char *url,
int apk_cache_download(struct apk_database *db, const char *arch, const char *url,
const char *item, const char *cache_item, int verify);
int apk_db_install_pkg(struct apk_database *db,
......
......@@ -49,6 +49,7 @@
extern int apk_verbosity;
extern unsigned int apk_flags;
extern const char *apk_arch;
#define APK_FORCE 0x0001
#define APK_SIMULATE 0x0002
......
......@@ -81,11 +81,13 @@ struct apk_installed_package {
struct apk_string_array *pending_triggers;
};
#define APK_PKG_UNINSTALLABLE ((char*) -1)
struct apk_package {
apk_hash_node hash_node;
unsigned repos;
struct apk_name *name;
char *version;
char *version, *arch;
char *url, *description, *license;
struct apk_dependency_array *depends;
size_t installed_size, size;
......@@ -148,7 +150,7 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg,
unsigned int type, char **argv);
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os, int write_arch);
int apk_pkg_version_compare(struct apk_package *a, struct apk_package *b);
......
......@@ -58,7 +58,7 @@ static int cache_download(struct apk_database *db)
continue;
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
apk_cache_download(db, repo->url, item, cacheitem,
apk_cache_download(db, pkg->arch, repo->url, item, cacheitem,
APK_SIGN_VERIFY_IDENTITY);
}
......
......@@ -30,6 +30,14 @@
#include "apk_archive.h"
#include "apk_print.h"
#if defined(__x86_64__)
#define APK_DEFAULT_ARCH "x86_64"
#elif defined(__i386__)
#define APK_DEFAULT_ARCH "x86"
#else
#define APK_DEFAULT_ARCH "noarch"
#endif
enum {
APK_DISALLOW_RMDIR = 0,
APK_ALLOW_RMDIR = 1
......@@ -37,6 +45,7 @@ enum {
int apk_verbosity = 1;
unsigned int apk_flags = 0;
const char *apk_arch = APK_DEFAULT_ARCH;
const char * const apkindex_tar_gz = "APKINDEX.tar.gz";
const char * const apk_index_gz = "APK_INDEX.gz";
......@@ -446,14 +455,19 @@ void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo, int ver)
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
}
int apk_cache_download(struct apk_database *db, const char *url,
int apk_cache_download(struct apk_database *db, const char *arch, const char *url,
const char *item, const char *cacheitem, int verify)
{
char fullurl[PATH_MAX];
int r;
snprintf(fullurl, sizeof(fullurl), "%s%s%s",
url, url[strlen(url)-1] == '/' ? "" : "/", item);
if (arch != NULL)
snprintf(fullurl, sizeof(fullurl), "%s%s%s/%s",
url, url[strlen(url)-1] == '/' ? "" : "/",
arch, item);
else
snprintf(fullurl, sizeof(fullurl), "%s%s%s",
url, url[strlen(url)-1] == '/' ? "" : "/", item);
apk_message("fetch %s", fullurl);
if (apk_flags & APK_SIMULATE)
......@@ -518,7 +532,6 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs)
struct hlist_node **diri_node = NULL, **file_diri_node = NULL;
struct apk_package *pkg;
struct apk_installed_package *ipkg;
struct apk_db_file *file;
apk_blob_t token = APK_BLOB_STR("\n"), line, bdir, bfile;
pkg = apk_pkg_new();
......@@ -544,7 +557,7 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs)
diri = apk_db_diri_new(db, pkg, bdir, &diri_node);
file_diri_node = &diri->owned_files.first;
}
file = apk_db_file_get(db, diri, bfile, &file_diri_node);
apk_db_file_get(db, diri, bfile, &file_diri_node);
}
}
......@@ -560,7 +573,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
struct hlist_node **diri_node = NULL;
struct hlist_node **file_diri_node = NULL;
apk_blob_t token = APK_BLOB_STR("\n"), l;
int field;
int field, r;
while (!APK_BLOB_IS_NULL(l = bs->read(bs, token))) {
if (l.len < 2 || l.ptr[1] != ':') {
......@@ -587,27 +600,25 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
/* If no package, create new */
if (pkg == NULL) {
pkg = apk_pkg_new();
ipkg = NULL;
ipkg = NULL;
diri = NULL;
file_diri_node = NULL;
}
/* Standard index line? */
if (apk_pkg_add_info(db, pkg, field, l) == 0) {
if (repo == -1 && field == 'S') {
/* Instert to installed database; this needs to
* happen after package name has been read, but
* before first FDB entry. */
ipkg = apk_pkg_install(db, pkg);
diri_node = hlist_tail_ptr(&ipkg->owned_dirs);
}
r = apk_pkg_add_info(db, pkg, field, l);
if (r == 0) {
if (repo == -1 && field == 'S') {
/* Instert to installed database; this needs to
* happen after package name has been read, but
* before first FDB entry. */
ipkg = apk_pkg_install(db, pkg);
diri_node = hlist_tail_ptr(&ipkg->owned_dirs);
}
continue;
}
if (repo != -1 || ipkg == NULL) {
apk_error("Invalid index entry '%c'", field);
return -1;
}
if (repo != -1 || ipkg == NULL)
continue;
/* Check FDB special entries */
switch (field) {
......@@ -645,8 +656,14 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
apk_blob_pull_csum(&l, &file->csum);
break;
default:
apk_error("FDB entry '%c' unsupported", field);
return -1;
if (r != 0 && !(apk_flags & APK_FORCE)) {
/* Installed db should not have unsupported fields */
apk_error("This apk-tools is too old to handle installed packages");
return -1;
}
/* Installed. So mark the package as installable. */
pkg->filename = NULL;
continue;
}
if (APK_BLOB_IS_NULL(l)) {
apk_error("FDB format error in entry '%c'", field);
......@@ -670,7 +687,7 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
pkg = ipkg->pkg;
r = apk_pkg_write_index_entry(pkg, os);
r = apk_pkg_write_index_entry(pkg, os, TRUE);
if (r < 0)
return r;
......@@ -877,7 +894,7 @@ static int apk_db_read_state(struct apk_database *db, int flags)
struct apk_istream *is;
struct apk_bstream *bs;
apk_blob_t blob;
int i;
int i, r;
/* Read:
* 1. installed repository
......@@ -901,8 +918,10 @@ static int apk_db_read_state(struct apk_database *db, int flags)
if (!(flags & APK_OPENF_NO_INSTALLED)) {
bs = apk_bstream_from_file(db->root_fd, "var/lib/apk/installed");
if (bs != NULL) {
apk_db_index_read(db, bs, -1);
r = apk_db_index_read(db, bs, -1);
bs->close(bs, NULL);
if (r != 0)
return -1;
}
bs = apk_bstream_from_file(db->root_fd, "var/lib/apk/triggers");
......@@ -933,6 +952,7 @@ struct index_write_ctx {
struct apk_ostream *os;
int count;
int force;
int write_arch;
};
static int write_index_entry(apk_hash_item item, void *ctx)
......@@ -944,7 +964,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
if (!iwctx->force && pkg->filename == NULL)
return 0;
r = apk_pkg_write_index_entry(pkg, iwctx->os);
r = apk_pkg_write_index_entry(pkg, iwctx->os, iwctx->write_arch);
if (r < 0)
return r;
......@@ -957,7 +977,7 @@ static int write_index_entry(apk_hash_item item, void *ctx)
static int apk_db_index_write_nr_cache(struct apk_database *db)
{
struct index_write_ctx ctx = { NULL, 0, TRUE };
struct index_write_ctx ctx = { NULL, 0, TRUE, TRUE };
struct apk_installed_package *ipkg;
struct apk_ostream *os;
int r;
......@@ -991,7 +1011,7 @@ static int apk_db_index_write_nr_cache(struct apk_database *db)
int apk_db_index_write(struct apk_database *db, struct apk_ostream *os)
{
struct index_write_ctx ctx = { os, 0, FALSE };
struct index_write_ctx ctx = { os, 0, FALSE, FALSE };
apk_hash_foreach(&db->available.packages, write_index_entry, &ctx);
......@@ -1038,7 +1058,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
struct apk_bstream *bs;
struct stat64 st;
apk_blob_t blob;
int r, rr = 0;
int r;
memset(db, 0, sizeof(*db));
if (apk_flags & APK_SIMULATE) {
......@@ -1120,6 +1140,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
blob = APK_BLOB_STR("etc:*etc/init.d");
apk_blob_for_each_segment(blob, ":", add_protected_path, db);
db->arch = apk_arch;
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY | O_CLOEXEC);
mkdirat(db->cache_fd, "tmp", 0644);
db->cachetmp_fd = openat(db->cache_fd, "tmp", O_RDONLY | O_CLOEXEC);
......@@ -1157,29 +1179,34 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
}
}
if (!(dbopts->open_flags & APK_OPENF_NO_SYS_REPOS)) {
list_for_each_entry(repo, &dbopts->repository_list, list) {
r = apk_db_add_repository(db, APK_BLOB_STR(repo->url));
rr = r ?: rr;
}
list_for_each_entry(repo, &dbopts->repository_list, list)
apk_db_add_repository(db, APK_BLOB_STR(repo->url));
blob = apk_blob_from_file(
db->root_fd,
dbopts->repositories_file ?: "etc/apk/repositories");
if (!APK_BLOB_IS_NULL(blob)) {
r = apk_blob_for_each_segment(
apk_blob_for_each_segment(
blob, "\n",
apk_db_add_repository, db);
rr = r ?: rr;
free(blob.ptr);
}
if (apk_flags & APK_UPDATE_CACHE)
apk_db_index_write_nr_cache(db);
}
if (rr != 0) {
r = rr;
if (db->bad_repos && !(apk_flags & APK_FORCE)) {
apk_error("Aborting due to some repositories failed to load. Use --force to ignore this error.");
r = -EBADMSG;
goto ret_r;
}
return rr;
if (db->compat_newfeatures) {
apk_warning("This apk-tools is OLD! Some packages %s.",
db->compat_notinstallable ?
"are not installable" :
"might not function properly");
}
return 0;
ret_errno:
r = -errno;
......@@ -1397,13 +1424,20 @@ static int apk_repo_is_remote(struct apk_repository *repo)
}
static struct apk_bstream *apk_repo_file_open(struct apk_repository *repo,
const char *arch,
const char *file,
char *buf, int buflen)
{
const char *url = repo->url;
snprintf(buf, buflen, "%s%s%s",
url, url[strlen(url)-1] == '/' ? "" : "/", file);
if (arch != NULL)
snprintf(buf, buflen, "%s%s%s/%s",
url, url[strlen(url)-1] == '/' ? "" : "/",
arch, file);
else
snprintf(buf, buflen, "%s%s%s",
url, url[strlen(url)-1] == '/' ? "" : "/",
file);
if ((apk_flags & APK_NO_NETWORK) && apk_repo_is_remote(repo))
return NULL;
......@@ -1425,7 +1459,7 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db,
0xf5,0xa7,0x0a,0x7c,0x17,0x26,0x69,0xb0,0x05,0x38 },
.csum.type = APK_CHECKSUM_SHA1,
};
unsigned int repos = pkg->repos;
unsigned int repos = pkg->repos & ~(db->bad_repos);
int i;
/* Always prefer local repositories */
......@@ -1463,7 +1497,7 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
return 0;
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 0);
r = apk_cache_download(db, repo->url, apkindex_tar_gz, cacheitem,
r = apk_cache_download(db, NULL, repo->url, apkindex_tar_gz, cacheitem,
(apk_flags & APK_ALLOW_UNTRUSTED) ?
APK_SIGN_NONE : APK_SIGN_VERIFY);
if (r == 0 || r == -ENOKEY || r == -EKEYREJECTED) {
......@@ -1473,7 +1507,7 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
}
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo, 1);
r = apk_cache_download(db, repo->url, apk_index_gz, cacheitem,
r = apk_cache_download(db, NULL, repo->url, apk_index_gz, cacheitem,
APK_SIGN_NONE);
if (r != 0)
apk_error("Failed to update %s: download failed", repo->url);
......@@ -1527,7 +1561,8 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs,
r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache);
is->close(is);
apk_sign_ctx_free(&ctx.sctx);
if (ctx.found == 0)
if (r >= 0 && ctx.found == 0)
r = -ENOMSG;
} else {
bs = apk_bstream_from_istream(apk_bstream_gunzip(bs));
......@@ -1585,21 +1620,24 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
} else {
db->local_repos |= BIT(r);
bs = apk_repo_file_open(repo, apkindex_tar_gz, buf, sizeof(buf));
bs = apk_repo_file_open(repo, NULL, apkindex_tar_gz, buf, sizeof(buf));
if (bs == NULL) {
bs = apk_repo_file_open(repo, apk_index_gz, buf, sizeof(buf));
bs = apk_repo_file_open(repo, NULL, apk_index_gz, buf, sizeof(buf));
targz = 0;
}
}
if (bs == NULL) {
apk_warning("Failed to open index for %s", repo->url);
return 0;
if (bs != NULL)
r = load_index(db, bs, targz, r);
else
r = -ENOENT;
if (r != 0) {
apk_warning("Ignoring %s: %s", buf, apk_error_str(r));
db->bad_repos |= BIT(r);
r = 0;
}
r = load_index(db, bs, targz, r);
if (r != 0)
apk_error("%s: Bad repository signature", repo->url);
return r;
return 0;
}
static void extract_cb(void *_ctx, size_t progress)
......@@ -2013,7 +2051,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (bs == NULL) {
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
bs = apk_repo_file_open(repo, item, file, sizeof(file));
bs = apk_repo_file_open(repo, pkg->arch, item, file, sizeof(file));
if (apk_repo_is_remote(repo))
need_copy = TRUE;
}
......@@ -2059,9 +2097,9 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (need_copy) {
if (r == 0)
renameat(db->cachetmp_fd, file, db->cache_fd, file);
renameat(db->cachetmp_fd, item, db->cache_fd, item);
else
unlinkat(db->cachetmp_fd, file, 0);
unlinkat(db->cachetmp_fd, item, 0);
}
if (r != 0) {
......
......@@ -27,6 +27,7 @@ struct apk_gzip_istream {
apk_multipart_cb cb;
void *cbctx;
void *cbprev;
apk_blob_t cbarg;
};
static ssize_t gzi_read(void *stream, void *ptr, size_t size)
......@@ -48,6 +49,18 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.next_out = ptr;
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;
goto ret;
}
gis->cbarg = APK_BLOB_NULL;
}
if (gis->zs.avail_in == 0) {
apk_blob_t blob;
......@@ -86,19 +99,22 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.avail_in == 0)
gis->err = 1;
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;
}
/* If we hit end of the bitstream (not end
* of just this gzip), we need to do the
* callback here, as we won't be called again.
* 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,
APK_BLOB_PTR_LEN(gis->cbprev, (void *) gis->zs.next_in - gis->cbprev));
gis->cbarg);
if (r > 0)
r = -ECANCELED;
if (r != 0) {
gis->err = r;
goto ret;
}
gis->cbprev = gis->zs.next_in;
}
if (gis->err)
goto ret;
}
inflateEnd(&gis->zs);
if (inflateInit2(&gis->zs, 15+32) != Z_OK)
return -ENOMEM;
......
......@@ -101,13 +101,16 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
struct apk_package *pkg;
struct apk_dependency_array *deps;
struct apk_dependency dep;
int i;
int i, r=0;
apk_dependency_array_init(&deps);
for (i = 0; i < argc; i++) {
pkg = apk_db_get_file_owner(db, APK_BLOB_STR(argv[i]));
if (pkg == NULL)
if (pkg == NULL) {
apk_error("%s: Could not find owner package", argv[i]);
r++;
continue;
}
if (apk_verbosity < 1) {
dep = (struct apk_dependency) {
......@@ -130,7 +133,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
}
apk_dependency_array_free(&deps);
return 0;
return r;
}
static void info_print_description(struct apk_package *pkg)
......
......@@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx)
EVP_MD_CTX_cleanup(&ctx->mdctx);
}
static int check_signing_key_trust(struct apk_sign_ctx *sctx)
{
switch (sctx->action) {
case APK_SIGN_VERIFY:
case APK_SIGN_VERIFY_AND_GENERATE:
if (sctx->signature.pkey == NULL) {
if (apk_flags & APK_ALLOW_UNTRUSTED)
break;
return -ENOKEY;
}
}
return 0;
}
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
const struct apk_file_info *fi,
struct apk_istream *is)
{
int r;
if (ctx->data_started)
return 1;
if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) {
ctx->data_started = 1;
ctx->control_started = 1;
r = check_signing_key_trust(ctx);
if (r < 0)
return r;
return 1;
}
......@@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
if (strncmp(&fi->name[6], "RSA.", 4) == 0 ||
strncmp(&fi->name[6], "DSA.", 4) == 0) {
int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC);
BIO *bio;
BIO *bio;
if (fd < 0)
return 0;
......@@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
return 0;
}
r = check_signing_key_trust(sctx);
if (r < 0)
return r;
switch (sctx->action) {
case APK_SIGN_VERIFY:
case APK_SIGN_VERIFY_AND_GENERATE:
if (sctx->signature.pkey == NULL) {
if (apk_flags & APK_ALLOW_UNTRUSTED)
break;
return -ENOKEY;
}
r = EVP_VerifyFinal(&sctx->mdctx,
(unsigned char *) sctx->signature.data.ptr,
sctx->signature.data.len,
......@@ -637,6 +654,9 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'L':
pkg->license = apk_blob_cstr(value);
break;
case 'A':
pkg->arch = apk_blob_cstr(value);
break;
case 'D':
apk_deps_parse(db, &pkg->depends, value);
break;
......@@ -649,8 +669,17 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'I':
pkg->installed_size = apk_blob_pull_uint(&value, 10);
break;
case 'F': case 'M': case 'R': case 'Z':
/* installed db entries which are handled in database.c */
return 1;
default:
return -1;
/* lower case index entries are safe to be ignored */
if (!islower(field)) {
pkg->filename = APK_PKG_UNINSTALLABLE;
db->compat_notinstallable = 1;
}
db->compat_newfeatures = 1;
return 1;
}
if (APK_BLOB_IS_NULL(value))
return -1;
......@@ -669,6 +698,7 @@ static int read_info_line(void *ctx, apk_blob_t line)
{ "url", 'U' },
{ "size", 'I' },
{ "license", 'L' },
{ "arch", 'A' },
{ "depend", 'D' },
};
struct read_info_ctx *ri = (struct read_info_ctx *) ctx;
......@@ -797,8 +827,9 @@ int apk_pkg_read(struct apk_database *db, const char *file,
tar->close(tar);
if (r < 0 && r != -ECANCELED)
goto err;
if (ctx.pkg->name == NULL) {
r = -ENOMSG;
if (ctx.pkg->name == NULL ||
ctx.pkg->filename == APK_PKG_UNINSTALLABLE) {
r = -ENOTSUP;
goto err;
}
if (sctx->action != APK_SIGN_VERIFY)
......@@ -829,6 +860,8 @@ void apk_pkg_free(struct apk_package *pkg)
free(pkg->description);
if (pkg->license)
free(pkg->license);
if (pkg->arch)
free(pkg->arch);
free(pkg);
}
......@@ -954,7 +987,7 @@ struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_
}
int apk_pkg_write_index_entry(struct apk_package *info,
struct apk_ostream *os)
struct apk_ostream *os, int write_arch)
{
char buf[512];
apk_blob_t bbuf = APK_BLOB_BUF(buf);
......@@ -966,6 +999,10 @@ int apk_pkg_write_index_entry(struct apk_package *info,
apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->name->name));
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nV:"));
apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->version));
if (write_arch && info->arch != NULL) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nA:"));
apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->arch));
}
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nS:"));
apk_blob_push_uint(&bbuf, info->size, 10);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nI:"));
......
......@@ -119,6 +119,15 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db,
memcpy(nc->pkgs, name->pkgs->item,
name->pkgs->num * sizeof(struct apk_package *));
for (j = 0; j < nc->num; ) {
if (nc->pkgs[j]->filename != APK_PKG_UNINSTALLABLE) {
j++;
} else {
nc->pkgs[j] = nc->pkgs[nc->num - 1];
nc->num--;
}
}
if (name->flags & APK_NAME_TOPLEVEL_OVERRIDE)
return nc;
......@@ -132,7 +141,7 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db,
for (j = 0; j < nc->num; ) {
if (apk_version_compare(nc->pkgs[j]->version, dep->version)
& dep->result_mask) {
j++;
j++;
} else {
nc->pkgs[j] = nc->pkgs[nc->num - 1];
nc->num--;
......
......@@ -70,7 +70,7 @@ static int fork_wget(const char *url, pid_t *ppid)
close(fds[0]);
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
dup2(fds[1], STDOUT_FILENO);
execlp("wget", "wget", "-q", "-O", "-", url, NULL);
execlp("busybox", "wget", "-q", "-O", "-", url, NULL);
exit(0);
}
......
......@@ -85,7 +85,7 @@ static int get_token(int *type, apk_blob_t *blob)
case TOKEN_DIGIT_OR_ZERO:
/* Leading zero digits get a special treatment */
if (blob->ptr[i] == '0') {
while (blob->ptr[i] == '0' && i < blob->len)
while (i < blob->len && blob->ptr[i] == '0')
i++;
nt = TOKEN_DIGIT;
v = -i;
......@@ -94,7 +94,7 @@ static int get_token(int *type, apk_blob_t *blob)
case TOKEN_DIGIT:
case TOKEN_SUFFIX_NO:
case TOKEN_REVISION_NO:
while (isdigit(blob->ptr[i]) && i < blob->len) {
while (i < blob->len && isdigit(blob->ptr[i])) {
v *= 10;
v += blob->ptr[i++] - '0';
}
......