summaryrefslogtreecommitdiff
path: root/src/fetch.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2013-06-17 14:24:34 +0300
committerTimo Teräs <timo.teras@iki.fi>2013-06-17 14:38:27 +0300
commit9d100378074d21f99dc26bae8417932dc110664e (patch)
treee66829190a5648b146698e372b2a9403d535f866 /src/fetch.c
parentdbb642206d2ef73c5428a04cb10bb27e7cdd3b29 (diff)
downloadapk-tools-9d100378074d21f99dc26bae8417932dc110664e.tar.gz
apk-tools-9d100378074d21f99dc26bae8417932dc110664e.tar.bz2
apk-tools-9d100378074d21f99dc26bae8417932dc110664e.tar.xz
apk-tools-9d100378074d21f99dc26bae8417932dc110664e.zip
db: refactor repository file construction
Fixes also 'fetch' applet to prefer copying/linking to files from cache if possible.
Diffstat (limited to 'src/fetch.c')
-rw-r--r--src/fetch.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/fetch.c b/src/fetch.c
index f3debd0..028a999 100644
--- a/src/fetch.c
+++ b/src/fetch.c
@@ -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)