From 55385f8857d702bc5c1af7b0a39fc974f16dd3ad Mon Sep 17 00:00:00 2001 From: kento2 Date: Fri, 4 Sep 2026 19:59:24 +0200 Subject: [PATCH] . --- README | 18 +++ builder/README | 9 ++ builder/run | 10 ++ conf.strff | 12 ++ example.source-template | 11 ++ .../index/fetcher.h.C36D6C766E6C351D.idx | Bin 0 -> 412 bytes .../clangd/index/main.c.4133924D837FB6CB.idx | Bin 0 -> 342 bytes .../index/spawnchild.c.CA3605D2CF26EC96.idx | Bin 0 -> 1382 bytes fetcher/README | 10 ++ fetcher/a.txt | 11 ++ fetcher/fetcher-worker.c | 5 + fetcher/fetcher.c | 60 +++++++++ fetcher/fetcher.h | 13 ++ fetcher/meson.build | 26 ++++ fetcher/meson.options | 1 + fetcher/spawnchild.c | 41 ++++++ meson.build | 23 ++++ .../index/command.h.727709215E1D2925.idx | Bin 0 -> 270 bytes .../index/command.h.E33C7F315E9CF039.idx | Bin 0 -> 330 bytes .../index/pkin-fetch.c.B7C410291EA526B1.idx | Bin 0 -> 1186 bytes .../index/pkin-search.c.8730E14F4B8BB0EA.idx | Bin 0 -> 1536 bytes .../index/pkin-search.c.D3DBB6646E975011.idx | Bin 0 -> 1538 bytes .../clangd/index/pkin.c.C675078E4F1A4042.idx | Bin 0 -> 1838 bytes .../clangd/index/pkin.c.D857533628058145.idx | Bin 0 -> 1768 bytes .../clangd/index/pkin.h.5D4259BBCB8EB07C.idx | Bin 0 -> 2238 bytes .../index/pkin__spawn.c.044553C952326624.idx | Bin 0 -> 1372 bytes .../pkin_internal.h.C7C817E1AC1D4889.idx | Bin 0 -> 344 bytes .../pkin_pkg_fetch_add.c.567D59DC572DF25C.idx | Bin 0 -> 722 bytes ...n_pkg_fetch_prepare.c.3C43AEA4633DFE94.idx | Bin 0 -> 688 bytes ...kin_pkg_fetch_start.c.00A52DA4899B5257.idx | Bin 0 -> 876 bytes .../index/pkin_repo.h.084305234E7EB486.idx | Bin 0 -> 1450 bytes .../pkin_repo_findpkg.c.ABF447006ED33B46.idx | Bin 0 -> 3768 bytes ...pkin_repo_iter_init.c.7D258EE86721E7C5.idx | Bin 0 -> 612 bytes ...pkin_repo_iter_init.c.9C0D1EC759DF3F44.idx | Bin 0 -> 612 bytes ...pkin_repo_iter_init.c.B9E838E2E779EB3F.idx | Bin 0 -> 610 bytes ...pkin_repo_iter_next.c.1FA39567996AB993.idx | Bin 0 -> 1948 bytes ...pkin_repo_iter_read.c.3F15063555755D99.idx | Bin 0 -> 2164 bytes ...pkin_repo_iter_read.c.491CCB70672EBC34.idx | Bin 0 -> 2164 bytes ...pkin_repo_iter_read.c.9FDBB2252A5F37B7.idx | Bin 0 -> 2102 bytes ...pkin_repo_query_end.c.B4AE0E46BC59281A.idx | Bin 0 -> 622 bytes ...kin_repo_query_next.c.9AE71B0E26964D21.idx | Bin 0 -> 1862 bytes ...in_repo_query_start.c.FD7A5877F7EA8868.idx | Bin 0 -> 560 bytes .../pkin_repo_simple.c.EAE9A2D3F20C471B.idx | Bin 0 -> 1850 bytes pkin/README | 17 +++ pkin/asset/example.a | 2 + pkin/asset/example.b | 2 + pkin/command.h | 8 ++ pkin/doc/pkin-repo.7.scd | 22 ++++ pkin/meson.build | 24 ++++ pkin/pkin-fetch.c | 54 ++++++++ pkin/pkin-search.c | 54 ++++++++ pkin/pkin.c | 90 +++++++++++++ pkin/pkin.h | 65 +++++++++ pkin/pkin/pkin_pkg_fetch.c | 2 + pkin/pkin/pkin_pkg_fetch_add.c | 8 ++ pkin/pkin/pkin_pkg_fetch_prepare.c | 15 +++ pkin/pkin/pkin_pkg_fetch_start.c | 27 ++++ pkin/pkin/pkin_repo_iter_init.c | 9 ++ pkin/pkin/pkin_repo_iter_read.c | 106 +++++++++++++++ pkin/pkin_internal.h | 8 ++ pkin/pkin_internal/pkin__spawn.c | 43 ++++++ strff.h | 51 +++++++ strff/strff_close.c | 6 + strff/strff_get.c | 8 ++ strff/strff_open.c | 8 ++ strff/strff_read.c | 44 +++++++ strff/strff_read_sa.c | 15 +++ strff/strff_seek.c | 124 ++++++++++++++++++ strff_test.c | 63 +++++++++ 69 files changed, 1125 insertions(+) create mode 100644 README create mode 100644 builder/README create mode 100755 builder/run create mode 100644 conf.strff create mode 100644 example.source-template create mode 100644 fetcher/.cache/clangd/index/fetcher.h.C36D6C766E6C351D.idx create mode 100644 fetcher/.cache/clangd/index/main.c.4133924D837FB6CB.idx create mode 100644 fetcher/.cache/clangd/index/spawnchild.c.CA3605D2CF26EC96.idx create mode 100644 fetcher/README create mode 100644 fetcher/a.txt create mode 100644 fetcher/fetcher-worker.c create mode 100644 fetcher/fetcher.c create mode 100644 fetcher/fetcher.h create mode 100644 fetcher/meson.build create mode 100644 fetcher/meson.options create mode 100644 fetcher/spawnchild.c create mode 100644 meson.build create mode 100644 pkin/.cache/clangd/index/command.h.727709215E1D2925.idx create mode 100644 pkin/.cache/clangd/index/command.h.E33C7F315E9CF039.idx create mode 100644 pkin/.cache/clangd/index/pkin-fetch.c.B7C410291EA526B1.idx create mode 100644 pkin/.cache/clangd/index/pkin-search.c.8730E14F4B8BB0EA.idx create mode 100644 pkin/.cache/clangd/index/pkin-search.c.D3DBB6646E975011.idx create mode 100644 pkin/.cache/clangd/index/pkin.c.C675078E4F1A4042.idx create mode 100644 pkin/.cache/clangd/index/pkin.c.D857533628058145.idx create mode 100644 pkin/.cache/clangd/index/pkin.h.5D4259BBCB8EB07C.idx create mode 100644 pkin/.cache/clangd/index/pkin__spawn.c.044553C952326624.idx create mode 100644 pkin/.cache/clangd/index/pkin_internal.h.C7C817E1AC1D4889.idx create mode 100644 pkin/.cache/clangd/index/pkin_pkg_fetch_add.c.567D59DC572DF25C.idx create mode 100644 pkin/.cache/clangd/index/pkin_pkg_fetch_prepare.c.3C43AEA4633DFE94.idx create mode 100644 pkin/.cache/clangd/index/pkin_pkg_fetch_start.c.00A52DA4899B5257.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo.h.084305234E7EB486.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_findpkg.c.ABF447006ED33B46.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_init.c.7D258EE86721E7C5.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_init.c.9C0D1EC759DF3F44.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_init.c.B9E838E2E779EB3F.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_next.c.1FA39567996AB993.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_read.c.3F15063555755D99.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_read.c.491CCB70672EBC34.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_iter_read.c.9FDBB2252A5F37B7.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_query_end.c.B4AE0E46BC59281A.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_query_next.c.9AE71B0E26964D21.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_query_start.c.FD7A5877F7EA8868.idx create mode 100644 pkin/.cache/clangd/index/pkin_repo_simple.c.EAE9A2D3F20C471B.idx create mode 100644 pkin/README create mode 100644 pkin/asset/example.a create mode 100644 pkin/asset/example.b create mode 100644 pkin/command.h create mode 100644 pkin/doc/pkin-repo.7.scd create mode 100644 pkin/meson.build create mode 100644 pkin/pkin-fetch.c create mode 100644 pkin/pkin-search.c create mode 100644 pkin/pkin.c create mode 100644 pkin/pkin.h create mode 100644 pkin/pkin/pkin_pkg_fetch.c create mode 100644 pkin/pkin/pkin_pkg_fetch_add.c create mode 100644 pkin/pkin/pkin_pkg_fetch_prepare.c create mode 100644 pkin/pkin/pkin_pkg_fetch_start.c create mode 100644 pkin/pkin/pkin_repo_iter_init.c create mode 100644 pkin/pkin/pkin_repo_iter_read.c create mode 100644 pkin/pkin_internal.h create mode 100644 pkin/pkin_internal/pkin__spawn.c create mode 100644 strff.h create mode 100644 strff/strff_close.c create mode 100644 strff/strff_get.c create mode 100644 strff/strff_open.c create mode 100644 strff/strff_read.c create mode 100644 strff/strff_read_sa.c create mode 100644 strff/strff_seek.c create mode 100644 strff_test.c diff --git a/README b/README new file mode 100644 index 0000000..7359a6d --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +depends: https://github.com/arp242/toml-c + +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/builder/README b/builder/README new file mode 100644 index 0000000..0d60c9c --- /dev/null +++ b/builder/README @@ -0,0 +1,9 @@ +build steps: + - create rootfs(empty fs) + - fetch all files(including dependencies) + cache + - extract/install files/deps + - chroot into rootfs + +impl details: + - use queues for fetch and extract with parallel workers + - rootfs diff --git a/builder/run b/builder/run new file mode 100755 index 0000000..521052d --- /dev/null +++ b/builder/run @@ -0,0 +1,10 @@ +#!/bin/sh +mkdir -p rootfs +podman run \ + -v ./rootfs:/data \ + docker.io/fedora \ + dnf5 \ + --installroot /data \ + --repofrompath "bootstrap,https://ftp.uni-stuttgart.de/fedora/releases/44/Everything/x86_64/os/" \ + --assumeyes \ + install basesystem ed diff --git a/conf.strff b/conf.strff new file mode 100644 index 0000000..2ca3868 --- /dev/null +++ b/conf.strff @@ -0,0 +1,12 @@ +name=pkg_add +version=0.1 +makedeps=muon samurai + +[build] +muon setup build +samu -C build + +[install] +install -d /usr/local/bin +install -m755 pkg_add /usr/local/bin + diff --git a/example.source-template b/example.source-template new file mode 100644 index 0000000..28e4cd2 --- /dev/null +++ b/example.source-template @@ -0,0 +1,11 @@ +name=lr +ver=2.0.1 +descr=List files, recursively + +build() { + make +} + +install() { + make install +} diff --git a/fetcher/.cache/clangd/index/fetcher.h.C36D6C766E6C351D.idx b/fetcher/.cache/clangd/index/fetcher.h.C36D6C766E6C351D.idx new file mode 100644 index 0000000000000000000000000000000000000000..b6b664dd36f8dea1fb111c69ca23a8dafa1e476a GIT binary patch literal 412 zcmWIYbaR`+$iU#7;#rZKT9U}Zz`!5^#Kk2=nYV$oDNwFrj&HwX9+M%D>*jgE6$hCF zWW{%#=CyDRU8wPKLPw_1O}W699o6YgUAs2z|NCZrzSRQxPfUI1KmGj2dVR^pPPtP{ zN`pL@_C4{5(`=ZQYSY3O!{>0u`Gs}DrOwT*vzVqZ*7zhhoH{z0L!@oH?UX$iTGMZ> z3ID$L>qWzy?cGtZMG{R^`Nr*sGeIa&N<Nd$3>~y|EnlO*>8-wd zTdat?)mEoA;KfFbO_OGXzDcmI{qwtRlI_;^w}~w#FOt~=7;jI%oLpU#R~E9olD&e( zX6x#A;kJx+cNq3bANh*kMd3K-bWG4^H#C22*zShI1N?b+uKd-pDnTir8jWpvZe zY&mtli=2PD-aD!6{NZ^+!)4=9?VKgE&95!B*Ll8>e_6Rpc*%|jkL_oy{ce82w>^ZR zxH2~h=s|{})U;vA|PezdK@V&5gAV zTQJ8kuA9E~UA8Tw-5rK~MI2vC7KHpxyo24(dmLY3nuZ~#40f_~6ynQoFxN~E5GW{NJt4_{dS?XFf zJ=6GS!g|A3Cw6PpmP$9q3rNd*`u+E`n9whz_S(Use^>aqxrYj;NuFOevn0?!EK2^4 z?8SOc|6KM3%3M3=BpdymALY7allqj02 zd7!i?o2USofJqmnrWI!}GcaU4_hzo*QsiKikrZMQ;)5Cb{^GO*pLMA+Kw)t{aUqyt z>00c0(izsKOgxg3ypo`p0s|gNc{X`o7!PI!lN5@BWF(bYl=)#M&AxUnMsewlC=MP; z4n7Vsm>wQUE&(nH1dm&Q8;Qpwz=Oo&=i^7xC%`9w#1rHbMB)kY3yH(btZIEI&!iL^ z!z2Rs0?a)kU@yRU(IpYz6Xu1d0llxpqQnIge)(y7cG~hul}s{{G8{5IFku-^*L4`daB2eJyrGx_nNO1wj75hIVJ zfTDmJO!&>#U#AvFnJi+LLGi2%if3gckv%ITiR@V!No3E;NFsYyMiSYx7roxR?spM7 zM2B!yOzMwGSQT*|82thg0t&E5>*_b#7I?zsIWYB$GKjLmqMt`noJpJ=#)Hv}QfT=t zClM5A#YM@*?m(JRGT5zXVt}_L3#*K@l$FS4aaIXlaV|baVFm!*zleMQ literal 0 HcmV?d00001 diff --git a/fetcher/README b/fetcher/README new file mode 100644 index 0000000..9e2d1ec --- /dev/null +++ b/fetcher/README @@ -0,0 +1,10 @@ +idea: + given a list of URL-to-path pairs, it downloads them in + parallel to the specified path. + +implementation: + These pairs are added to a queue(FIFO) along with an + attempt counter. Multiple worker processes are spawned + that each handle an entry in a queue. + + workers write to an error pipe and to a out pipe. diff --git a/fetcher/a.txt b/fetcher/a.txt new file mode 100644 index 0000000..f8fbf60 --- /dev/null +++ b/fetcher/a.txt @@ -0,0 +1,11 @@ + + + +lab 0x13 + + +

welcome to the lab!

+

git

+

intellij colorscheme +inspired by this blog post

+ diff --git a/fetcher/fetcher-worker.c b/fetcher/fetcher-worker.c new file mode 100644 index 0000000..2c9a0c4 --- /dev/null +++ b/fetcher/fetcher-worker.c @@ -0,0 +1,5 @@ +/* + * stdin serves as a queue in the form of + * URL outputDir + * where outputDir is the directory to save the downloaded + * file in. diff --git a/fetcher/fetcher.c b/fetcher/fetcher.c new file mode 100644 index 0000000..161415c --- /dev/null +++ b/fetcher/fetcher.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include "fetcher.h" + +#define dieusage() die(100, "usage: ", argv0, " [-v] [-j jobs] URL...\n\ + (-v means verbose)") + +int verbose = 0; +int jobs = 5; + +int queuepipe[2]; +/* merged stdout of workers */ +int errpipe[2]; +/* merged stderr of workers */ +int outpipe[2]; + +int main(int argc, char **argv) +{ + errmsg_iam(*argv); + int i; + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') break; + if (argv[i][1] == '-' && !argv[i][2]) break; + switch (argv[i][1]) { + case 'j': + i++; + jobs = atoi(argv[i]); + if (jobs < 1) + die(100, "value for -n must be >= 1"); + break; + case 'v': + verbose = 1; + break; + default: dieusage(); + } + } + argc -= i; + argv += i; + if (argc < 1) dieusage(); + + if (pipe(errpipe)<0 + || pipe(outpipe)<0 + ) diesys(111, "pipe"); + + if (verbose) { + buffer_puts(buffer_2, "Using "); + buffer_putlong(buffer_2, jobs); + buffer_puts(buffer_2, " parallel jobs\n"); + buffer_flush(buffer_2); + } + + char **fetchcmd = (char *[]){"curl", "-o", "a.txt", "https://lab0x13.site/index.html", NULL}; + pid_t pid = spawnchild(fetchcmd, outpipe[1], errpipe[1]); + if (pid<0) + exit(111); + waitpid(pid, NULL, 0); + exit(0); +} diff --git a/fetcher/fetcher.h b/fetcher/fetcher.h new file mode 100644 index 0000000..0bd196c --- /dev/null +++ b/fetcher/fetcher.h @@ -0,0 +1,13 @@ +#ifndef FETCHER_H +#define FETCHER_H + +#include + +/* + * execs args[0] with args. output is connected to outfd + * and errfd. + * return: pid of child process or -1 on error. + */ +pid_t spawnchild(char **args, int outfd, int errfd); + +#endif diff --git a/fetcher/meson.build b/fetcher/meson.build new file mode 100644 index 0000000..15e55b7 --- /dev/null +++ b/fetcher/meson.build @@ -0,0 +1,26 @@ +project( + 'fetcher', 'c', + default_options: [ + 'c_std=c99', + 'warning_level=2', + ], +) + +cc = meson.get_compiler('c') +deps = [ + cc.find_library('libowfat'), + dependency('libtoml'), +] + +tmpdir = get_option('tmpdir') +add_project_arguments('-DTMPDIR="'+tmpdir+'"', language: 'c') + +executable('fetcher', files( + 'fetcher.c', + 'spawnchild.c', +), dependencies:deps) + +executable('fetcher-worker', files( + 'fetcher-worker.c', + 'spawnchild.c', +), dependencies:deps) diff --git a/fetcher/meson.options b/fetcher/meson.options new file mode 100644 index 0000000..78c7680 --- /dev/null +++ b/fetcher/meson.options @@ -0,0 +1 @@ +option('tmpdir', type : 'string', value : '/tmp', description : 'writable directory for temporary files') diff --git a/fetcher/spawnchild.c b/fetcher/spawnchild.c new file mode 100644 index 0000000..cbb6b18 --- /dev/null +++ b/fetcher/spawnchild.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include + +static void carpsysargs(char *args[]) +{ + buffer_puts(buffer_2, "failed to exec"); + while (*args) { + buffer_puts(buffer_2, " \'"); + buffer_puts(buffer_2, *args); + buffer_puts(buffer_2, "'"); + args++; + } + buffer_puts(buffer_2, ": "); + buffer_puts(buffer_2, strerror(errno)); + buffer_puts(buffer_2, "\n"); + buffer_flush(buffer_2); +} + +pid_t spawnchild(char *args[], int infd, int outfd, int errfd) +{ + pid_t pid = fork(); + switch (pid) { + case -1: carpsys("fork: "); return -1; + case 0: + // TODO pipe + if (dup2(1, outfd)<0 + || dup2(2, errfd)<0 + ) { + carpsys("dup2"); + return -1; + } + execvp(args[0], args); + carpsysargs(args); + return -1; + default: + return pid; + } +} diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..80541dd --- /dev/null +++ b/meson.build @@ -0,0 +1,23 @@ +project( + 'pkg_add', 'c', + default_options: [ + 'c_std=c99', + 'warning_level=2', + ], +) + +cc = meson.get_compiler('c') +deps = [ + cc.find_library('libowfat'), + dependency('libtoml'), +] + +executable('pkg_add', files( + 'pkg_add.c', + 'strff/strff_open.c', + 'strff/strff_close.c', + 'strff/strff_seek.c', + 'strff/strff_read.c', + 'strff/strff_read_sa.c', + 'strff/strff_get.c', +), dependencies:deps) diff --git a/pkin/.cache/clangd/index/command.h.727709215E1D2925.idx b/pkin/.cache/clangd/index/command.h.727709215E1D2925.idx new file mode 100644 index 0000000000000000000000000000000000000000..c4363982965d64f211ee2e40a450f9c75e1274c4 GIT binary patch literal 270 zcmWIYbaP{4WMFVk@vO*AElFfyU|L-7j@4bBa^paX_*#LBF6$>2c=!0V+m`LHl9uE7elI#%!QJ{0D}TTCzT(QvAsH8_R8Pn zz%B;&_nI>@r=9t>G*;uT#qLlOrCTppIlmv-;c=qyNN(Xn>-|f%2P`r!VEiPhKd-nl zH^~WTvva1N@2!hZop~5ofjkgkV`gO*X5eIEWMF4zWMef{7s`t&-wN6J)_JN|NVCQu6RT3$iekOzc+q9W*{f~Y-!=j1p%K6 z!+Q9-CrNW1EtzHfw~*=a`&Vl$w0#%^KQMkMocq}BxbcI_vJbc;XNT@z>d?Rwq3OK! zv!P_)iF>~`DD7VUog;#|>cE1<@0qeg)YhbkH*ZN(Ui&tB=M4VzZBJg+F!p$^t=P%J z=+ux?vs(3}L`2?J?>fcu=*M=cmnB!PQ&vCdrJl!fcz(P2%mg;Q>V*5-o?Ll-z$tZ& z-qJl*zg9cnaf_GOx%FYrx0AaHbF7!9KKF^cw0_Z7pKt6Z_ka1_HR+1tmW}&*do_6y z;tuy!cyDbxc=X+&y&wLkw>Dj{e6ct117oD`#j4`U+@yG5s2QpYs{muAMr5A z0i`*)ImN*QOq!u6HLVyFBlRy>a~(><*%@Ud`8fGxVA>pNWlMaLSh*NkB=z|9#9^+f z{8;jOy5&qe)dPB4EeCREvNehv0!6hu|TH+>DLsT@D+bHv-+H$)w2xv!>$q z)6=dSxVwR2A+Id22Ge`H_38C}k6Aa7ZQaAUiSB=+9-Uwm0Y?><*+EB{`=uW#s?8S9;FCvD7QGURFdt6^@y zaA^9WW1cxHg4$QTx*{m4E+e>;#d7Cj(MNZs7pz?nD%iaC#=o5ZolJl4)x|{4=bAK& zfAOO2^F#KiX|^4n^OBGGMSZyYQP)Iw! z{1%w}v_mFlg5*xwT9*S-1`J)D3q{RVtUVJV?P|F@+GTx0&n2 znaY_ZE4A3eHF2wy?ppb3XKX(!=x5Qr%`WuI95a;jP?jad^X~ zb0J=LW&T|ay5}D6y>t8Hq#uEMzP^dd4SAhgw>;iee8wIAN$(}gw7pJsm~7nF-|J~q z5w&M;SWH{}rKN3apYU(V@KKs@%~^a+n?H~0rN70Mxk>TBP;<`I^SyQPsWT6QI0J*E z8mpSH1T!nMFaswOBZHC{qXetE*m|ut=XM_+21TF(VIE$u`WLLZ4yEDjj53mvoRTsyQ!}1>GgombasY*u*p!4| z!Va~vB|b^4T#PJ|di;9gFh_QMe!A%Htof=fR2}7k`RUIscL;F&!iL^!zco_2_{^vlU~(Zdou;-N^V7NRU}tR$;iPJh2NUi zc_Mp98aq%CAGa7n5f2{^5|5XU7m3Hm$A`q@=i^7>3GfLZ@sxy>q+wQVS$n_f(4$FJ zKxZO{@fM4JD^~w5sAdz90iO0*ti^St&;zQ!`Gw~zw1egTiycrwQ zyBsz=Zv=*zCX*%)EFhOQIjZYvS1n)z`Wk2_EE0IYb|QEnI}tpPod_PtP6Q8RCye)Z z+4p;{&bt=?Bc4~0R|DpuH(P(5S{!Avh)o8?pE4-^l#xXCr;H@BKV>A5{V5}f?9ZjQ zgf3NGN?FGwBPqizBM1v}AWv7u7{8i$iF5LvCR8DbDWtf9_B*mD-_+YLF=IoqAkmHJrl8fCz3>gps z0a7pq1A{D_$tbx$Ezp4VSY|4#jI6Yj1cNkOia`RwOwLWo0da-JLe`Q*6ynMDAgf5puJ literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin-search.c.D3DBB6646E975011.idx b/pkin/.cache/clangd/index/pkin-search.c.D3DBB6646E975011.idx new file mode 100644 index 0000000000000000000000000000000000000000..a561e61b9e0da185558045b2f688ee54a165cadb GIT binary patch literal 1538 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 BaWVh^ literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_pkg_fetch_add.c.567D59DC572DF25C.idx b/pkin/.cache/clangd/index/pkin_pkg_fetch_add.c.567D59DC572DF25C.idx new file mode 100644 index 0000000000000000000000000000000000000000..d5b4f6e359b568bee68ed0f0339ed2db2727962a GIT binary patch literal 722 zcmWIYbaOk!#K7R3;#rZKT9U}Zz`!5^#Kk2=nOuwv48}mYiaEW3zW#>|c)t3-Ol;4c zB^>6r`iivEqXq%>zR*`oa<8n>{Hd`Z^Z(pSy_}q8Wgj-r|2i-Aw88wh*COw~TDKx( z!Lo{8tyL+OOaE%ke0!-!>fxl+lC($L-Sd)PB;U|as5`dT%kS9xPY)s)lpZiYczjpl zd$J9)-Cc%#9La7W?+0&o5-n zcRe}A6FqO;@>xAEUQJ~9rBHk;r-3o~fb{Orn1c5m+gEX$J&jM7SzStE-v8s0q%O@DH>hrH@%-`e)<(|et3q~+hS~cx ziz{=J6oDb5toF5j$^>5%9tLR!1_>rsCSh?)R!d<9P9{bM88Jq2R)(U~v|?Rg*s;Gh zDcSr?N}riWf<=r)2Ch+pRg4vh$0o)G=fTu4N`XxVS_cNxUw*Ir#OG$t$Roid!lVLI zwZ-D!iq*dhs+mP3SeRINVZtI3tW2y(JT@jaIB#i_qq?4U)dG;4fLdS{@PM@-cpxn> z-kYtzPA!fyS;Q=ZVv7ulEiw|wwp{dj^Sa+f=nx4G1BO~oBFM_(qU2(65Ccqr7z~UO vEz;`E6K7d&VH9Ub&P~aY0166=i3;#?aB=dm2(k#VvP-f_@kw&?Gm8KKgMI2t literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_pkg_fetch_prepare.c.3C43AEA4633DFE94.idx b/pkin/.cache/clangd/index/pkin_pkg_fetch_prepare.c.3C43AEA4633DFE94.idx new file mode 100644 index 0000000000000000000000000000000000000000..4f3878c047be61d0d6279f1d26ca29f50974af70 GIT binary patch literal 688 zcmWIYbaPw5#K7R3;#rZKT9U}Zz`!5^#Kk2=nSzWA48cITiaEWL{Ii)11&%&n{N+Nk zm|F1OoezAu`9GjR*UgoQJWKb-at zPG;hf;Nj&Fg$V! z+T4aP9?;J@i6FNX7bO?#gBVgE0s_Qg39;FgEr5*!sS>MJ1-qvd?c2>U`NEOoqM?7kw=H&BAv)!tU(){Pd&F7UR`JYz-jEt} zX+o4`f8qLV8P_8wuS&YH!fex|3){1|E6=yon>2Mo;|uSruIeRA+`V+WKbOu^INLZ? z+bFGfQM`92uS@(cHE*Tq6K6oP4Fe{E8- z`I(eHBabAfG^Zj=I9-c9PddZe6e!Ha!o>}=2@Iyc{9gHq&&?bt%qq&N3R7Lx`cR%p zDK>^t1gsh++)}?^^|r$ALZFrW9Q?vC;Voh|NqqV7)MR@qqQhc(S$U3ZBe5y9KC-PnXXSCd?x# zDl94vC4KVsdEV#lz4v`` zX~_;plNh1I+~gvUt8j}5A*9AXU!m7+BM>@4B2-j&;G=6hyI*8_{FCXAJNM4BM_g$L z>>5j08I@L%_X*n{6SwcL$rPFX{B~7E;Of|0OUBY0J7d2sZ#L&X-QRl0^IDZRweeKV z^2}EI@zl1<1ID9I6WWMaC2h-Z`tYYxuCMfF!G!z%-6{LOH6@*e-mHwwVS6xs`h{mV z#^PVS@O{w5))mtUONah!_ASn?Tye&k5w-S;ysyN4@STY@AB^pf}a_qT6KT2(b#9pI9_RQYf1a9&az|EBPjQhKvCBkpC>h^b<< zXhX{z$fJNyDMk z66FR48NqK7o3uz5F^ilh$NrKf+x8sr59P8*i~R~pArk=n|D2o}S)JI{$fCJe<|vL8 z0Oavo>ewBh{n5%I8p}FLM+*RQ{@!ioW$ix<$&en;PDQF%0sf!e^j6XN!|l}*EQ-N? zgVdlD0Q_E8p3jQ2zma-;WK%&7A{b6XY9#Q^=0yX)T%3GFU|LV=X&5DJoX~|f9e#1x zGeL*;8>TNkT37S)A+Z9}goKC;v#9oV*R*GF%tkni*0KP4g%IH`_yj>0^>-Gna}Bze;VzVN<$Rza zQ@ENB6wojLO!Gkk8hR(Bq3nctm?Ey`V*}ODAD*6&lrRrD!PR_7pjsb5rG8t)PTZh^ zQOpH8vHqI<+0vXMOmhluA<&Q}d=oxOKtqZ!%|{4mNDoPeQWNGG&SJ5|!Qfy6*vrQU yyk1xS7XIw>=J=BM!;FH^%#Lv;yV4s{E6Q9oVr5jMT7^`6Y3PcAL+Dc+{`ViIJbI1* literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_findpkg.c.ABF447006ED33B46.idx b/pkin/.cache/clangd/index/pkin_repo_findpkg.c.ABF447006ED33B46.idx new file mode 100644 index 0000000000000000000000000000000000000000..5a2a086e773128c641590dbf8dd4a5fe4da5bf33 GIT binary patch literal 3768 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 GZvO+va zF?)N>$Wee+G<=*M^Y8@2|W6xn(wV*X*Lce!<5mp23~zxUt6M;n$}J9ZTCDf86LOyJ1*z!*`#mAkkyH%So~0$xAoO$)3R2;pIn zVPKGCVr7z$&|=k+V31^HVw4qUlwf5jN=++14^-*u&0TqCZvhu0k0cuhn;=YM*XO5; z?#|k;0u*MFWKxF-vlz`<_u+z?4N#bcgM|wweDjLJRHI|BoPomZ;_T8eVcESMC+-M*R1~hT;N-O5TlGFn+Tf%Oc+KpN`V~=bQ>5*R~qRkeL7JNRL#!B&JR=d zJBek@^gUDG0?lUSV1)|<{gsml(pOxRTr3V^NPq}1V3d?&4r*S|A79BR!H}Grk^_0K)W_-3D;C|} zxPI|lr@t3&R|sro`n-91>d(OEImw0pb{+VWoy(|n!SuzmqAja0zH`_vzM%T)osMss z?yQ#<^d?^YHNoh$i`5PR?Wb~A6&s@h7+hyN$!}FXym3-(*QG+`xzgW?w%Q!KrFp-P zQzJF_tCx^Vl_q^Nhx-2)l)Aqy!)@2K3r`z( zt)snu`aca`rY;aI6Z?JlG!FHEmV^AVJdM2f7^=iK%QF;L<|ZiuL%{3jylH{e0wFvM zG7Jn7Osq^2lIpDL5)6{eOpLPPjFPMjMX71U=Yc9+y}2vz>@DD8pomivjGaTaIkQ}gl}F^m}+$Fl`~M7U7TGSCM>(R=}IFVrB5fyfvVY=*!f|q zekZZ4nZ9T0TcFvj9IS9*puchwLHde|l8ePb3`r0H28Hz}({i4`d)@HPSFDZZj^2<8|%^SsOPk-DMTlK>1 z&FhTa0sFt0y*skxz?WCaasSR(-j0Z=KWFgQdUhj634hfN*+TP2oL?%KtHRFp=G-p| zQQ(b|3|q^ux!G??Gxx@zccE{ERahNN_F z&GUJpue;YCXXNAFb$Jm-dP-t}(?Nk754bZd*0wVgSLP-u0=@6`bKbPTYJm_Q1{nqh zNhVe%2?-5W4G9KGW+p~iaYhMNhN9H8;`2b2uHM|0clH)=G4e>Vaj*%(Ggv_R1M3%r4F@4HK5#+i~KaQM4P# zY$Y}wm~hSN&(8(E^#?J^NV18rDZqqbG@}&Q!Jt?K0qII39i>kv%7Locnb`SZs(vT2 zteL)N>RX`MtQ@RxVW7Wq5<%LEi;|1QK@15H0S1hcPZNxm9c;gHlu?2qIX5K-Bqbsy aCdkLh&Be01uQBLn?g~1p@2@n86YYWqHcoV z#MeZk_|`BL(ZMuA#9`1mx2d2}0Uau=#)&%3nAw;?cS>@4*-h@b|M&mr|IYuq$CeNu zzlTo{maK$z`PoI8T!J9P=q)TN_$-@45KSHgvFOG3A|8QLaUc2v_IU&*qBPlD?&W|z&alm~C~ zY1x*zZ(@3%tY$~gi5Sxca|z%LUyZ20c)h_Zw@ojqtlGZp!StKAyAI#)uFx@Cbj>+G zzT(Nq=T~a39G35nQI~K&OyztyeI{|*@Ek!iZ;>;;`u3I;MNc1QBvaXIS1LBvT#0#W zzZG?2*Yk2oleem2-t62bn&{d?w;yU8b;P=gA#=xba%^krHB&zRw&7%RYu*p^H~C*5&pVJXydkv2 zHgKV7vGwljwPjmvqEn?&MZIEA+srkJMpV!*;-^X`VfyU#V+`72GjCZcboec17 z4bz4@V!rE7UrlC@jujx)@cRd^)S~V$;fSKm-#6q$r9WS&(Jq zaTca@`~Lig9T4M@Sw*Sf$b!vR+dJEj%*bp2gc_NxT&tAUadlDxdXSuPQV#7&6lCWV z4x<+TE)8%h!%I0H4D=`cDSRvgX_6j=A`k+BEmu z5RMo|lhFWgI`uML|K{jWs0V$8$&I8i;_COGecP#?>J8vTFj0to0n`XI?g#-46^6QV1yCEJ9nbEx z2rZ**v0kwP)|LuVg*bfx)BMu>S(GkF2N?C-Q&#J*4_J5r>cjLpmcT$87#2l~qiGfy zWkv;yOj=Voi|kUn43h_4uDJ17pAnB*nIuV4V)f1Tl-_CG_fxniAx0a-`s&B&gIQ#j zn58Uo&<=EALE|i<{2%A6QcHgjz->(=jVerF;K#jj6w{L zaijAMPrhjH-@P6UqKRwr!pHSdk2`API2%a@T1X2Ys~MQaP4mWqFYqtUIX6IULdA3q zG0sjC9Y8R9leeQi4o@D1diMUIDjQ9P8~R#kp3N_bmfHAuO5jf<(_-dj3~8Q ztsavg^r&Sui=_GO@h>+r*y-Y?~zscEf# zjc$cR-$V&kBcw}=Vo{PIX*x#e7R<|ZC0hxm*r>Wxm?8(iAd;834A>LJ;(68RQwQM74YK* F{0FNQuvh>9 literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_iter_read.c.3F15063555755D99.idx b/pkin/.cache/clangd/index/pkin_repo_iter_read.c.3F15063555755D99.idx new file mode 100644 index 0000000000000000000000000000000000000000..1263daee674276ba9bd4e3985a779f5f50802162 GIT binary patch literal 2164 zcmY*Z3s4hR6x}Q#BxL!zguHx85)u?Y5F$!IVq+sAu{s8ijolS3qpH_|#MCVR5SO=V@w3u(-q>)-3l zYY=br-p2ZCJfdgS>Eyxi8G{>c_CENzOKP7p_?`Up=EX~o;mQ5Q>vS!ZEm$l4cl%d4 z--}CIfs|TX%+&(@-cQ z)P;rv10IOxm(XYeK;k4D)rg9r@un(4BI4d=7u{{!=t(1hF~~RzMRCqJs;jw?Bs7Og zLKmXwNL9P%ouYN58v)pI_Cmx>059B&Ng+PYXCmRV4;^u2v=54)94)T(MJ?Mi_ORw& z)j26n07Zx*5}65*#7zo8D()-O#_b6WG8zfu@pu9So%n5y;@Q#hIZ&KTD3hQ}nX^6e z_*shhC?d)mQ4&DusdObEK(u$XODX|WGSy5f zGQm4xnlF)==t=o3gvA@FCxF%0>QA8z&kO>go?D_y#ibDqg8=HeYB@!qi^K@`%5>*rI*9BAeva$(!9EBy+i7WT))F^Q15^St5S;ybqubXbr;C8WMpOVq&> zGH?um6iVl&14Qs|-!JRSZ;d6uqf|50JQP%1IuwLUQcO5G)pukjr}~c2*14I*WhFgU zs7WXkiqV-laxTt@8`+ox&EgR8VsuK)>a(BgqYiF>nYIObMf4`#GjRbyl zKi9yKAPf&3Sy0JH+n)=};W)16%+S@B|NJ762>V%0h*i{EIT`N7#0#!Z~M1 zMPc8=YjF+iz0e#g3>BdS71DLvs_fUCW|>qLgQ90g2VjCvSAGmNtLQ2cWvVUhe%SVI z^#N!$<7OX}@^8n>{y0s`7tX?kVkzRj^K4fNc1?E@&ah6T6C)A==p*$D5K7HDarl&e z%{TBCI@^E*5L0cSkh2X4jrNiA*4IC2hP#wAv_!QOp~;CFO;E|%E+|#$qjU`( za^t+${%!)0LZt9eJvMu$Y<}y_9ynY;1|m>B@OH;4bclffk$B{^JC_ue6oUw^a2|bf z;?bF5*brf`P>F;m5+nN@!dFkACKKC4qUih8w+(;3SUv)e)qopZlmd`WPxnPZlV*DD zXRVb_VV{gXMh-GVBsWG;$fPvAi4f8aYjyswkqQCOdFWh6ish%<(wwe>d`rRm&P|YW z`TuzXZ7|IBIfn5mtB~4?s4dU6rGc%w-K=-4jv*Fb@P<$nB<683fy<4FsjVf~YI7zb bIUGN47TeRy-QRr%gDLX}@sSa}^nm{W+{p0} literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_iter_read.c.491CCB70672EBC34.idx b/pkin/.cache/clangd/index/pkin_repo_iter_read.c.491CCB70672EBC34.idx new file mode 100644 index 0000000000000000000000000000000000000000..beedf5703ee46557d6507753c61b8d4ea798c846 GIT binary patch literal 2164 zcmY*Z3rrJd9KRl=l=djEqy74_Ew(5kuktPwtGwFjw5<~q3X@VmLJ zbxvWMERabQ5uL**YS1hyGM$RUAukaH+@g-4AR2e=^7ZhN`||(&AHVH1`KcjKCVtUK7+3h={K`SF;{pK%k4JVnp&ou|$G+&`-EceSU z%nH7Dsc7^-x1xW>U9moZH}7f5nUIa2_D=s&r8XDTwGF3lzH})z!@YBp;Of|+`nE_j zR%iD)WoOySXR`XOL-|2NqPu@dS7+5;@z|8gTNfc}&{g>4D}5XLZVlQ}xDbzqh-_CZehvLe9P8 zk1zXR4#{b|g+E%OlN!9WGmNvR4>MogzFwBL)w9p=M+&}^zA2}H*YC=))7i%yS6mod)3CStj+)W_fOapr zZmKK#YR*9S$f~aG&QhOYj`O3#gUJ=Es*u8xJmU^x_U+P_S6{ImC>SyyK>(Ak{mE(0bx$0CUUs`RDTY_wL>YM917RoH2p;U`@YF;3|UAx$eD7k^?>nf zvnNeGjg7MyA|=dRCKp%_XfDXiDm-mZR$LL1h$*0N^OjggwG$C_HN?u!y+j%#uePn-~-fq=-@$La$)uHAZhqGH!6Ib)u7qkMilT!bL~FZ_2thBqs94qwy|qHoGTB8~Tr2mZBJtd&z^L8Uu+S(F>+~ z9G*T?p=*^0C7x*Az&41X`c|j5Kf1R^OC=f-D1~IK%2PF;L|V3% zL!wNO$%OpGwsx2^-CZHu!@_m(|05j6>g zLJ3@DyXyQ8ny~Nk2}%}?KvfA0GOyIN7$Ibtt9Kz1hayOwOl_KTiiF= z71zqFCe+?SZ!yffD8d5~99mUF)U2c`aY%V$*PYRhwE6>t+K3vRA@}>HHv@4o7k(s2 zBtnT4lJvf)OhvlX&BPs6i`5cHf&opiCIq7O8;;ktXx5$~zCz0wU|pDX3?#CQ0V2~L zx-#_VfnO~(dwPdL_1}HCZ|+o+jb+IFa1IG~iJExV}gG@6?J3Vy#+KYl{_tOlqbJbec6%Pkejv z;6KFpQk+xRP)(qKlrRz*!VOCxf&~&yS^n2>1OlLTP}??*6l9vyEvCYPjKZxJL1a1p zf962}LAa#ICq*GCib;`Y6DeSuy2|l0Q`4{`UocN77D;$qL|`)`5>m{_Gnp+l;%v4n X%aO@&vUjt0r_p5&Ud}Sih3fGi)$i+J literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_iter_read.c.9FDBB2252A5F37B7.idx b/pkin/.cache/clangd/index/pkin_repo_iter_read.c.9FDBB2252A5F37B7.idx new file mode 100644 index 0000000000000000000000000000000000000000..35fc60463eb29e1fb866c16e0a77c47d06579e4d GIT binary patch literal 2102 zcmY*Z2~-nT6rBtq0cHqGhmfCSBmsho7?C9;7&nqoVgtq4NKWE)_RK7E7gdsp}CJ>an1p#f73pL`A7};i&z|IX|Ow&iwQ5d;i^c-}`UIsE>@4 zJ7Ab5L%%2|b3rN_!!QcI`3v&q%w=I%iyek7+FDlLkc*EeS4MtWeMSIrvpfk&0~U(KV}clIgGZ%z*^UApgFLR73BW2Cm-&U>K*w%D$ zm*VWZ^S2c9c2a1H*$Y+p-cS&A8ntp>Y8GTPwU^m zwr{z1SDgHx;D$c*#h&#o-0ShIg}Hb9-{59`c={=y%OWu!3~p3R#BoV%By=0uMo)p9E%(HL9nSLhWC`puUiM1b)(u@Iu~G1VoR9kmb+K6=hEdg_H`8!Wju5!DRMi0wH!#W!>NvKeZzXg2`YWq9j3xQ;01A2|{_H zHmM{~$y6hmlhM5B_k1x9F;0vxnM~#(^(07fO>t*Xno}ByP*=NTQ_#774Tl8k0CgZk z5Fv;VGe|>e1Ps!Ov|bF-jnf4)D9JNPgvjY*E6?8wniUEAW8#}6$b9KkZ1<$jj#xG< zNUWlnShcs>hd~Cu!IMF$f>eMA-rc-DZ(aM)ba<6&j#`KgEiS$5g?lH?#wlyxk(sjg z9ib%wS&Pexx-y_9nx>`b&W=oJ`B5MC!xxZ}$Kg4n$vS-S_Oeqw<%{ho;Kp{d4IBmh zaeoeqrGSpDb3h6161V=S(y@whF^I;axyURADeM$SRKaZbLi3@1q6Dh23=|p)f0YL& z-u&rzP=$)EqEKvY>6LrOlBz49ISEg4K_qW#Ufj}Ye%lU7q_or*$?1HuG7-BNwI7b3 zR-%<65)$Y_bfE|}mwjwEn^qpQw84i~A^|Dc`?l8UO-=A~v($^sq_tiKS?Wb-;3hS8 z-k}FaU^>+}RS-%5(NvWdq2bp%HC{z6mth4VE+Mv2LT+66!H-J};>ma+Dsz5GmMr+_ z)h;+LKnBL6GU4~CmPa855(MIb?|nr^xiK6O7|H&%HT25|Fu92^QOMj=-4XljxuG9k zlmR!`V#Oepo$87X4X3edzdyR^5o}1DOB^4WAqtEOV~|N{nv4(<2#d1(b5WnfK+DzI zt`y75oS$lO<>#g6FSKmDEQ|GFf!FRYo;T+2*z710kDw)9QlS7FfxH+dVzxB1l`vZ& rv$dtiFfn75GTZc=jQN&B6rbEjc$J$PSRpn9On+$p5)siz}_vx&vdtW1*D?jUa z&f|}dUX}7~p8Qlsfbl)Ub@Qcp-glYv)-lR&@o@ZY)ecRf7f7`@`mfvX(R>f4ll-45USTmFA{xBt_WW0li#bW-1Y z{rgllX~n-iL9OxUP92!Z-E&Z~f>}Cdy#+&YWp0up(C*uW?w z!NJ182@_t^dg1BbxVck+!fZ@z{4n815$#+%mpxd@%p<|h%MKUjk>C*I5QZt@k>KLy z;)U_j7k-~K{d>$UpuH@TEE+K3y_^awr|*|}02F4EV3UCf!)Qh+uxEho27^a)uLgYj z>hlWd98MNa0hp?y)SN_+d~s27u`-Au4k92x62@R)l;H9gYCFMpZ3C0IBtvp;N{$3j dPFPG-fR}@dlZQo+MTnJMicOkNikqKV1OTKp*DnA7 literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_query_next.c.9AE71B0E26964D21.idx b/pkin/.cache/clangd/index/pkin_repo_query_next.c.9AE71B0E26964D21.idx new file mode 100644 index 0000000000000000000000000000000000000000..513a4cb97556a0c9ace1a5bd05504b29543a5e3f GIT binary patch literal 1862 zcmY*Z3s4hR6y0n>0_+k(NW#AS2pFISB@hYbQ!OQs32K5ewOYh#6pRYOKo})bs#H*H z{j`ost@r^e4lQbFts^QpRY$F#(K<3Hl^7AMpHhD~2&nXh&db`J$>yGS&%N)Q`(Bcn zZZ=QmV3;WwY_iJgUEm;ip9CB;j=WMJ3`6T?btw{5XzND_E!|Eisrz~Qc5u(QYf z{q5;d+|^&JUQ({UTN|r7+(S%p#M?55Y01>)!*h|_rd-U=mhk{j|$D26o zTIKnjs^0f5Yz=`_8`_NOJGqRFECtmX)d1**p`wTH7z&dm3uL_pGr!?cvt` z0&(Y!qx%!T=@Nct&YV*IPeXIj-uR7|bL(fYU4nh~&MJJ3ZHL=Tox9xowB|wX>pQJS zo*szR{e6nrR+@Xw=~}j69z2=KUD>^FIl*Nl7L8%R!m?0Q94n5(0260KhA}9=4pAXB z>$ISe#9|;pNhrmmFIYPId|1a92MSBNNNfyD69hqxzEBz~&RyiJgxBCfn6O7Np`5{# z0zS?sP?;1^IQ0&a<8mLG`Q|9z_VZ#cP6D+?t@Q~3>NK?lp~OjN18=&r1Pl^zajrk= ztJ=A{VbNKSf*}PuT*pJ~Zk>IwV#ZHV3<1#NdJ-)+KAx?4Qa2dOBmv+65;Y-#JVY*{ zQ8*{umrK8|Xd60Hn+Qv+JZqS5jKDgs(k%7OdxL-<14PbeqUH|!+Ade)&|kL5!@YMEM&YDu6Oqfyc*B`k$P$fopve&teD zA(U#3u&R*MW63Rh(kJdHgeT2o^McTJQXpcB-a%5f)Q657yz|BB?ky|fu^3rKf3yMW z$PkZSOf;gqg!}5wG{$N;3lnbQAa*w2wdn98q5{hCo-Jal^g>L!J!2DOt66FRV!vq^ zaHpA0?1gM9grbnj?%C@CTN*t3*(4YnG&UHqNuVNBK{SdDjt!xaIz~N~My6oXJGs<= zR08GDH~#;hkQ8K)84_gn=9B8V*d@yk@U#pOhDcOH0;ATLgwXuOjkSl;Xa54#dk2QR z4iD9v!pmE(K(8vE3LtiVg(GUh$?LaRBp{-Q1mu+j$`6!N5s3uRcr=$rmITWrq{&e? zu%%`oyAx_s#wdL%NMHe$_YeuSh3>q614xq;7&r#s*job>jWwsF9zS@o;xrn1I~~x; zXrveFed^&Hqy`0@GsYVe5y~VVZD^3adI$~M2%7*&>E6{o{rSsjkKl3&p5ilAoSSd= z%5oMjbgu9Q;ojGOj~oRU1C*+HtG0pW?Ew<0T&4(*5L1}Mm&Rmt=rf673VKychf+F> jpu>gBa`L^U0+A?$8$bjG`SJZi+5SpSRIrldv4sBuXs$@h literal 0 HcmV?d00001 diff --git a/pkin/.cache/clangd/index/pkin_repo_query_start.c.FD7A5877F7EA8868.idx b/pkin/.cache/clangd/index/pkin_repo_query_start.c.FD7A5877F7EA8868.idx new file mode 100644 index 0000000000000000000000000000000000000000..28f360f862cf68fdfabda1b79f6176f93824d86d GIT binary patch literal 560 zcmWIYbaT^SVqkDi@vO*AElFfyU|-h|WIKNiqu>jldijP} zz{-V_ze@3)Yb^gMaI@I(VeOo(xQ~1MFYo5{zVyMkXyd&{bACTpy|q*SYIJFnzib;@ zcfxFwdj|jCF2DV^|Nn)DMdhE%H=f?lr1#)7&-(P=(-$%nSLPFbgLOH%u5tGoo5@^NPY$qhqg}fvVXh*kxdkv%7Mb{OziwH;onItYo_m+`W9#iD<`V} zOqii4H760|!{VakVsQ`y6v+_4DC%JRO(ASpQ(5g`!l{(yD{jQY%tLK(q>289&7jU|;CG#O}<#x#zum?>YD0x2uZ? z4_9$9EM!&0+VsSncs7P%BKT(KWTh7174L5tO5eL| z*XJHX;*!JOcByNCA>9-zbPA`OS~hi79{J?)?qf+KNe0b^(!Fz=f9Srpy&&QC-ukiO z&FreSYu!H;WZn)uR3+Rpme#D^oIFz8%DGy2m$jj}^PX49jJ^`TbNkDia<8^T;5W|= zU;d`!m0$!j{^ggthcX6-YuaZ>TUOD;Uv$(Fb#K2vqo{Ti-L+-lP%#_L@_4n8PSG#1=+d`M8 zbTqWR@3)i8Jb0aaAbzgy>Ii%2Y_qV*i+mxT@J@7@JT*_-Ub3`7R^T#T9Ei0{*E(e9 zrhmE;PUFX{q(Sepd!Z!u9)UXdonnJVZ+ailE*> zGD2oS%9)-0r~iJA<0SARyrv;0{ls@f+vyZOK?1{UgO^1iFf29%BQ$@}#cAESF(Met zC-}CA&ZBByUDCxq1x^Ehw!aXi9Pp2SRj933;vx{h4&bBhBf|#OliF9aStI~lK%yih zkU7f4RwU=jEoTuA6m73BRL_Uvv<_M^l0yRBLR|<#$sXL#Bq^E&&}ji@fj#OK3G^Jj z1)=;DEq1GSx6j1)@GZvCZK6&nuA)QNQpMDX^{n`tG#Khwf8RkkV`d9N$#mlN*G zjf7~57j28Ccu{QLoaA*o@^7tz;)ISuXC#9JPFyF;XnaN6*e9EsO|Ua6rD{6L1ScXj z$WSH{#DZ8?gqAS2Pdl%~WI(A}H?0TSZVqbMAK_P-0q=!?Bd|wwG!S#d?;x5(TTtVP zyPM7rl&yo)(r`4Edx0|Iu2c6Ebv189-##gV-d zs|v$6!uA>2Mmw}^6y_$K8sZhg3e2|z5&YvD6gqyip$HN%5{9u7L=jOu6bt7wOQ%A} zBfuG>E0*qr1O~Q2gtm_t{d)iGikdwH4T3m9PAC%%!ijJPgeL07dc#6mzlJI(M~XrX z>wdCzId2#BF}H>gmR+oqJ>C~ zsW4eN@62zv*d*X7c|M2?$ z1d%h5la3rJu9Loe1j%(gouwB8H8++$eGxSTw`19{0_2Tyz^}smuR#^iAcl;QAg2M} zjHWf%#5gQ-vBP43V&K2X6mO2m&PvE$V>aaG<-bRU3=ET4O{vwStfsJGNMB_#rxS_Aj(j`bG literal 0 HcmV?d00001 diff --git a/pkin/README b/pkin/README new file mode 100644 index 0000000..15f559f --- /dev/null +++ b/pkin/README @@ -0,0 +1,17 @@ +pkin is the binary package management frontend. +think of this as something like debian's apt or alpine's apk. + +source package templates specify compile-time dependencies, +i.e. packages that are required to be present in the build +environment, e.g. gcc and glibc to compile a c project. + +repositories +------------ + +goal: + - lazy pkg building + - lazy metadata + - + +deps: aria2 +makedeps: meson(or muon), ninja(or samu), a c compiler diff --git a/pkin/asset/example.a b/pkin/asset/example.a new file mode 100644 index 0000000..f74ba44 --- /dev/null +++ b/pkin/asset/example.a @@ -0,0 +1,2 @@ +lr 1.0 foo https://lab0x13.site/index.html +asd 1.0 asd http://kentoj/index.html diff --git a/pkin/asset/example.b b/pkin/asset/example.b new file mode 100644 index 0000000..95953bf --- /dev/null +++ b/pkin/asset/example.b @@ -0,0 +1,2 @@ +lsasdr 1.0 folo +lasd 1.0 asdl diff --git a/pkin/command.h b/pkin/command.h new file mode 100644 index 0000000..55d6623 --- /dev/null +++ b/pkin/command.h @@ -0,0 +1,8 @@ +#ifndef PKIN_SUBCOMMAND_H +#define PKIN_SUBCOMMAND_H + +void command_search(int argc, char **argv); + +void command_fetch(int argc, char **argv); + +#endif diff --git a/pkin/doc/pkin-repo.7.scd b/pkin/doc/pkin-repo.7.scd new file mode 100644 index 0000000..29d5c9d --- /dev/null +++ b/pkin/doc/pkin-repo.7.scd @@ -0,0 +1,22 @@ +pkin-repo(8) + +# DESCRIPTION + +Every repository really just consists of an indexfile. +The indexfile is used for querying/filtering available packages for e.g +pkin-search(8). + +The indexfile plain text file where each line presents a package's most +crucial metadata: name, version and description. +These fields are tab-separated. + +``` +foo 1.0 foo's description +foo 1.0 foo's description +``` + +# LIMITATIONS + +- it's hard to add fields to the indexfile with this format +- the format is not versioned. changing the format requires + changing the filename diff --git a/pkin/meson.build b/pkin/meson.build new file mode 100644 index 0000000..2b4245e --- /dev/null +++ b/pkin/meson.build @@ -0,0 +1,24 @@ +project( + 'pkin', 'c', + default_options: [ + 'c_std=c99', + 'warning_level=2', + ], +) + +cc = meson.get_compiler('c') +deps = [ + cc.find_library('libowfat'), +] + +executable('pkin', files( + './pkin.c', + './pkin-search.c', + './pkin-fetch.c', + './pkin/pkin_repo_iter_init.c', + './pkin/pkin_repo_iter_read.c', + './pkin/pkin_pkg_fetch_prepare.c', + './pkin/pkin_pkg_fetch_add.c', + './pkin/pkin_pkg_fetch_start.c', + './pkin_internal/pkin__spawn.c', +), dependencies:deps) diff --git a/pkin/pkin-fetch.c b/pkin/pkin-fetch.c new file mode 100644 index 0000000..da9cb94 --- /dev/null +++ b/pkin/pkin-fetch.c @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "../pkin.h" +#include "command.h" + +#define dieusage() die(100, "usage: ", argv0, " PACKGE") + +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_fetch_queue queue; + if (!pkin_fetch_prepare(&queue)) + die(111, "failed to create package fetch queue"); + + for (i = 0; i < argc; i++) { + if (!find_package(argv[i], &pkgmeta)) + die(100, "package '", argv[i], "' not found "); + pkin_fetch_add(&queue, pkgmeta.url, pkgmeta.name); + } + + if (!pkin_fetch_start(&queue)) + die(111, "failed fetching packages"); +} + +void command_fetch(int argc, char **argv) +{ + int i; + errmsg_iam("pkin-fetch"); + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') break; + if (argv[i][1] == '-' && !argv[i][2]) break; + switch (argv[i][1]) { + default: dieusage(); + } + } + argc -= i; + argv += i; + + run(argc, argv); +} diff --git a/pkin/pkin-search.c b/pkin/pkin-search.c new file mode 100644 index 0000000..9cb1281 --- /dev/null +++ b/pkin/pkin-search.c @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "../pkin.h" +#include "command.h" + +#define dieusage() die(100, "usage: ",argv0, " PATTERN...") + +static void print_meta(pkin_pkgmeta *pkgmeta) +{ + buffer_puts(buffer_1, pkgmeta->name); + buffer_puts(buffer_1, "-"); + buffer_puts(buffer_1, pkgmeta->version); + buffer_puts(buffer_1, ": "); + buffer_puts(buffer_1, pkgmeta->descr); + buffer_puts(buffer_1, "\n"); +} + +static void run(int argc, char **argv) +{ + pkin_repo_iter iter; + pkin_pkgmeta pkgmeta; + int i; + pkin_repo_iter_init(&iter); + while (pkin_repo_iter_read(&iter, &pkgmeta)) { + int matches = 1; + for (i = 0; i < argc; i++) { + if (!strstr(pkgmeta.name, argv[i]) && !strstr(pkgmeta.descr, argv[i])) + matches = 0; + } + if (matches) + print_meta(&pkgmeta); + } + if (buffer_flush(buffer_1) < 0) + carpsys("write to stdout"); +} + +void command_search(int argc, char **argv) +{ + int i; + errmsg_iam("pkin-search"); + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') break; + if (argv[i][1] == '-' && !argv[i][2]) break; + switch (argv[i][1]) { + default: dieusage(); + } + } + argc -= i; + argv += i; + + run(argc, argv); +} diff --git a/pkin/pkin.c b/pkin/pkin.c new file mode 100644 index 0000000..7fb92d9 --- /dev/null +++ b/pkin/pkin.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include + +#include "../pkin.h" +#include "command.h" + +#define dienoarg(OPT) \ + do { \ + carp("missing argument for -"OPT); \ + dieusage(); \ + } while(0) + +int pkin_verbose = 0; +array pkin_repos; + +static void add_repo(char *path, size_t pathlen) +{ + char **repo; + repo = array_allocate(&pkin_repos, sizeof(char *), array_length(&pkin_repos, sizeof(char *))); + if (!repo) diesys(111, "failed allocating repository entry"); + *repo = malloc(pathlen + 1); + if (!*repo) diesys(111, "failed allocating repository"); + byte_copy(*repo, pathlen, path); + (*repo)[pathlen] = 0; + + if (pkin_verbose) { + buffer_puts(buffer_2, "added repository "); + buffer_put(buffer_2, path, pathlen); + buffer_putsflush(buffer_2, "\n"); + } +} + +/* imports repositories defined by the PKIN_REPOS env var */ +static void env_import_repos(void) { + char *repos; + size_t l; + repos = getenv("PKIN_REPOS"); + if (!repos) { + carp("PKIN_REPOS not defined"); + return; + } + + for (;;) { + l = str_chr(repos, ':'); + add_repo(repos, l); + if (l == str_len(repos)) break; + repos += l + 1; + } +} + +static void dieusage() +{ + die(100, "usage: ",argv0, " [-r repository]... [-v] COMMAND\n" + " -v for verbose\n" + "Commands: search, fetch"); +} + +int main(int argc, char **argv) +{ + int i; + errmsg_iam(*argv); + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') break; + if (argv[i][1] == '-' && !argv[i][2]) break; + switch (argv[i][1]) { + case 'r': + if (!argv[++i]) dienoarg("r"); + add_repo(argv[i], str_len(argv[i])); + break; + case 'v': + pkin_verbose = 1; + break; + default: dieusage(); + } + } + argc -= i; + argv += i; + + if (argc == 0) dieusage(); + env_import_repos(); + + if (str_equal(*argv, "search")) + command_search(argc, argv); + else if (str_equal(*argv, "fetch")) + command_fetch(argc, argv); + else dieusage(); +} diff --git a/pkin/pkin.h b/pkin/pkin.h new file mode 100644 index 0000000..c29776b --- /dev/null +++ b/pkin/pkin.h @@ -0,0 +1,65 @@ +#ifndef PKIN_REPO_H +#define PKIN_REPO_H + +/* + * each repo is a directory with a repo-index json file. + */ + +#include +#include +#include +#include +#include + +#define PKIN_PKGMETA_NAME_MAX 128 +#define PKIN_PKGMETA_DESCR_MAX 256 +#define PKIN_PKGMETA_VERSION_MAX 256 +#define PKIN_PKGMETA_URL_MAX 2048 + +extern int pkin_verbose; +extern array pkin_repos; /* of char * */ + +typedef struct { + char name[PKIN_PKGMETA_NAME_MAX]; + char descr[PKIN_PKGMETA_DESCR_MAX]; + char version[PKIN_PKGMETA_VERSION_MAX]; + char url[PKIN_PKGMETA_URL_MAX]; /* url to download binary package from */ +} pkin_pkgmeta; + +typedef struct { + buffer b; + int fd; + char buf[4096]; + stralloc line; + size_t repos_i; + size_t repos_len; +} pkin_repo_iter; + +/* parlallel querying would be nice */ + +/* + * initialize a pkin_repo_query. + */ +void pkin_repo_iter_init(pkin_repo_iter *); + +/* + * gets the next pkgmeta. + * return: 1 if found, 0 if no next + */ +int pkin_repo_iter_read(pkin_repo_iter *, pkin_pkgmeta *res); + +typedef struct { + buffer writeb; + char writebuf[1024]; + int pipefd[2]; +} pkin_fetch_queue; + +int pkin_fetch_prepare(pkin_fetch_queue *queue); +void pkin_fetch_add(pkin_fetch_queue *queue, char *url, char *output); +/* + * downloads the binary package from url to the given + * directory and writes the resulting path to rest + */ +int pkin_fetch_start(pkin_fetch_queue *queue); + +#endif diff --git a/pkin/pkin/pkin_pkg_fetch.c b/pkin/pkin/pkin_pkg_fetch.c new file mode 100644 index 0000000..f5c3071 --- /dev/null +++ b/pkin/pkin/pkin_pkg_fetch.c @@ -0,0 +1,2 @@ + +int pkin_pkg_fetch(char *url, char *dir, stralloc *result); diff --git a/pkin/pkin/pkin_pkg_fetch_add.c b/pkin/pkin/pkin_pkg_fetch_add.c new file mode 100644 index 0000000..b92f3a3 --- /dev/null +++ b/pkin/pkin/pkin_pkg_fetch_add.c @@ -0,0 +1,8 @@ +#include "../pkin.h" + +void pkin_fetch_add(pkin_fetch_queue *queue, char *url, char *output) +{ + buffer_puts(&queue->writeb, url); + buffer_puts(&queue->writeb, "\n -o "); + buffer_puts(&queue->writeb, output); +} diff --git a/pkin/pkin/pkin_pkg_fetch_prepare.c b/pkin/pkin/pkin_pkg_fetch_prepare.c new file mode 100644 index 0000000..f28d836 --- /dev/null +++ b/pkin/pkin/pkin_pkg_fetch_prepare.c @@ -0,0 +1,15 @@ +#include +#include + +#include "../pkin.h" + +int pkin_fetch_prepare(pkin_fetch_queue *queue) +{ + if (pipe(queue->pipefd) < 0) { + carpsys("pipe"); + return 0; + } + buffer_init_write(&queue->writeb, queue->pipefd[1], + queue->writebuf, sizeof(queue->writebuf)); + return 1; +} diff --git a/pkin/pkin/pkin_pkg_fetch_start.c b/pkin/pkin/pkin_pkg_fetch_start.c new file mode 100644 index 0000000..8272b3d --- /dev/null +++ b/pkin/pkin/pkin_pkg_fetch_start.c @@ -0,0 +1,27 @@ +#include +#include +#include "../pkin.h" +#include "../pkin_internal.h" + +int pkin_fetch_start(pkin_fetch_queue *queue) +{ + char **fetchcmd; + pid_t pid; + if (buffer_flush(&queue->writeb) < 0) { + carpsys("write to pipe"); + return 0; + } + + fetchcmd = (char *[]){"aria2c", "-i", "-", NULL}; + pid = pkin__spawn(fetchcmd, queue->pipefd[0], 1, 2); + if (pid < 0) { + carp("failed spawning aria2c to fetch files"); + return 0; + } + + if (waitpid(pid, NULL, 0) < 0) { + carp("waitpid"); + return 0; + } + return 1; +} diff --git a/pkin/pkin/pkin_repo_iter_init.c b/pkin/pkin/pkin_repo_iter_init.c new file mode 100644 index 0000000..6b0a99c --- /dev/null +++ b/pkin/pkin/pkin_repo_iter_init.c @@ -0,0 +1,9 @@ +#include "../pkin.h" + +void pkin_repo_iter_init(pkin_repo_iter *iter) +{ + iter->fd = -1; + iter->repos_i = 0; + iter->repos_len = array_length(&pkin_repos, sizeof(char *)); + stralloc_init(&iter->line); +} diff --git a/pkin/pkin/pkin_repo_iter_read.c b/pkin/pkin/pkin_repo_iter_read.c new file mode 100644 index 0000000..322c153 --- /dev/null +++ b/pkin/pkin/pkin_repo_iter_read.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../pkin.h" + +static int parse_field(char *line, char *field, size_t fieldmax) +{ + size_t l; + l = str_chr(line, '\t'); + if (l == 0) return 0; + if (l >= fieldmax) { + carp("field ", field, " is too long "); + return 0; + } + byte_copy(field, l, line); + field[l] = 0; + return l; +} + +static int parse_pkgmeta(char *line, pkin_pkgmeta *res) +{ + size_t l; + + l = parse_field(line, res->name, PKIN_PKGMETA_NAME_MAX); + if (l == 0) goto skip; + line += l+1; + + l = parse_field(line, res->version, PKIN_PKGMETA_VERSION_MAX); + if (l == 0) goto skip; + line += l+1; + + l = parse_field(line, res->descr, PKIN_PKGMETA_DESCR_MAX); + if (l == 0) goto skip; + line += l+1; + + l = parse_field(line, res->url, PKIN_PKGMETA_URL_MAX); + if (l == 0) goto skip; + + return 1; +skip: + carp("skipping malformed pkgmeta: '", line, "'"); + return 0; +} + +static int repo_iter_read(char *repo, pkin_repo_iter *iter, pkin_pkgmeta *res) +{ + pkin_pkgmeta pkgmeta; + int r; + + if (iter->fd < 0) { + iter->fd = open_read(repo); + if (iter->fd < 0) { + carpsys("open_read repo indexfile ", repo); + return 0; + } + buffer_init_read(&iter->b, iter->fd, iter->buf, sizeof(iter->buf)); + } + + r = buffer_getnewline_sa(&iter->b, &iter->line); + if (r == 0) return 0; + if (r < 0) { + carpsys("failed to read ", repo); + goto notfound; + } + stralloc_chomp(&iter->line); + stralloc_0(&iter->line); + if (!parse_pkgmeta(iter->line.s, &pkgmeta)) { + carp("bad pkgmeta in ", repo, ": '", iter->line.s, "'"); + goto notfound; + } + *res = pkgmeta; + return 1; + +notfound: + buffer_close(&iter->b); + close(iter->fd); + iter->fd = -1; + return 0; +} + +int pkin_repo_iter_read(pkin_repo_iter *iter, pkin_pkgmeta *res) +{ + char **repo; + int found; + + for (; iter->repos_i < iter->repos_len; iter->repos_i++) { + repo = array_get(&pkin_repos, sizeof(char *), iter->repos_i); + found = repo_iter_read(*repo, iter, res); + if (found) + return 1; + } + + stralloc_free(&iter->line); + if (iter->fd >= 0) { + close(iter->fd); + buffer_close(&iter->b); + iter->fd = -1; + } + return 0; +} diff --git a/pkin/pkin_internal.h b/pkin/pkin_internal.h new file mode 100644 index 0000000..f5b6eb1 --- /dev/null +++ b/pkin/pkin_internal.h @@ -0,0 +1,8 @@ +#ifndef PKIN_INTERNAL +#define PKIN_INTERNAL + +#include + +pid_t pkin__spawn(char *args[], int infd, int outfd, int errfd); + +#endif diff --git a/pkin/pkin_internal/pkin__spawn.c b/pkin/pkin_internal/pkin__spawn.c new file mode 100644 index 0000000..1c44256 --- /dev/null +++ b/pkin/pkin_internal/pkin__spawn.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +static void carpsysargs(char *args[]) +{ + buffer_puts(buffer_2, "failed to exec"); + while (*args) { + buffer_puts(buffer_2, " \'"); + buffer_puts(buffer_2, *args); + buffer_puts(buffer_2, "'"); + args++; + } + buffer_puts(buffer_2, ": "); + buffer_puts(buffer_2, strerror(errno)); + buffer_puts(buffer_2, "\n"); + buffer_flush(buffer_2); +} + +pid_t pkin__spawn(char *args[], int infd, int outfd, int errfd) +{ + pid_t pid = fork(); + switch (pid) { + case -1: carpsys("fork: "); return -1; + case 0: + // TODO pipe + if (dup2(0, infd)<0 + || dup2(1, outfd)<0 + || dup2(2, errfd)<0 + ) { + carpsys("dup2"); + return -1; + } + execvp(args[0], args); + carpsysargs(args); + return -1; + default: + return pid; + } +} + diff --git a/strff.h b/strff.h new file mode 100644 index 0000000..d866878 --- /dev/null +++ b/strff.h @@ -0,0 +1,51 @@ +/* string file format */ +#ifndef STRFF_H +#define STRFF_H + +#include +#include + +enum strff_type { + STRFF_TYPE_NONE = 0, + STRFF_TYPE_BRACKET, + STRFF_TYPE_EQUAL +}; + +struct strff { + buffer b; + char buf[1024]; + int fd; + enum strff_type fieldtype; +}; + +void strff_open(struct strff *, int fd); +void strff_close(struct strff *); + +/* + * seeks for a field with the specified key in the file. + * sets cursor position ofc. + * strff_read can be used to get the value. + * key may not contain '['. + * if key not found, sets errno to ENOKEY + * return: 1 if found, 0 on error. + */ +int strff_seek(struct strff *, char *key); + +/* + * reads n bytes into buf. + * return: bytes read, 0 on end-of-field, -1 on error. + */ +int strff_read(struct strff *, size_t buflen, char buf[buflen]); + +/* + * same as strff_read but reads the whole value into sa + * return: 1 on success, 0 on error. + */ +int strff_read_sa(struct strff *, stralloc *sa); + +/* + * wrapper around strff_seek and strff_read_sa. + */ +int strff_get(struct strff *, char *key, stralloc *sa); + +#endif diff --git a/strff/strff_close.c b/strff/strff_close.c new file mode 100644 index 0000000..2150a05 --- /dev/null +++ b/strff/strff_close.c @@ -0,0 +1,6 @@ +#include "../strff.h" + +void strff_close(struct strff *strff) +{ + buffer_close(&strff->b); +} diff --git a/strff/strff_get.c b/strff/strff_get.c new file mode 100644 index 0000000..8eb17d5 --- /dev/null +++ b/strff/strff_get.c @@ -0,0 +1,8 @@ +#include "../strff.h" + +int strff_get(struct strff *strff, char *key, stralloc *sa) +{ + if (!strff_seek(strff, key)) + return 0; + return strff_read_sa(strff, sa); +} diff --git a/strff/strff_open.c b/strff/strff_open.c new file mode 100644 index 0000000..d5732a5 --- /dev/null +++ b/strff/strff_open.c @@ -0,0 +1,8 @@ +#include "../strff.h" +#include + +void strff_open(struct strff *strff, int fd) +{ + byte_zero(strff, sizeof *strff); + strff->fd = fd; +} diff --git a/strff/strff_read.c b/strff/strff_read.c new file mode 100644 index 0000000..354e717 --- /dev/null +++ b/strff/strff_read.c @@ -0,0 +1,44 @@ +#include "../strff.h" + +#include + +int strff_read(struct strff *strff, size_t buflen, char buf[buflen]) +{ + size_t nread; + int r; + char c; + int isnewline; + if (strff->fieldtype == STRFF_TYPE_NONE) { + errno = EINVAL; /* cannot read NONE field */ + return -1; + } + + isnewline = 1; + nread = 0; + while (nread < buflen) { + r = buffer_peekc(&strff->b, &c); + if (r < 0) return -1; + if (r == 0) { + if (isnewline && nread > 0) + nread--; /* remove last \n */ + break; + } + + if (strff->fieldtype == STRFF_TYPE_EQUAL && c == '\n') + break; + else if (strff->fieldtype == STRFF_TYPE_BRACKET) { + if (isnewline && c == '[') { + if (nread > 0) + nread--; /* remove last \n */ + break; + } + isnewline = 0; + if (c == '\n') + isnewline = 1; + } + + buf[nread++] = c; + strff->b.p++; + } + return nread; +} diff --git a/strff/strff_read_sa.c b/strff/strff_read_sa.c new file mode 100644 index 0000000..88f9f63 --- /dev/null +++ b/strff/strff_read_sa.c @@ -0,0 +1,15 @@ +#include "../strff.h" +#include + +int strff_read_sa(struct strff *strff, stralloc *sa) +{ + int n; + char buf[1024]; + for (;;) { + n = strff_read(strff, sizeof buf, buf); + if (n == 0) break; + if (n < 0) return 0; + if (!stralloc_catb(sa, buf, n)) return 0; + } + return 1; +} diff --git a/strff/strff_seek.c b/strff/strff_seek.c new file mode 100644 index 0000000..b3b8395 --- /dev/null +++ b/strff/strff_seek.c @@ -0,0 +1,124 @@ +#include "../strff.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + keys can be defined either with key= or with [key]. + The first is the equalform, the second the bracketform. + There can be no keyforms after the bracketform. + */ + +static int skip_to_next_line(buffer *b) +{ + int r; + char c; + for (;;) { + r = buffer_getc(b, &c); + if (r == 0 || c == '\n') break; + if (r < 0) return 0; + } + return 1; +} + +/* + * advances the cursor until it is positioned at the value of a + * field. It will look for both the equalform and bracketform of + * the field, and returns STRFF_TYPE_BRACKET or STRFF_TYPE_EQUAL + * accordingly. If no such field is found, it returns STRFF_TYPE_NONE. + * On error, -1 is returned. + */ +static int seek_field(buffer *b, char *equalform, char *bracketform) +{ + size_t linemax, linelen; + char *line; + int r; + /* bracketform is longer */ + linemax = str_len(bracketform) + 1; + line = alloca(linemax); + linelen = 0; + + for (;;) { + r = buffer_getc(b, line + linelen); + if (r < 0) return -1; + if (r == 0) break; + linelen++; + + if (byte_starts(line, linelen, bracketform)) { + return STRFF_TYPE_BRACKET; + } + if (line[0] == '[') { + /* equalform cannot come after a bracketform */ + equalform = NULL; + } + if (equalform && byte_starts(line, linelen, equalform)){ + return STRFF_TYPE_EQUAL; + } + + if (line[linelen-1] == '\n') { + /* reset line */ + linelen = 0; + continue; + } + if (linelen == linemax) { + if (!skip_to_next_line(b)) + return -1; + linelen = 0; + } + } + + /* not found */ + return STRFF_TYPE_NONE; +} + +static int to_equalform(char *key, char *result) +{ + size_t l; + l = str_copy(result, key); + result[l++] = '='; + result[l++] = 0; + return 1; +} + +static int to_bracketform(char *key, char *result) +{ + size_t l; + l = 0; + result[l++] = '['; + l += str_copy(result + l, key); + result[l++] = ']'; + result[l++] = '\n'; + result[l++] = 0; + return 1; +} + +int strff_seek(struct strff *strff, char *key) { + char *equalform, *bracketform; + int fieldtype; + if (str_chr(key, '[') != str_len(key)) { + errno = EINVAL; /* key cannot contain '[' */ + return 0; + } + + equalform = alloca(str_len(key) + 2); + to_equalform(key, equalform); + bracketform = alloca(str_len(key) + 4); + to_bracketform(key, bracketform); + + buffer_init(&strff->b, read, strff->fd, strff->buf, sizeof strff->buf); + lseek(strff->fd, 0, SEEK_SET); + fieldtype = seek_field(&strff->b, equalform, bracketform); + if (fieldtype < 0) return 0; + strff->fieldtype = fieldtype; + if (fieldtype == STRFF_TYPE_NONE) { + errno = ENOKEY; + return 0; + } + return 1; +} diff --git a/strff_test.c b/strff_test.c new file mode 100644 index 0000000..d5160f2 --- /dev/null +++ b/strff_test.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include "strff.h" + +typedef struct { + stralloc name; + stralloc version; + stralloc makedeps; + stralloc buildcmd; + stralloc installcmd; +} pkg; + +static struct strff cfgff; + +static void pkg_load(pkg *pkg, char *path) +{ + int fd; + fd = open_read(path); + if (fd < 0) + diesys(111, "open_read ", path); + + stralloc_init(&pkg->name); + stralloc_init(&pkg->version); + stralloc_init(&pkg->makedeps); + stralloc_init(&pkg->buildcmd); + stralloc_init(&pkg->installcmd); + strff_open(&cfgff, fd); + + if (!strff_get(&cfgff, "name", &pkg->name)) + diesys(111, "cannot get value for name"); + if (!strff_get(&cfgff, "version", &pkg->version)) + diesys(111, "cannot get value for version"); + if (!strff_get(&cfgff, "makedeps", &pkg->makedeps)) + diesys(111, "cannot get value for makedeps"); + if (!strff_get(&cfgff, "build", &pkg->buildcmd)) + diesys(111, "cannot get value for buildcmd"); + if (!strff_get(&cfgff, "install", &pkg->installcmd)) + diesys(111, "cannot get value for installcmd"); +} + +int main() +{ + pkg pkg; + pkg_load(&pkg, "./conf.strff"); + + buffer_puts(buffer_1, "name is '"); + buffer_put(buffer_1, pkg.name.s, pkg.name.len); + buffer_puts(buffer_1, "', "); + buffer_puts(buffer_1, "version is '"); + buffer_put(buffer_1, pkg.version.s, pkg.version.len); + buffer_puts(buffer_1, "', "); + buffer_puts(buffer_1, "makedeps is '"); + buffer_put(buffer_1, pkg.makedeps.s, pkg.makedeps.len); + buffer_puts(buffer_1, "', "); + buffer_puts(buffer_1, "buildcmd is '"); + buffer_put(buffer_1, pkg.buildcmd.s, pkg.buildcmd.len); + buffer_puts(buffer_1, "', "); + buffer_puts(buffer_1, "installcmd is '"); + buffer_put(buffer_1, pkg.installcmd.s, pkg.installcmd.len); + buffer_putsflush(buffer_1, "'\n"); + return 0; +}