summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile3
-rw-r--r--src/apk.c5
-rw-r--r--src/url.c99
3 files changed, 51 insertions, 56 deletions
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 <openssl/engine.h>
#endif
+#include <fetch.h>
+
#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 <unistd.h>
#include <sys/wait.h>
+#include <fetch.h>
+
#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));
}