summaryrefslogtreecommitdiffstats
path: root/src/fetch.c
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2009-06-09 11:06:22 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2009-06-09 11:12:06 +0200
commit50cdcca8339d73ea8fe29fc54c2300c674f91dc5 (patch)
treeaaeb8593a75e1cd2de54f2d8d31728fcc234e17c /src/fetch.c
parent9c4fdf9ead1a6b694e0b96c3d04d2bc4939daca8 (diff)
downloadapk-tools-50cdcca8339d73ea8fe29fc54c2300c674f91dc5.tar.bz2
apk-tools-50cdcca8339d73ea8fe29fc54c2300c674f91dc5.tar.xz
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.
Diffstat (limited to 'src/fetch.c')
-rw-r--r--src/fetch.c52
1 files changed, 33 insertions, 19 deletions
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 <stdio.h>
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
#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,