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