Blame


1 b8c14089 2003-11-23 devnull #include <u.h>
2 b8c14089 2003-11-23 devnull #include <libc.h>
3 b8c14089 2003-11-23 devnull #include <bio.h>
4 b8c14089 2003-11-23 devnull #include <regexp.h>
5 b8c14089 2003-11-23 devnull #include <thread.h>
6 b8c14089 2003-11-23 devnull #include <plumb.h>
7 b8c14089 2003-11-23 devnull #include "plumber.h"
8 b8c14089 2003-11-23 devnull
9 b8c14089 2003-11-23 devnull static char*
10 b8c14089 2003-11-23 devnull nonnil(char *s)
11 b8c14089 2003-11-23 devnull {
12 b8c14089 2003-11-23 devnull if(s == nil)
13 b8c14089 2003-11-23 devnull return "";
14 b8c14089 2003-11-23 devnull return s;
15 b8c14089 2003-11-23 devnull }
16 b8c14089 2003-11-23 devnull
17 b8c14089 2003-11-23 devnull int
18 b8c14089 2003-11-23 devnull verbis(int obj, Plumbmsg *m, Rule *r)
19 b8c14089 2003-11-23 devnull {
20 b8c14089 2003-11-23 devnull switch(obj){
21 b8c14089 2003-11-23 devnull default:
22 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'is' object %d\n", obj);
23 b8c14089 2003-11-23 devnull break;
24 b8c14089 2003-11-23 devnull case OData:
25 b8c14089 2003-11-23 devnull return strcmp(m->data, r->qarg) == 0;
26 b8c14089 2003-11-23 devnull case ODst:
27 b8c14089 2003-11-23 devnull return strcmp(m->dst, r->qarg) == 0;
28 b8c14089 2003-11-23 devnull case OType:
29 b8c14089 2003-11-23 devnull return strcmp(m->type, r->qarg) == 0;
30 b8c14089 2003-11-23 devnull case OWdir:
31 b8c14089 2003-11-23 devnull return strcmp(m->wdir, r->qarg) == 0;
32 b8c14089 2003-11-23 devnull case OSrc:
33 b8c14089 2003-11-23 devnull return strcmp(m->src, r->qarg) == 0;
34 b8c14089 2003-11-23 devnull }
35 b8c14089 2003-11-23 devnull return 0;
36 b8c14089 2003-11-23 devnull }
37 b8c14089 2003-11-23 devnull
38 b8c14089 2003-11-23 devnull static void
39 b8c14089 2003-11-23 devnull setvar(Resub rs[10], char *match[10])
40 b8c14089 2003-11-23 devnull {
41 b8c14089 2003-11-23 devnull int i, n;
42 b8c14089 2003-11-23 devnull
43 b8c14089 2003-11-23 devnull for(i=0; i<10; i++){
44 b8c14089 2003-11-23 devnull free(match[i]);
45 b8c14089 2003-11-23 devnull match[i] = nil;
46 b8c14089 2003-11-23 devnull }
47 b8c14089 2003-11-23 devnull for(i=0; i<10 && rs[i].sp!=nil; i++){
48 b8c14089 2003-11-23 devnull n = rs[i].ep-rs[i].sp;
49 b8c14089 2003-11-23 devnull match[i] = emalloc(n+1);
50 b8c14089 2003-11-23 devnull memmove(match[i], rs[i].sp, n);
51 b8c14089 2003-11-23 devnull match[i][n] = '\0';
52 b8c14089 2003-11-23 devnull }
53 b8c14089 2003-11-23 devnull }
54 b8c14089 2003-11-23 devnull
55 b8c14089 2003-11-23 devnull int
56 b8c14089 2003-11-23 devnull clickmatch(Reprog *re, char *text, Resub rs[10], int click)
57 b8c14089 2003-11-23 devnull {
58 b8c14089 2003-11-23 devnull char *clickp;
59 b8c14089 2003-11-23 devnull int i, w;
60 b8c14089 2003-11-23 devnull Rune r;
61 b8c14089 2003-11-23 devnull
62 b8c14089 2003-11-23 devnull /* click is in characters, not bytes */
63 b8c14089 2003-11-23 devnull for(i=0; i<click && text[i]!='\0'; i+=w)
64 b8c14089 2003-11-23 devnull w = chartorune(&r, text+i);
65 b8c14089 2003-11-23 devnull clickp = text+i;
66 b8c14089 2003-11-23 devnull for(i=0; i<=click; i++){
67 b8c14089 2003-11-23 devnull memset(rs, 0, 10*sizeof(Resub));
68 b8c14089 2003-11-23 devnull if(regexec(re, text+i, rs, 10))
69 b8c14089 2003-11-23 devnull if(rs[0].sp<=clickp && clickp<=rs[0].ep)
70 b8c14089 2003-11-23 devnull return 1;
71 b8c14089 2003-11-23 devnull }
72 b8c14089 2003-11-23 devnull return 0;
73 b8c14089 2003-11-23 devnull }
74 b8c14089 2003-11-23 devnull
75 b8c14089 2003-11-23 devnull int
76 b8c14089 2003-11-23 devnull verbmatches(int obj, Plumbmsg *m, Rule *r, Exec *e)
77 b8c14089 2003-11-23 devnull {
78 b8c14089 2003-11-23 devnull Resub rs[10];
79 b8c14089 2003-11-23 devnull char *clickval, *alltext;
80 b8c14089 2003-11-23 devnull int p0, p1, ntext;
81 b8c14089 2003-11-23 devnull
82 b8c14089 2003-11-23 devnull memset(rs, 0, sizeof rs);
83 b8c14089 2003-11-23 devnull ntext = -1;
84 b8c14089 2003-11-23 devnull switch(obj){
85 b8c14089 2003-11-23 devnull default:
86 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'matches' object %d\n", obj);
87 b8c14089 2003-11-23 devnull break;
88 b8c14089 2003-11-23 devnull case OData:
89 b8c14089 2003-11-23 devnull clickval = plumblookup(m->attr, "click");
90 b8c14089 2003-11-23 devnull if(clickval == nil){
91 b8c14089 2003-11-23 devnull alltext = m->data;
92 b8c14089 2003-11-23 devnull ntext = m->ndata;
93 b8c14089 2003-11-23 devnull goto caseAlltext;
94 b8c14089 2003-11-23 devnull }
95 b8c14089 2003-11-23 devnull if(!clickmatch(r->regex, m->data, rs, atoi(clickval)))
96 b8c14089 2003-11-23 devnull break;
97 b8c14089 2003-11-23 devnull p0 = rs[0].sp - m->data;
98 b8c14089 2003-11-23 devnull p1 = rs[0].ep - m->data;
99 b8c14089 2003-11-23 devnull if(e->p0 >=0 && !(p0==e->p0 && p1==e->p1))
100 b8c14089 2003-11-23 devnull break;
101 b8c14089 2003-11-23 devnull e->clearclick = 1;
102 b8c14089 2003-11-23 devnull e->setdata = 1;
103 b8c14089 2003-11-23 devnull e->p0 = p0;
104 b8c14089 2003-11-23 devnull e->p1 = p1;
105 b8c14089 2003-11-23 devnull setvar(rs, e->match);
106 b8c14089 2003-11-23 devnull return 1;
107 b8c14089 2003-11-23 devnull case ODst:
108 b8c14089 2003-11-23 devnull alltext = m->dst;
109 b8c14089 2003-11-23 devnull goto caseAlltext;
110 b8c14089 2003-11-23 devnull case OType:
111 b8c14089 2003-11-23 devnull alltext = m->type;
112 b8c14089 2003-11-23 devnull goto caseAlltext;
113 b8c14089 2003-11-23 devnull case OWdir:
114 b8c14089 2003-11-23 devnull alltext = m->wdir;
115 b8c14089 2003-11-23 devnull goto caseAlltext;
116 b8c14089 2003-11-23 devnull case OSrc:
117 b8c14089 2003-11-23 devnull alltext = m->src;
118 b8c14089 2003-11-23 devnull /* fall through */
119 b8c14089 2003-11-23 devnull caseAlltext:
120 b8c14089 2003-11-23 devnull /* must match full text */
121 b8c14089 2003-11-23 devnull if(ntext < 0)
122 b8c14089 2003-11-23 devnull ntext = strlen(alltext);
123 b8c14089 2003-11-23 devnull if(!regexec(r->regex, alltext, rs, 10) || rs[0].sp!=alltext || rs[0].ep!=alltext+ntext)
124 b8c14089 2003-11-23 devnull break;
125 b8c14089 2003-11-23 devnull setvar(rs, e->match);
126 b8c14089 2003-11-23 devnull return 1;
127 b8c14089 2003-11-23 devnull }
128 b8c14089 2003-11-23 devnull return 0;
129 b8c14089 2003-11-23 devnull }
130 b8c14089 2003-11-23 devnull
131 b8c14089 2003-11-23 devnull int
132 b8c14089 2003-11-23 devnull isfile(char *file, ulong maskon, ulong maskoff)
133 b8c14089 2003-11-23 devnull {
134 b8c14089 2003-11-23 devnull Dir *d;
135 b8c14089 2003-11-23 devnull int mode;
136 b8c14089 2003-11-23 devnull
137 b8c14089 2003-11-23 devnull d = dirstat(file);
138 b8c14089 2003-11-23 devnull if(d == nil)
139 b8c14089 2003-11-23 devnull return 0;
140 b8c14089 2003-11-23 devnull mode = d->mode;
141 b8c14089 2003-11-23 devnull free(d);
142 b8c14089 2003-11-23 devnull if((mode & maskon) == 0)
143 b8c14089 2003-11-23 devnull return 0;
144 b8c14089 2003-11-23 devnull if(mode & maskoff)
145 b8c14089 2003-11-23 devnull return 0;
146 b8c14089 2003-11-23 devnull return 1;
147 b8c14089 2003-11-23 devnull }
148 b8c14089 2003-11-23 devnull
149 b8c14089 2003-11-23 devnull char*
150 b8c14089 2003-11-23 devnull absolute(char *dir, char *file)
151 b8c14089 2003-11-23 devnull {
152 b8c14089 2003-11-23 devnull char *p;
153 b8c14089 2003-11-23 devnull
154 b8c14089 2003-11-23 devnull if(file[0] == '/')
155 b8c14089 2003-11-23 devnull return estrdup(file);
156 b8c14089 2003-11-23 devnull p = emalloc(strlen(dir)+1+strlen(file)+1);
157 b8c14089 2003-11-23 devnull sprint(p, "%s/%s", dir, file);
158 b8c14089 2003-11-23 devnull return cleanname(p);
159 b8c14089 2003-11-23 devnull }
160 b8c14089 2003-11-23 devnull
161 b8c14089 2003-11-23 devnull int
162 b8c14089 2003-11-23 devnull verbisfile(int obj, Plumbmsg *m, Rule *r, Exec *e, ulong maskon, ulong maskoff, char **var)
163 b8c14089 2003-11-23 devnull {
164 b8c14089 2003-11-23 devnull char *file;
165 b8c14089 2003-11-23 devnull
166 b8c14089 2003-11-23 devnull switch(obj){
167 b8c14089 2003-11-23 devnull default:
168 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'isfile' object %d\n", obj);
169 b8c14089 2003-11-23 devnull break;
170 b8c14089 2003-11-23 devnull case OArg:
171 b8c14089 2003-11-23 devnull file = absolute(m->wdir, expand(e, r->arg, nil));
172 b8c14089 2003-11-23 devnull if(isfile(file, maskon, maskoff)){
173 b8c14089 2003-11-23 devnull *var = file;
174 b8c14089 2003-11-23 devnull return 1;
175 b8c14089 2003-11-23 devnull }
176 b8c14089 2003-11-23 devnull free(file);
177 b8c14089 2003-11-23 devnull break;
178 b8c14089 2003-11-23 devnull case OData:
179 b8c14089 2003-11-23 devnull case OWdir:
180 b8c14089 2003-11-23 devnull file = absolute(m->wdir, obj==OData? m->data : m->wdir);
181 b8c14089 2003-11-23 devnull if(isfile(file, maskon, maskoff)){
182 b8c14089 2003-11-23 devnull *var = file;
183 b8c14089 2003-11-23 devnull return 1;
184 b8c14089 2003-11-23 devnull }
185 b8c14089 2003-11-23 devnull free(file);
186 b8c14089 2003-11-23 devnull break;
187 b8c14089 2003-11-23 devnull }
188 b8c14089 2003-11-23 devnull return 0;
189 b8c14089 2003-11-23 devnull }
190 b8c14089 2003-11-23 devnull
191 b8c14089 2003-11-23 devnull int
192 b8c14089 2003-11-23 devnull verbset(int obj, Plumbmsg *m, Rule *r, Exec *e)
193 b8c14089 2003-11-23 devnull {
194 b8c14089 2003-11-23 devnull char *new;
195 b8c14089 2003-11-23 devnull
196 b8c14089 2003-11-23 devnull switch(obj){
197 b8c14089 2003-11-23 devnull default:
198 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'is' object %d\n", obj);
199 b8c14089 2003-11-23 devnull break;
200 b8c14089 2003-11-23 devnull case OData:
201 b8c14089 2003-11-23 devnull new = estrdup(expand(e, r->arg, nil));
202 b8c14089 2003-11-23 devnull m->ndata = strlen(new);
203 b8c14089 2003-11-23 devnull free(m->data);
204 b8c14089 2003-11-23 devnull m->data = new;
205 b8c14089 2003-11-23 devnull e->p0 = -1;
206 b8c14089 2003-11-23 devnull e->p1 = -1;
207 b8c14089 2003-11-23 devnull e->setdata = 0;
208 b8c14089 2003-11-23 devnull return 1;
209 b8c14089 2003-11-23 devnull case ODst:
210 b8c14089 2003-11-23 devnull new = estrdup(expand(e, r->arg, nil));
211 b8c14089 2003-11-23 devnull free(m->dst);
212 b8c14089 2003-11-23 devnull m->dst = new;
213 b8c14089 2003-11-23 devnull return 1;
214 b8c14089 2003-11-23 devnull case OType:
215 b8c14089 2003-11-23 devnull new = estrdup(expand(e, r->arg, nil));
216 b8c14089 2003-11-23 devnull free(m->type);
217 b8c14089 2003-11-23 devnull m->type = new;
218 b8c14089 2003-11-23 devnull return 1;
219 b8c14089 2003-11-23 devnull case OWdir:
220 b8c14089 2003-11-23 devnull new = estrdup(expand(e, r->arg, nil));
221 b8c14089 2003-11-23 devnull free(m->wdir);
222 b8c14089 2003-11-23 devnull m->wdir = new;
223 b8c14089 2003-11-23 devnull return 1;
224 b8c14089 2003-11-23 devnull case OSrc:
225 b8c14089 2003-11-23 devnull new = estrdup(expand(e, r->arg, nil));
226 b8c14089 2003-11-23 devnull free(m->src);
227 b8c14089 2003-11-23 devnull m->src = new;
228 b8c14089 2003-11-23 devnull return 1;
229 b8c14089 2003-11-23 devnull }
230 b8c14089 2003-11-23 devnull return 0;
231 b8c14089 2003-11-23 devnull }
232 b8c14089 2003-11-23 devnull
233 b8c14089 2003-11-23 devnull int
234 b8c14089 2003-11-23 devnull verbadd(int obj, Plumbmsg *m, Rule *r, Exec *e)
235 b8c14089 2003-11-23 devnull {
236 b8c14089 2003-11-23 devnull switch(obj){
237 b8c14089 2003-11-23 devnull default:
238 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'add' object %d\n", obj);
239 b8c14089 2003-11-23 devnull break;
240 b8c14089 2003-11-23 devnull case OAttr:
241 b8c14089 2003-11-23 devnull m->attr = plumbaddattr(m->attr, plumbunpackattr(expand(e, r->arg, nil)));
242 b8c14089 2003-11-23 devnull return 1;
243 b8c14089 2003-11-23 devnull }
244 b8c14089 2003-11-23 devnull return 0;
245 b8c14089 2003-11-23 devnull }
246 b8c14089 2003-11-23 devnull
247 b8c14089 2003-11-23 devnull int
248 b8c14089 2003-11-23 devnull verbdelete(int obj, Plumbmsg *m, Rule *r, Exec *e)
249 b8c14089 2003-11-23 devnull {
250 b8c14089 2003-11-23 devnull char *a;
251 b8c14089 2003-11-23 devnull
252 b8c14089 2003-11-23 devnull switch(obj){
253 b8c14089 2003-11-23 devnull default:
254 b8c14089 2003-11-23 devnull fprint(2, "unimplemented 'delete' object %d\n", obj);
255 b8c14089 2003-11-23 devnull break;
256 b8c14089 2003-11-23 devnull case OAttr:
257 b8c14089 2003-11-23 devnull a = expand(e, r->arg, nil);
258 b8c14089 2003-11-23 devnull if(plumblookup(m->attr, a) == nil)
259 b8c14089 2003-11-23 devnull break;
260 b8c14089 2003-11-23 devnull m->attr = plumbdelattr(m->attr, a);
261 b8c14089 2003-11-23 devnull return 1;
262 b8c14089 2003-11-23 devnull }
263 b8c14089 2003-11-23 devnull return 0;
264 b8c14089 2003-11-23 devnull }
265 b8c14089 2003-11-23 devnull
266 b8c14089 2003-11-23 devnull int
267 b8c14089 2003-11-23 devnull matchpat(Plumbmsg *m, Exec *e, Rule *r)
268 b8c14089 2003-11-23 devnull {
269 b8c14089 2003-11-23 devnull switch(r->verb){
270 b8c14089 2003-11-23 devnull default:
271 b8c14089 2003-11-23 devnull fprint(2, "unimplemented verb %d\n", r->verb);
272 b8c14089 2003-11-23 devnull break;
273 b8c14089 2003-11-23 devnull case VAdd:
274 b8c14089 2003-11-23 devnull return verbadd(r->obj, m, r, e);
275 b8c14089 2003-11-23 devnull case VDelete:
276 b8c14089 2003-11-23 devnull return verbdelete(r->obj, m, r, e);
277 b8c14089 2003-11-23 devnull case VIs:
278 b8c14089 2003-11-23 devnull return verbis(r->obj, m, r);
279 b8c14089 2003-11-23 devnull case VIsdir:
280 b8c14089 2003-11-23 devnull return verbisfile(r->obj, m, r, e, DMDIR, 0, &e->dir);
281 b8c14089 2003-11-23 devnull case VIsfile:
282 b8c14089 2003-11-23 devnull return verbisfile(r->obj, m, r, e, ~DMDIR, DMDIR, &e->file);
283 b8c14089 2003-11-23 devnull case VMatches:
284 b8c14089 2003-11-23 devnull return verbmatches(r->obj, m, r, e);
285 b8c14089 2003-11-23 devnull case VSet:
286 b8c14089 2003-11-23 devnull verbset(r->obj, m, r, e);
287 b8c14089 2003-11-23 devnull return 1;
288 b8c14089 2003-11-23 devnull }
289 b8c14089 2003-11-23 devnull return 0;
290 b8c14089 2003-11-23 devnull }
291 b8c14089 2003-11-23 devnull
292 b8c14089 2003-11-23 devnull void
293 b8c14089 2003-11-23 devnull freeexec(Exec *exec)
294 b8c14089 2003-11-23 devnull {
295 b8c14089 2003-11-23 devnull int i;
296 b8c14089 2003-11-23 devnull
297 b8c14089 2003-11-23 devnull if(exec == nil)
298 b8c14089 2003-11-23 devnull return;
299 b8c14089 2003-11-23 devnull free(exec->dir);
300 b8c14089 2003-11-23 devnull free(exec->file);
301 b8c14089 2003-11-23 devnull for(i=0; i<10; i++)
302 b8c14089 2003-11-23 devnull free(exec->match[i]);
303 b8c14089 2003-11-23 devnull free(exec);
304 b8c14089 2003-11-23 devnull }
305 b8c14089 2003-11-23 devnull
306 b8c14089 2003-11-23 devnull Exec*
307 b8c14089 2003-11-23 devnull newexec(Plumbmsg *m)
308 b8c14089 2003-11-23 devnull {
309 b8c14089 2003-11-23 devnull Exec *exec;
310 b8c14089 2003-11-23 devnull
311 b8c14089 2003-11-23 devnull exec = emalloc(sizeof(Exec));
312 b8c14089 2003-11-23 devnull exec->msg = m;
313 b8c14089 2003-11-23 devnull exec->p0 = -1;
314 b8c14089 2003-11-23 devnull exec->p1 = -1;
315 b8c14089 2003-11-23 devnull return exec;
316 b8c14089 2003-11-23 devnull }
317 b8c14089 2003-11-23 devnull
318 b8c14089 2003-11-23 devnull void
319 b8c14089 2003-11-23 devnull rewrite(Plumbmsg *m, Exec *e)
320 b8c14089 2003-11-23 devnull {
321 b8c14089 2003-11-23 devnull Plumbattr *a, *prev;
322 b8c14089 2003-11-23 devnull
323 b8c14089 2003-11-23 devnull if(e->clearclick){
324 b8c14089 2003-11-23 devnull prev = nil;
325 b8c14089 2003-11-23 devnull for(a=m->attr; a!=nil; a=a->next){
326 b8c14089 2003-11-23 devnull if(strcmp(a->name, "click") == 0){
327 b8c14089 2003-11-23 devnull if(prev == nil)
328 b8c14089 2003-11-23 devnull m->attr = a->next;
329 b8c14089 2003-11-23 devnull else
330 b8c14089 2003-11-23 devnull prev->next = a->next;
331 b8c14089 2003-11-23 devnull free(a->name);
332 b8c14089 2003-11-23 devnull free(a->value);
333 b8c14089 2003-11-23 devnull free(a);
334 b8c14089 2003-11-23 devnull break;
335 b8c14089 2003-11-23 devnull }
336 b8c14089 2003-11-23 devnull prev = a;
337 b8c14089 2003-11-23 devnull }
338 b8c14089 2003-11-23 devnull if(e->setdata){
339 b8c14089 2003-11-23 devnull free(m->data);
340 b8c14089 2003-11-23 devnull m->data = estrdup(expand(e, "$0", nil));
341 b8c14089 2003-11-23 devnull m->ndata = strlen(m->data);
342 b8c14089 2003-11-23 devnull }
343 b8c14089 2003-11-23 devnull }
344 b8c14089 2003-11-23 devnull }
345 b8c14089 2003-11-23 devnull
346 b8c14089 2003-11-23 devnull char**
347 b8c14089 2003-11-23 devnull buildargv(char *s, Exec *e)
348 b8c14089 2003-11-23 devnull {
349 b8c14089 2003-11-23 devnull char **av;
350 b8c14089 2003-11-23 devnull int ac;
351 b8c14089 2003-11-23 devnull
352 b8c14089 2003-11-23 devnull ac = 0;
353 b8c14089 2003-11-23 devnull av = nil;
354 b8c14089 2003-11-23 devnull for(;;){
355 b8c14089 2003-11-23 devnull av = erealloc(av, (ac+1) * sizeof(char*));
356 b8c14089 2003-11-23 devnull av[ac] = nil;
357 b8c14089 2003-11-23 devnull while(*s==' ' || *s=='\t')
358 b8c14089 2003-11-23 devnull s++;
359 b8c14089 2003-11-23 devnull if(*s == '\0')
360 b8c14089 2003-11-23 devnull break;
361 b8c14089 2003-11-23 devnull av[ac++] = estrdup(expand(e, s, &s));
362 b8c14089 2003-11-23 devnull }
363 b8c14089 2003-11-23 devnull return av;
364 b8c14089 2003-11-23 devnull }
365 b8c14089 2003-11-23 devnull
366 b8c14089 2003-11-23 devnull Exec*
367 b8c14089 2003-11-23 devnull matchruleset(Plumbmsg *m, Ruleset *rs)
368 b8c14089 2003-11-23 devnull {
369 b8c14089 2003-11-23 devnull int i;
370 b8c14089 2003-11-23 devnull Exec *exec;
371 b8c14089 2003-11-23 devnull
372 b8c14089 2003-11-23 devnull if(m->dst!=nil && m->dst[0]!='\0' && rs->port!=nil && strcmp(m->dst, rs->port)!=0)
373 b8c14089 2003-11-23 devnull return nil;
374 b8c14089 2003-11-23 devnull exec = newexec(m);
375 b8c14089 2003-11-23 devnull for(i=0; i<rs->npat; i++)
376 b8c14089 2003-11-23 devnull if(!matchpat(m, exec, rs->pat[i])){
377 b8c14089 2003-11-23 devnull freeexec(exec);
378 b8c14089 2003-11-23 devnull return nil;
379 b8c14089 2003-11-23 devnull }
380 b8c14089 2003-11-23 devnull if(rs->port!=nil && (m->dst==nil || m->dst[0]=='\0')){
381 b8c14089 2003-11-23 devnull free(m->dst);
382 b8c14089 2003-11-23 devnull m->dst = estrdup(rs->port);
383 b8c14089 2003-11-23 devnull }
384 b8c14089 2003-11-23 devnull rewrite(m, exec);
385 b8c14089 2003-11-23 devnull return exec;
386 b8c14089 2003-11-23 devnull }
387 b8c14089 2003-11-23 devnull
388 b8c14089 2003-11-23 devnull enum
389 b8c14089 2003-11-23 devnull {
390 b8c14089 2003-11-23 devnull NARGS = 100,
391 b8c14089 2003-11-23 devnull NARGCHAR = 8*1024,
392 b8c14089 2003-11-23 devnull EXECSTACK = 4096+(NARGS+1)*sizeof(char*)+NARGCHAR
393 b8c14089 2003-11-23 devnull };
394 b8c14089 2003-11-23 devnull
395 b8c14089 2003-11-23 devnull /* copy argv to stack and free the incoming strings, so we don't leak argument vectors */
396 b8c14089 2003-11-23 devnull void
397 b8c14089 2003-11-23 devnull stackargv(char **inargv, char *argv[NARGS+1], char args[NARGCHAR])
398 b8c14089 2003-11-23 devnull {
399 b8c14089 2003-11-23 devnull int i, n;
400 b8c14089 2003-11-23 devnull char *s, *a;
401 b8c14089 2003-11-23 devnull
402 b8c14089 2003-11-23 devnull s = args;
403 b8c14089 2003-11-23 devnull for(i=0; i<NARGS; i++){
404 b8c14089 2003-11-23 devnull a = inargv[i];
405 b8c14089 2003-11-23 devnull if(a == nil)
406 b8c14089 2003-11-23 devnull break;
407 b8c14089 2003-11-23 devnull n = strlen(a)+1;
408 b8c14089 2003-11-23 devnull if((s-args)+n >= NARGCHAR) /* too many characters */
409 b8c14089 2003-11-23 devnull break;
410 b8c14089 2003-11-23 devnull argv[i] = s;
411 b8c14089 2003-11-23 devnull memmove(s, a, n);
412 b8c14089 2003-11-23 devnull s += n;
413 b8c14089 2003-11-23 devnull free(a);
414 b8c14089 2003-11-23 devnull }
415 b8c14089 2003-11-23 devnull argv[i] = nil;
416 b8c14089 2003-11-23 devnull }
417 b8c14089 2003-11-23 devnull
418 b8c14089 2003-11-23 devnull
419 b8c14089 2003-11-23 devnull void
420 b8c14089 2003-11-23 devnull execproc(void *v)
421 b8c14089 2003-11-23 devnull {
422 b8c14089 2003-11-23 devnull char **av;
423 b8c14089 2003-11-23 devnull char buf[1024], *args[NARGS+1], argc[NARGCHAR];
424 b8c14089 2003-11-23 devnull
425 b8c14089 2003-11-23 devnull rfork(RFFDG);
426 b8c14089 2003-11-23 devnull close(0);
427 b8c14089 2003-11-23 devnull open("/dev/null", OREAD);
428 b8c14089 2003-11-23 devnull av = v;
429 b8c14089 2003-11-23 devnull stackargv(av, args, argc);
430 b8c14089 2003-11-23 devnull free(av);
431 b8c14089 2003-11-23 devnull procexec(nil, args[0], args);
432 b8c14089 2003-11-23 devnull if(args[0][0]!='/' && strncmp(args[0], "./", 2)!=0 && strncmp(args[0], "../", 3)!=0)
433 b8c14089 2003-11-23 devnull snprint(buf, sizeof buf, "/bin/%s", args[0]);
434 b8c14089 2003-11-23 devnull procexec(nil, buf, args);
435 b8c14089 2003-11-23 devnull threadexits("can't exec");
436 b8c14089 2003-11-23 devnull }
437 b8c14089 2003-11-23 devnull
438 b8c14089 2003-11-23 devnull char*
439 b8c14089 2003-11-23 devnull startup(Ruleset *rs, Exec *e)
440 b8c14089 2003-11-23 devnull {
441 b8c14089 2003-11-23 devnull char **argv;
442 b8c14089 2003-11-23 devnull int i;
443 b8c14089 2003-11-23 devnull
444 b8c14089 2003-11-23 devnull if(rs != nil)
445 b8c14089 2003-11-23 devnull for(i=0; i<rs->nact; i++){
446 b8c14089 2003-11-23 devnull if(rs->act[i]->verb == VStart)
447 b8c14089 2003-11-23 devnull goto Found;
448 b8c14089 2003-11-23 devnull if(rs->act[i]->verb == VClient){
449 b8c14089 2003-11-23 devnull if(e->msg->dst==nil || e->msg->dst[0]=='\0')
450 b8c14089 2003-11-23 devnull return "no port for \"client\" rule";
451 b8c14089 2003-11-23 devnull e->holdforclient = 1;
452 b8c14089 2003-11-23 devnull goto Found;
453 b8c14089 2003-11-23 devnull }
454 b8c14089 2003-11-23 devnull }
455 b8c14089 2003-11-23 devnull return "no start action for plumb message";
456 b8c14089 2003-11-23 devnull
457 b8c14089 2003-11-23 devnull Found:
458 b8c14089 2003-11-23 devnull argv = buildargv(rs->act[i]->arg, e);
459 b8c14089 2003-11-23 devnull if(argv[0] == nil)
460 b8c14089 2003-11-23 devnull return "empty argument list";
461 b8c14089 2003-11-23 devnull proccreate(execproc, argv, EXECSTACK);
462 b8c14089 2003-11-23 devnull return nil;
463 b8c14089 2003-11-23 devnull }