hlfw.ca

task

Download patch

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
+}