ref: 832e8448b3bd0aec97693691c7bd190bf8dcd504
parent: 759814888eb9e89c061b62fe9c615308ab52fa2c
author: Michael Misch <michaelmisch1985@gmail.com>
date: Wed Aug 28 17:06:50 PDT 2024
Use a config, set up init and related, use pro/ namespace, ns for namespace
--- /dev/null
+++ b/conf.c
@@ -1,0 +1,134 @@
+#include <u.h>
+#include <libc.h>
+#include <ctype.h>
+#include <bio.h>
+
+#include "pro.h"
+
+static char*
+strip(char *s)
+{
+ char *e;
+
+ while(isspace(*s))
+ s++;
+ e = s + strlen(s);
+ while(e > s && isspace(*--e))
+ *e = 0;
+ return s;
+}
+
+static char*
+wd2sfile(void)
+{
+ char pathname[512];
+ char *pr;
+
+ if(getwd(pathname, sizeof(pathname)) == 0)
+ return "/srv/work";
+ if((pr = utfrrune(pathname, '/')))
+ return strcat("/srv", pr);
+ return "/srv/work";
+}
+
+static char**
+fromCSV(char *s, int *nfields)
+{
+ char **fields;
+ int i, cap, nf;
+ char *token;
+
+ cap = 1;
+ nf = 0;
+
+ fields = malloc(sizeof(char*));
+ if(!fields)
+ return nil;
+
+ token = strtok(s, ",");
+ while(token){
+ if(nf >= cap){
+ cap *= 2;
+ char **tmp = realloc(fields, cap * sizeof(char*));
+ if(!tmp)
+ goto Fail;
+ fields = tmp;
+ }
+
+ fields[nf] = strdup(token);
+ if(!fields[nf])
+ goto Fail;
+ nf++;
+ token = strtok(nil, ",");
+ }
+ *nfields = nf;
+ return fields;
+Fail:
+ for(i = 0; i < nf; i++)
+ free(fields[i]);
+ free(fields);
+ werrstr("failed to parse csv");
+ return nil;
+}
+
+void
+freeconf(Proconf *conf)
+{
+ int i;
+ if(!conf)
+ return;
+
+ if(conf->stubs){
+ for(i = 0; i < conf->nstub; i++)
+ free(conf->stubs[i]);
+ free(conf->stubs);
+ }
+ free(conf);
+
+}
+
+Proconf*
+pconf(void)
+{
+ Proconf *conf;
+ Biobuf *f;
+ char *ln, *p;
+
+ if((f = Bopen(".pro/config", OREAD)) == nil)
+ return nil;
+
+ conf = malloc(sizeof(Proconf));
+ conf->nstub = 0;
+ conf->stubs = nil;
+ while((ln = Brdstr(f, '\n', 1)) != nil){
+ p = strip(ln);
+ if(strncmp(p, "name", 4) == 0){
+print("Starting sfile\n");
+ p = strip(p + 4);
+ if(*p == '='){
+ p = strip(p + 1);
+ conf->sfile = strcat("/srv/", p);
+ }
+print("Finishing sfile\n");
+ } else if(strncmp(p, "stubs", 5) == 0){
+print("Starting stubs\n");
+ p = strip(p + 5);
+ if(*p == '='){
+ p = strip(p + 1);
+ conf->stubs = fromCSV(p, &conf->nstub);
+ if(!conf->stubs){
+ freeconf(conf);
+ free(ln);
+ return nil;
+ }
+ }
+print("Finishing stubs\n");
+ } else {
+ // TBD
+ }
+ free(ln);
+ }
+ if(!conf->sfile)
+ conf->sfile = wd2sfile();
+ return conf;
+}
--- /dev/null
+++ b/init
@@ -1,0 +1,20 @@
+#!/bin/rc -e
+rfork ne
+
+dir=$1
+if(~ $#dir 0)
+ dir=.
+if(test -e $dir/.pro){
+ echo $0: $dir/.pro already exists >[1=2]
+ exit 'exists'
+}
+
+name=`{basename `{cleanname -d `{pwd} $dir}}
+mkdir -p $dir/.pro/todo
+
+touch $dir/.pro/ns
+>$dir/.pro/config {
+ echo '[project '$name']'
+ echo ' srvname='$name
+ echo ' stubs='
+}
--- a/mkfile
+++ b/mkfile
@@ -1,10 +1,27 @@
</$objtype/mkfile
-BIN=/$objtype/bin
-TARG=proj
+BIN=/$objtype/bin/proj
+TARG=\
+ ns\
+ todo\
+RC=\
+ init\
+
OFILES=\
- proj.$O\
+ conf.$O\
-</sys/src/cmd/mkone
+HFILES=proj.h
+</sys/src/cmd/mkmany
+
+install:V:
+ mkdir -p $BIN
+ for (i in $TARG)
+ mk $MKFLAGS $i.install
+ for (i in $RC)
+ mk $MKFLAGS $i.rcinstall
+
+%.rcinstall:V:
+ cp $stem $BIN/$stem
+ chmod +x $BIN/$stem
--- /dev/null
+++ b/ns.c
@@ -1,0 +1,69 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+
+#include "pro.h"
+
+static void
+usage(char *argv0)
+{
+ fprint(2, "usage: %s\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ Proconf *conf;
+ int i, fd, pipefd[2];
+
+ if(argc != 1)
+ usage(argv[0]);
+
+ conf = pconf();
+ if(conf == nil){
+ fprint(2, "can't parse: %r\n");
+ exits("config");
+ }
+ for(i = 0; i < conf->nstub; i++)
+print("%s\n", conf->stubs[i]);
+exits(0);
+ // execl("/bin/aux/stub", "-d", conf->stubs[i]);
+
+ if(addns(getuser(), ".pro/ns") < 0){
+ fprint(2, "can't addns: %r\n");
+ exits("addns");
+ }
+ if(pipe(pipefd) < 0){
+ fprint(2, "can't pipe: %r\n");
+ exits("pipe");
+ }
+ if(access(conf->sfile, 0) == 0)
+ remove(conf->sfile);
+ fd = create(conf->sfile, OWRITE|ORCLOSE, 0600);
+ if(fd < 0){
+ fprint(2, "can't create %s: %r\n", conf->sfile);
+ exits("create");
+ }
+
+ fprint(fd, "%d", pipefd[1]);
+ close(pipefd[1]);
+ freeconf(conf);
+
+ switch(rfork(RFPROC|RFNOWAIT|RFNOTEG|RFFDG)){
+ case -1:
+ fprint(2, "can't rfork: %r\n");
+ exits("rfork");
+ case 0:
+ dup(pipefd[0], 0);
+ dup(pipefd[0], 1);
+ close(pipefd[0]);
+
+ execl("/bin/exportfs", "exportfs", "-r", ".");
+ fprint(2, "can't exec exportfs: %r\n");
+ exits("exec");
+ default:
+ break;
+ }
+ exits(0);
+}
--- /dev/null
+++ b/pro.h
@@ -1,0 +1,10 @@
+typedef struct Proconf Proconf;
+struct Proconf
+{
+ char *sfile;
+ char **stubs;
+ int nstub;
+};
+
+void freeconf(Proconf*);
+Proconf *pconf(void);
--- /dev/null
+++ b/todo.c
@@ -1,0 +1,19 @@
+#include <u.h>
+#include <libc.h>
+
+#include "pro.h"
+
+static void
+usage(char *argv0)
+{
+ fprint(2, "usage: %s\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ USED(argc);
+ USED(argv);
+ //walks our zk-backed DAG to find the next task, answers queries, etc
+}