diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-05-13 13:53:27 +0200 |
---|---|---|
committer | Daniel Borkmann <dborkman@redhat.com> | 2013-05-13 15:10:16 +0200 |
commit | d0009856814c13d13770db5aadd7b2fabf947776 (patch) | |
tree | 6d18a94439f27f3c2685f05c57435116673f40cc /staging/llist.c | |
parent | 2b100f7515dbd01032967c2d1b81d2f8d63bf9b5 (diff) |
staging: add mausezahn staging directory
After some back and forth, we decided that it is easier to maintain
mausezahn in a staging directory until it is fully reworked and
cleaned up to be ready to be fully integrated. This way, it is better
than having it in a separate branch, and we can also accept patches
from outside more easily. Also, while at it, fix up some function
mismatches with libcli.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'staging/llist.c')
-rw-r--r-- | staging/llist.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/staging/llist.c b/staging/llist.c new file mode 100644 index 0000000..d729e46 --- /dev/null +++ b/staging/llist.c @@ -0,0 +1,176 @@ +/* + * Mausezahn - A fast versatile traffic generator + * Copyright (C) 2010 Herbert Haas + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html + * +*/ + + +#include "mz.h" +#include "cli.h" +#include "mops.h" +#include "llist.h" + +/* PURPOSE: + * General doubly linked list with management functions. + * + * NOTE: + * There is no dummy head element. Every element may contain data! + * Therefore there is only one general "create_new_element" function. + * + * You cannot delete the head element except you want to delete the whole list. + * Usually you delete the head element at last. + * + * head->refcount always contains the number of elements. + * + * Each element has a unique index number. + * + * The user must assign her/his data to (void*) elem->data. + * + */ + + +// Create new list element - may be the first one (list==NULL) +// +struct mz_ll * mz_ll_create_new_element(struct mz_ll *list) +{ + struct mz_ll *new_element; + new_element = (struct mz_ll*) malloc (sizeof(struct mz_ll)); + if (new_element==NULL) return NULL; + _mz_ll_set_default(new_element); + if (list==NULL) { + new_element->next=new_element; + new_element->prev=new_element; + new_element->head=new_element; + new_element->refcount=1; + new_element->index=0; + new_element->index_last=0; + } else { + new_element->prev=list->prev; + new_element->next=list; + new_element->prev->next=new_element; + list->prev = new_element; + new_element->head=list; + list->refcount++; + list->index_last++; + new_element->index=list->index_last; + } + + return new_element; +} + +// Delete ONE list element. +int mz_ll_delete_element (struct mz_ll *cur) +{ + if ((cur==NULL)||(cur==cur->head)) return -1; // don't delete head! + if (cur->data!=NULL) { free(cur->data); cur->data=NULL; } + + if ((cur->next!=cur)&&(cur->prev!=cur)) { + cur->prev->next=cur->next; + cur->next->prev=cur->prev; + } + cur->head->refcount--; + if (cur!=NULL) { free(cur); cur=NULL; } + return 0; +} + + +int mz_ll_delete_list (struct mz_ll *list) +{ + struct mz_ll *cur=list, + *tmp; + + if (cur==NULL) return 1; + while (cur!=cur->next) { + tmp=cur->next; + mz_ll_delete_element(cur); + cur=tmp; + } + // Finally free list head: + if (list->data!=NULL) { free(list->data); list->data=NULL; } + free(list); + list=NULL; + return 0; +} + +struct mz_ll * mz_ll_search_name (struct mz_ll *list, char *str) +{ + struct mz_ll *cur=list; + do { + if (strncmp(cur->name, str, MZ_LL_NAME_LEN)==0) return cur; + cur=cur->next; + } + while (cur!=list); + return NULL; +} + +struct mz_ll * mz_ll_search_index (struct mz_ll *list, int i) +{ + struct mz_ll *cur=list; + do { + if (cur->index==i) return cur; + cur=cur->next; + } + while (cur!=list); + return NULL; +} + +int mz_ll_size(struct mz_ll *list) +{ + int i=0; + struct mz_ll *cur=list; + + if (list==NULL) return 0; + + do { + i++; + cur=cur->next; + } + while (cur!=list); + if (i!=list->refcount) fprintf(stderr, "MZ_LL_SIZE: Anomalous situation. Report this.\n"); + return i; +} + + +int mz_ll_dump_all(struct mz_ll *list) +{ + int i=0; + struct mz_ll *cur=list; + + if (list==NULL) return 0; + + do { + i++; + fprintf(stdout, "Element %i: '%s', index=%i\n",i,cur->name, cur->index); + cur=cur->next; + } + while (cur!=list); + return i; +} + + + +// ------ PRIVATE: initialize list-element +void _mz_ll_set_default (struct mz_ll *cur) +{ + cur->refcount = 0; + cur->data = NULL; + cur->name[0]='\0'; + cur->index=0; + cur->state=0; +} + + + + |