From 50cdcca8339d73ea8fe29fc54c2300c674f91dc5 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Tue, 9 Jun 2009 11:06:22 +0200 Subject: fetch: added --link/-L option fixes #42 This will also fix a bug that left an empty file in destination dir when source file did not exist in repository. There are still issues with paths longer than 255 chars. --- src/fetch.c | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'src/fetch.c') diff --git a/src/fetch.c b/src/fetch.c index f3c651b..5668eae 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "apk_applet.h" #include "apk_database.h" @@ -20,6 +21,7 @@ #define FETCH_RECURSIVE 1 #define FETCH_STDOUT 2 +#define FETCH_LINK 4 struct fetch_ctx { unsigned int flags; @@ -37,6 +39,9 @@ static int fetch_parse(void *ctx, int optch, int optindex, const char *optarg) case 's': fctx->flags |= FETCH_STDOUT; break; + case 'L': + fctx->flags |= FETCH_LINK; + break; case 'o': fctx->outdir = optarg; break; @@ -51,29 +56,22 @@ static int fetch_package(struct fetch_ctx *fctx, struct apk_package *pkg) { struct apk_istream *is; - char file[256]; + char infile[256]; + char outfile[256]; int i, r, fd; - if (fctx->flags & FETCH_STDOUT) { - fd = STDOUT_FILENO; - } else { + printf("DEBUG: hello\n"); + if (!(fctx->flags & FETCH_STDOUT)) { struct apk_file_info fi; - snprintf(file, sizeof(file), "%s/%s-%s.apk", + snprintf(outfile, sizeof(outfile), "%s/%s-%s.apk", fctx->outdir ? fctx->outdir : ".", pkg->name->name, pkg->version); - if (apk_file_get_info(file, &fi) == 0 && + if (apk_file_get_info(outfile, &fi) == 0 && fi.size == pkg->size) return 0; - - fd = creat(file, 0644); - if (fd < 0) { - apk_error("Unable to create '%s'", file); - return -1; - } } - apk_message("Downloading %s-%s", pkg->name->name, pkg->version); for (i = 0; i < APK_MAX_REPOS; i++) @@ -86,11 +84,26 @@ static int fetch_package(struct fetch_ctx *fctx, return -1; } - snprintf(file, sizeof(file), "%s/%s-%s.apk", + snprintf(infile, sizeof(infile), "%s/%s-%s.apk", db->repos[i].url, pkg->name->name, pkg->version); - is = apk_istream_from_url(file); + + if (fctx->flags & FETCH_STDOUT) { + fd = STDOUT_FILENO; + } else { + if ((fctx->flags & FETCH_LINK) && apk_url_local_file(infile)) { + if (link(infile, outfile) == 0) + return 0; + } + fd = creat(outfile, 0644); + if (fd < 0) { + apk_error("%s: %s", outfile, strerror(errno)); + return -1; + } + } + + is = apk_istream_from_url(infile); if (is == NULL) { - apk_error("Unable to download '%s'", file); + apk_error("Unable to download '%s'", infile); return -1; } @@ -99,8 +112,8 @@ static int fetch_package(struct fetch_ctx *fctx, if (fd != STDOUT_FILENO) close(fd); if (r != pkg->size) { - apk_error("Unable to download '%s'", file); - unlink(file); + apk_error("Unable to download '%s'", infile); + unlink(outfile); return -1; } @@ -171,12 +184,13 @@ err: static struct option fetch_options[] = { { "recursive", no_argument, NULL, 'R' }, { "stdout", no_argument, NULL, 's' }, + { "link", no_argument, NULL, 'L' }, { "output", required_argument, NULL, 'o' }, }; static struct apk_applet apk_fetch = { .name = "fetch", - .usage = "[-R|--recursive|--stdout] [-o dir] apkname...", + .usage = "[-R|--recursive|--stdout] [--link|-L] [-o dir] apkname...", .context_size = sizeof(struct fetch_ctx), .num_options = ARRAY_SIZE(fetch_options), .options = fetch_options, -- cgit v1.2.3-60-g2f50