io: prepartions for url handling
parent
5ea81ca564
commit
4bafa681fe
1
TODO
1
TODO
|
@ -6,7 +6,6 @@
|
|||
- index/package fetching from URLs
|
||||
- read from config file
|
||||
- cache .apks on USB stick when using network repo for reboot
|
||||
- Installation of .APK files not in any repository
|
||||
|
||||
- Error handling and rollback
|
||||
- Dependency manipulation API: deletion, overwrite, check compatibility
|
||||
|
|
|
@ -16,6 +16,7 @@ apk_OBJS = \
|
|||
archive.o \
|
||||
version.o \
|
||||
io.o \
|
||||
url.o \
|
||||
gunzip.o \
|
||||
blob.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_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_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_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);
|
||||
|
||||
|
|
|
@ -840,7 +840,7 @@ int apk_db_install_pkg(struct apk_database *db,
|
|||
struct install_ctx ctx;
|
||||
csum_t csum;
|
||||
char file[256];
|
||||
int fd, r;
|
||||
int r;
|
||||
|
||||
if (fchdir(db->root_fd) < 0)
|
||||
return errno;
|
||||
|
@ -866,22 +866,15 @@ int apk_db_install_pkg(struct apk_database *db,
|
|||
snprintf(file, sizeof(file),
|
||||
"%s/%s-%s.apk",
|
||||
db->repos[0].url, newpkg->name->name, newpkg->version);
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
bs = apk_bstream_from_url(file);
|
||||
} 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));
|
||||
return errno;
|
||||
}
|
||||
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
bs = apk_bstream_from_fd(fd);
|
||||
if (bs == NULL)
|
||||
goto err_close;
|
||||
|
||||
ctx = (struct install_ctx) {
|
||||
.db = db,
|
||||
.pkg = newpkg,
|
||||
|
@ -909,8 +902,7 @@ int apk_db_install_pkg(struct apk_database *db,
|
|||
write(STDOUT_FILENO, ".", 1);
|
||||
}
|
||||
return r;
|
||||
|
||||
err_close:
|
||||
close(fd);
|
||||
bs->close(bs, NULL);
|
||||
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;
|
||||
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
fis = malloc(sizeof(struct apk_fd_istream));
|
||||
if (fis == NULL)
|
||||
return NULL;
|
||||
|
@ -81,6 +84,8 @@ struct apk_istream *apk_istream_from_file(const char *file)
|
|||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
return apk_istream_from_fd(fd);
|
||||
}
|
||||
|
||||
|
@ -278,6 +283,9 @@ struct apk_bstream *apk_bstream_from_fd(int fd)
|
|||
{
|
||||
struct apk_bstream *bs;
|
||||
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
bs = apk_mmap_bstream_from_fd(fd);
|
||||
if (bs != NULL)
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
void *ptr;
|
||||
|
@ -338,7 +358,6 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
|
|||
{
|
||||
struct stat st;
|
||||
struct apk_bstream *bs;
|
||||
int fd;
|
||||
|
||||
if (stat(filename, &st) != 0)
|
||||
return -1;
|
||||
|
@ -352,11 +371,7 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
|
|||
.device = st.st_dev,
|
||||
};
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
bs = apk_bstream_from_fd(fd);
|
||||
bs = apk_bstream_from_file(filename);
|
||||
if (bs != NULL)
|
||||
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)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
return apk_gunzip_bstream(apk_bstream_from_fd(fd));
|
||||
return apk_gunzip_bstream(apk_bstream_from_file(file));
|
||||
}
|
||||
|
||||
|
|
|
@ -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