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

cute-signatures
Timo Teräs 2014-10-08 10:10:45 +03:00
parent aab5f46959
commit 555363f056
3 changed files with 52 additions and 57 deletions

View File

@ -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

View File

@ -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;
}

101
src/url.c
View File

@ -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)
{
if (!WIFEXITED(status))
return -EFAULT;
struct apk_fetch_istream {
struct apk_istream is;
fetchIO *fetchIO;
};
switch (WEXITSTATUS(status)) {
case 0:
return 0;
case 3:
return -EIO;
case 4:
return -ECONNABORTED;
case 8:
return -ENOENT;
default:
return -EFAULT;
static ssize_t fetch_read(void *stream, void *ptr, size_t size)
{
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;
io = fetchGetURL(url, "");
if (!io) return NULL;
fis = malloc(sizeof(*fis));
if (!fis) {
fetchIO_close(io);
return NULL;
}
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);
}
*fis = (struct apk_fetch_istream) {
.is.read = fetch_read,
.is.close = fetch_close,
.fetchIO = io,
};
close(fds[1]);
if (ppid != NULL)
*ppid = pid;
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));
}