io: prepartions for url handling
parent
5ea81ca564
commit
4bafa681fe
1
TODO
1
TODO
|
@ -6,7 +6,6 @@
|
||||||
- index/package fetching from URLs
|
- index/package fetching from URLs
|
||||||
- read from config file
|
- read from config file
|
||||||
- cache .apks on USB stick when using network repo for reboot
|
- cache .apks on USB stick when using network repo for reboot
|
||||||
- Installation of .APK files not in any repository
|
|
||||||
|
|
||||||
- Error handling and rollback
|
- Error handling and rollback
|
||||||
- Dependency manipulation API: deletion, overwrite, check compatibility
|
- Dependency manipulation API: deletion, overwrite, check compatibility
|
||||||
|
|
|
@ -16,6 +16,7 @@ apk_OBJS = \
|
||||||
archive.o \
|
archive.o \
|
||||||
version.o \
|
version.o \
|
||||||
io.o \
|
io.o \
|
||||||
|
url.o \
|
||||||
gunzip.o \
|
gunzip.o \
|
||||||
blob.o \
|
blob.o \
|
||||||
hash.o \
|
hash.o \
|
||||||
|
|
|
@ -42,11 +42,14 @@ struct apk_istream *apk_gunzip_bstream(struct apk_bstream *);
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_fd(int fd);
|
struct apk_istream *apk_istream_from_fd(int fd);
|
||||||
struct apk_istream *apk_istream_from_file(const char *file);
|
struct apk_istream *apk_istream_from_file(const char *file);
|
||||||
|
struct apk_istream *apk_istream_from_url(const char *url);
|
||||||
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
|
size_t apk_istream_skip(struct apk_istream *istream, size_t size);
|
||||||
size_t apk_istream_splice(void *stream, int fd, size_t size);
|
size_t apk_istream_splice(void *stream, int fd, size_t size);
|
||||||
|
|
||||||
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
|
struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream);
|
||||||
struct apk_bstream *apk_bstream_from_fd(int fd);
|
struct apk_bstream *apk_bstream_from_fd(int fd);
|
||||||
|
struct apk_bstream *apk_bstream_from_file(const char *file);
|
||||||
|
struct apk_bstream *apk_bstream_from_url(const char *url);
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_file_gz(const char *file);
|
struct apk_istream *apk_istream_from_file_gz(const char *file);
|
||||||
|
|
||||||
|
|
|
@ -840,7 +840,7 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
struct install_ctx ctx;
|
struct install_ctx ctx;
|
||||||
csum_t csum;
|
csum_t csum;
|
||||||
char file[256];
|
char file[256];
|
||||||
int fd, r;
|
int r;
|
||||||
|
|
||||||
if (fchdir(db->root_fd) < 0)
|
if (fchdir(db->root_fd) < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -866,22 +866,15 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
snprintf(file, sizeof(file),
|
snprintf(file, sizeof(file),
|
||||||
"%s/%s-%s.apk",
|
"%s/%s-%s.apk",
|
||||||
db->repos[0].url, newpkg->name->name, newpkg->version);
|
db->repos[0].url, newpkg->name->name, newpkg->version);
|
||||||
|
bs = apk_bstream_from_url(file);
|
||||||
fd = open(file, O_RDONLY);
|
|
||||||
} else
|
} else
|
||||||
fd = open(newpkg->filename, O_RDONLY);
|
bs = apk_bstream_from_file(newpkg->filename);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (bs == NULL) {
|
||||||
apk_error("%s: %s", file, strerror(errno));
|
apk_error("%s: %s", file, strerror(errno));
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
|
||||||
|
|
||||||
bs = apk_bstream_from_fd(fd);
|
|
||||||
if (bs == NULL)
|
|
||||||
goto err_close;
|
|
||||||
|
|
||||||
ctx = (struct install_ctx) {
|
ctx = (struct install_ctx) {
|
||||||
.db = db,
|
.db = db,
|
||||||
.pkg = newpkg,
|
.pkg = newpkg,
|
||||||
|
@ -909,8 +902,7 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
write(STDOUT_FILENO, ".", 1);
|
write(STDOUT_FILENO, ".", 1);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
err_close:
|
err_close:
|
||||||
close(fd);
|
bs->close(bs, NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
35
src/io.c
35
src/io.c
|
@ -60,6 +60,9 @@ struct apk_istream *apk_istream_from_fd(int fd)
|
||||||
{
|
{
|
||||||
struct apk_fd_istream *fis;
|
struct apk_fd_istream *fis;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
fis = malloc(sizeof(struct apk_fd_istream));
|
fis = malloc(sizeof(struct apk_fd_istream));
|
||||||
if (fis == NULL)
|
if (fis == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -81,6 +84,8 @@ struct apk_istream *apk_istream_from_file(const char *file)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
return apk_istream_from_fd(fd);
|
return apk_istream_from_fd(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +283,9 @@ struct apk_bstream *apk_bstream_from_fd(int fd)
|
||||||
{
|
{
|
||||||
struct apk_bstream *bs;
|
struct apk_bstream *bs;
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
bs = apk_mmap_bstream_from_fd(fd);
|
bs = apk_mmap_bstream_from_fd(fd);
|
||||||
if (bs != NULL)
|
if (bs != NULL)
|
||||||
return bs;
|
return bs;
|
||||||
|
@ -285,6 +293,18 @@ struct apk_bstream *apk_bstream_from_fd(int fd)
|
||||||
return apk_bstream_from_istream(apk_istream_from_fd(fd));
|
return apk_bstream_from_istream(apk_istream_from_fd(fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct apk_bstream *apk_bstream_from_file(const char *file)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(file, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
return apk_bstream_from_fd(fd);
|
||||||
|
}
|
||||||
|
|
||||||
apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
|
apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
@ -338,7 +358,6 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct apk_bstream *bs;
|
struct apk_bstream *bs;
|
||||||
int fd;
|
|
||||||
|
|
||||||
if (stat(filename, &st) != 0)
|
if (stat(filename, &st) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -352,11 +371,7 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
|
||||||
.device = st.st_dev,
|
.device = st.st_dev,
|
||||||
};
|
};
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY);
|
bs = apk_bstream_from_file(filename);
|
||||||
if (fd < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bs = apk_bstream_from_fd(fd);
|
|
||||||
if (bs != NULL)
|
if (bs != NULL)
|
||||||
bs->close(bs, fi->csum);
|
bs->close(bs, fi->csum);
|
||||||
|
|
||||||
|
@ -365,12 +380,6 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
|
||||||
|
|
||||||
struct apk_istream *apk_istream_from_file_gz(const char *file)
|
struct apk_istream *apk_istream_from_file_gz(const char *file)
|
||||||
{
|
{
|
||||||
int fd;
|
return apk_gunzip_bstream(apk_bstream_from_file(file));
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return apk_gunzip_bstream(apk_bstream_from_fd(fd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* url.c - Alpine Package Keeper (APK)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
|
||||||
|
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation. See http://www.gnu.org/ for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "apk_io.h"
|
||||||
|
|
||||||
|
static const char *url_is_file(const char *url)
|
||||||
|
{
|
||||||
|
if (strncmp(url, "file:", 5) == 0)
|
||||||
|
return &url[5];
|
||||||
|
|
||||||
|
if (strncmp(url, "http:", 5) != 0 &&
|
||||||
|
strncmp(url, "https:", 6) != 0 &&
|
||||||
|
strncmp(url, "ftp:", 4) != 0)
|
||||||
|
return url;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fork_wget(const char *url)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
int fds[2];
|
||||||
|
|
||||||
|
if (pipe(fds) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
close(fds[0]);
|
||||||
|
close(fds[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
setsid();
|
||||||
|
close(fds[0]);
|
||||||
|
dup2(open("/dev/null", O_WRONLY), STDERR_FILENO);
|
||||||
|
dup2(open("/dev/null", O_RDONLY), STDIN_FILENO);
|
||||||
|
dup2(fds[1], STDOUT_FILENO);
|
||||||
|
execlp("wget", "wget", "-O", "-", url, NULL);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fds[1]);
|
||||||
|
return fds[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct apk_istream *apk_istream_from_url(const char *url)
|
||||||
|
{
|
||||||
|
if (url_is_file(url) != NULL)
|
||||||
|
return apk_istream_from_file(url_is_file(url));
|
||||||
|
|
||||||
|
return apk_istream_from_fd(fork_wget(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct apk_bstream *apk_bstream_from_url(const char *url)
|
||||||
|
{
|
||||||
|
if (url_is_file(url))
|
||||||
|
return apk_bstream_from_file(url);
|
||||||
|
|
||||||
|
return apk_bstream_from_fd(fork_wget(url));
|
||||||
|
}
|
Loading…
Reference in New Issue