Commit 555363f0 authored by Timo Teräs's avatar Timo Teräs

url: use libfetch to retrieve http/https/ftp files

parent aab5f469
...@@ -66,7 +66,8 @@ LDFLAGS_apk += -L$(obj) ...@@ -66,7 +66,8 @@ LDFLAGS_apk += -L$(obj)
LDFLAGS_apk-test += -L$(obj) LDFLAGS_apk-test += -L$(obj)
CFLAGS_ALL += $(shell $(PKG_CONFIG) --cflags $(PKGDEPS)) CFLAGS_ALL += $(shell $(PKG_CONFIG) --cflags $(PKGDEPS))
LIBS := -Wl,--as-needed \ LIBS := /usr/lib/libfetch.a \
-Wl,--as-needed \
$(shell $(PKG_CONFIG) --libs $(PKGDEPS)) \ $(shell $(PKG_CONFIG) --libs $(PKGDEPS)) \
-Wl,--no-as-needed -Wl,--no-as-needed
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include <openssl/engine.h> #include <openssl/engine.h>
#endif #endif
#include <fetch.h>
#include "apk_defines.h" #include "apk_defines.h"
#include "apk_database.h" #include "apk_database.h"
#include "apk_applet.h" #include "apk_applet.h"
...@@ -367,6 +369,7 @@ int main(int argc, char **argv) ...@@ -367,6 +369,7 @@ int main(int argc, char **argv)
init_openssl(); init_openssl();
setup_automatic_flags(); setup_automatic_flags();
fetchConnectionCacheInit(16, 1);
optindex = 0; optindex = 0;
while ((r = getopt_long(argc, argv, short_options, while ((r = getopt_long(argc, argv, short_options,
...@@ -554,5 +557,7 @@ int main(int argc, char **argv) ...@@ -554,5 +557,7 @@ int main(int argc, char **argv)
err: err:
if (ctx) if (ctx)
free(ctx); free(ctx);
fetchConnectionCacheClose();
return r; return r;
} }
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <fetch.h>
#include "apk_io.h" #include "apk_io.h"
const char *apk_url_local_file(const char *url) const char *apk_url_local_file(const char *url)
...@@ -31,72 +33,64 @@ const char *apk_url_local_file(const char *url) ...@@ -31,72 +33,64 @@ const char *apk_url_local_file(const char *url)
return NULL; 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)) struct apk_fetch_istream *fis = container_of(stream, struct apk_fetch_istream, is);
return -EFAULT; ssize_t i = 0, r;
switch (WEXITSTATUS(status)) { if (ptr == NULL) return apk_istream_skip(&fis->is, size);
case 0:
return 0; while (i < size) {
case 3: r = fetchIO_read(fis->fetchIO, ptr + i, size - i);
return -EIO; if (r < 0) return -EIO;
case 4: if (r == 0) break;
return -ECONNABORTED; i += r;
case 8:
return -ENOENT;
default:
return -EFAULT;
} }
return i;
} }
static int fork_wget(const char *url, pid_t *ppid) static void fetch_close(void *stream)
{ {
pid_t pid; struct apk_fetch_istream *fis = container_of(stream, struct apk_fetch_istream, is);
int fds[2];
if (pipe(fds) < 0) fetchIO_close(fis->fetchIO);
return -1; free(fis);
}
pid = fork(); static struct apk_istream *apk_istream_fetch(const char *url)
if (pid == -1) { {
close(fds[0]); struct apk_fetch_istream *fis;
close(fds[1]); fetchIO *io;
return -1;
}
if (pid == 0) { io = fetchGetURL(url, "");
setsid(); if (!io) return NULL;
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);
}
close(fds[1]); fis = malloc(sizeof(*fis));
if (!fis) {
fetchIO_close(io);
return NULL;
}
if (ppid != NULL) *fis = (struct apk_fetch_istream) {
*ppid = pid; .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) 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) if (apk_url_local_file(url) != NULL)
return apk_istream_from_file(atfd, apk_url_local_file(url)); return apk_istream_from_file(atfd, apk_url_local_file(url));
return apk_istream_fetch(url);
fd = fork_wget(url, &pid);
return apk_istream_from_fd_pid(fd, pid, translate_wget);
} }
struct apk_istream *apk_istream_from_url_gz(const char *file) 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) ...@@ -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) 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) if (apk_url_local_file(url) != NULL)
return apk_bstream_from_file(atfd, apk_url_local_file(url)); return apk_bstream_from_file(atfd, apk_url_local_file(url));
return apk_bstream_from_istream(apk_istream_fetch(url));
fd = fork_wget(url, &pid);
return apk_bstream_from_fd_pid(fd, pid, translate_wget);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment