.
This commit is contained in:
parent
1112bf28c8
commit
7af09a8b2a
9 changed files with 217 additions and 66 deletions
21
README
21
README
|
|
@ -1,18 +1,5 @@
|
||||||
depends: https://github.com/arp242/toml-c
|
most development currently happens in ./pkin.
|
||||||
|
# development is kinda stuck
|
||||||
|
cause c does not support
|
||||||
|
coroutines/concurrency/parallelism properly.
|
||||||
|
|
||||||
expected usage:
|
|
||||||
(1) pkg_add /path/to/source/code/with/template/file
|
|
||||||
(2) pkg_add name of source template in source repo
|
|
||||||
|
|
||||||
We need a template format that specifies compiletime
|
|
||||||
dependencies in addition to the standart rpm spec fields
|
|
||||||
such as name, description, build script, etc..
|
|
||||||
In the case of (2), it must also specify an URL to get the
|
|
||||||
source code from.
|
|
||||||
|
|
||||||
in the end it should produce an rpm package and install it
|
|
||||||
(with dnf). referenced packages(like in dependencies) should
|
|
||||||
use the name from fedoras package list.
|
|
||||||
If a source template depends on another package that only
|
|
||||||
exists as a source template, pkg_add must make sure to
|
|
||||||
compile that first.
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
lr 1.0 foo http://localhost:8081/example.binpkg.tar
|
lr 1.0 foo http://localhost:8081/example.binpkg.tar 95f7a5fbfe6e126c88543b1291e031719d67bc28df6f9753b0a6fd891056500a
|
||||||
asd 1.0 asd http://kentoj/index.html
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ project(
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
deps = [
|
deps = [
|
||||||
cc.find_library('libowfat'),
|
cc.find_library('libowfat'),
|
||||||
|
cc.find_library('libbearssl'),
|
||||||
]
|
]
|
||||||
|
|
||||||
add_project_arguments(
|
add_project_arguments(
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,9 @@ int extract(char *in, const char *out)
|
||||||
{
|
{
|
||||||
struct archive *reader = NULL, *writer = NULL;
|
struct archive *reader = NULL, *writer = NULL;
|
||||||
struct archive_entry *ent;
|
struct archive_entry *ent;
|
||||||
|
stralloc path;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int r;
|
int r;
|
||||||
size_t l;
|
|
||||||
const char *oldpath;
|
|
||||||
char *newpath;
|
|
||||||
|
|
||||||
reader = archive_read_new();
|
reader = archive_read_new();
|
||||||
archive_read_support_filter_all(reader);
|
archive_read_support_filter_all(reader);
|
||||||
|
|
@ -68,13 +66,15 @@ int extract(char *in, const char *out)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
oldpath = archive_entry_pathname(ent);
|
if (!stralloc_copys(&path, out)
|
||||||
newpath = alloca(str_len(oldpath) + str_len(out) + 1);
|
|| !stralloc_cats(&path, "/")
|
||||||
l = str_copy(newpath, out);
|
|| !stralloc_cats(&path, archive_entry_pathname(ent))
|
||||||
l += str_copy(newpath + l, "/");
|
|| !stralloc_0(&path)
|
||||||
str_copy(newpath + l, oldpath);
|
) {
|
||||||
msg(oldpath, " -> ", newpath);
|
carpsys("append to stralloc");
|
||||||
archive_entry_set_pathname(ent, newpath);
|
goto done;
|
||||||
|
}
|
||||||
|
archive_entry_set_pathname(ent, path.s);
|
||||||
|
|
||||||
if (archive_write_header(writer, ent) != 0) {
|
if (archive_write_header(writer, ent) != 0) {
|
||||||
carp("failed to write header ", errstr(writer));
|
carp("failed to write header ", errstr(writer));
|
||||||
|
|
@ -100,6 +100,7 @@ done:
|
||||||
archive_write_close(writer);
|
archive_write_close(writer);
|
||||||
archive_write_free(writer);
|
archive_write_free(writer);
|
||||||
}
|
}
|
||||||
|
stralloc_free(&path);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <libowfat/errmsg.h>
|
#include <libowfat/errmsg.h>
|
||||||
#include <libowfat/str.h>
|
#include <libowfat/str.h>
|
||||||
|
#include <libowfat/stralloc.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "../pkin.h"
|
#include "../pkin.h"
|
||||||
|
|
@ -11,44 +12,12 @@ static int find_package(char *name, pkin_pkgmeta *pkgmeta)
|
||||||
{
|
{
|
||||||
pkin_repo_iter iter;
|
pkin_repo_iter iter;
|
||||||
pkin_repo_iter_init(&iter);
|
pkin_repo_iter_init(&iter);
|
||||||
|
|
||||||
while (pkin_repo_iter_read(&iter, pkgmeta))
|
while (pkin_repo_iter_read(&iter, pkgmeta))
|
||||||
if (str_equal(pkgmeta->name, name))
|
if (str_equal(pkgmeta->name, name))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
pkin_pkgmeta pkgmeta;
|
|
||||||
pkin_queue fetchq, extractq;
|
|
||||||
stralloc archivename;
|
|
||||||
if (!pkin_queue_prepare(&fetchq)
|
|
||||||
|| !pkin_queue_prepare(&extractq)
|
|
||||||
) die(111, "failed to create queue");
|
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
if (!find_package(argv[i], &pkgmeta))
|
|
||||||
die(100, "package '", argv[i], "' not found ");
|
|
||||||
stralloc_copys(&archivename, pkgmeta.name);
|
|
||||||
stralloc_cats(&archivename, ".archive");
|
|
||||||
stralloc_0(&archivename);
|
|
||||||
pkin_queue_fetch_add(&fetchq, pkgmeta.url, archivename.s);
|
|
||||||
pkin_queue_extract_add(&extractq, archivename.s, pkgmeta.name);
|
|
||||||
if (pkin_verbose)
|
|
||||||
msg("queueing fetch/extract: ", pkgmeta.url);
|
|
||||||
}
|
|
||||||
stralloc_free(&archivename);
|
|
||||||
|
|
||||||
msg("fetching binary packages");
|
|
||||||
if (!pkin_queue_fetch_start(&fetchq))
|
|
||||||
die(111, "failed fetching packages");
|
|
||||||
msg("extracting fetched packages");
|
|
||||||
if (!pkin_queue_extract_start(&extractq))
|
|
||||||
die(111, "failed extracting packages");
|
|
||||||
}
|
|
||||||
|
|
||||||
void command_fetch(int argc, char **argv)
|
void command_fetch(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -63,5 +32,5 @@ void command_fetch(int argc, char **argv)
|
||||||
argc -= i;
|
argc -= i;
|
||||||
argv += i;
|
argv += i;
|
||||||
|
|
||||||
run(argc, argv);
|
//run(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
#include <libowfat/stralloc.h>
|
#include <libowfat/stralloc.h>
|
||||||
#include <libowfat/array.h>
|
#include <libowfat/array.h>
|
||||||
#include <libowfat/buffer.h>
|
#include <libowfat/buffer.h>
|
||||||
|
#include <bearssl_hash.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <jansson.h>
|
|
||||||
|
|
||||||
#define PKIN_PKGMETA_NAME_MAX 128
|
#define PKIN_PKGMETA_NAME_MAX 128
|
||||||
#define PKIN_PKGMETA_DESCR_MAX 256
|
#define PKIN_PKGMETA_DESCR_MAX 256
|
||||||
|
|
@ -25,6 +25,7 @@ typedef struct {
|
||||||
char descr[PKIN_PKGMETA_DESCR_MAX];
|
char descr[PKIN_PKGMETA_DESCR_MAX];
|
||||||
char version[PKIN_PKGMETA_VERSION_MAX];
|
char version[PKIN_PKGMETA_VERSION_MAX];
|
||||||
char url[PKIN_PKGMETA_URL_MAX]; /* url to download binary package from */
|
char url[PKIN_PKGMETA_URL_MAX]; /* url to download binary package from */
|
||||||
|
char sha256sum[br_sha256_SIZE];
|
||||||
} pkin_pkgmeta;
|
} pkin_pkgmeta;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -56,10 +57,14 @@ typedef struct {
|
||||||
} pkin_queue;
|
} pkin_queue;
|
||||||
int pkin_queue_prepare(pkin_queue *queue);
|
int pkin_queue_prepare(pkin_queue *queue);
|
||||||
|
|
||||||
|
#define pkin_queue_fetch_prepare(q) pkin_queue_prepare(q)
|
||||||
void pkin_queue_fetch_add(pkin_queue *fetchqueue, char *url, char *output);
|
void pkin_queue_fetch_add(pkin_queue *fetchqueue, char *url, char *output);
|
||||||
int pkin_queue_fetch_start(pkin_queue *fetchqueue);
|
int pkin_queue_fetch_start(pkin_queue *fetchqueue);
|
||||||
|
|
||||||
|
#define pkin_queue_extract_prepare(q) pkin_queue_prepare(q)
|
||||||
void pkin_queue_extract_add(pkin_queue *extractqueue, char *src, char *dest);
|
void pkin_queue_extract_add(pkin_queue *extractqueue, char *src, char *dest);
|
||||||
int pkin_queue_extract_start(pkin_queue *extractqueue);
|
int pkin_queue_extract_start(pkin_queue *extractqueue);
|
||||||
|
|
||||||
|
int pkin_fetch_and_install(array *pkgmetas);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
170
pkin/src/pkin/pkin_fetch_and_install.c
Normal file
170
pkin/src/pkin/pkin_fetch_and_install.c
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include <asm-generic/errno-base.h>
|
||||||
|
#include <bearssl_hash.h>
|
||||||
|
#include <libowfat/array.h>
|
||||||
|
#include <libowfat/buffer.h>
|
||||||
|
#include <libowfat/byte.h>
|
||||||
|
#include <libowfat/errmsg.h>
|
||||||
|
#include <libowfat/str.h>
|
||||||
|
#include <libowfat/stralloc.h>
|
||||||
|
#include <libowfat/open.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../pkin.h"
|
||||||
|
|
||||||
|
static int get_cache_path(stralloc *sa, pkin_pkgmeta *pkgmeta)
|
||||||
|
{
|
||||||
|
if (!stralloc_copys(sa, PATH_CACHE)
|
||||||
|
|| !stralloc_cats(sa, "/")
|
||||||
|
|| !stralloc_cats(sa, pkgmeta->name)
|
||||||
|
|| !stralloc_cats(sa, "-")
|
||||||
|
|| !stralloc_cats(sa, pkgmeta->version)
|
||||||
|
|| !stralloc_cats(sa, ".pkinpkg")
|
||||||
|
|| !stralloc_0(sa)
|
||||||
|
) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int verify_checksum(pkin_pkgmeta *pkgmeta, int fd)
|
||||||
|
{
|
||||||
|
br_sha256_context ctx;
|
||||||
|
char buf[8192];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
r = read(fd, buf, sizeof(buf));
|
||||||
|
if (r == 0) break;
|
||||||
|
if (r < 0) { close(fd); return 0; }
|
||||||
|
br_sha224_update(&ctx, buf, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
char out[br_sha256_SIZE];
|
||||||
|
br_sha256_out(&ctx, out);
|
||||||
|
return byte_diff(out, br_sha256_SIZE, pkgmeta->sha256sum) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fetch_all(array *pkgmetas)
|
||||||
|
{
|
||||||
|
array pkgbindirs;
|
||||||
|
char pkgbindir[] = PATH_TMP"/pkin.XXXXX";
|
||||||
|
pkin_queue queue;
|
||||||
|
int success, i, len;
|
||||||
|
stralloc path;
|
||||||
|
pkin_pkgmeta *pkgmeta;
|
||||||
|
success = 0;
|
||||||
|
if (!pkin_queue_fetch_prepare(&queue)) {
|
||||||
|
carpsys("prepare queue");
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add all pkgmetas with no valid cache entry to fetch-queue */
|
||||||
|
len = array_length(pkgmetas, sizeof(pkin_pkgmeta));
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
pkgmeta = array_get(pkgmetas, sizeof(pkin_pkgmeta), i);
|
||||||
|
if (!get_cache_path(&path, pkgmeta)) {
|
||||||
|
carpsys("append to stralloc");
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actually fetch files */
|
||||||
|
if (!pkin_queue_fetch_start(&queue)) {
|
||||||
|
carpsys("failed to fetch some packages");
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify checksums */
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
pkgmeta = array_get(pkgmetas, sizeof(pkin_pkgmeta), i);
|
||||||
|
if (!get_cache_path(&path, pkgmeta)) {
|
||||||
|
carpsys("append to stralloc");
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
fd = open_read(path.s);
|
||||||
|
if (fd < 0) {
|
||||||
|
carpsys("open_read ", path.s, "(fetched from ", pkgmeta->url, ")");
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
if (!verify_checksum(pkgmeta, fd)) {
|
||||||
|
carpsys("Checksum mismatch for ", path.s, " from ", pkgmeta->url);
|
||||||
|
goto fetch_out;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
success = 1;
|
||||||
|
fetch_out:
|
||||||
|
stralloc_free(&path);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int extract_all(array *pkgmetas)
|
||||||
|
{
|
||||||
|
pkin_queue queue;
|
||||||
|
int success, i, len;
|
||||||
|
stralloc path;
|
||||||
|
pkin_pkgmeta *pkgmeta;
|
||||||
|
success = 0;
|
||||||
|
if (!pkin_queue_extract_prepare(&queue)) {
|
||||||
|
carpsys("prepare queue");
|
||||||
|
goto extract_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
char binpkgdir[] = "/tmp/pkin.XXXXX";
|
||||||
|
|
||||||
|
len = array_length(pkgmetas, sizeof(pkin_pkgmeta));
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
pkgmeta = array_get(pkgmetas, sizeof(pkin_pkgmeta), i);
|
||||||
|
if (!get_cache_path(&path, pkgmeta)) {
|
||||||
|
carpsys("append to stralloc");
|
||||||
|
goto extract_out;
|
||||||
|
}
|
||||||
|
pkin_queue_extract_add(&queue, path.s, );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pkin_queue_extract_start(&queue)) {
|
||||||
|
carpsys("failed to fetch package");
|
||||||
|
goto extract_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
success = 1;
|
||||||
|
extract_out:
|
||||||
|
stralloc_free(&path);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int install(pkin_pkgmeta *pkgmeta, char *binkpgdir)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
pkin_pkgmeta pkgmeta;
|
||||||
|
pkin_queue fetchq, extractq;
|
||||||
|
stralloc archive_part, archive;
|
||||||
|
if (!pkin_queue_fetch_prepare(&fetchq)
|
||||||
|
|| !pkin_queue_extract_prepare(&extractq)
|
||||||
|
) die(111, "failed to create queue");
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
if (!find_package(argv[i], &pkgmeta))
|
||||||
|
die(100, "package '", argv[i], "' not found ");
|
||||||
|
if (!cache_part_path(&archive_part, &pkgmeta)
|
||||||
|
|| !cache_completed_path(&archive, &pkgmeta)
|
||||||
|
) diesys(111, "append to stralloc");
|
||||||
|
|
||||||
|
pkin_queue_fetch_add(&fetchq, pkgmeta.url, archive_part.s);
|
||||||
|
pkin_queue_extract_add(&extractq, archivename.s, pkgmeta.name);
|
||||||
|
if (pkin_verbose)
|
||||||
|
msg("queueing fetch/extract: ", pkgmeta.url);
|
||||||
|
}
|
||||||
|
stralloc_free(&archivename);
|
||||||
|
|
||||||
|
msg("fetching binary packages");
|
||||||
|
if (!pkin_queue_fetch_start(&fetchq))
|
||||||
|
die(111, "failed fetching packages");
|
||||||
|
msg("extracting fetched packages");
|
||||||
|
if (!pkin_queue_extract_start(&extractq))
|
||||||
|
die(111, "failed extracting packages");
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,8 @@ int pkin_queue_fetch_start(pkin_queue *queue)
|
||||||
* to not flood the terminal. It will still always send the
|
* to not flood the terminal. It will still always send the
|
||||||
* "Download Results"-report. */
|
* "Download Results"-report. */
|
||||||
cmd = (char *[]){"aria2c", "--console-log-level=warn",
|
cmd = (char *[]){"aria2c", "--console-log-level=warn",
|
||||||
"--enable-color=false", "--allow-overwrite=true", "-i", "-", NULL};
|
"--enable-color=false", "--allow-overwrite=true", "--input-file=-",
|
||||||
|
"--dir=/", NULL};
|
||||||
pid = pkin__spawn(cmd, queue->pipefd[0], 1, 2);
|
pid = pkin__spawn(cmd, queue->pipefd[0], 1, 2);
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
carp("failed spawning aria2c to fetch files");
|
carp("failed spawning aria2c to fetch files");
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <bearssl_hash.h>
|
||||||
#include <libowfat/array.h>
|
#include <libowfat/array.h>
|
||||||
#include <libowfat/buffer.h>
|
#include <libowfat/buffer.h>
|
||||||
#include <libowfat/errmsg.h>
|
#include <libowfat/errmsg.h>
|
||||||
|
|
@ -23,9 +24,17 @@ static int parse_field(char *line, char *field, size_t fieldmax)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hexval(char c) {
|
||||||
|
if (c>='0' && c<='9') return c-'0';
|
||||||
|
if (c>='a' && c<='f') return c-'a'+10;
|
||||||
|
if (c>='A' && c<='F') return c-'A'+10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_pkgmeta(char *line, pkin_pkgmeta *res)
|
static int parse_pkgmeta(char *line, pkin_pkgmeta *res)
|
||||||
{
|
{
|
||||||
size_t l;
|
size_t l, i;
|
||||||
|
int high, low;
|
||||||
|
|
||||||
l = parse_field(line, res->name, PKIN_PKGMETA_NAME_MAX);
|
l = parse_field(line, res->name, PKIN_PKGMETA_NAME_MAX);
|
||||||
if (l == 0) goto skip;
|
if (l == 0) goto skip;
|
||||||
|
|
@ -41,10 +50,19 @@ static int parse_pkgmeta(char *line, pkin_pkgmeta *res)
|
||||||
|
|
||||||
l = parse_field(line, res->url, PKIN_PKGMETA_URL_MAX);
|
l = parse_field(line, res->url, PKIN_PKGMETA_URL_MAX);
|
||||||
if (l == 0) goto skip;
|
if (l == 0) goto skip;
|
||||||
|
line += l+1;
|
||||||
|
|
||||||
|
// TODO use bearssl length var
|
||||||
|
if (str_len(line) != 64) goto skip;
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
high = hexval(line[i*2]);
|
||||||
|
low = hexval(line[i*2+1]);
|
||||||
|
if (high < 0 || low < 0) goto skip;
|
||||||
|
res->sha256sum[i] = (unsigned char)((high<<4)|low);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
skip:
|
skip:
|
||||||
carp("skipping malformed pkgmeta: '", line, "'");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue