...
 
Commits (14)
## ##
# Building apk-tools # Building apk-tools
-include config.mk
PACKAGE := apk-tools PACKAGE := apk-tools
VERSION := 2.0.7 VERSION := 2.0.10
## ##
# Default directories # Default directories
......
...@@ -103,9 +103,11 @@ struct apk_database { ...@@ -103,9 +103,11 @@ struct apk_database {
char *root; char *root;
int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd; int root_fd, lock_fd, cache_fd, cachetmp_fd, keys_fd;
unsigned name_id, num_repos; unsigned name_id, num_repos;
const char *cache_dir; const char *cache_dir, *arch;
int permanent; unsigned int local_repos, bad_repos;
unsigned int local_repos; int permanent : 1;
int compat_newfeatures : 1;
int compat_notinstallable : 1;
struct apk_dependency_array *world; struct apk_dependency_array *world;
struct apk_string_array *protected_paths; struct apk_string_array *protected_paths;
...@@ -179,7 +181,7 @@ int apk_repository_update(struct apk_database *db, struct apk_repository *repo); ...@@ -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); int apk_db_cache_active(struct apk_database *db);
void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo, int ver); 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); const char *item, const char *cache_item, int verify);
int apk_db_install_pkg(struct apk_database *db, int apk_db_install_pkg(struct apk_database *db,
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
extern int apk_verbosity; extern int apk_verbosity;
extern unsigned int apk_flags; extern unsigned int apk_flags;
extern const char *apk_arch;
#define APK_FORCE 0x0001 #define APK_FORCE 0x0001
#define APK_SIMULATE 0x0002 #define APK_SIMULATE 0x0002
......
...@@ -81,11 +81,13 @@ struct apk_installed_package { ...@@ -81,11 +81,13 @@ struct apk_installed_package {
struct apk_string_array *pending_triggers; struct apk_string_array *pending_triggers;
}; };
#define APK_PKG_UNINSTALLABLE ((char*) -1)
struct apk_package { struct apk_package {
apk_hash_node hash_node; apk_hash_node hash_node;
unsigned repos; unsigned repos;
struct apk_name *name; struct apk_name *name;
char *version; char *version, *arch;
char *url, *description, *license; char *url, *description, *license;
struct apk_dependency_array *depends; struct apk_dependency_array *depends;
size_t installed_size, size; size_t installed_size, size;
...@@ -148,7 +150,7 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg, ...@@ -148,7 +150,7 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg,
unsigned int type, char **argv); unsigned int type, char **argv);
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry); 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); 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) ...@@ -58,7 +58,7 @@ static int cache_download(struct apk_database *db)
continue; continue;
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item)); 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); APK_SIGN_VERIFY_IDENTITY);
} }
......
This diff is collapsed.
...@@ -27,6 +27,7 @@ struct apk_gzip_istream { ...@@ -27,6 +27,7 @@ struct apk_gzip_istream {
apk_multipart_cb cb; apk_multipart_cb cb;
void *cbctx; void *cbctx;
void *cbprev; void *cbprev;
apk_blob_t cbarg;
}; };
static ssize_t gzi_read(void *stream, void *ptr, size_t size) 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) ...@@ -48,6 +49,18 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.next_out = ptr; gis->zs.next_out = ptr;
while (gis->zs.avail_out != 0 && gis->err == 0) { 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) { if (gis->zs.avail_in == 0) {
apk_blob_t blob; apk_blob_t blob;
...@@ -86,19 +99,22 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size) ...@@ -86,19 +99,22 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size)
gis->zs.avail_in == 0) gis->zs.avail_in == 0)
gis->err = 1; gis->err = 1;
if (gis->cb != NULL) { 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, r = gis->cb(gis->cbctx,
gis->err ? APK_MPART_END : APK_MPART_BOUNDARY, 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) if (r > 0)
r = -ECANCELED; r = -ECANCELED;
if (r != 0) {
gis->err = r;
goto ret;
}
gis->cbprev = gis->zs.next_in;
}
if (gis->err)
goto ret; goto ret;
}
inflateEnd(&gis->zs); inflateEnd(&gis->zs);
if (inflateInit2(&gis->zs, 15+32) != Z_OK) if (inflateInit2(&gis->zs, 15+32) != Z_OK)
return -ENOMEM; return -ENOMEM;
......
...@@ -101,13 +101,16 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db, ...@@ -101,13 +101,16 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
struct apk_package *pkg; struct apk_package *pkg;
struct apk_dependency_array *deps; struct apk_dependency_array *deps;
struct apk_dependency dep; struct apk_dependency dep;
int i; int i, r=0;
apk_dependency_array_init(&deps); apk_dependency_array_init(&deps);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
pkg = apk_db_get_file_owner(db, APK_BLOB_STR(argv[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; continue;
}
if (apk_verbosity < 1) { if (apk_verbosity < 1) {
dep = (struct apk_dependency) { dep = (struct apk_dependency) {
...@@ -130,7 +133,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db, ...@@ -130,7 +133,7 @@ static int info_who_owns(struct info_ctx *ctx, struct apk_database *db,
} }
apk_dependency_array_free(&deps); apk_dependency_array_free(&deps);
return 0; return r;
} }
static void info_print_description(struct apk_package *pkg) static void info_print_description(struct apk_package *pkg)
......
...@@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx) ...@@ -410,16 +410,35 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx)
EVP_MD_CTX_cleanup(&ctx->mdctx); 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, int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
const struct apk_file_info *fi, const struct apk_file_info *fi,
struct apk_istream *is) struct apk_istream *is)
{ {
int r;
if (ctx->data_started) if (ctx->data_started)
return 1; return 1;
if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) { if (fi->name[0] != '.' || strchr(fi->name, '/') != NULL) {
ctx->data_started = 1; ctx->data_started = 1;
ctx->control_started = 1; ctx->control_started = 1;
r = check_signing_key_trust(ctx);
if (r < 0)
return r;
return 1; return 1;
} }
...@@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx, ...@@ -446,7 +465,7 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
if (strncmp(&fi->name[6], "RSA.", 4) == 0 || if (strncmp(&fi->name[6], "RSA.", 4) == 0 ||
strncmp(&fi->name[6], "DSA.", 4) == 0) { strncmp(&fi->name[6], "DSA.", 4) == 0) {
int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC); int fd = openat(ctx->keys_fd, &fi->name[10], O_RDONLY|O_CLOEXEC);
BIO *bio; BIO *bio;
if (fd < 0) if (fd < 0)
return 0; return 0;
...@@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data) ...@@ -557,15 +576,13 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
return 0; return 0;
} }
r = check_signing_key_trust(sctx);
if (r < 0)
return r;
switch (sctx->action) { switch (sctx->action) {
case APK_SIGN_VERIFY: case APK_SIGN_VERIFY:
case APK_SIGN_VERIFY_AND_GENERATE: 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, r = EVP_VerifyFinal(&sctx->mdctx,
(unsigned char *) sctx->signature.data.ptr, (unsigned char *) sctx->signature.data.ptr,
sctx->signature.data.len, sctx->signature.data.len,
...@@ -637,6 +654,9 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg, ...@@ -637,6 +654,9 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'L': case 'L':
pkg->license = apk_blob_cstr(value); pkg->license = apk_blob_cstr(value);
break; break;
case 'A':
pkg->arch = apk_blob_cstr(value);
break;
case 'D': case 'D':
apk_deps_parse(db, &pkg->depends, value); apk_deps_parse(db, &pkg->depends, value);
break; break;
...@@ -649,8 +669,17 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg, ...@@ -649,8 +669,17 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'I': case 'I':
pkg->installed_size = apk_blob_pull_uint(&value, 10); pkg->installed_size = apk_blob_pull_uint(&value, 10);
break; break;
case 'F': case 'M': case 'R': case 'Z':
/* installed db entries which are handled in database.c */
return 1;
default: 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)) if (APK_BLOB_IS_NULL(value))
return -1; return -1;
...@@ -669,6 +698,7 @@ static int read_info_line(void *ctx, apk_blob_t line) ...@@ -669,6 +698,7 @@ static int read_info_line(void *ctx, apk_blob_t line)
{ "url", 'U' }, { "url", 'U' },
{ "size", 'I' }, { "size", 'I' },
{ "license", 'L' }, { "license", 'L' },
{ "arch", 'A' },
{ "depend", 'D' }, { "depend", 'D' },
}; };
struct read_info_ctx *ri = (struct read_info_ctx *) ctx; 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, ...@@ -797,8 +827,9 @@ int apk_pkg_read(struct apk_database *db, const char *file,
tar->close(tar); tar->close(tar);
if (r < 0 && r != -ECANCELED) if (r < 0 && r != -ECANCELED)
goto err; goto err;
if (ctx.pkg->name == NULL) { if (ctx.pkg->name == NULL ||
r = -ENOMSG; ctx.pkg->filename == APK_PKG_UNINSTALLABLE) {
r = -ENOTSUP;
goto err; goto err;
} }
if (sctx->action != APK_SIGN_VERIFY) if (sctx->action != APK_SIGN_VERIFY)
...@@ -829,6 +860,8 @@ void apk_pkg_free(struct apk_package *pkg) ...@@ -829,6 +860,8 @@ void apk_pkg_free(struct apk_package *pkg)
free(pkg->description); free(pkg->description);
if (pkg->license) if (pkg->license)
free(pkg->license); free(pkg->license);
if (pkg->arch)
free(pkg->arch);
free(pkg); free(pkg);
} }
...@@ -954,7 +987,7 @@ struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_ ...@@ -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, int apk_pkg_write_index_entry(struct apk_package *info,
struct apk_ostream *os) struct apk_ostream *os, int write_arch)
{ {
char buf[512]; char buf[512];
apk_blob_t bbuf = APK_BLOB_BUF(buf); apk_blob_t bbuf = APK_BLOB_BUF(buf);
...@@ -966,6 +999,10 @@ int apk_pkg_write_index_entry(struct apk_package *info, ...@@ -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(info->name->name));
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nV:")); apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nV:"));
apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->version)); 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_blob(&bbuf, APK_BLOB_STR("\nS:"));
apk_blob_push_uint(&bbuf, info->size, 10); apk_blob_push_uint(&bbuf, info->size, 10);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nI:")); 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, ...@@ -119,6 +119,15 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db,
memcpy(nc->pkgs, name->pkgs->item, memcpy(nc->pkgs, name->pkgs->item,
name->pkgs->num * sizeof(struct apk_package *)); 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) if (name->flags & APK_NAME_TOPLEVEL_OVERRIDE)
return nc; return nc;
...@@ -132,7 +141,7 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db, ...@@ -132,7 +141,7 @@ static struct apk_name_choices *name_choices_new(struct apk_database *db,
for (j = 0; j < nc->num; ) { for (j = 0; j < nc->num; ) {
if (apk_version_compare(nc->pkgs[j]->version, dep->version) if (apk_version_compare(nc->pkgs[j]->version, dep->version)
& dep->result_mask) { & dep->result_mask) {
j++; j++;
} else { } else {
nc->pkgs[j] = nc->pkgs[nc->num - 1]; nc->pkgs[j] = nc->pkgs[nc->num - 1];
nc->num--; nc->num--;
......
...@@ -70,7 +70,7 @@ static int fork_wget(const char *url, pid_t *ppid) ...@@ -70,7 +70,7 @@ static int fork_wget(const char *url, pid_t *ppid)
close(fds[0]); close(fds[0]);
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO); dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
dup2(fds[1], STDOUT_FILENO); dup2(fds[1], STDOUT_FILENO);
execlp("wget", "wget", "-q", "-O", "-", url, NULL); execlp("busybox", "wget", "-q", "-O", "-", url, NULL);
exit(0); exit(0);
} }
......
...@@ -85,7 +85,7 @@ static int get_token(int *type, apk_blob_t *blob) ...@@ -85,7 +85,7 @@ static int get_token(int *type, apk_blob_t *blob)
case TOKEN_DIGIT_OR_ZERO: case TOKEN_DIGIT_OR_ZERO:
/* Leading zero digits get a special treatment */ /* Leading zero digits get a special treatment */
if (blob->ptr[i] == '0') { if (blob->ptr[i] == '0') {
while (blob->ptr[i] == '0' && i < blob->len) while (i < blob->len && blob->ptr[i] == '0')
i++; i++;
nt = TOKEN_DIGIT; nt = TOKEN_DIGIT;
v = -i; v = -i;
...@@ -94,7 +94,7 @@ static int get_token(int *type, apk_blob_t *blob) ...@@ -94,7 +94,7 @@ static int get_token(int *type, apk_blob_t *blob)
case TOKEN_DIGIT: case TOKEN_DIGIT:
case TOKEN_SUFFIX_NO: case TOKEN_SUFFIX_NO:
case TOKEN_REVISION_NO: case TOKEN_REVISION_NO:
while (isdigit(blob->ptr[i]) && i < blob->len) { while (i < blob->len && isdigit(blob->ptr[i])) {
v *= 10; v *= 10;
v += blob->ptr[i++] - '0'; v += blob->ptr[i++] - '0';
} }
......