diff --git a/README b/README index 7359a6d..7154d77 100644 --- a/README +++ b/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. diff --git a/pkin/asset/example.a b/pkin/asset/example.a index eacc288..8eb577b 100644 --- a/pkin/asset/example.a +++ b/pkin/asset/example.a @@ -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 diff --git a/pkin/meson.build b/pkin/meson.build index 35850ad..e690aac 100644 --- a/pkin/meson.build +++ b/pkin/meson.build @@ -9,6 +9,7 @@ project( cc = meson.get_compiler('c') deps = [ cc.find_library('libowfat'), + cc.find_library('libbearssl'), ] add_project_arguments( diff --git a/pkin/src/bin-internal/extraction-worker.c b/pkin/src/bin-internal/extraction-worker.c index 90bbacc..c9a8e35 100644 --- a/pkin/src/bin-internal/extraction-worker.c +++ b/pkin/src/bin-internal/extraction-worker.c @@ -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; } diff --git a/pkin/src/bin/pkin-fetch.c b/pkin/src/bin/pkin-fetch.c index e1b0e50..ae0f28e 100644 --- a/pkin/src/bin/pkin-fetch.c +++ b/pkin/src/bin/pkin-fetch.c @@ -1,5 +1,6 @@ #include #include +#include #include #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); } diff --git a/pkin/src/pkin.h b/pkin/src/pkin.h index e6da3d6..78fbf51 100644 --- a/pkin/src/pkin.h +++ b/pkin/src/pkin.h @@ -8,8 +8,8 @@ #include #include #include +#include #include -#include #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 diff --git a/pkin/src/pkin/pkin_fetch_and_install.c b/pkin/src/pkin/pkin_fetch_and_install.c new file mode 100644 index 0000000..566cf70 --- /dev/null +++ b/pkin/src/pkin/pkin_fetch_and_install.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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"); +} diff --git a/pkin/src/pkin/pkin_queue_fetch_start.c b/pkin/src/pkin/pkin_queue_fetch_start.c index 920fa3c..68392a9 100644 --- a/pkin/src/pkin/pkin_queue_fetch_start.c +++ b/pkin/src/pkin/pkin_queue_fetch_start.c @@ -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"); diff --git a/pkin/src/pkin/pkin_repo_iter_read.c b/pkin/src/pkin/pkin_repo_iter_read.c index 322c153..478e26a 100644 --- a/pkin/src/pkin/pkin_repo_iter_read.c +++ b/pkin/src/pkin/pkin_repo_iter_read.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -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; }