xref: /plan9/sys/src/cmd/plumb/plumber.c (revision 9b7bf7df4595c26f1e9b67beb0c6e44c9876fb05)
1 #include <u.h>
2 #include <libc.h>
3 #include <regexp.h>
4 #include <thread.h>
5 #include <plumb.h>
6 #include <auth.h>
7 #include <fcall.h>
8 #include "plumber.h"
9 
10 char	*plumbfile;
11 char *user;
12 char *home;
13 char *progname;
14 Ruleset **rules;
15 int	printerrors=1;
16 jmp_buf	parsejmp;
17 char	*lasterror;
18 int mainstacksize = 20*1024;
19 
20 void
makeports(Ruleset * rules[])21 makeports(Ruleset *rules[])
22 {
23 	int i;
24 
25 	for(i=0; rules[i]; i++)
26 		addport(rules[i]->port);
27 }
28 
29 void
mainproc(void * v)30 mainproc(void *v)
31 {
32 	Channel *c;
33 
34 	c = v;
35 	printerrors = 0;
36 	makeports(rules);
37 	startfsys();
38 	sendp(c, nil);
39 }
40 
41 void
threadmain(int argc,char * argv[])42 threadmain(int argc, char *argv[])
43 {
44 	char buf[512];
45 	int fd;
46 	Channel *c;
47 
48 	progname = "plumber";
49 
50 	ARGBEGIN{
51 	case 'p':
52 		plumbfile = ARGF();
53 		break;
54 	}ARGEND
55 
56 	user = getenv("user");
57 	home = getenv("home");
58 	if(user==nil || home==nil)
59 		error("can't initialize $user or $home: %r");
60 	if(plumbfile == nil){
61 		sprint(buf, "%s/lib/plumbing", home);
62 		plumbfile = estrdup(buf);
63 	}
64 
65 	fd = open(plumbfile, OREAD);
66 	if(fd < 0)
67 		error("can't open rules file %s: %r", plumbfile);
68 	if(setjmp(parsejmp))
69 		error("parse error");
70 
71 	rules = readrules(plumbfile, fd);
72 	close(fd);
73 
74 	/*
75 	 * Start all processes and threads from other proc
76 	 * so we (main pid) can return to user.
77 	 */
78 	c = chancreate(sizeof(void*), 0);
79 	proccreate(mainproc, c, 8192);
80 	recvp(c);
81 	chanfree(c);
82 	threadexits(nil);
83 }
84 
85 void
error(char * fmt,...)86 error(char *fmt, ...)
87 {
88 	char buf[512];
89 	va_list args;
90 
91 	va_start(args, fmt);
92 	vseprint(buf, buf+sizeof buf, fmt, args);
93 	va_end(args);
94 
95 	fprint(2, "%s: %s\n", progname, buf);
96 	threadexitsall("error");
97 }
98 
99 void
parseerror(char * fmt,...)100 parseerror(char *fmt, ...)
101 {
102 	char buf[512];
103 	va_list args;
104 
105 	va_start(args, fmt);
106 	vseprint(buf, buf+sizeof buf, fmt, args);
107 	va_end(args);
108 
109 	if(printerrors){
110 		printinputstack();
111 		fprint(2, "%s\n", buf);
112 	}
113 	do; while(popinput());
114 	lasterror = estrdup(buf);
115 	longjmp(parsejmp, 1);
116 }
117 
118 void*
emalloc(long n)119 emalloc(long n)
120 {
121 	void *p;
122 
123 	p = malloc(n);
124 	if(p == nil)
125 		error("malloc failed: %r");
126 	memset(p, 0, n);
127 	return p;
128 }
129 
130 void*
erealloc(void * p,long n)131 erealloc(void *p, long n)
132 {
133 	p = realloc(p, n);
134 	if(p == nil)
135 		error("realloc failed: %r");
136 	return p;
137 }
138 
139 char*
estrdup(char * s)140 estrdup(char *s)
141 {
142 	char *t;
143 
144 	t = strdup(s);
145 	if(t == nil)
146 		error("estrdup failed: %r");
147 	setmalloctag(t, getcallerpc(&s));
148 	return t;
149 }
150