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 @@
#include "apk_provider_data.h"
#include "apk_solver_data.h"
extern const char * const apk_index_gz;
extern const char * const apkindex_tar_gz;
struct apk_name;
APK_ARRAY(apk_name_array, struct apk_name *);
......@@ -71,8 +68,8 @@ struct apk_db_dir {
char name[];
};
#define PKG_FILE_FMT "%s%s%s"
#define PKG_FILE_PRINTF(dir,file) (dir)->name, (dir)->namelen ? "/" : "", (file)->name
#define DIR_FILE_FMT "%s%s%s"
#define DIR_FILE_PRINTF(dir,file) (dir)->name, (dir)->namelen ? "/" : "", (file)->name
struct apk_db_dir_instance {
struct hlist_node pkg_dirs_list;
......@@ -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);
struct apk_repository *apk_db_select_repo(struct apk_database *db,
struct apk_package *pkg);
int apk_repo_format_filename(char *buf, size_t len,
const char *repourl, apk_blob_t *arch,
const char *pkgfile);
int apk_repo_format_cache_index(apk_blob_t to, struct apk_repository *repo);
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);
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, const char *url, apk_blob_t *arch,
const char *item, const char *cache_item, int verify);
int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
struct apk_package *pkg, int verify);
typedef void (*apk_cache_item_cb)(struct apk_database *db,
int dirfd, const char *name,
......
......@@ -123,6 +123,8 @@ APK_ARRAY(apk_package_array, struct apk_package *);
#define PKG_VER_FMT "%s-" BLOB_FMT
#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[];
......@@ -160,8 +162,6 @@ int apk_script_type(const char *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);
int apk_pkg_read(struct apk_database *db, const char *name,
struct apk_sign_ctx *ctx, struct apk_package **pkg);
......
......@@ -31,7 +31,6 @@ static int cache_download(struct apk_database *db)
struct apk_change *change;
struct apk_package *pkg;
struct apk_repository *repo;
char item[PATH_MAX], cacheitem[PATH_MAX];
int i, r, ret = 0;
r = apk_solver_solve(db, 0, db->world, &changeset);
......@@ -50,13 +49,9 @@ static int cache_download(struct apk_database *db)
if (repo == NULL)
continue;
apk_pkg_format_cache(pkg, APK_BLOB_BUF(cacheitem));
apk_pkg_format_plain(pkg, APK_BLOB_BUF(item));
r = apk_cache_download(db, repo->url, pkg->arch,
item, cacheitem,
APK_SIGN_VERIFY_IDENTITY);
r = apk_cache_download(db, repo, pkg, APK_SIGN_VERIFY_IDENTITY);
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++;
}
}
......@@ -76,7 +71,7 @@ static void cache_clean_item(struct apk_database *db, int dirfd, const char *nam
b = APK_BLOB_STR(name);
for (i = 0; i < db->num_repos; i++) {
/* 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)
return;
}
......
This diff is collapsed.
......@@ -95,67 +95,74 @@ static int fetch_package(struct fetch_ctx *fctx,
{
struct apk_istream *is;
struct apk_repository *repo;
char pkgfile[PATH_MAX], url[PATH_MAX];
int r, fd;
struct apk_file_info fi;
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)) {
struct apk_file_info fi;
if (snprintf(filename, sizeof(filename), PKG_FILE_FMT, PKG_FILE_PRINTF(pkg)) >= sizeof(filename)) {
r = -ENOBUFS;
goto err;
}
if (apk_file_get_info(fctx->outdir_fd, pkgfile,
APK_CHECKSUM_NONE, &fi) == 0 &&
if (!(fctx->flags & FETCH_STDOUT)) {
if (apk_file_get_info(fctx->outdir_fd, filename, APK_CHECKSUM_NONE, &fi) == 0 &&
fi.size == pkg->size)
return 0;
}
apk_message("Downloading " PKG_VER_FMT, PKG_VER_PRINTF(pkg));
repo = apk_db_select_repo(db, pkg);
if (repo == NULL) {
apk_error(PKG_VER_FMT ": package is not currently available",
PKG_VER_PRINTF(pkg));
return -1;
}
if (apk_flags & APK_SIMULATE)
return 0;
apk_repo_format_filename(url, sizeof(url), repo->url, pkg->arch, pkgfile);
r = apk_repo_format_item(db, repo, pkg, &urlfd, url, sizeof(url));
if (r < 0)
goto err;
if (fctx->flags & FETCH_STDOUT) {
fd = STDOUT_FILENO;
} else {
if ((fctx->flags & FETCH_LINK) && apk_url_local_file(url)) {
if (linkat(AT_FDCWD, url,
fctx->outdir_fd, pkgfile,
if ((fctx->flags & FETCH_LINK) && urlfd >= 0) {
if (linkat(urlfd, url,
fctx->outdir_fd, filename,
AT_SYMLINK_FOLLOW) == 0)
return 0;
}
fd = openat(fctx->outdir_fd, pkgfile,
fd = openat(fctx->outdir_fd, filename,
O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644);
if (fd < 0) {
apk_error("%s: %s", pkgfile, strerror(errno));
return -1;
r = -errno;
goto err;
}
}
is = apk_istream_from_url(url);
is = apk_istream_from_fd_url(urlfd, url);
if (is == NULL) {
apk_error("Unable to download '%s'", url);
return -1;
r = -EIO;
goto err;
}
r = apk_istream_splice(is, fd, pkg->size, NULL, NULL);
is->close(is);
if (fd != STDOUT_FILENO)
close(fd);
if (r != pkg->size) {
apk_error("Unable to download '%s'", url);
unlinkat(fctx->outdir_fd, pkgfile, 0);
return -1;
unlinkat(fctx->outdir_fd, filename, 0);
if (r >= 0) r = -EIO;
goto err;
}
return 0;
err:
apk_error(PKG_VER_FMT ": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
return r;
}
static int fetch_main(void *ctx, struct apk_database *db, int argc, char **argv)
......
......@@ -314,7 +314,7 @@ static void info_print_contents(struct apk_database *db, struct apk_package *pkg
diri_files_list) {
if (apk_verbosity > 1)
printf("%s: ", pkg->name->name);
printf(PKG_FILE_FMT "\n", PKG_FILE_PRINTF(diri->dir, file));
printf(DIR_FILE_FMT "\n", DIR_FILE_PRINTF(diri->dir, file));
}
}
}
......
......@@ -53,29 +53,6 @@ struct apk_package *apk_pkg_get_installed(struct apk_name *name)
return NULL;
}
void apk_pkg_format_plain(struct apk_package *pkg, apk_blob_t to)
{
/* pkgname-1.0.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"));
apk_blob_push_blob(&to, APK_BLOB_PTR_LEN("", 1));
}
void apk_pkg_format_cache(struct apk_package *pkg, apk_blob_t to)
{
/* 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));
}
struct apk_package *apk_pkg_new(void)
{
struct apk_package *pkg;
......
......@@ -84,6 +84,8 @@ const char *apk_error_str(int error)
return "BAD archive";
case ENOMSG:
return "archive does not contain expected data";
case ENOPKG:
return "package not available";
default:
return strerror(error);
}
......
......@@ -427,7 +427,7 @@ static int compare_providers(struct apk_solver_state *ss,
return r;
/* Prefer available */
if (solver_flags & APK_SOLVERF_AVAILABLE) {
if (solver_flags & (APK_SOLVERF_AVAILABLE | APK_SOLVERF_REINSTALL)) {
r = !!(pkgA->repos & db->available_repos) -
!!(pkgB->repos & db->available_repos);
if (r)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment