From 555363f056377508040d3a555d198c4b87aff3a3 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 8 Oct 2014 10:10:45 +0300 Subject: url: use libfetch to retrieve http/https/ftp files --- src/Makefile | 3 +- src/apk.c | 5 +++ src/url.c | 99 +++++++++++++++++++++++++++--------------------------------- 3 files changed, 51 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 8fdaf4b..b0b9537 100644 --- a/src/Makefile +++ b/src/Makefile @@ -66,7 +66,8 @@ LDFLAGS_apk += -L$(obj) LDFLAGS_apk-test += -L$(obj) CFLAGS_ALL += $(shell $(PKG_CONFIG) --cflags $(PKGDEPS)) -LIBS := -Wl,--as-needed \ +LIBS := /usr/lib/libfetch.a \ + -Wl,--as-needed \ $(shell $(PKG_CONFIG) --libs $(PKGDEPS)) \ -Wl,--no-as-needed diff --git a/src/apk.c b/src/apk.c index 8d44b1f..e677e88 100644 --- a/src/apk.c +++ b/src/apk.c @@ -26,6 +26,8 @@ #include #endif +#include + #include "apk_defines.h" #include "apk_database.h" #include "apk_applet.h" @@ -367,6 +369,7 @@ int main(int argc, char **argv) init_openssl(); setup_automatic_flags(); + fetchConnectionCacheInit(16, 1); optindex = 0; while ((r = getopt_long(argc, argv, short_options, @@ -554,5 +557,7 @@ int main(int argc, char **argv) err: if (ctx) free(ctx); + + fetchConnectionCacheClose(); return r; } diff --git a/src/url.c b/src/url.c index a8354ee..f3c6631 100644 --- a/src/url.c +++ b/src/url.c @@ -16,6 +16,8 @@ #include #include +#include + #include "apk_io.h" const char *apk_url_local_file(const char *url) @@ -31,72 +33,64 @@ const char *apk_url_local_file(const char *url) return NULL; } -static int translate_wget(int status) +struct apk_fetch_istream { + struct apk_istream is; + fetchIO *fetchIO; +}; + +static ssize_t fetch_read(void *stream, void *ptr, size_t size) { - if (!WIFEXITED(status)) - return -EFAULT; - - switch (WEXITSTATUS(status)) { - case 0: - return 0; - case 3: - return -EIO; - case 4: - return -ECONNABORTED; - case 8: - return -ENOENT; - default: - return -EFAULT; + struct apk_fetch_istream *fis = container_of(stream, struct apk_fetch_istream, is); + ssize_t i = 0, r; + + if (ptr == NULL) return apk_istream_skip(&fis->is, size); + + while (i < size) { + r = fetchIO_read(fis->fetchIO, ptr + i, size - i); + if (r < 0) return -EIO; + if (r == 0) break; + i += r; } + + return i; } -static int fork_wget(const char *url, pid_t *ppid) +static void fetch_close(void *stream) { - pid_t pid; - int fds[2]; + struct apk_fetch_istream *fis = container_of(stream, struct apk_fetch_istream, is); - if (pipe(fds) < 0) - return -1; + fetchIO_close(fis->fetchIO); + free(fis); +} - pid = fork(); - if (pid == -1) { - close(fds[0]); - close(fds[1]); - return -1; - } +static struct apk_istream *apk_istream_fetch(const char *url) +{ + struct apk_fetch_istream *fis; + fetchIO *io; - if (pid == 0) { - setsid(); - close(fds[0]); - dup2(open("/dev/null", O_RDONLY), STDIN_FILENO); - dup2(fds[1], STDOUT_FILENO); - execlp("wget", "wget", "-q", "-O", "-", url, (void*) 0); - /* fall back to busybox wget - * See http://redmine.alpinelinux.org/issues/347 - */ - execlp("busybox", "wget", "-q", "-O", "-", url, (void*) 0); - execlp("busybox.static", "wget", "-q", "-O", "-", url, (void*) 0); - exit(0); - } + io = fetchGetURL(url, ""); + if (!io) return NULL; - close(fds[1]); + fis = malloc(sizeof(*fis)); + if (!fis) { + fetchIO_close(io); + return NULL; + } - if (ppid != NULL) - *ppid = pid; + *fis = (struct apk_fetch_istream) { + .is.read = fetch_read, + .is.close = fetch_close, + .fetchIO = io, + }; - return fds[0]; + return &fis->is; } struct apk_istream *apk_istream_from_fd_url(int atfd, const char *url) { - pid_t pid; - int fd; - if (apk_url_local_file(url) != NULL) return apk_istream_from_file(atfd, apk_url_local_file(url)); - - fd = fork_wget(url, &pid); - return apk_istream_from_fd_pid(fd, pid, translate_wget); + return apk_istream_fetch(url); } struct apk_istream *apk_istream_from_url_gz(const char *file) @@ -106,12 +100,7 @@ struct apk_istream *apk_istream_from_url_gz(const char *file) struct apk_bstream *apk_bstream_from_fd_url(int atfd, const char *url) { - pid_t pid; - int fd; - if (apk_url_local_file(url) != NULL) return apk_bstream_from_file(atfd, apk_url_local_file(url)); - - fd = fork_wget(url, &pid); - return apk_bstream_from_fd_pid(fd, pid, translate_wget); + return apk_bstream_from_istream(apk_istream_fetch(url)); } -- cgit v1.2.3-70-g09d2