xref: /plan9-contrib/sys/src/cmd/plumb/plumber.c (revision 9b7bf7df4595c26f1e9b67beb0c6e44c9876fb05)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <regexp.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <plumb.h>
67dd7cddfSDavid du Colombier #include <auth.h>
77dd7cddfSDavid du Colombier #include <fcall.h>
87dd7cddfSDavid du Colombier #include "plumber.h"
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier char	*plumbfile;
117dd7cddfSDavid du Colombier char *user;
127dd7cddfSDavid du Colombier char *home;
137dd7cddfSDavid du Colombier char *progname;
147dd7cddfSDavid du Colombier Ruleset **rules;
157dd7cddfSDavid du Colombier int	printerrors=1;
167dd7cddfSDavid du Colombier jmp_buf	parsejmp;
177dd7cddfSDavid du Colombier char	*lasterror;
18b94bb474SDavid du Colombier int mainstacksize = 20*1024;
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier void
makeports(Ruleset * rules[])217dd7cddfSDavid du Colombier makeports(Ruleset *rules[])
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier 	int i;
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	for(i=0; rules[i]; i++)
267dd7cddfSDavid du Colombier 		addport(rules[i]->port);
277dd7cddfSDavid du Colombier }
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier void
mainproc(void * v)3080ee5cbfSDavid du Colombier mainproc(void *v)
317dd7cddfSDavid du Colombier {
3280ee5cbfSDavid du Colombier 	Channel *c;
3380ee5cbfSDavid du Colombier 
3480ee5cbfSDavid du Colombier 	c = v;
357dd7cddfSDavid du Colombier 	printerrors = 0;
367dd7cddfSDavid du Colombier 	makeports(rules);
379a747e4fSDavid du Colombier 	startfsys();
387dd7cddfSDavid du Colombier 	sendp(c, nil);
397dd7cddfSDavid du Colombier }
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier void
threadmain(int argc,char * argv[])427dd7cddfSDavid du Colombier threadmain(int argc, char *argv[])
437dd7cddfSDavid du Colombier {
447dd7cddfSDavid du Colombier 	char buf[512];
457dd7cddfSDavid du Colombier 	int fd;
467dd7cddfSDavid du Colombier 	Channel *c;
477dd7cddfSDavid du Colombier 
487dd7cddfSDavid du Colombier 	progname = "plumber";
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier 	ARGBEGIN{
517dd7cddfSDavid du Colombier 	case 'p':
527dd7cddfSDavid du Colombier 		plumbfile = ARGF();
537dd7cddfSDavid du Colombier 		break;
547dd7cddfSDavid du Colombier 	}ARGEND
557dd7cddfSDavid du Colombier 
567dd7cddfSDavid du Colombier 	user = getenv("user");
577dd7cddfSDavid du Colombier 	home = getenv("home");
587dd7cddfSDavid du Colombier 	if(user==nil || home==nil)
597dd7cddfSDavid du Colombier 		error("can't initialize $user or $home: %r");
607dd7cddfSDavid du Colombier 	if(plumbfile == nil){
617dd7cddfSDavid du Colombier 		sprint(buf, "%s/lib/plumbing", home);
627dd7cddfSDavid du Colombier 		plumbfile = estrdup(buf);
637dd7cddfSDavid du Colombier 	}
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier 	fd = open(plumbfile, OREAD);
667dd7cddfSDavid du Colombier 	if(fd < 0)
677dd7cddfSDavid du Colombier 		error("can't open rules file %s: %r", plumbfile);
687dd7cddfSDavid du Colombier 	if(setjmp(parsejmp))
697dd7cddfSDavid du Colombier 		error("parse error");
707dd7cddfSDavid du Colombier 
717dd7cddfSDavid du Colombier 	rules = readrules(plumbfile, fd);
727dd7cddfSDavid du Colombier 	close(fd);
737dd7cddfSDavid du Colombier 
747dd7cddfSDavid du Colombier 	/*
757dd7cddfSDavid du Colombier 	 * Start all processes and threads from other proc
767dd7cddfSDavid du Colombier 	 * so we (main pid) can return to user.
777dd7cddfSDavid du Colombier 	 */
787dd7cddfSDavid du Colombier 	c = chancreate(sizeof(void*), 0);
7980ee5cbfSDavid du Colombier 	proccreate(mainproc, c, 8192);
807dd7cddfSDavid du Colombier 	recvp(c);
8159cc4ca5SDavid du Colombier 	chanfree(c);
827dd7cddfSDavid du Colombier 	threadexits(nil);
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier 
857dd7cddfSDavid du Colombier void
error(char * fmt,...)867dd7cddfSDavid du Colombier error(char *fmt, ...)
877dd7cddfSDavid du Colombier {
887dd7cddfSDavid du Colombier 	char buf[512];
897dd7cddfSDavid du Colombier 	va_list args;
907dd7cddfSDavid du Colombier 
917dd7cddfSDavid du Colombier 	va_start(args, fmt);
929a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof buf, fmt, args);
937dd7cddfSDavid du Colombier 	va_end(args);
947dd7cddfSDavid du Colombier 
959a747e4fSDavid du Colombier 	fprint(2, "%s: %s\n", progname, buf);
967dd7cddfSDavid du Colombier 	threadexitsall("error");
977dd7cddfSDavid du Colombier }
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier void
parseerror(char * fmt,...)1007dd7cddfSDavid du Colombier parseerror(char *fmt, ...)
1017dd7cddfSDavid du Colombier {
1027dd7cddfSDavid du Colombier 	char buf[512];
1037dd7cddfSDavid du Colombier 	va_list args;
1047dd7cddfSDavid du Colombier 
1057dd7cddfSDavid du Colombier 	va_start(args, fmt);
1069a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof buf, fmt, args);
1077dd7cddfSDavid du Colombier 	va_end(args);
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 	if(printerrors){
1107dd7cddfSDavid du Colombier 		printinputstack();
1119a747e4fSDavid du Colombier 		fprint(2, "%s\n", buf);
1127dd7cddfSDavid du Colombier 	}
1137dd7cddfSDavid du Colombier 	do; while(popinput());
1147dd7cddfSDavid du Colombier 	lasterror = estrdup(buf);
1157dd7cddfSDavid du Colombier 	longjmp(parsejmp, 1);
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier void*
emalloc(long n)1197dd7cddfSDavid du Colombier emalloc(long n)
1207dd7cddfSDavid du Colombier {
1217dd7cddfSDavid du Colombier 	void *p;
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier 	p = malloc(n);
1247dd7cddfSDavid du Colombier 	if(p == nil)
1257dd7cddfSDavid du Colombier 		error("malloc failed: %r");
1267dd7cddfSDavid du Colombier 	memset(p, 0, n);
1277dd7cddfSDavid du Colombier 	return p;
1287dd7cddfSDavid du Colombier }
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier void*
erealloc(void * p,long n)1317dd7cddfSDavid du Colombier erealloc(void *p, long n)
1327dd7cddfSDavid du Colombier {
1337dd7cddfSDavid du Colombier 	p = realloc(p, n);
1347dd7cddfSDavid du Colombier 	if(p == nil)
1357dd7cddfSDavid du Colombier 		error("realloc failed: %r");
1367dd7cddfSDavid du Colombier 	return p;
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier char*
estrdup(char * s)1407dd7cddfSDavid du Colombier estrdup(char *s)
1417dd7cddfSDavid du Colombier {
1427dd7cddfSDavid du Colombier 	char *t;
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier 	t = strdup(s);
1457dd7cddfSDavid du Colombier 	if(t == nil)
1467dd7cddfSDavid du Colombier 		error("estrdup failed: %r");
147*9b7bf7dfSDavid du Colombier 	setmalloctag(t, getcallerpc(&s));
1487dd7cddfSDavid du Colombier 	return t;
1497dd7cddfSDavid du Colombier }
150