Commit 9d100378 authored by Timo Teräs's avatar Timo Teräs

db: refactor repository file construction

Fixes also 'fetch' applet to prefer copying/linking to files from
cache if possible.
parent dbb64220
...@@ -21,9 +21,6 @@ ...@@ -21,9 +21,6 @@
#include "apk_provider_data.h" #include "apk_provider_data.h"
#include "apk_solver_data.h" #include "apk_solver_data.h"
extern const char * const apk_index_gz;
extern const char * const apkindex_tar_gz;
struct apk_name; struct apk_name;
APK_ARRAY(apk_name_array, struct apk_name *); APK_ARRAY(apk_name_array, struct apk_name *);
...@@ -71,8 +68,8 @@ struct apk_db_dir { ...@@ -71,8 +68,8 @@ struct apk_db_dir {
char name[]; char name[];
}; };
#define PKG_FILE_FMT "%s%s%s" #define DIR_FILE_FMT "%s%s%s"
#define PKG_FILE_PRINTF(dir,file) (dir)->name, (dir)->namelen ? "/" : "", (file)->name #define DIR_FILE_PRINTF(dir,file) (dir)->name, (dir)->namelen ? "/" : "", (file)->name
struct apk_db_dir_instance { struct apk_db_dir_instance {
struct hlist_node pkg_dirs_list; struct hlist_node pkg_dirs_list;
...@@ -220,15 +217,16 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os); ...@@ -220,15 +217,16 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
int apk_db_add_repository(apk_database_t db, apk_blob_t repository); int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
struct apk_repository *apk_db_select_repo(struct apk_database *db, struct apk_repository *apk_db_select_repo(struct apk_database *db,
struct apk_package *pkg); struct apk_package *pkg);
int apk_repo_format_filename(char *buf, size_t len,
const char *repourl, apk_blob_t *arch, int apk_repo_format_cache_index(apk_blob_t to, struct apk_repository *repo);
const char *pkgfile); int apk_repo_format_item(struct apk_database *db, struct apk_repository *repo, struct apk_package *pkg,
int *fd, char *buf, size_t len);
unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned short pinning_mask); unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned short pinning_mask);
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 apk_cache_download(struct apk_database *db, struct apk_repository *repo,
int apk_cache_download(struct apk_database *db, const char *url, apk_blob_t *arch, struct apk_package *pkg, int verify);
const char *item, const char *cache_item, int verify);
typedef void (*apk_cache_item_cb)(struct apk_database *db, typedef void (*apk_cache_item_cb)(struct apk_database *db,
int dirfd, const char *name, int dirfd, const char *name,
......
...@@ -123,6 +123,8 @@ APK_ARRAY(apk_package_array, struct apk_package *); ...@@ -123,6 +123,8 @@ APK_ARRAY(apk_package_array, struct apk_package *);
#define PKG_VER_FMT "%s-" BLOB_FMT #define PKG_VER_FMT "%s-" BLOB_FMT
#define PKG_VER_PRINTF(pkg) pkg->name->name, BLOB_PRINTF(*pkg->version) #define PKG_VER_PRINTF(pkg) pkg->name->name, BLOB_PRINTF(*pkg->version)
#define PKG_FILE_FMT PKG_VER_FMT ".apk"
#define PKG_FILE_PRINTF(pkg) PKG_VER_PRINTF(pkg)
extern const char *apk_script_types[]; extern const char *apk_script_types[];
...@@ -160,8 +162,6 @@ int apk_script_type(const char *name); ...@@ -160,8 +162,6 @@ int apk_script_type(const char *name);
struct apk_package *apk_pkg_get_installed(struct apk_name *name); struct apk_package *apk_pkg_get_installed(struct apk_name *name);
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to);
void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to);
struct apk_package *apk_pkg_new(void); struct apk_package *apk_pkg_new(void);
int apk_pkg_read(struct apk_database *db, const char *name, int apk_pkg_read(struct apk_database *db, const char *name,
struct apk_sign_ctx *ctx, struct apk_package **pkg); struct apk_sign_ctx *ctx, struct apk_package **pkg);
......
...@@ -31,7 +31,6 @@ static int cache_download(struct apk_database *db) ...@@ -31,7 +31,6 @@ static int cache_download(struct apk_database *db)
struct apk_change *change; struct apk_change *change;
struct apk_package *pkg; struct apk_package *pkg;
struct apk_repository *repo; struct apk_repository *repo;
char item[PATH_MAX], cacheitem[PATH_MAX];
int i, r, ret = 0; int i, r, ret = 0;
r = apk_solver_solve(db, 0, db->world, &changeset); r = apk_solver_solve(db, 0, db->world, &changeset);
...@@ -50,13 +49,9 @@ static int cache_download(struct apk_database *db) ...@@ -50,13 +49,9 @@ static int cache_download(struct apk_database *db)
if (repo == NULL) if (repo == NULL)
continue; continue;
apk_pkg_format_cache(pkg, APK_BLOB_BUF(cacheitem)); r = apk_cache_download(db, repo, pkg, APK_SIGN_VERIFY_IDENTITY);
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
r = apk_cache_download(db, repo->url, pkg->arch,
item, cacheitem,
APK_SIGN_VERIFY_IDENTITY);
if (r) { if (r) {
apk_error("%s: %s", item, apk_error_str(r)); apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
ret++; ret++;
} }
} }
...@@ -76,7 +71,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam ...@@ -76,7 +71,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam
b = APK_BLOB_STR(name); b = APK_BLOB_STR(name);
for (i = 0; i < db->num_repos; i++) { for (i = 0; i < db->num_repos; i++) {
/* Check if this is a valid index */ /* Check if this is a valid index */
apk_cache_format_index(APK_BLOB_BUF(tmp), &db->repos[i]); apk_repo_format_cache_index(APK_BLOB_BUF(tmp), &db->repos[i]);
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0)
return; return;
} }
......
...@@ -46,7 +46,8 @@ enum { ...@@ -46,7 +46,8 @@ enum {
int apk_verbosity = 1; int apk_verbosity = 1;
unsigned int apk_flags = 0; unsigned int apk_flags = 0;
const char * const apkindex_tar_gz = "APKINDEX.tar.gz"; static const char * const apkindex_tar_gz = "APKINDEX.tar.gz";
static const char * const apk_static_cache_dir = "var/cache/apk"; static const char * const apk_static_cache_dir = "var/cache/apk";
static const char * const apk_linked_cache_dir = "etc/apk/cache"; static const char * const apk_linked_cache_dir = "etc/apk/cache";
...@@ -562,49 +563,111 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package * ...@@ -562,49 +563,111 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
return idb; return idb;
} }
void apk_cache_format_index(apk_blob_t to, struct apk_repository *repo) static int apk_pkg_format_cache_pkg(apk_blob_t to, struct apk_package *pkg)
{
/* pkgname-1.0_alpha1.12345678.apk */
apk_blob_push_blob(&to, APK_BLOB_STR(pkg->name->name));
apk_blob_push_blob(&to, APK_BLOB_STR("-"));
apk_blob_push_blob(&to, *pkg->version);
apk_blob_push_blob(&to, APK_BLOB_STR("."));
apk_blob_push_hexdump(&to, APK_BLOB_PTR_LEN((char *) pkg->csum.data,
APK_CACHE_CSUM_BYTES));
apk_blob_push_blob(&to, APK_BLOB_STR(".apk"));
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
if (APK_BLOB_IS_NULL(to))
return -ENOBUFS;
return 0;
}
int apk_repo_format_cache_index(apk_blob_t to, struct apk_repository *repo)
{ {
/* APKINDEX.12345678.tar.gz */ /* APKINDEX.12345678.tar.gz */
apk_blob_push_blob(&to, APK_BLOB_STR("APKINDEX.")); apk_blob_push_blob(&to, APK_BLOB_STR("APKINDEX."));
apk_blob_push_hexdump(&to, APK_BLOB_PTR_LEN((char *) repo->csum.data, apk_blob_push_hexdump(&to, APK_BLOB_PTR_LEN((char *) repo->csum.data, APK_CACHE_CSUM_BYTES));
APK_CACHE_CSUM_BYTES));
apk_blob_push_blob(&to, APK_BLOB_STR(".tar.gz")); apk_blob_push_blob(&to, APK_BLOB_STR(".tar.gz"));
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1)); apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
if (APK_BLOB_IS_NULL(to))
return -ENOBUFS;
return 0;
} }
int apk_cache_download(struct apk_database *db, const char *url, apk_blob_t *arch, int apk_repo_format_real_url(struct apk_database *db, struct apk_repository *repo,
const char *item, const char *cacheitem, int verify) struct apk_package *pkg, char *buf, size_t len)
{ {
char fullurl[PATH_MAX];
int r; int r;
apk_repo_format_filename(fullurl, sizeof(fullurl), url, arch, item); if (pkg != NULL)
apk_message("fetch %s", fullurl); r = snprintf(buf, len, "%s%s" BLOB_FMT "/" PKG_FILE_FMT,
repo->url, repo->url[strlen(repo->url)-1] == '/' ? "" : "/",
BLOB_PRINTF(*db->arch), PKG_FILE_PRINTF(pkg));
else
r = snprintf(buf, len, "%s%s" BLOB_FMT "/%s",
repo->url, repo->url[strlen(repo->url)-1] == '/' ? "" : "/",
BLOB_PRINTF(*db->arch), apkindex_tar_gz);
if (r >= len)
return -ENOBUFS;
return 0;
}
if (apk_flags & APK_SIMULATE) int apk_repo_format_item(struct apk_database *db, struct apk_repository *repo, struct apk_package *pkg,
return 0; int *fd, char *buf, size_t len)
{
if (strcmp(repo->url, "cache") == 0) {
*fd = db->cache_fd;
return apk_pkg_format_cache_pkg(APK_BLOB_PTR_LEN(buf, len), pkg);
} else {
*fd = AT_FDCWD;
return apk_repo_format_real_url(db, repo, pkg, buf, len);
}
}
r = apk_url_download(fullurl, db->cachetmp_fd, cacheitem); int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
struct apk_package *pkg, int verify)
{
char cacheitem[128], url[PATH_MAX];
struct apk_istream *is;
struct apk_bstream *bs;
struct apk_sign_ctx sctx;
int r, fd;
if (pkg != NULL)
r = apk_pkg_format_cache_pkg(APK_BLOB_BUF(cacheitem), pkg);
else
r = apk_repo_format_cache_index(APK_BLOB_BUF(cacheitem), repo);
if (r < 0) if (r < 0)
return r; return r;
if (verify != APK_SIGN_NONE) { r = apk_repo_format_real_url(db, repo, pkg, url, sizeof(url));
struct apk_istream *is; if (r < 0)
struct apk_sign_ctx sctx; return r;
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); apk_message("fetch %s", url);
is = apk_bstream_gunzip_mpart(
apk_bstream_from_file(db->cachetmp_fd, cacheitem), if (apk_flags & APK_SIMULATE)
apk_sign_ctx_mpart_cb, &sctx); return 0;
if (verify != APK_SIGN_NONE) {
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
bs = apk_bstream_from_url(url);
bs = apk_bstream_tee(bs, db->cachetmp_fd, cacheitem);
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache); r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache);
is->close(is);
apk_sign_ctx_free(&sctx); apk_sign_ctx_free(&sctx);
if (r != 0) { } else {
unlinkat(db->cachetmp_fd, cacheitem, 0); is = apk_istream_from_url(url);
return r; fd = openat(db->cachetmp_fd, cacheitem, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (fd >= 0) {
r = apk_istream_splice(is, fd, APK_SPLICE_ALL, NULL, NULL);
close(fd);
} else {
r = -errno;
} }
} }
is->close(is);
if (r < 0) {
unlinkat(db->cachetmp_fd, cacheitem, 0);
return r;
}
if (db->cachetmp_fd != db->cache_fd) { if (db->cachetmp_fd != db->cache_fd) {
if (renameat(db->cachetmp_fd, cacheitem, db->cache_fd, cacheitem) < 0) if (renameat(db->cachetmp_fd, cacheitem, db->cache_fd, cacheitem) < 0)
...@@ -1802,7 +1865,7 @@ static int foreach_cache_file(void *pctx, int dirfd, const char *name) ...@@ -1802,7 +1865,7 @@ static int foreach_cache_file(void *pctx, int dirfd, const char *name)
if (pkg0->name != name) if (pkg0->name != name)
continue; continue;
apk_pkg_format_cache(pkg0, APK_BLOB_BUF(tmp)); apk_pkg_format_cache_pkg(APK_BLOB_BUF(tmp), pkg0);
if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) { if (apk_blob_compare(b, APK_BLOB_STR(tmp)) == 0) {
pkg = pkg0; pkg = pkg0;
break; break;
...@@ -1878,24 +1941,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db, ...@@ -1878,24 +1941,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db,
return dbf->diri->pkg; return dbf->diri->pkg;
} }
int apk_repo_format_filename(char *buf, size_t len,
const char *repourl, apk_blob_t *arch,
const char *item)
{
int n;
if (arch != NULL)
n = snprintf(buf, len, "%s%s" BLOB_FMT "/%s",
repourl, repourl[strlen(repourl)-1] == '/' ? "" : "/",
BLOB_PRINTF(*arch), item);
else
n = snprintf(buf, len, "%s%s%s",
repourl, repourl[strlen(repourl)-1] == '/' ? "" : "/",
item);
return n;
}
unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned short pinning_mask) unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned short pinning_mask)
{ {
unsigned int repository_mask = 0; unsigned int repository_mask = 0;
...@@ -1910,22 +1955,6 @@ unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned sho ...@@ -1910,22 +1955,6 @@ unsigned int apk_db_get_pinning_mask_repos(struct apk_database *db, unsigned sho
return repository_mask; return repository_mask;
} }
static struct apk_bstream *apk_repo_file_open(struct apk_repository *repo,
apk_blob_t *arch,
const char *file,
char *buf, int buflen)
{
const char *url = repo->url;
apk_repo_format_filename(buf, buflen, url, arch, file);
/* We should not get called for non-repository files */
if (strcmp(repo->url, "cache") == 0)
return NULL;
return apk_bstream_from_url(buf);
}
struct apk_repository *apk_db_select_repo(struct apk_database *db, struct apk_repository *apk_db_select_repo(struct apk_database *db,
struct apk_package *pkg) struct apk_package *pkg)
{ {
...@@ -1950,13 +1979,9 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db, ...@@ -1950,13 +1979,9 @@ struct apk_repository *apk_db_select_repo(struct apk_database *db,
static int apk_repository_update(struct apk_database *db, struct apk_repository *repo) static int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
{ {
char cacheitem[PATH_MAX]; int r, verify = (apk_flags & APK_ALLOW_UNTRUSTED) ? APK_SIGN_NONE : APK_SIGN_VERIFY;
int r;
apk_cache_format_index(APK_BLOB_BUF(cacheitem), repo); r = apk_cache_download(db, repo, NULL, verify);
r = apk_cache_download(db, repo->url, db->arch, apkindex_tar_gz, cacheitem,
(apk_flags & APK_ALLOW_UNTRUSTED) ?
APK_SIGN_NONE : APK_SIGN_VERIFY);
if (r != 0) if (r != 0)
apk_error("%s: %s", repo->url, apk_error_str(r)); apk_error("%s: %s", repo->url, apk_error_str(r));
...@@ -2083,17 +2108,19 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository) ...@@ -2083,17 +2108,19 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t _repository)
if (apk_flags & APK_UPDATE_CACHE) if (apk_flags & APK_UPDATE_CACHE)
apk_repository_update(db, repo); apk_repository_update(db, repo);
} }
apk_cache_format_index(APK_BLOB_BUF(buf), repo); r = apk_repo_format_cache_index(APK_BLOB_BUF(buf), repo);
bs = apk_bstream_from_file(db->cache_fd, buf);
} else { } else {
db->local_repos |= BIT(repo_num); db->local_repos |= BIT(repo_num);
db->available_repos |= BIT(repo_num); db->available_repos |= BIT(repo_num);
bs = apk_repo_file_open(repo, db->arch, apkindex_tar_gz, buf, sizeof(buf)); 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 (bs != NULL)
r = load_index(db, bs, targz, repo_num);
else
r = -ENOENT;
} }
if (bs != NULL)
r = load_index(db, bs, targz, repo_num);
else
r = -ENOENT;
if (r != 0) { if (r != 0) {
apk_warning("Ignoring %s: %s", buf, apk_error_str(r)); apk_warning("Ignoring %s: %s", buf, apk_error_str(r));
...@@ -2386,8 +2413,8 @@ static void apk_db_purge_pkg(struct apk_database *db, ...@@ -2386,8 +2413,8 @@ static void apk_db_purge_pkg(struct apk_database *db,
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) { hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
snprintf(name, sizeof(name), snprintf(name, sizeof(name),
PKG_FILE_FMT "%s", DIR_FILE_FMT "%s",
PKG_FILE_PRINTF(diri->dir, file), DIR_FILE_PRINTF(diri->dir, file),
exten ?: ""); exten ?: "");
key = (struct apk_db_file_hash_key) { key = (struct apk_db_file_hash_key) {
...@@ -2433,10 +2460,10 @@ static void apk_db_migrate_files(struct apk_database *db, ...@@ -2433,10 +2460,10 @@ static void apk_db_migrate_files(struct apk_database *db,
dir->modified = 1; dir->modified = 1;
hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) { hlist_for_each_entry_safe(file, fc, fn, &diri->owned_files, diri_files_list) {
snprintf(name, sizeof(name), PKG_FILE_FMT, snprintf(name, sizeof(name), DIR_FILE_FMT,
PKG_FILE_PRINTF(diri->dir, file)); DIR_FILE_PRINTF(diri->dir, file));
snprintf(tmpname, sizeof(tmpname), PKG_FILE_FMT ".apk-new", snprintf(tmpname, sizeof(tmpname), DIR_FILE_FMT ".apk-new",
PKG_FILE_PRINTF(diri->dir, file)); DIR_FILE_PRINTF(diri->dir, file));
key = (struct apk_db_file_hash_key) { key = (struct apk_db_file_hash_key) {
.dirname = APK_BLOB_PTR_LEN(dir->name, dir->namelen), .dirname = APK_BLOB_PTR_LEN(dir->name, dir->namelen),
...@@ -2510,49 +2537,43 @@ static int apk_db_unpack_pkg(struct apk_database *db, ...@@ -2510,49 +2537,43 @@ static int apk_db_unpack_pkg(struct apk_database *db,
struct install_ctx ctx; struct install_ctx ctx;
struct apk_bstream *bs = NULL; struct apk_bstream *bs = NULL;
struct apk_istream *tar; struct apk_istream *tar;
struct apk_repository *repo;
struct apk_package *pkg = ipkg->pkg; struct apk_package *pkg = ipkg->pkg;
const char *action = "";
char file[PATH_MAX], item[128]; char file[PATH_MAX], item[128];
int r, need_copy = FALSE; int r, filefd = AT_FDCWD, need_copy = FALSE;
if (pkg->filename == NULL) { if (pkg->filename == NULL) {
struct apk_repository *repo;
repo = apk_db_select_repo(db, pkg); repo = apk_db_select_repo(db, pkg);
if (repo == NULL) { if (repo == NULL) {
apk_error("%s-%s: package is not currently available", action = "unable to select package: ";
pkg->name->name, pkg->version); r = -ENOPKG;
return -1; goto err_msg;
}
if (strcmp(repo->url, "cache") == 0) {
apk_pkg_format_cache(pkg, APK_BLOB_BUF(file));
bs = apk_bstream_from_file(db->cache_fd, file);
} else {
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
bs = apk_repo_file_open(repo, pkg->arch,
item, file, sizeof(file));
if (!(pkg->repos & db->local_repos))
need_copy = TRUE;
} }
r = apk_repo_format_item(db, repo, pkg, &filefd, file, sizeof(file));
if (r < 0)
goto err_msg;
if (!(pkg->repos & db->local_repos))
need_copy = TRUE;
} else { } else {
bs = apk_bstream_from_file(AT_FDCWD, pkg->filename);
strncpy(file, pkg->filename, sizeof(file)); strncpy(file, pkg->filename, sizeof(file));
need_copy = TRUE; need_copy = TRUE;
} }
if (!apk_db_cache_active(db)) if (!apk_db_cache_active(db))
need_copy = FALSE; need_copy = FALSE;
bs = apk_bstream_from_fd_url(filefd, file);
if (bs == NULL) { if (bs == NULL) {
apk_error("%s: %s", file, strerror(errno)); r = -errno;
return errno; goto err_msg;
} }
if (need_copy) { if (need_copy) {
apk_pkg_format_cache(pkg, APK_BLOB_BUF(item)); apk_pkg_format_cache_pkg(APK_BLOB_BUF(item), pkg);
bs = apk_bstream_tee(bs, db->cachetmp_fd, item); bs = apk_bstream_tee(bs, db->cachetmp_fd, item);
if (bs == NULL) { if (bs == NULL) {
apk_error("Unable to cache %s: %s", action = "unable cache package: ";
file, strerror(errno)); r = -errno;
return errno; goto err_msg;
} }
} }
...@@ -2580,19 +2601,20 @@ static int apk_db_unpack_pkg(struct apk_database *db, ...@@ -2580,19 +2601,20 @@ static int apk_db_unpack_pkg(struct apk_database *db,
unlinkat(db->cachetmp_fd, item, 0); unlinkat(db->cachetmp_fd, item, 0);
} }
} }
if (r != 0)
goto err_msg;
r = apk_db_run_pending_script(&ctx);
if (r != 0) { if (r != 0) {
apk_error("%s: %s", file, apk_error_str(r)); action = "unable to run script: ";
goto err; goto err_msg;
} }
r = apk_db_run_pending_script(&ctx);
if (r != 0)
goto err;
apk_db_migrate_files(db, ipkg); apk_db_migrate_files(db, ipkg);
return 0; return 0;
err: err_msg:
apk_error("%s: %s%s", file, action, apk_error_str(r));
if (!reinstall) if (!reinstall)
apk_db_purge_pkg(db, ipkg, ".apk-new"); apk_db_purge_pkg(db, ipkg, ".apk-new");
return r; return r;
......
...@@ -95,67 +95,74 @@ static int fetch_package(struct fetch_ctx *fctx, ...@@ -95,67 +95,74 @@ static int fetch_package(struct fetch_ctx *fctx,
{ {
struct apk_istream *is; struct apk_istream *is;
struct apk_repository *repo; struct apk_repository *repo;
char pkgfile[PATH_MAX], url[PATH_MAX]; struct apk_file_info fi;
int r, fd; char url[PATH_MAX], filename[256];
int r, fd, urlfd;
apk_pkg_format_plain(pkg, APK_BLOB_BUF(pkgfile)); repo = apk_db_select_repo(db, pkg);
if (repo == NULL) {
r = -ENOPKG;
goto err;
}
if (!(fctx->flags & FETCH_STDOUT)) { if (snprintf(filename, sizeof(filename), PKG_FILE_FMT, PKG_FILE_PRINTF(pkg)) >= sizeof(filename)) {
struct apk_file_info fi; r = -ENOBUFS;
goto err;
}