Blame


1 5cdb1798 2005-10-29 devnull #include "common.h"
2 5cdb1798 2005-10-29 devnull #include "send.h"
3 5cdb1798 2005-10-29 devnull
4 5cdb1798 2005-10-29 devnull extern int debug;
5 5cdb1798 2005-10-29 devnull
6 5cdb1798 2005-10-29 devnull /*
7 5cdb1798 2005-10-29 devnull * Routines for dealing with the rewrite rules.
8 5cdb1798 2005-10-29 devnull */
9 5cdb1798 2005-10-29 devnull
10 5cdb1798 2005-10-29 devnull /* globals */
11 5cdb1798 2005-10-29 devnull typedef struct rule rule;
12 5cdb1798 2005-10-29 devnull
13 5cdb1798 2005-10-29 devnull #define NSUBEXP 10
14 5cdb1798 2005-10-29 devnull struct rule {
15 5cdb1798 2005-10-29 devnull String *matchre; /* address match */
16 5cdb1798 2005-10-29 devnull String *repl1; /* first replacement String */
17 5cdb1798 2005-10-29 devnull String *repl2; /* second replacement String */
18 5cdb1798 2005-10-29 devnull d_status type; /* type of rule */
19 5cdb1798 2005-10-29 devnull Reprog *program;
20 5cdb1798 2005-10-29 devnull Resub subexp[NSUBEXP];
21 5cdb1798 2005-10-29 devnull rule *next;
22 5cdb1798 2005-10-29 devnull };
23 5cdb1798 2005-10-29 devnull static rule *rulep;
24 5cdb1798 2005-10-29 devnull static rule *rlastp;
25 5cdb1798 2005-10-29 devnull
26 5cdb1798 2005-10-29 devnull /* predeclared */
27 5cdb1798 2005-10-29 devnull static String *substitute(String *, Resub *, message *);
28 5cdb1798 2005-10-29 devnull static rule *findrule(String *, int);
29 5cdb1798 2005-10-29 devnull
30 5cdb1798 2005-10-29 devnull
31 5cdb1798 2005-10-29 devnull /*
32 5cdb1798 2005-10-29 devnull * Get the next token from `line'. The symbol `\l' is replaced by
33 5cdb1798 2005-10-29 devnull * the name of the local system.
34 5cdb1798 2005-10-29 devnull */
35 5cdb1798 2005-10-29 devnull extern String *
36 5cdb1798 2005-10-29 devnull rule_parse(String *line, char *system, int *backl)
37 5cdb1798 2005-10-29 devnull {
38 5cdb1798 2005-10-29 devnull String *token;
39 5cdb1798 2005-10-29 devnull String *expanded;
40 5cdb1798 2005-10-29 devnull char *cp;
41 5cdb1798 2005-10-29 devnull
42 5cdb1798 2005-10-29 devnull token = s_parse(line, 0);
43 5cdb1798 2005-10-29 devnull if(token == 0)
44 5cdb1798 2005-10-29 devnull return(token);
45 5cdb1798 2005-10-29 devnull if(strchr(s_to_c(token), '\\')==0)
46 5cdb1798 2005-10-29 devnull return(token);
47 5cdb1798 2005-10-29 devnull expanded = s_new();
48 5cdb1798 2005-10-29 devnull for(cp = s_to_c(token); *cp; cp++) {
49 5cdb1798 2005-10-29 devnull if(*cp == '\\') switch(*++cp) {
50 5cdb1798 2005-10-29 devnull case 'l':
51 5cdb1798 2005-10-29 devnull s_append(expanded, system);
52 5cdb1798 2005-10-29 devnull *backl = 1;
53 5cdb1798 2005-10-29 devnull break;
54 5cdb1798 2005-10-29 devnull case '\\':
55 5cdb1798 2005-10-29 devnull s_putc(expanded, '\\');
56 5cdb1798 2005-10-29 devnull break;
57 5cdb1798 2005-10-29 devnull default:
58 5cdb1798 2005-10-29 devnull s_putc(expanded, '\\');
59 5cdb1798 2005-10-29 devnull s_putc(expanded, *cp);
60 5cdb1798 2005-10-29 devnull break;
61 5cdb1798 2005-10-29 devnull } else
62 5cdb1798 2005-10-29 devnull s_putc(expanded, *cp);
63 5cdb1798 2005-10-29 devnull }
64 5cdb1798 2005-10-29 devnull s_free(token);
65 5cdb1798 2005-10-29 devnull s_terminate(expanded);
66 5cdb1798 2005-10-29 devnull return(expanded);
67 5cdb1798 2005-10-29 devnull }
68 5cdb1798 2005-10-29 devnull
69 5cdb1798 2005-10-29 devnull static int
70 5cdb1798 2005-10-29 devnull getrule(String *line, String *type, char *system)
71 5cdb1798 2005-10-29 devnull {
72 5cdb1798 2005-10-29 devnull rule *rp;
73 5cdb1798 2005-10-29 devnull String *re;
74 5cdb1798 2005-10-29 devnull int backl;
75 5cdb1798 2005-10-29 devnull
76 5cdb1798 2005-10-29 devnull backl = 0;
77 5cdb1798 2005-10-29 devnull
78 5cdb1798 2005-10-29 devnull /* get a rule */
79 5cdb1798 2005-10-29 devnull re = rule_parse(s_restart(line), system, &backl);
80 5cdb1798 2005-10-29 devnull if(re == 0)
81 5cdb1798 2005-10-29 devnull return 0;
82 5cdb1798 2005-10-29 devnull rp = (rule *)malloc(sizeof(rule));
83 5cdb1798 2005-10-29 devnull if(rp == 0) {
84 5cdb1798 2005-10-29 devnull perror("getrules:");
85 5cdb1798 2005-10-29 devnull exit(1);
86 5cdb1798 2005-10-29 devnull }
87 5cdb1798 2005-10-29 devnull rp->next = 0;
88 5cdb1798 2005-10-29 devnull s_tolower(re);
89 5cdb1798 2005-10-29 devnull rp->matchre = s_new();
90 5cdb1798 2005-10-29 devnull s_append(rp->matchre, s_to_c(re));
91 5cdb1798 2005-10-29 devnull s_restart(rp->matchre);
92 5cdb1798 2005-10-29 devnull s_free(re);
93 5cdb1798 2005-10-29 devnull s_parse(line, s_restart(type));
94 5cdb1798 2005-10-29 devnull rp->repl1 = rule_parse(line, system, &backl);
95 5cdb1798 2005-10-29 devnull rp->repl2 = rule_parse(line, system, &backl);
96 5cdb1798 2005-10-29 devnull rp->program = 0;
97 5cdb1798 2005-10-29 devnull if(strcmp(s_to_c(type), "|") == 0)
98 5cdb1798 2005-10-29 devnull rp->type = d_pipe;
99 5cdb1798 2005-10-29 devnull else if(strcmp(s_to_c(type), ">>") == 0)
100 5cdb1798 2005-10-29 devnull rp->type = d_cat;
101 5cdb1798 2005-10-29 devnull else if(strcmp(s_to_c(type), "alias") == 0)
102 5cdb1798 2005-10-29 devnull rp->type = d_alias;
103 5cdb1798 2005-10-29 devnull else if(strcmp(s_to_c(type), "translate") == 0)
104 5cdb1798 2005-10-29 devnull rp->type = d_translate;
105 5cdb1798 2005-10-29 devnull else if(strcmp(s_to_c(type), "auth") == 0)
106 5cdb1798 2005-10-29 devnull rp->type = d_auth;
107 5cdb1798 2005-10-29 devnull else {
108 5cdb1798 2005-10-29 devnull s_free(rp->matchre);
109 5cdb1798 2005-10-29 devnull s_free(rp->repl1);
110 5cdb1798 2005-10-29 devnull s_free(rp->repl2);
111 5cdb1798 2005-10-29 devnull free((char *)rp);
112 5cdb1798 2005-10-29 devnull fprint(2,"illegal rewrite rule: %s\n", s_to_c(line));
113 5cdb1798 2005-10-29 devnull return 0;
114 5cdb1798 2005-10-29 devnull }
115 5cdb1798 2005-10-29 devnull if(rulep == 0)
116 5cdb1798 2005-10-29 devnull rulep = rlastp = rp;
117 5cdb1798 2005-10-29 devnull else
118 5cdb1798 2005-10-29 devnull rlastp = rlastp->next = rp;
119 5cdb1798 2005-10-29 devnull return backl;
120 5cdb1798 2005-10-29 devnull }
121 5cdb1798 2005-10-29 devnull
122 5cdb1798 2005-10-29 devnull /*
123 5cdb1798 2005-10-29 devnull * rules are of the form:
124 5cdb1798 2005-10-29 devnull * <reg exp> <String> <repl exp> [<repl exp>]
125 5cdb1798 2005-10-29 devnull */
126 5cdb1798 2005-10-29 devnull extern int
127 5cdb1798 2005-10-29 devnull getrules(void)
128 5cdb1798 2005-10-29 devnull {
129 5cdb1798 2005-10-29 devnull Biobuf *rfp;
130 5cdb1798 2005-10-29 devnull String *line;
131 5cdb1798 2005-10-29 devnull String *type;
132 5cdb1798 2005-10-29 devnull String *file;
133 5cdb1798 2005-10-29 devnull
134 b5f65921 2006-02-11 devnull file = abspath("rewrite", UPASLIB, (String *)0);
135 5cdb1798 2005-10-29 devnull rfp = sysopen(s_to_c(file), "r", 0);
136 5cdb1798 2005-10-29 devnull if(rfp == 0) {
137 5cdb1798 2005-10-29 devnull rulep = 0;
138 5cdb1798 2005-10-29 devnull return -1;
139 5cdb1798 2005-10-29 devnull }
140 5cdb1798 2005-10-29 devnull rlastp = 0;
141 5cdb1798 2005-10-29 devnull line = s_new();
142 5cdb1798 2005-10-29 devnull type = s_new();
143 5cdb1798 2005-10-29 devnull while(s_getline(rfp, s_restart(line)))
144 5cdb1798 2005-10-29 devnull if(getrule(line, type, thissys) && altthissys)
145 5cdb1798 2005-10-29 devnull getrule(s_restart(line), type, altthissys);
146 5cdb1798 2005-10-29 devnull s_free(type);
147 5cdb1798 2005-10-29 devnull s_free(line);
148 5cdb1798 2005-10-29 devnull s_free(file);
149 5cdb1798 2005-10-29 devnull sysclose(rfp);
150 5cdb1798 2005-10-29 devnull return 0;
151 5cdb1798 2005-10-29 devnull }
152 5cdb1798 2005-10-29 devnull
153 5cdb1798 2005-10-29 devnull /* look up a matching rule */
154 5cdb1798 2005-10-29 devnull static rule *
155 5cdb1798 2005-10-29 devnull findrule(String *addrp, int authorized)
156 5cdb1798 2005-10-29 devnull {
157 5cdb1798 2005-10-29 devnull rule *rp;
158 5cdb1798 2005-10-29 devnull static rule defaultrule;
159 5cdb1798 2005-10-29 devnull
160 5cdb1798 2005-10-29 devnull if(rulep == 0)
161 5cdb1798 2005-10-29 devnull return &defaultrule;
162 5cdb1798 2005-10-29 devnull for (rp = rulep; rp != 0; rp = rp->next) {
163 5cdb1798 2005-10-29 devnull if(rp->type==d_auth && authorized)
164 5cdb1798 2005-10-29 devnull continue;
165 5cdb1798 2005-10-29 devnull if(rp->program == 0)
166 5cdb1798 2005-10-29 devnull rp->program = regcomp(rp->matchre->base);
167 5cdb1798 2005-10-29 devnull if(rp->program == 0)
168 5cdb1798 2005-10-29 devnull continue;
169 5cdb1798 2005-10-29 devnull memset(rp->subexp, 0, sizeof(rp->subexp));
170 5cdb1798 2005-10-29 devnull if(debug)
171 b5f65921 2006-02-11 devnull fprint(2, "matching %s aginst %s\n", s_to_c(addrp), rp->matchre->base);
172 5cdb1798 2005-10-29 devnull if(regexec(rp->program, s_to_c(addrp), rp->subexp, NSUBEXP))
173 5cdb1798 2005-10-29 devnull if(s_to_c(addrp) == rp->subexp[0].s.sp)
174 5cdb1798 2005-10-29 devnull if((s_to_c(addrp) + strlen(s_to_c(addrp))) == rp->subexp[0].e.ep)
175 5cdb1798 2005-10-29 devnull return rp;
176 5cdb1798 2005-10-29 devnull }
177 5cdb1798 2005-10-29 devnull return 0;
178 5cdb1798 2005-10-29 devnull }
179 5cdb1798 2005-10-29 devnull
180 5cdb1798 2005-10-29 devnull /* Transforms the address into a command.
181 5cdb1798 2005-10-29 devnull * Returns: -1 ifaddress not matched by reules
182 5cdb1798 2005-10-29 devnull * 0 ifaddress matched and ok to forward
183 5cdb1798 2005-10-29 devnull * 1 ifaddress matched and not ok to forward
184 5cdb1798 2005-10-29 devnull */
185 5cdb1798 2005-10-29 devnull extern int
186 5cdb1798 2005-10-29 devnull rewrite(dest *dp, message *mp)
187 5cdb1798 2005-10-29 devnull {
188 5cdb1798 2005-10-29 devnull rule *rp; /* rewriting rule */
189 5cdb1798 2005-10-29 devnull String *lower; /* lower case version of destination */
190 5cdb1798 2005-10-29 devnull
191 5cdb1798 2005-10-29 devnull /*
192 5cdb1798 2005-10-29 devnull * Rewrite the address. Matching is case insensitive.
193 5cdb1798 2005-10-29 devnull */
194 5cdb1798 2005-10-29 devnull lower = s_clone(dp->addr);
195 5cdb1798 2005-10-29 devnull s_tolower(s_restart(lower));
196 5cdb1798 2005-10-29 devnull rp = findrule(lower, dp->authorized);
197 5cdb1798 2005-10-29 devnull if(rp == 0){
198 5cdb1798 2005-10-29 devnull s_free(lower);
199 5cdb1798 2005-10-29 devnull return -1;
200 5cdb1798 2005-10-29 devnull }
201 5cdb1798 2005-10-29 devnull strcpy(s_to_c(lower), s_to_c(dp->addr));
202 5cdb1798 2005-10-29 devnull dp->repl1 = substitute(rp->repl1, rp->subexp, mp);
203 5cdb1798 2005-10-29 devnull dp->repl2 = substitute(rp->repl2, rp->subexp, mp);
204 5cdb1798 2005-10-29 devnull dp->status = rp->type;
205 5cdb1798 2005-10-29 devnull if(debug){
206 b5f65921 2006-02-11 devnull fprint(2, "\t->");
207 5cdb1798 2005-10-29 devnull if(dp->repl1)
208 b5f65921 2006-02-11 devnull fprint(2, "%s", s_to_c(dp->repl1));
209 5cdb1798 2005-10-29 devnull if(dp->repl2)
210 b5f65921 2006-02-11 devnull fprint(2, "%s", s_to_c(dp->repl2));
211 b5f65921 2006-02-11 devnull fprint(2, "\n");
212 5cdb1798 2005-10-29 devnull }
213 5cdb1798 2005-10-29 devnull s_free(lower);
214 5cdb1798 2005-10-29 devnull return 0;
215 b5f65921 2006-02-11 devnull }
216 b5f65921 2006-02-11 devnull
217 b5f65921 2006-02-11 devnull /* stolen from rc/lex.c */
218 b5f65921 2006-02-11 devnull static int
219 b5f65921 2006-02-11 devnull idchr(int c)
220 b5f65921 2006-02-11 devnull {
221 b5f65921 2006-02-11 devnull return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c);
222 b5f65921 2006-02-11 devnull }
223 b5f65921 2006-02-11 devnull
224 b5f65921 2006-02-11 devnull static char*
225 b5f65921 2006-02-11 devnull getrcvar(char* p, char** rv)
226 b5f65921 2006-02-11 devnull {
227 b5f65921 2006-02-11 devnull char* p0;
228 b5f65921 2006-02-11 devnull char buf[128];
229 b5f65921 2006-02-11 devnull char* bufe;
230 b5f65921 2006-02-11 devnull
231 b5f65921 2006-02-11 devnull *rv = 0;
232 b5f65921 2006-02-11 devnull p0=p;
233 b5f65921 2006-02-11 devnull bufe=buf+sizeof buf-1;
234 b5f65921 2006-02-11 devnull while(p<bufe && idchr(*p))
235 b5f65921 2006-02-11 devnull p++;
236 b5f65921 2006-02-11 devnull
237 b5f65921 2006-02-11 devnull memcpy(buf, p0, p-p0);
238 b5f65921 2006-02-11 devnull buf[p-p0]=0;
239 b5f65921 2006-02-11 devnull *rv = getenv(buf);
240 b5f65921 2006-02-11 devnull if (debug)
241 b5f65921 2006-02-11 devnull fprint(2, "varsubst: %s → %s\n", buf, *rv);
242 b5f65921 2006-02-11 devnull return p;
243 5cdb1798 2005-10-29 devnull }
244 5cdb1798 2005-10-29 devnull
245 5cdb1798 2005-10-29 devnull static String *
246 5cdb1798 2005-10-29 devnull substitute(String *source, Resub *subexp, message *mp)
247 5cdb1798 2005-10-29 devnull {
248 5cdb1798 2005-10-29 devnull int i;
249 5cdb1798 2005-10-29 devnull char *s;
250 5cdb1798 2005-10-29 devnull char *sp;
251 5cdb1798 2005-10-29 devnull String *stp;
252 5cdb1798 2005-10-29 devnull
253 5cdb1798 2005-10-29 devnull if(source == 0)
254 5cdb1798 2005-10-29 devnull return 0;
255 5cdb1798 2005-10-29 devnull sp = s_to_c(source);
256 5cdb1798 2005-10-29 devnull
257 5cdb1798 2005-10-29 devnull /* someplace to put it */
258 5cdb1798 2005-10-29 devnull stp = s_new();
259 5cdb1798 2005-10-29 devnull
260 5cdb1798 2005-10-29 devnull /* do the substitution */
261 5cdb1798 2005-10-29 devnull while (*sp != '\0') {
262 5cdb1798 2005-10-29 devnull if(*sp == '\\') {
263 5cdb1798 2005-10-29 devnull switch (*++sp) {
264 5cdb1798 2005-10-29 devnull case '0': case '1': case '2': case '3': case '4':
265 5cdb1798 2005-10-29 devnull case '5': case '6': case '7': case '8': case '9':
266 5cdb1798 2005-10-29 devnull i = *sp-'0';
267 5cdb1798 2005-10-29 devnull if(subexp[i].s.sp != 0)
268 5cdb1798 2005-10-29 devnull for (s = subexp[i].s.sp;
269 5cdb1798 2005-10-29 devnull s < subexp[i].e.ep;
270 5cdb1798 2005-10-29 devnull s++)
271 5cdb1798 2005-10-29 devnull s_putc(stp, *s);
272 5cdb1798 2005-10-29 devnull break;
273 5cdb1798 2005-10-29 devnull case '\\':
274 5cdb1798 2005-10-29 devnull s_putc(stp, '\\');
275 5cdb1798 2005-10-29 devnull break;
276 5cdb1798 2005-10-29 devnull case '\0':
277 5cdb1798 2005-10-29 devnull sp--;
278 5cdb1798 2005-10-29 devnull break;
279 5cdb1798 2005-10-29 devnull case 's':
280 5cdb1798 2005-10-29 devnull for(s = s_to_c(mp->replyaddr); *s; s++)
281 5cdb1798 2005-10-29 devnull s_putc(stp, *s);
282 5cdb1798 2005-10-29 devnull break;
283 5cdb1798 2005-10-29 devnull case 'p':
284 5cdb1798 2005-10-29 devnull if(mp->bulk)
285 5cdb1798 2005-10-29 devnull s = "bulk";
286 5cdb1798 2005-10-29 devnull else
287 5cdb1798 2005-10-29 devnull s = "normal";
288 5cdb1798 2005-10-29 devnull for(;*s; s++)
289 5cdb1798 2005-10-29 devnull s_putc(stp, *s);
290 5cdb1798 2005-10-29 devnull break;
291 5cdb1798 2005-10-29 devnull default:
292 5cdb1798 2005-10-29 devnull s_putc(stp, *sp);
293 5cdb1798 2005-10-29 devnull break;
294 5cdb1798 2005-10-29 devnull }
295 b5f65921 2006-02-11 devnull } else if(*sp == '&') {
296 5cdb1798 2005-10-29 devnull if(subexp[0].s.sp != 0)
297 5cdb1798 2005-10-29 devnull for (s = subexp[0].s.sp;
298 5cdb1798 2005-10-29 devnull s < subexp[0].e.ep; s++)
299 5cdb1798 2005-10-29 devnull s_putc(stp, *s);
300 b5f65921 2006-02-11 devnull } else if(*sp == '$') {
301 b5f65921 2006-02-11 devnull sp = getrcvar(sp+1, &s);
302 b5f65921 2006-02-11 devnull s_append(stp, s);
303 b5f65921 2006-02-11 devnull free(s);
304 5cc53af9 2006-02-12 devnull sp--; /* counter sp++ below */
305 5cdb1798 2005-10-29 devnull } else
306 5cdb1798 2005-10-29 devnull s_putc(stp, *sp);
307 5cdb1798 2005-10-29 devnull sp++;
308 5cdb1798 2005-10-29 devnull }
309 5cdb1798 2005-10-29 devnull s_terminate(stp);
310 5cdb1798 2005-10-29 devnull
311 5cdb1798 2005-10-29 devnull return s_restart(stp);
312 5cdb1798 2005-10-29 devnull }
313 5cdb1798 2005-10-29 devnull
314 5cdb1798 2005-10-29 devnull extern void
315 5cdb1798 2005-10-29 devnull regerror(char* s)
316 5cdb1798 2005-10-29 devnull {
317 5cdb1798 2005-10-29 devnull fprint(2, "rewrite: %s\n", s);
318 5cdb1798 2005-10-29 devnull }
319 5cdb1798 2005-10-29 devnull
320 5cdb1798 2005-10-29 devnull extern void
321 5cdb1798 2005-10-29 devnull dumprules(void)
322 5cdb1798 2005-10-29 devnull {
323 5cdb1798 2005-10-29 devnull rule *rp;
324 5cdb1798 2005-10-29 devnull
325 5cdb1798 2005-10-29 devnull for (rp = rulep; rp != 0; rp = rp->next) {
326 5cdb1798 2005-10-29 devnull fprint(2, "'%s'", rp->matchre->base);
327 5cdb1798 2005-10-29 devnull switch (rp->type) {
328 5cdb1798 2005-10-29 devnull case d_pipe:
329 5cdb1798 2005-10-29 devnull fprint(2, " |");
330 5cdb1798 2005-10-29 devnull break;
331 5cdb1798 2005-10-29 devnull case d_cat:
332 5cdb1798 2005-10-29 devnull fprint(2, " >>");
333 5cdb1798 2005-10-29 devnull break;
334 5cdb1798 2005-10-29 devnull case d_alias:
335 5cdb1798 2005-10-29 devnull fprint(2, " alias");
336 5cdb1798 2005-10-29 devnull break;
337 5cdb1798 2005-10-29 devnull case d_translate:
338 5cdb1798 2005-10-29 devnull fprint(2, " translate");
339 5cdb1798 2005-10-29 devnull break;
340 5cdb1798 2005-10-29 devnull default:
341 5cdb1798 2005-10-29 devnull fprint(2, " UNKNOWN");
342 5cdb1798 2005-10-29 devnull break;
343 5cdb1798 2005-10-29 devnull }
344 5cdb1798 2005-10-29 devnull fprint(2, " '%s'", rp->repl1 ? rp->repl1->base:"...");
345 5cdb1798 2005-10-29 devnull fprint(2, " '%s'\n", rp->repl2 ? rp->repl2->base:"...");
346 5cdb1798 2005-10-29 devnull }
347 5cdb1798 2005-10-29 devnull }
348 5cdb1798 2005-10-29 devnull