This commit was manufactured by cvs2svn to create branch
[iptables.git] / libiptc2 / foo.diff
1 --- libiptc.c   2003-06-30 18:26:59.000000000 +0200
2 +++ libiptc.c   2003-06-30 18:27:24.000000000 +0200
3 @@ -64,19 +61,35 @@
4         char error[TABLE_MAXNAMELEN];
5  };
6  
7 -struct chain_cache
8 +struct rule_head
9  {
10 +       struct list_head list;
11 +       
12 +       struct chain_head *chain;
13 +
14 +       unsigned int size;
15 +       STRUCT_ENTRY entry[0];
16 +}
17 +
18 +struct chain_head
19 +{
20 +       struct list_head list;
21 +
22         char name[TABLE_MAXNAMELEN];
23 -       /* This is the first rule in chain. */
24 -       unsigned int start_off;
25 -       /* Last rule in chain */
26 -       unsigned int end_off;
27 +       unsigned int hooknum;
28 +       struct list_head rules;
29  };
30  
31  STRUCT_TC_HANDLE
32  {
33         /* Have changes been made? */
34         int changed;
35 +
36 +       struct list_head chains;
37 +       
38 +       struct chain_head *chain_iterator_cur;
39 +
40 +#if 0
41         /* Size in here reflects original state. */
42         STRUCT_GETINFO info;
43  
44 @@ -98,6 +111,7 @@
45         /* Number in here reflects current state. */
46         unsigned int new_number;
47         STRUCT_GET_ENTRIES entries;
48 +#endif
49  };
50  
51  static void
52 @@ -375,173 +389,25 @@
53         }
54         return 0;
55  }
56 -
57 -static inline int
58 -add_chain(STRUCT_ENTRY *e, TC_HANDLE_T h, STRUCT_ENTRY **prev)
59 -{
60 -       unsigned int builtin;
61 -
62 -       /* Last entry.  End it. */
63 -       if (entry2offset(h, e) + e->next_offset == h->entries.size) {
64 -               /* This is the ERROR node at end of the table */
65 -               h->cache_chain_heads[h->cache_num_chains-1].end_off = 
66 -                       entry2offset(h, *prev);
67 -               return 0;
68 -       }
69 -
70 -       /* We know this is the start of a new chain if it's an ERROR
71 -          target, or a hook entry point */
72 -       if (strcmp(GET_TARGET(e)->u.user.name, ERROR_TARGET) == 0) {
73 -               /* prev was last entry in previous chain */
74 -               h->cache_chain_heads[h->cache_num_chains-1].end_off
75 -                       = entry2offset(h, *prev);
76 -
77 -               strcpy(h->cache_chain_heads[h->cache_num_chains].name,
78 -                      (const char *)GET_TARGET(e)->data);
79 -               h->cache_chain_heads[h->cache_num_chains].start_off
80 -                       = entry2offset(h, (void *)e + e->next_offset);
81 -               h->cache_num_chains++;
82 -       } else if ((builtin = is_hook_entry(e, h)) != 0) {
83 -               if (h->cache_num_chains > 0)
84 -                       /* prev was last entry in previous chain */
85 -                       h->cache_chain_heads[h->cache_num_chains-1].end_off
86 -                               = entry2offset(h, *prev);
87 -
88 -               strcpy(h->cache_chain_heads[h->cache_num_chains].name,
89 -                      h->hooknames[builtin-1]);
90 -               h->cache_chain_heads[h->cache_num_chains].start_off
91 -                       = entry2offset(h, (void *)e);
92 -               h->cache_num_chains++;
93 -       }
94 -
95 -       *prev = e;
96 -       return 0;
97 -}
98 -
99  static int alphasort(const void *a, const void *b)
100  {
101         return strcmp(((struct chain_cache *)a)->name,
102                       ((struct chain_cache *)b)->name);
103  }
104  
105 -static int populate_cache(TC_HANDLE_T h)
106 -{
107 -       unsigned int i;
108 -       STRUCT_ENTRY *prev;
109 -
110 -       /* # chains < # rules / 2 + num builtins - 1 */
111 -       h->cache_chain_heads = malloc((h->new_number / 2 + 4)
112 -                                     * sizeof(struct chain_cache));
113 -       if (!h->cache_chain_heads) {
114 -               errno = ENOMEM;
115 -               return 0;
116 -       }
117 -
118 -       h->cache_num_chains = 0;
119 -       h->cache_num_builtins = 0;
120 -
121 -       /* Count builtins */
122 -       for (i = 0; i < NUMHOOKS; i++) {
123 -               if (h->info.valid_hooks & (1 << i))
124 -                       h->cache_num_builtins++;
125 -       }
126 -
127 -       prev = NULL;
128 -       ENTRY_ITERATE(h->entries.entrytable, h->entries.size,
129 -                     add_chain, h, &prev);
130 -
131 -       qsort(h->cache_chain_heads + h->cache_num_builtins,
132 -             h->cache_num_chains - h->cache_num_builtins,
133 -             sizeof(struct chain_cache), alphasort);
134 -
135 -       return 1;
136 -}
137 -
138 -static int 
139 -correct_cache(TC_HANDLE_T h, unsigned int offset, int delta)
140 -{
141 -       int i;          /* needs to be signed because deleting first
142 -                          chain can make it drop to -1 */
143 -
144 -       if (!delta)
145 -               return 1;
146 -
147 -       for (i = 0; i < h->cache_num_chains; i++) {
148 -               struct chain_cache *cc = &h->cache_chain_heads[i];
149 -
150 -               if (delta < 0) {
151 -                       /* take care about deleted chains */
152 -                       if (cc->start_off >= offset+delta
153 -                           && cc->end_off <= offset) {
154 -                               /* this chain is within the deleted range,
155 -                                * let's remove it from the cache */
156 -                               void *start;
157 -                               unsigned int size;
158 -
159 -                               h->cache_num_chains--;
160 -                               if (i+1 >= h->cache_num_chains)
161 -                                       continue;
162 -                               start = &h->cache_chain_heads[i+1];
163 -                               size = (h->cache_num_chains-i)
164 -                                       * sizeof(struct chain_cache);
165 -                               memmove(cc, start, size);
166 -
167 -                               /* iterate over same index again, since
168 -                                * it is now a different chain */
169 -                               i--;
170 -                               continue;
171 -                       }
172 -               }
173 -
174 -               if (cc->start_off > offset)
175 -                       cc->start_off += delta;
176 -
177 -               if (cc->end_off >= offset)
178 -                       cc->end_off += delta;
179 -       }
180 -       /* HW_FIXME: sorting might be needed, but just in case a new chain was
181 -        * added */
182 -
183 -       return 1;
184 -}
185 -
186 -static int
187 -add_chain_cache(TC_HANDLE_T h, const char *name, unsigned int start_off,
188 -               unsigned int end_off)
189 -{
190 -       struct chain_cache *ccs = realloc(h->cache_chain_heads, 
191 -                                         (h->new_number / 2 + 4 + 1)
192 -                                          * sizeof(struct chain_cache));
193 -       struct chain_cache *newcc;
194 -       
195 -       if (!ccs)
196 -               return 0;
197 -
198 -       h->cache_chain_heads = ccs;
199 -       newcc = &h->cache_chain_heads[h->cache_num_chains];
200 -       h->cache_num_chains++;
201 -
202 -       strncpy(newcc->name, name, TABLE_MAXNAMELEN-1);
203 -       newcc->start_off = start_off;
204 -       newcc->end_off = end_off;
205 -
206 -       return 1;
207 -}
208 -
209 -/* Returns cache ptr if found, otherwise NULL. */
210 -static struct chain_cache *
211 +/* Returns chain head if found, otherwise NULL. */
212 +static struct chain_head *
213  find_label(const char *name, TC_HANDLE_T handle)
214  {
215 -       unsigned int i;
216 +       struct list_head *pos;
217  
218 -       if (handle->cache_chain_heads == NULL
219 -           && !populate_cache(handle))
220 +       if (!handle->chains)
221                 return NULL;
222  
223 -       /* FIXME: Linear search through builtins, then binary --RR */
224 -       for (i = 0; i < handle->cache_num_chains; i++) {
225 -               if (strcmp(handle->cache_chain_heads[i].name, name) == 0)
226 -                       return &handle->cache_chain_heads[i];
227 +       list_for_each(pos, &handle->chains) {
228 +               struct chain_head *c = list_entry(pos, struct chain_head, list);
229 +               if (!strcmp(c->name, name))
230 +                       return c;
231         }
232  
233         return NULL;
234 @@ -594,34 +460,30 @@
235  const char *
236  TC_FIRST_CHAIN(TC_HANDLE_T *handle)
237  {
238 -       if ((*handle)->cache_chain_heads == NULL
239 -           && !populate_cache(*handle))
240 -               return NULL;
241 +       (*handle)->chain_iterator_cur = (*handle)->chains;
242  
243 -       (*handle)->cache_chain_iteration
244 -               = &(*handle)->cache_chain_heads[0];
245 -
246 -       return (*handle)->cache_chain_iteration->name;
247 +       return (*handle)->chains.name;
248  }
249  
250  /* Iterator functions to run through the chains.  Returns NULL at end. */
251  const char *
252  TC_NEXT_CHAIN(TC_HANDLE_T *handle)
253  {
254 -       (*handle)->cache_chain_iteration++;
255 +       struct chain_head *next = list_entry(&(*handle)->chain_iterator_cur->list.next, struct chain_head, list);
256 +       (*handle)->chain_iterator_cur = next;
257  
258 -       if ((*handle)->cache_chain_iteration - (*handle)->cache_chain_heads
259 -           == (*handle)->cache_num_chains)
260 +       if (next == (*handle)->chains)
261                 return NULL;
262  
263 -       return (*handle)->cache_chain_iteration->name;
264 +       return next->name;
265  }
266  
267  /* Get first rule in the given chain: NULL for empty chain. */
268  const STRUCT_ENTRY *
269  TC_FIRST_RULE(const char *chain, TC_HANDLE_T *handle)
270  {
271 -       struct chain_cache *c;
272 +       struct chain_head *c;
273 +       struct rule_head *r;
274  
275         c = find_label(chain, *handle);
276         if (!c) {
277 @@ -630,22 +492,26 @@
278         }
279  
280         /* Empty chain: single return/policy rule */
281 -       if (c->start_off == c->end_off)
282 +       if (list_empty(c->rules))
283                 return NULL;
284  
285 -       (*handle)->cache_rule_end = offset2entry(*handle, c->end_off);
286 -       return offset2entry(*handle, c->start_off);
287 +       r = list_entry(&c->rules.next, struct rule_head, list);
288 +       (*handle)->rule_iterator_cur = r;
289 +
290 +       return r->entry;
291  }
292  
293  /* Returns NULL when rules run out. */
294  const STRUCT_ENTRY *
295  TC_NEXT_RULE(const STRUCT_ENTRY *prev, TC_HANDLE_T *handle)
296  {
297 -       if ((void *)prev + prev->next_offset
298 -           == (void *)(*handle)->cache_rule_end)
299 +       struct rule_head *r = list_entry((*handle)->rule_iterator_cur->list.next, struct rule_head, list);
300 +
301 +       if (r == r->chain)
302                 return NULL;
303  
304 -       return (void *)prev + prev->next_offset;
305 +       /* NOTE: prev is without any influence ! */
306 +       return r->entry;
307  }
308  
309  #if 0
310 @@ -773,7 +639,7 @@
311         return target_name(*handle, e);
312  }
313  
314 -static inline int
315 +static int
316  correct_verdict(STRUCT_ENTRY *e,
317                 char *base,
318                 unsigned int offset, int delta_offset)
319 @@ -874,16 +740,8 @@
320         newh->entries.size = (*handle)->entries.size + rules_size;
321         newh->hooknames = (*handle)->hooknames;
322  
323 -       newh->cache_chain_heads = (*handle)->cache_chain_heads;
324 -       newh->cache_num_builtins = (*handle)->cache_num_builtins;
325 -       newh->cache_num_chains = (*handle)->cache_num_chains;
326 -       newh->cache_rule_end = (*handle)->cache_rule_end;
327 -       newh->cache_chain_iteration = (*handle)->cache_chain_iteration;
328 -       if (!correct_cache(newh, offset, rules_size)) {
329 -               free(newh);
330 -               return 0;
331 -       }
332 -
333 +       if ((*handle)->cache_chain_heads)
334 +               free((*handle)->cache_chain_heads);
335         free(*handle);
336         *handle = newh;
337  
338 @@ -942,10 +800,6 @@
339         (*handle)->new_number -= num_rules;
340         (*handle)->entries.size -= rules_size;
341  
342 -       /* Fix the chain cache */
343 -       if (!correct_cache(*handle, offset, -(int)rules_size))
344 -               return 0;
345 -
346         return set_verdict(offset, -(int)rules_size, handle);
347  }
348  
349 @@ -1449,7 +1303,6 @@
350                 STRUCT_ENTRY ret;
351                 STRUCT_STANDARD_TARGET target;
352         } newc;
353 -       unsigned int destination;
354  
355         iptc_fn = TC_CREATE_CHAIN;
356  
357 @@ -1487,21 +1340,11 @@
358                 = ALIGN(sizeof(STRUCT_STANDARD_TARGET));
359         newc.target.verdict = RETURN;
360  
361 -       destination = index2offset(*handle, (*handle)->new_number -1);
362 -
363         /* Add just before terminal entry */
364         ret = insert_rules(2, sizeof(newc), &newc.head,
365 -                          destination,
366 +                          index2offset(*handle, (*handle)->new_number - 1),
367                            (*handle)->new_number - 1,
368                            0, handle);
369 -
370 -       set_changed(*handle);
371 -
372 -       /* add chain cache info for this chain */
373 -       add_chain_cache(*handle, chain, 
374 -                       destination+newc.head.next_offset, 
375 -                       destination+newc.head.next_offset);
376 -
377         return ret;
378  }
379  
380 @@ -1629,11 +1472,6 @@
381  
382         memset(t->error, 0, sizeof(t->error));
383         strcpy(t->error, newname);
384 -
385 -       /* update chain cache */
386 -       memset(c->name, 0, sizeof(c->name));
387 -       strcpy(c->name, newname);
388 -
389         set_changed(*handle);
390  
391         return 1;