diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2009-12-13 10:27:33 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2009-12-13 10:27:33 +0000 |
commit | ef8cc767b201e4798a060282d4a6f280094bb8cc (patch) | |
tree | 4f19eae6870321f280959be4b7b24cd0e38d4c2a | |
parent | 7dd703c9af5f8b4a50f056c47588a9e51d4ea681 (diff) |
change dict and set API to perform loops with a list of strings instead of loop_first() and loop_next() functions
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1028 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | common/dict.c | 69 | ||||
-rw-r--r-- | common/dict.h | 16 | ||||
-rw-r--r-- | common/set.c | 20 | ||||
-rw-r--r-- | common/set.h | 14 | ||||
-rw-r--r-- | nslcd/group.c | 33 | ||||
-rw-r--r-- | nslcd/myldap.c | 67 | ||||
-rw-r--r-- | tests/test_dict.c | 51 | ||||
-rw-r--r-- | tests/test_set.c | 17 |
8 files changed, 116 insertions, 171 deletions
diff --git a/common/dict.c b/common/dict.c index a0f9f35..128321d 100644 --- a/common/dict.c +++ b/common/dict.c @@ -2,7 +2,7 @@ dict.c - dictionary functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -46,9 +46,6 @@ All the keys are copied in a separate linked list of buffers where each new buffer that is allocated is larger than the previous one. The first buffer in the linked list is always the current one. - - Note that the initial sizes of hashtable and the loadfactor still need to - be tuned to the use in this application. */ /* an entry stores one key/value pair */ @@ -70,8 +67,6 @@ struct dictionary { int size; /* size of the hashtable */ int num; /* total number of keys stored */ struct dict_entry **table; /* the hashtable */ - int loop_idx; /* for looping */ - struct dict_entry *loop_entry; /* for looping */ }; /* Simple hash function that computes the hash value of a lower-cased @@ -243,27 +238,47 @@ int dict_put(DICT *dict,const char *key,void *value) return 0; } -void dict_loop_first(DICT *dict) -{ - dict->loop_idx=0; - dict->loop_entry=NULL; -} - -const char *dict_loop_next(DICT *dict,const char **key,void **value) +const char **dict_keys(DICT *dict) { + int i; struct dict_entry *entry; - /* find non-empty entry */ - while ( (dict->loop_idx<dict->size) && (dict->loop_entry==NULL) ) - dict->loop_entry=dict->table[dict->loop_idx++]; - if (dict->loop_entry==NULL) - return NULL; /* no more entries to check */ - /* save current result and go to next entry */ - entry=dict->loop_entry; - dict->loop_entry=entry->next; - /* return results */ - if (key!=NULL) - *key=entry->key; - if (value!=NULL) - *value=entry->value; - return entry->key; + char *buf; + const char **values; + size_t sz; + int num; + /* figure out how much memory to allocate */ + num=0; + sz=0; + for (i=0;i<dict->size;i++) + { + entry=dict->table[i]; + while (entry!=NULL) + { + num++; + sz+=strlen(entry->key)+1; + entry=entry->next; + } + } + /* allocate the needed memory */ + buf=(char *)malloc((num+1)*sizeof(char *)+sz); + if (buf==NULL) + return NULL; + values=(const char **)(void *)buf; + buf+=(num+1)*sizeof(char *); + /* fill the array with the keys */ + num=0; + for (i=0;i<dict->size;i++) + { + entry=dict->table[i]; + while (entry!=NULL) + { + strcpy(buf,entry->key); + values[num++]=buf; + buf+=strlen(buf)+1; + entry=entry->next; + } + } + values[num]=NULL; + /* done */ + return values; } diff --git a/common/dict.h b/common/dict.h index ba9fd6a..3a6108f 100644 --- a/common/dict.h +++ b/common/dict.h @@ -2,7 +2,7 @@ dict.h - dictionary functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -59,17 +59,9 @@ void *dict_get(DICT *dict,const char *key) of the caller. */ void dict_free(DICT *dict); -/* Function for looping over all dictionary keys and values. - This resets the search to the beginning of the dictionary. - This is required before calling dict_loop_next(); */ -void dict_loop_first(DICT *dict); - -/* Function for looping over all dictionary keys and values. - This returns a stored key. NULL is returned when all - keys have been returned. The key and value are - stored in the key and value parameters if they aren't - NULL. */ -const char *dict_loop_next(DICT *dict,const char **key,void **value) +/* Return the keys of the dicta as a list of strings. + The caller should free the memory with a single call to free(). */ +const char **dict_keys(DICT *dict) MUST_USE; #endif /* _DICT_H */ diff --git a/common/set.c b/common/set.c index 7e82730..d36ce2d 100644 --- a/common/set.c +++ b/common/set.c @@ -2,7 +2,7 @@ set.c - set functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2008 Arthur de Jong + Copyright (C) 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,12 @@ #include "set.h" #include "dict.h" +/* + The SET object is just a DICT which is passed around. The value + for each entry in the dict is just the pointer to the dict. + Another API is provided to give it a more set-like interface. +*/ + SET *set_new(void) { return (SET *)dict_new(); @@ -50,15 +56,7 @@ void set_free(SET *set) dict_free((DICT *)set); } -void set_loop_first(SET *set) -{ - dict_loop_first((DICT *)set); -} - -const char *set_loop_next(SET *set) +const char **set_tolist(SET *set) { - const char *value=NULL; - if (dict_loop_next((DICT *)set,&value,NULL)==NULL) - return NULL; - return value; + return dict_keys((DICT *)set); } diff --git a/common/set.h b/common/set.h index e38b52e..111a2cc 100644 --- a/common/set.h +++ b/common/set.h @@ -2,7 +2,7 @@ set.h - set functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2008 Arthur de Jong + Copyright (C) 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -51,15 +51,9 @@ int set_contains(SET *set,const char *value) for the set and the values is freed. */ void set_free(SET *set); -/* Function for looping over all set values. - This resets the search to the beginning of the set. - This is required before calling set_loop_next(); */ -void set_loop_first(SET *set); - -/* Function for looping over all set values. - This returns a stored value. NULL is returned when all - values have been returned. */ -const char *set_loop_next(SET *set) +/* Return the content of the set as a list of strings. + The caller should free the memory with a single call to free(). */ +const char **set_tolist(SET *set) MUST_USE; #endif /* _SET_H */ diff --git a/nslcd/group.c b/nslcd/group.c index 12021b2..cc2a95d 100644 --- a/nslcd/group.c +++ b/nslcd/group.c @@ -153,20 +153,10 @@ void group_init(void) static int do_write_group( TFILE *fp,MYLDAP_ENTRY *entry,const char **names,gid_t gids[],int numgids, - const char *passwd,SET *members,const char *reqname) + const char *passwd,const char **members,const char *reqname) { - int32_t tmpint32; + int32_t tmpint32,tmp2int32,tmp3int32; int i,j; - int nummembers; - const char *tmp; - /* count the number of members */ - nummembers=0; - if (members!=NULL) - { - set_loop_first(members); - while (set_loop_next(members)!=NULL) - nummembers++; - } /* write entries for all names and gids */ for (i=0;names[i]!=NULL;i++) { @@ -183,14 +173,7 @@ static int do_write_group( WRITE_STRING(fp,names[i]); WRITE_STRING(fp,passwd); WRITE_TYPE(fp,gids[j],gid_t); - /* write a list of values */ - WRITE_INT32(fp,nummembers); - if (members!=NULL) - { - set_loop_first(members); - while ((tmp=set_loop_next(members))!=NULL) - { WRITE_STRING(fp,tmp); } - } + WRITE_STRINGLIST(fp,members); } } } @@ -199,7 +182,7 @@ static int do_write_group( /* return the list of members as a \0 separated string with an extra \0 at the end (doing dn->uid lookups as needed) */ -static SET *getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session) +static const char **getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session) { char buf[20]; int i; @@ -227,7 +210,9 @@ static SET *getmembers(MYLDAP_ENTRY *entry,MYLDAP_SESSION *session) set_add(set,buf); } /* return the members */ - return set; + values=set_tolist(set); + set_free(set); + return values; } /* the maximum number of gidNumber attributes per entry */ @@ -239,7 +224,7 @@ static int write_group(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname, { const char **names,**gidvalues; const char *passwd; - SET *members; + const char **members; gid_t gids[MAXGIDS_PER_ENTRY]; int numgids; char *tmp; @@ -292,7 +277,7 @@ static int write_group(TFILE *fp,MYLDAP_ENTRY *entry,const char *reqname, rc=do_write_group(fp,entry,names,gids,numgids,passwd,members,reqname); /* free and return */ if (members!=NULL) - set_free(members); + free(members); return rc; } diff --git a/nslcd/myldap.c b/nslcd/myldap.c index 518e0c3..8118464 100644 --- a/nslcd/myldap.c +++ b/nslcd/myldap.c @@ -75,7 +75,6 @@ #include "common.h" #include "log.h" #include "cfg.h" -#include "attmap.h" #include "common/set.h" #include "compat/ldap_compat.h" @@ -1215,57 +1214,10 @@ char *myldap_cpy_dn(MYLDAP_ENTRY *entry,char *buf,size_t buflen) return buf; } -/* Return a buffer that is an a list of strings that can be freed - with a single call to free(). This function frees the set. */ -static char **set2values(SET *set) -{ - char *buf; - char **values; - const char *val; - size_t sz; - int num; - /* check set */ - if (set==NULL) - return NULL; - /* count number of entries and needed space */ - sz=0; - num=1; - set_loop_first(set); - while ((val=set_loop_next(set))!=NULL) - { - num++; - sz+=strlen(val)+1; - } - /* allocate the needed memory */ - buf=(char *)malloc(num*sizeof(char *)+sz); - if (buf==NULL) - { - log_log(LOG_CRIT,"set2values(): malloc() failed to allocate memory"); - set_free(set); - return NULL; - } - values=(char **)(void *)buf; - buf+=num*sizeof(char *); - /* copy set into buffer */ - sz=0; - num=0; - set_loop_first(set); - while ((val=set_loop_next(set))!=NULL) - { - strcpy(buf,val); - values[num++]=buf; - buf+=strlen(buf)+1; - } - values[num]=NULL; - /* we're done */ - set_free(set); - return values; -} - /* Perform ranged retreival of attributes. http://msdn.microsoft.com/en-us/library/aa367017(vs.85).aspx http://www.tkk.fi/cc/docs/kerberos/draft-kashi-incremental-00.txt */ -static char **myldap_get_ranged_values(MYLDAP_ENTRY *entry,const char *attr) +static SET *myldap_get_ranged_values(MYLDAP_ENTRY *entry,const char *attr) { char **values; char *attn; @@ -1345,7 +1297,8 @@ static char **myldap_get_ranged_values(MYLDAP_ENTRY *entry,const char *attr) /* close any started searches */ if (search!=NULL) myldap_search_close(search); - return set2values(set); + /* return the contents of the set as a list */ + return set; } /* Simple wrapper around ldap_get_values(). */ @@ -1354,6 +1307,7 @@ const char **myldap_get_values(MYLDAP_ENTRY *entry,const char *attr) char **values; int rc; int i; + SET *set; /* check parameters */ if (!is_valid_entry(entry)) { @@ -1385,19 +1339,20 @@ const char **myldap_get_values(MYLDAP_ENTRY *entry,const char *attr) { /* we have a success code but no values, let's try to get ranged values */ - values=myldap_get_ranged_values(entry,attr); - if (values==NULL) + set=myldap_get_ranged_values(entry,attr); + if (set==NULL) return NULL; /* store values entry so we can free it later on */ for (i=0;i<MAX_RANGED_ATTRIBUTES_PER_ENTRY;i++) if (entry->rangedattributevalues[i]==NULL) { - entry->rangedattributevalues[i]=values; - return (const char **)values; + entry->rangedattributevalues[i]=(char **)set_tolist(set); + set_free(set); + return (const char **)entry->rangedattributevalues[i]; } /* we found no room to store the values */ log_log(LOG_ERR,"ldap_get_values() couldn't store results, increase MAX_RANGED_ATTRIBUTES_PER_ENTRY"); - free(values); + set_free(set); return NULL; } else @@ -1651,7 +1606,7 @@ int myldap_passwd( { log_log(LOG_ERR,"myldap_exop_passwd(): invalid parameter passed"); errno=EINVAL; - return NULL; + return LDAP_OTHER; } /* log the call */ log_log(LOG_DEBUG,"myldap_exop_passwd(userdn=\"%s\")",userdn); diff --git a/tests/test_dict.c b/tests/test_dict.c index 905d916..4e0adf9 100644 --- a/tests/test_dict.c +++ b/tests/test_dict.c @@ -2,7 +2,7 @@ test_dict.c - simple test for the dict module This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -35,11 +35,12 @@ static void test_simple(void) { DICT *dict; - const char *key; void *val; static char *value1="value1"; static char *value2="value2"; static char *replace2="replace2"; + const char **keys; + int i; /* initialize */ dict=dict_new(); /* store some entries */ @@ -61,13 +62,15 @@ static void test_simple(void) val=dict_get(dict,"keY3"); assert(val==NULL); /* loop over dictionary contents */ - dict_loop_first(dict); - while (dict_loop_next(dict,&key,&val)!=NULL) + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) { + val=dict_get(dict,keys[i]); assert(((val==value1)||(val==replace2))); } - /* free dictionary */ + /* free stuff */ dict_free(dict); + free(keys); } /* Test to insert a large number of elements in the dict. */ @@ -76,8 +79,8 @@ static void test_lotsofelements(void) DICT *dict; char buf[80]; int i,r; - const char *key; void *val; + const char **keys; /* initialize */ dict=dict_new(); /* insert a number of entries */ @@ -102,13 +105,15 @@ static void test_lotsofelements(void) dict_put(dict,buf,&buf); } /* loop over dictionary contents */ - dict_loop_first(dict); - while (dict_loop_next(dict,&key,&val)!=NULL) + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) { + val=dict_get(dict,keys[i]); assert(val==buf); } - /* free dictionary */ + /* free stuff */ dict_free(dict); + free(keys); } /* Test to insert a large number of elements in the dict. */ @@ -117,8 +122,9 @@ static void test_readelements(const char *fname) DICT *dict; char buf[80]; FILE *fp; - const char *key; void *val; + const char **keys; + int i; /* initialize */ dict=dict_new(); /* read file and insert all entries */ @@ -132,22 +138,23 @@ static void test_readelements(const char *fname) } fclose(fp); /* loop over dictionary contents */ - dict_loop_first(dict); - while (dict_loop_next(dict,&key,&val)!=NULL) + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++) { + val=dict_get(dict,keys[i]); assert(val==buf); } - /* free dictionary */ + /* free stuff */ dict_free(dict); + free(keys); } static void test_countelements(int num) { DICT *dict; char buf[80]; - int i,j,r; - const char *key; - void *val; + int i,r; + const char **keys; /* initialize */ dict=dict_new(); /* insert a number of entries */ @@ -158,17 +165,13 @@ static void test_countelements(int num) dict_put(dict,buf,&buf); } /* loop over dictionary contents */ - dict_loop_first(dict); - i=0; - while (dict_loop_next(dict,&key,&val)!=NULL) - { - assert(val==buf); - i++; - } + keys=dict_keys(dict); + for (i=0;keys[i]!=NULL;i++); /* we should have num elements */ assert(i==num); - /* free dictionary */ + /* free stuff */ dict_free(dict); + free(keys); } /* the main program... */ diff --git a/tests/test_set.c b/tests/test_set.c index 7ebfe4e..2623906 100644 --- a/tests/test_set.c +++ b/tests/test_set.c @@ -2,7 +2,7 @@ test_set.c - simple test for the set module This file is part of the nss-pam-ldapd library. - Copyright (C) 2008 Arthur de Jong + Copyright (C) 2008, 2009 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ #include <stdio.h> #include <string.h> #include <assert.h> +#include <stdlib.h> #include "common/set.h" #include "compat/attrs.h" @@ -33,7 +34,8 @@ int main(int UNUSED(argc),char UNUSED(*argv[])) { SET *set; - const char *val; + const char **list; + int i; /* initialize */ set=set_new(); @@ -51,16 +53,17 @@ int main(int UNUSED(argc),char UNUSED(*argv[])) assert(!set_contains(set,"key4")); /* loop over set contents */ - set_loop_first(set); - while ((val=set_loop_next(set))!=NULL) + list=set_tolist(set); + for (i=0;list[i]!=NULL;i++) { - assert( (strcasecmp(val,"key1")==0) || - (strcasecmp(val,"key2")==0) || - (strcasecmp(val,"key3")==0) ); + assert( (strcasecmp(list[i],"key1")==0) || + (strcasecmp(list[i],"key2")==0) || + (strcasecmp(list[i],"key3")==0) ); } /* free set */ set_free(set); + free(list); return 0; } |