1 #include "stralloc.h"
2 #include "str.h"
3 #include "case.h"
4 #include "rewritehost.h"
5 
6 static stralloc work = {0};
7 
doit(rule)8 static int doit(rule)
9 char *rule;
10 {
11   int colon;
12   char ch;
13   int prefixlen;
14 
15   ch = *rule++;
16   if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1;
17   colon = str_chr(rule,':');
18   if (!rule[colon]) return 1;
19   if (work.len < colon) return 1;
20 
21   prefixlen = work.len - colon;
22   if ((ch == '=') && prefixlen) return 1;
23   if (case_diffb(rule,colon,work.s + prefixlen)) return 1;
24 
25   if (ch == '?') {
26     if (byte_chr(work.s,prefixlen,'.') < prefixlen) return 1;
27     if (byte_chr(work.s,prefixlen,'[') < prefixlen) return 1;
28     if (byte_chr(work.s,prefixlen,']') < prefixlen) return 1;
29   }
30 
31   work.len = prefixlen;
32   if (ch == '-') work.len = 0;
33 
34   return stralloc_cats(&work,rule + colon + 1);
35 }
36 
appendwork(out,rules)37 static int appendwork(out,rules)
38 stralloc *out;
39 stralloc *rules;
40 {
41   int i;
42   int j;
43 
44   for (j = i = 0;j < rules->len;++j)
45     if (!rules->s[j]) {
46       if (!doit(rules->s + i)) return 0;
47       i = j + 1;
48     }
49   return stralloc_cat(out,&work);
50 }
51 
appendaddr(out,in,len,rules)52 static int appendaddr(out,in,len,rules)
53 stralloc *out;
54 char *in;
55 unsigned int len;
56 stralloc *rules;
57 {
58   int at;
59 
60   at = byte_chr(in,len,'@');
61   if (!at) if (len <= 1) return 1;
62   if (!stralloc_catb(out,in,at)) return 0;
63   if (!stralloc_append(out,"@")) return 0;
64   if (at < len) ++at;
65   if (!stralloc_copyb(&work,in + at,len - at)) return 0;
66   return appendwork(out,rules);
67 }
68 
rewritehost(out,in,len,rules)69 int rewritehost(out,in,len,rules)
70 stralloc *out;
71 char *in;
72 unsigned int len;
73 stralloc *rules;
74 {
75   if (!stralloc_copys(out,"")) return 0;
76   if (!stralloc_copyb(&work,in,len)) return 0;
77   return appendwork(out,rules);
78 }
79 
rewritehost_addr(out,in,len,rules)80 int rewritehost_addr(out,in,len,rules)
81 stralloc *out;
82 char *in;
83 unsigned int len;
84 stralloc *rules;
85 {
86   if (!stralloc_copys(out,"")) return 0;
87   return appendaddr(out,in,len,rules);
88 }
89 
rewritehost_list(out,in,len,rules)90 int rewritehost_list(out,in,len,rules)
91 stralloc *out;
92 char *in;
93 unsigned int len;
94 stralloc *rules;
95 {
96   int i;
97   int j;
98 
99   if (!stralloc_copys(out,"")) return 0;
100   for (j = i = 0;j < len;++j)
101     if (!in[j]) {
102       if (in[i] == '+') {
103 	if (!stralloc_append(out,"+")) return 0;
104 	if (!appendaddr(out,in + i + 1,j - i - 1,rules)) return 0;
105 	if (!stralloc_0(out)) return 0;
106       }
107       else
108 	if (!stralloc_catb(out,in + i,j - i + 1)) return 0;
109       i = j + 1;
110     }
111   return 1;
112 }
113