.
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
|
||||
asd 1.0 asd http://kentoj/index.html
|
||||
lr 1.0 foo http://localhost:8081/example.binpkg.tar 95f7a5fbfe6e126c88543b1291e031719d67bc28df6f9753b0a6fd891056500a
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ project(
|
|||
cc = meson.get_compiler('c')
|
||||
deps = [
|
||||
cc.find_library('libowfat'),
|
||||
cc.find_library('libbearssl'),
|
||||
]
|
||||
|
||||
add_project_arguments(
|
||||
|
|
|
|||
|
|
@ -42,11 +42,9 @@ int extract(char *in, const char *out)
|
|||
{
|
||||
struct archive *reader = NULL, *writer = NULL;
|
||||
struct archive_entry *ent;
|
||||
stralloc path;
|
||||
int ret = 0;
|
||||
int r;
|
||||
size_t l;
|
||||
const char *oldpath;
|
||||
char *newpath;
|
||||
|
||||
reader = archive_read_new();
|
||||
archive_read_support_filter_all(reader);
|
||||
|
|
@ -68,13 +66,15 @@ int extract(char *in, const char *out)
|
|||
goto done;
|
||||
}
|
||||
|
||||
oldpath = archive_entry_pathname(ent);
|
||||
newpath = alloca(str_len(oldpath) + str_len(out) + 1);
|
||||
l = str_copy(newpath, out);
|
||||
l += str_copy(newpath + l, "/");
|
||||
str_copy(newpath + l, oldpath);
|
||||
msg(oldpath, " -> ", newpath);
|
||||
archive_entry_set_pathname(ent, newpath);
|
||||
if (!stralloc_copys(&path, out)
|
||||
|| !stralloc_cats(&path, "/")
|
||||
|| !stralloc_cats(&path, archive_entry_pathname(ent))
|
||||
|| !stralloc_0(&path)
|
||||
) {
|
||||
carpsys("append to stralloc");
|
||||
goto done;
|
||||
}
|
||||
archive_entry_set_pathname(ent, path.s);
|
||||
|
||||
if (archive_write_header(writer, ent) != 0) {
|
||||
carp("failed to write header ", errstr(writer));
|
||||
|
|
@ -100,6 +100,7 @@ done:
|
|||
archive_write_close(writer);
|
||||
archive_write_free(writer);
|
||||
}
|
||||
stralloc_free(&path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <libowfat/errmsg.h>
|
||||
#include <libowfat/str.h>
|
||||
#include <libowfat/stralloc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../pkin.h"
|
||||
|
|
@ -11,44 +12,12 @@ static int find_package(char *name, pkin_pkgmeta *pkgmeta)
|
|||
{
|
||||
pkin_repo_iter iter;
|
||||
pkin_repo_iter_init(&iter);
|
||||
|
||||
while (pkin_repo_iter_read(&iter, pkgmeta))
|
||||
if (str_equal(pkgmeta->name, name))
|
||||
return 1;
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -63,5 +32,5 @@ void command_fetch(int argc, char **argv)
|
|||
argc -= i;
|
||||
argv += i;
|
||||
|
||||
run(argc, argv);
|
||||
//run(argc, argv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
#include <libowfat/stralloc.h>
|
||||
#include <libowfat/array.h>
|
||||
#include <libowfat/buffer.h>
|
||||
#include <bearssl_hash.h>
|
||||
#include <limits.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#define PKIN_PKGMETA_NAME_MAX 128
|
||||
#define PKIN_PKGMETA_DESCR_MAX 256
|
||||
|
|
@ -25,6 +25,7 @@ typedef struct {
|
|||
char descr[PKIN_PKGMETA_DESCR_MAX];
|
||||
char version[PKIN_PKGMETA_VERSION_MAX];
|
||||
char url[PKIN_PKGMETA_URL_MAX]; /* url to download binary package from */
|
||||
char sha256sum[br_sha256_SIZE];
|
||||
} pkin_pkgmeta;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -56,10 +57,14 @@ typedef struct {
|
|||
} pkin_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);
|
||||
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);
|
||||
int pkin_queue_extract_start(pkin_queue *extractqueue);
|
||||
|
||||
int pkin_fetch_and_install(array *pkgmetas);
|
||||
|
||||
#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
|
||||
* "Download Results"-report. */
|
||||
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);
|
||||
if (pid < 0) {
|
||||
carp("failed spawning aria2c to fetch files");
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <bearssl_hash.h>
|
||||
#include <libowfat/array.h>
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
|
|
@ -23,9 +24,17 @@ static int parse_field(char *line, char *field, size_t fieldmax)
|
|||
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)
|
||||
{
|
||||
size_t l;
|
||||
size_t l, i;
|
||||
int high, low;
|
||||
|
||||
l = parse_field(line, res->name, PKIN_PKGMETA_NAME_MAX);
|
||||
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);
|
||||
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;
|
||||
skip:
|
||||
carp("skipping malformed pkgmeta: '", line, "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue