From 482fbafe27ee88899c54417d89633ddc01ece1df Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Sun, 28 Aug 2005 13:16:25 +0000 Subject: put reference to cc in each entry --- communication.c | 85 ++++++++-------- ebtables.c | 16 +-- include/ebtables_u.h | 17 ++-- libebtc.c | 271 ++++++++++++++------------------------------------- 4 files changed, 135 insertions(+), 254 deletions(-) diff --git a/communication.c b/communication.c index 01b69c9..472c7ed 100644 --- a/communication.c +++ b/communication.c @@ -297,7 +297,7 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style) struct ebt_counter *old, *new, *newcounters; socklen_t optlen; struct ebt_replace repl; - struct ebt_cntchanges *cc = u_repl->counterchanges, *cc2, **cc3; + struct ebt_cntchanges *cc = u_repl->cc->next, *cc2; struct ebt_u_entries *entries; struct ebt_u_entry *next = NULL; int i, chainnr = 0; @@ -312,13 +312,11 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style) memset(newcounters, 0, u_repl->nentries * sizeof(struct ebt_counter)); old = u_repl->counters; new = newcounters; - while (cc) { + while (cc != u_repl->cc) { if (!next) { - while (!(entries = u_repl->chains[chainnr++])) - if (chainnr > NF_BR_NUMHOOKS) - goto letscontinue;/* Prevent infinite loop for -D x:-1 */ - if (!(next = entries->entries)) - continue; + while (chainnr < u_repl->num_chains && (!(entries = u_repl->chains[chainnr++]) || !(next = entries->entries))); + if (chainnr == u_repl->num_chains) + break; } if (cc->type == CNT_NORM) { /* 'Normal' rule, meaning we didn't do anything to it @@ -326,17 +324,13 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style) *new = *old; next->cnt = *new; next->cnt_surplus.pcnt = next->cnt_surplus.bcnt = 0; - /* We've used an old counter */ - old++; - /* We've set a new counter */ - new++; + old++; /* We've used an old counter */ + new++; /* We've set a new counter */ next = next->next; } else if (cc->type == CNT_DEL) { - /* Don't use this old counter */ - old++; + old++; /* Don't use this old counter */ } else { if (cc->type == CNT_CHANGE) { - new->pcnt = old->pcnt; if (cc->change % 3 == 1) new->pcnt = old->pcnt + next->cnt_surplus.pcnt; else if (cc->change % 3 == 2) @@ -363,11 +357,29 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style) } cc = cc->next; } -letscontinue: free(u_repl->counters); u_repl->counters = newcounters; u_repl->num_counters = u_repl->nentries; + /* Reset the counterchanges to CNT_NORM and delete the unused cc */ + i = 0; + cc = u_repl->cc->next; + while (cc != u_repl->cc) { + if (cc->type == CNT_DEL) { + cc->prev->next = cc->next; + cc->next->prev = cc->prev; + cc2 = cc->next; + free(cc); + cc = cc2; + } else { + cc->type = CNT_NORM; + cc->change = 0; + i++; + cc = cc->next; + } + } + if (i != u_repl->nentries) + ebt_print_bug("i != u_repl->nentries"); if (u_repl->filename != NULL) { store_counters_in_file(u_repl->filename, u_repl); return; @@ -386,20 +398,6 @@ letscontinue: if (exec_style != EXEC_STYLE_DAEMON) return; - /* Reset the counterchanges to CNT_NORM */ - cc = u_repl->counterchanges; - for (i = 0; i < u_repl->nentries; i++) { - cc->type = CNT_NORM; - cc->change = 0; - cc3 = &cc->next; - cc = cc->next; - } - *cc3 = NULL; - while (cc) { - cc2 = cc->next; - free(cc); - cc = cc2; - } } static int @@ -458,7 +456,7 @@ ebt_translate_watcher(struct ebt_entry_watcher *w, static int ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt, int *totalcnt, struct ebt_u_entry ***u_e, struct ebt_u_replace *u_repl, - unsigned int valid_hooks, char *base) + unsigned int valid_hooks, char *base, struct ebt_cntchanges **cc) { /* An entry */ if (e->bitmask & EBT_ENTRY_OR_ENTRIES) { @@ -490,6 +488,8 @@ ebt_translate_entry(struct ebt_entry *e, unsigned int *hook, int *n, int *cnt, ebt_print_bug("*totalcnt >= u_repl->nentries"); new->cnt = u_repl->counters[*totalcnt]; new->cnt_surplus.pcnt = new->cnt_surplus.bcnt = 0; + new->cc = *cc; + *cc = (*cc)->next; new->m_list = NULL; new->w_list = NULL; new->next = NULL; @@ -709,8 +709,7 @@ int ebt_get_table(struct ebt_u_replace *u_repl, int init) int i, j, k, hook; struct ebt_replace repl; struct ebt_u_entry **u_e; - struct ebt_cntchanges *new_cc; - struct ebt_cntchanges **prev_cc = &(u_repl->counterchanges); + struct ebt_cntchanges *new_cc, *cc; strcpy(repl.name, u_repl->name); if (u_repl->filename != NULL) { @@ -728,17 +727,24 @@ int ebt_get_table(struct ebt_u_replace *u_repl, int init) u_repl->nentries = repl.nentries; u_repl->num_counters = repl.num_counters; u_repl->counters = repl.counters; - u_repl->counterchanges = NULL; + u_repl->cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges)); + if (!u_repl->cc) + ebt_print_memory(); + u_repl->cc->next = u_repl->cc->prev = u_repl->cc; + cc = u_repl->cc; for (i = 0; i < repl.nentries; i++) { - new_cc = (struct ebt_cntchanges *) - malloc(sizeof(struct ebt_cntchanges)); + new_cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges)); if (!new_cc) ebt_print_memory(); new_cc->type = CNT_NORM; new_cc->change = 0; - new_cc->next = NULL; - *prev_cc = new_cc; - prev_cc = &(new_cc->next); + new_cc->prev = cc; + cc->next = new_cc; + cc = new_cc; + } + if (repl.nentries) { + new_cc->next = u_repl->cc; + u_repl->cc->prev = new_cc; } u_repl->chains = (struct ebt_u_entries **)calloc(EBT_ORI_MAX_CHAINS, sizeof(void *)); u_repl->max_chains = EBT_ORI_MAX_CHAINS; @@ -753,10 +759,11 @@ int ebt_get_table(struct ebt_u_replace *u_repl, int init) i = 0; /* Holds the expected nr. of entries for the chain */ j = 0; /* Holds the up to now counted entries for the chain */ k = 0; /* Holds the total nr. of entries, should equal u_repl->nentries afterwards */ + cc = u_repl->cc->next; hook = -1; EBT_ENTRY_ITERATE((char *)repl.entries, repl.entries_size, ebt_translate_entry, &hook, &i, &j, &k, &u_e, u_repl, - u_repl->valid_hooks, (char *)repl.entries); + u_repl->valid_hooks, (char *)repl.entries, &cc); if (k != u_repl->nentries) ebt_print_bug("Wrong total nentries"); return 0; diff --git a/ebtables.c b/ebtables.c index 717c66b..dc04f4e 100644 --- a/ebtables.c +++ b/ebtables.c @@ -182,7 +182,7 @@ static void print_iface(const char *iface) #define LIST_MAC2 0x20 /* Helper function for list_rules() */ -static void list_em(struct ebt_u_entries *entries, struct ebt_cntchanges *cc) +static void list_em(struct ebt_u_entries *entries) { int i, j, space = 0, digits; struct ebt_u_entry *hlp; @@ -320,13 +320,6 @@ static void list_em(struct ebt_u_entries *entries, struct ebt_cntchanges *cc) uint64_t pcnt = hlp->cnt.pcnt; uint64_t bcnt = hlp->cnt.bcnt; -#ifdef EBT_DEBUG - while (cc->type == CNT_DEL) - cc = cc->next; - if (cc->change != 0) /* In daemon mode, only change==0 is allowed */ - ebt_print_bug("cc->change != 0"); - cc = cc->next; -#endif if (replace->flags & LIST_X) printf("-c %llu %llu", pcnt, bcnt); else @@ -406,12 +399,11 @@ ATOMIC_ENV_VARIABLE " : if set (see above) will equal its value" static void list_rules() { int i; - struct ebt_cntchanges *cc = replace->counterchanges; if (!(replace->flags & LIST_X)) printf("Bridge table: %s\n", table->name); if (replace->selected_chain != -1) - list_em(ebt_to_chain(replace), cc); + list_em(ebt_to_chain(replace)); else { /* Create new chains and rename standard chains when necessary */ if (replace->flags & LIST_X && replace->num_chains > NF_BR_NUMHOOKS) { @@ -423,7 +415,7 @@ static void list_rules() } for (i = 0; i < replace->num_chains; i++) if (replace->chains[i]) - list_em(replace->chains[i], cc); + list_em(replace->chains[i]); } } @@ -1215,7 +1207,7 @@ delete_the_rule: if (exec_style == EXEC_STYLE_PRG) {/* Implies ebt_errormsg[0] == '\0' */ ebt_deliver_table(replace); - if (replace->counterchanges) + if (replace->cc) ebt_deliver_counters(replace, EXEC_STYLE_PRG); } return 0; diff --git a/include/ebtables_u.h b/include/ebtables_u.h index c74118b..1c87117 100644 --- a/include/ebtables_u.h +++ b/include/ebtables_u.h @@ -52,6 +52,7 @@ struct ebt_cntchanges { unsigned short type; unsigned short change; /* determines incremental/decremental/change */ + struct ebt_cntchanges *prev; struct ebt_cntchanges *next; }; @@ -82,8 +83,8 @@ struct ebt_u_replace int selected_chain; /* used for the atomic option */ char *filename; - /* tells what happened to the old rules */ - struct ebt_cntchanges *counterchanges; + /* tells what happened to the old rules (counter changes) */ + struct ebt_cntchanges *cc; }; struct ebt_u_table @@ -125,6 +126,7 @@ struct ebt_u_entry struct ebt_u_entry *next; struct ebt_counter cnt; struct ebt_counter cnt_surplus; /* for increasing/decreasing a counter and for option 'C' */ + struct ebt_cntchanges *cc; /* the standard target needs this to know the name of a udc when * printing out rules. */ struct ebt_u_replace *replace; @@ -236,7 +238,6 @@ void ebt_double_chains(struct ebt_u_replace *replace); void ebt_free_u_entry(struct ebt_u_entry *e); struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, const char* arg); -struct ebt_u_entries *ebt_to_chain(const struct ebt_u_replace *replace); struct ebt_u_entries *ebt_name_to_chain(const struct ebt_u_replace *replace, const char* arg); int ebt_get_chainnr(const struct ebt_u_replace *replace, const char* arg); @@ -294,7 +295,11 @@ int do_command(int argc, char *argv[], int exec_style, struct ethertypeent *parseethertypebynumber(int type); -#define ebt_to_chain(repl) repl->chains[repl->selected_chain] +#define ebt_to_chain(repl) \ +({struct ebt_u_entries *_ch = NULL; \ +if (repl->selected_chain != -1) \ + _ch = repl->chains[repl->selected_chain]; \ +_ch;}) #define ebt_print_bug(format, args...) \ __ebt_print_bug(__FILE__, __LINE__, format, ##args) #define ebt_print_error(format,args...) __ebt_print_error(format, ##args); @@ -320,9 +325,7 @@ __ret;}) #define CNT_NORM 0 #define CNT_DEL 1 #define CNT_ADD 2 -#define CNT_OWRITE 3 -#define CNT_ZERO 4 -#define CNT_CHANGE 5 +#define CNT_CHANGE 3 extern const char *ebt_hooknames[NF_BR_NUMHOOKS]; extern const char *ebt_standard_targets[NUM_STANDARD_TARGETS]; diff --git a/libebtc.c b/libebtc.c index 451e9c2..9f93ee1 100644 --- a/libebtc.c +++ b/libebtc.c @@ -207,13 +207,13 @@ void ebt_cleanup_replace(struct ebt_u_replace *replace) free(entries); replace->chains[i] = NULL; } - cc1 = replace->counterchanges; - while (cc1) { + cc1 = replace->cc->next; + while (cc1 != replace->cc) { cc2 = cc1->next; free(cc1); cc1 = cc2; } - replace->counterchanges = NULL; + replace->cc->next = replace->cc->prev = replace->cc; } /* Should be called, e.g., between 2 rule adds */ @@ -399,15 +399,23 @@ void ebt_change_policy(struct ebt_u_replace *replace, int policy) entries->policy = policy; } +void ebt_delete_cc(struct ebt_cntchanges *cc) +{ + if (cc->type == CNT_ADD) { + cc->prev->next = cc->next; + cc->next->prev = cc->prev; + free(cc); + } + cc->type = CNT_DEL; +} + /* Flush one chain or the complete table * If selected_chain == -1 then flush the complete table */ void ebt_flush_chains(struct ebt_u_replace *replace) { - int i, j, numdel; + int i, numdel; struct ebt_u_entry *u_e, *tmp; struct ebt_u_entries *entries = ebt_to_chain(replace); - struct ebt_cntchanges *cc = replace->counterchanges; - struct ebt_cntchanges **prev_cc = &(replace->counterchanges); /* Flush whole table */ if (!entries) { @@ -424,24 +432,13 @@ void ebt_flush_chains(struct ebt_u_replace *replace) u_e = entries->entries; entries->entries = NULL; while (u_e) { + ebt_delete_cc(u_e->cc); ebt_free_u_entry(u_e); tmp = u_e->next; free(u_e); u_e = tmp; } } - /* Update the counters */ - while (cc) { - if (cc->type == CNT_ADD) { - *prev_cc = cc->next; - free(cc); - cc = *prev_cc; - continue; - } - cc->type = CNT_DEL; - prev_cc = &(cc->next); - cc = cc->next; - } return; } @@ -450,41 +447,18 @@ void ebt_flush_chains(struct ebt_u_replace *replace) replace->nentries -= entries->nentries; numdel = entries->nentries; - /* Delete the counters belonging to the specified chain, - * update counter_offset */ - for (i = 0; i < replace->num_chains; i++) { + /* Update counter_offset */ + for (i = replace->selected_chain+1; i < replace->num_chains; i++) { if (!(entries = replace->chains[i])) continue; - if (i > replace->selected_chain) { - entries->counter_offset -= numdel; - continue; - } - j = entries->nentries; - while (j) { - /* Don't count deleted entries */ - if (cc->type == CNT_DEL) - goto letscontinue; - if (i == replace->selected_chain) { - if (cc->type == CNT_ADD) { - *prev_cc = cc->next; - free(cc); - cc = *prev_cc; - j--; - continue; - } - cc->type = CNT_DEL; - } - j--; -letscontinue: - prev_cc = &(cc->next); - cc = cc->next; - } + entries->counter_offset -= numdel; } entries = ebt_to_chain(replace); entries->nentries = 0; u_e = entries->entries; while (u_e) { + ebt_delete_cc(u_e->cc); ebt_free_u_entry(u_e); tmp = u_e->next; free(u_e); @@ -607,13 +581,12 @@ letscontinue:; * don't reuse the new_entry after a successful call to ebt_add_rule() */ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, int rule_nr) { - int i, j; + int i; struct ebt_u_entry **u_e; struct ebt_u_match_list *m_l; struct ebt_u_watcher_list *w_l; struct ebt_u_entries *entries = ebt_to_chain(replace); - struct ebt_cntchanges *cc = replace->counterchanges, *new_cc; - struct ebt_cntchanges **prev_cc = &(replace->counterchanges); + struct ebt_cntchanges *cc, *new_cc; if (rule_nr <= 0) rule_nr += entries->nentries; @@ -626,37 +599,6 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, /* We're adding one rule */ replace->nentries++; entries->nentries++; - - /* Handle counter stuff */ - for (i = 0; i < replace->selected_chain; i++) { - if (!(replace->chains[i])) - continue; - j = replace->chains[i]->nentries; - while (j) { - if (cc->type != CNT_DEL) - j--; - prev_cc = &(cc->next); - cc = cc->next; - } - } - j = rule_nr; - while (j) { - if (cc->type != CNT_DEL) - j--; - prev_cc = &(cc->next); - cc = cc->next; - } - if (cc && cc->type == CNT_DEL) - cc->type = CNT_OWRITE; - else { - new_cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges)); - if (!new_cc) - ebt_print_memory(); - new_cc->type = CNT_ADD; - new_cc->change = 0; - new_cc->next = cc; - *prev_cc = new_cc; - } /* Go to the right position in the chain */ u_e = &entries->entries; for (i = 0; i < rule_nr; i++) @@ -664,6 +606,27 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, /* Insert the rule */ new_entry->next = *u_e; *u_e = new_entry; + new_cc = (struct ebt_cntchanges *)malloc(sizeof(struct ebt_cntchanges)); + if (!new_cc) + ebt_print_memory(); + new_cc->type = CNT_ADD; + new_cc->change = 0; + if (!new_entry->next) { + for (i = replace->selected_chain+1; i < replace->num_chains; i++) + if (!replace->chains[i] || replace->chains[i]->nentries == 0) + continue; + else + break; + if (i == replace->num_chains) + cc = replace->cc; + else + cc = replace->chains[i]->entries->cc; + } else + cc = new_entry->next->cc; + new_cc->next = cc; + new_cc->prev = cc->prev; + cc->prev->next = new_cc; + cc->prev = new_cc; /* Put the ebt_{match, watcher, target} pointers in place */ m_l = new_entry->m_list; @@ -730,73 +693,32 @@ static int check_and_change_rule_number(struct ebt_u_replace *replace, void ebt_delete_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, int begin, int end) { - int i, j, nr_deletes; + int i, nr_deletes; struct ebt_u_entry **u_e, *u_e2; struct ebt_u_entries *entries = ebt_to_chain(replace); - struct ebt_cntchanges *cc = replace->counterchanges; - struct ebt_cntchanges **prev_cc = &(replace->counterchanges); if (check_and_change_rule_number(replace, new_entry, &begin, &end)) return; - /* We're deleting rules */ nr_deletes = end - begin + 1; replace->nentries -= nr_deletes; entries->nentries -= nr_deletes; - - /* Handle counter stuff */ - for (i = 0; i < replace->selected_chain; i++) { - if (!(replace->chains[i])) - continue; - j = replace->chains[i]->nentries; - while (j) { - if (cc->type != CNT_DEL) - j--; - prev_cc = &(cc->next); - cc = cc->next; - } - } - j = begin; - while (j) { - if (cc->type != CNT_DEL) - j--; - prev_cc = &(cc->next); - cc = cc->next; - } - j = nr_deletes; - while (j) { - if (cc->type != CNT_DEL) { - j--; - if (cc->type == CNT_ADD) { - *prev_cc = cc->next; - free(cc); - cc = *prev_cc; - continue; - } - cc->type = CNT_DEL; - } - prev_cc = &(cc->next); - cc = cc->next; - } - /* Go to the right position in the chain */ u_e = &entries->entries; - for (j = 0; j < begin; j++) + for (i = 0; i < begin; i++) u_e = &(*u_e)->next; /* Remove the rules */ - j = nr_deletes; - while (j--) { + for (i = 0; i < nr_deletes; i++) { u_e2 = *u_e; + ebt_delete_cc(u_e2->cc); *u_e = (*u_e)->next; /* Free everything */ ebt_free_u_entry(u_e2); free(u_e2); } - /* Update the counter_offset of chains behind this one */ - j = replace->selected_chain; - for (j = replace->selected_chain+1; j < replace->num_chains; j++) { - if (!(entries = replace->chains[j])) + for (i = replace->selected_chain+1; i < replace->num_chains; i++) { + if (!(entries = replace->chains[i])) continue; entries->counter_offset -= nr_deletes; } @@ -816,64 +738,41 @@ void ebt_change_counters(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry, int begin, int end, struct ebt_counter *cnt, int mask) { - int i, j; + int i; struct ebt_u_entry *u_e; struct ebt_u_entries *entries = ebt_to_chain(replace); - struct ebt_cntchanges *cc = replace->counterchanges; if (check_and_change_rule_number(replace, new_entry, &begin, &end)) return; - - for (i = 0; i < replace->selected_chain; i++) { - if (!(replace->chains[i])) - continue; - j = replace->chains[i]->nentries; - while (j) { - if (cc->type != CNT_DEL) - j--; - cc = cc->next; - } - } - i = begin; - while (i) { - if (cc->type != CNT_DEL) - i--; - cc = cc->next; - } u_e = entries->entries; for (i = 0; i < begin; i++) u_e = u_e->next; - i = end - begin + 1; - while (i) { - if (cc->type != CNT_DEL) { - i--; - if (mask % 3 == 0) { - u_e->cnt.pcnt = (*cnt).pcnt; - u_e->cnt_surplus.pcnt = 0; - } else { + for (i = end-begin+1; i > 0; i--) { + if (mask % 3 == 0) { + u_e->cnt.pcnt = (*cnt).pcnt; + u_e->cnt_surplus.pcnt = 0; + } else { #ifdef EBT_DEBUG - if (cc->type != CNT_NORM) - ebt_print_bug("cc->type != CNT_NORM"); + if (u_e->cc->type != CNT_NORM) + ebt_print_bug("cc->type != CNT_NORM"); #endif - u_e->cnt_surplus.pcnt = (*cnt).pcnt; - } + u_e->cnt_surplus.pcnt = (*cnt).pcnt; + } - if (mask / 3 == 0) { - u_e->cnt.bcnt = (*cnt).bcnt; - u_e->cnt_surplus.bcnt = 0; - } else { + if (mask / 3 == 0) { + u_e->cnt.bcnt = (*cnt).bcnt; + u_e->cnt_surplus.bcnt = 0; + } else { #ifdef EBT_DEBUG - if (cc->type != CNT_NORM) - ebt_print_bug("cc->type != CNT_NORM"); + if (u_e->cc->type != CNT_NORM) + ebt_print_bug("cc->type != CNT_NORM"); #endif - u_e->cnt_surplus.bcnt = (*cnt).bcnt; - } - if (cc->type == CNT_NORM || cc->type == CNT_ZERO) - cc->type = CNT_CHANGE; - cc->change = mask; - u_e = u_e->next; + u_e->cnt_surplus.bcnt = (*cnt).bcnt; } - cc = cc->next; + if (u_e->cc->type != CNT_ADD) + u_e->cc->type = CNT_CHANGE; + u_e->cc->change = mask; + u_e = u_e->next; } } @@ -882,22 +781,19 @@ void ebt_change_counters(struct ebt_u_replace *replace, void ebt_zero_counters(struct ebt_u_replace *replace) { struct ebt_u_entries *entries = ebt_to_chain(replace); - struct ebt_cntchanges *cc = replace->counterchanges; struct ebt_u_entry *next; - int i, j; + int i; if (!entries) { - while (cc) { - if (cc->type == CNT_NORM) - cc->type = CNT_ZERO; - cc = cc->next; - } for (i = 0; i < replace->num_chains; i++) { if (!(entries = replace->chains[i])) continue; next = entries->entries; while (next) { + if (next->cc->type == CNT_NORM) + next->cc->type = CNT_CHANGE; next->cnt.bcnt = next->cnt.pcnt = 0; + next->cc->change = 0; next = next->next; } } @@ -905,27 +801,10 @@ void ebt_zero_counters(struct ebt_u_replace *replace) if (entries->nentries == 0) return; - for (i = 0; i < replace->selected_chain; i++) { - if (!(replace->chains[i])) - continue; - j = replace->chains[i]->nentries; - while (j) { - if (cc->type != CNT_DEL) - j--; - cc = cc->next; - } - } - j = entries->nentries; - while (j) { - if (cc->type != CNT_DEL) { - j--; - if (cc->type == CNT_NORM) - cc->type = CNT_ZERO; - } - cc = cc->next; - } next = entries->entries; while (next) { + if (next->cc->type == CNT_NORM) + next->cc->type = CNT_CHANGE; next->cnt.bcnt = next->cnt.pcnt = 0; next = next->next; } -- cgit v1.2.3