summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2009-12-13 10:27:33 +0000
committerArthur de Jong <arthur@arthurdejong.org>2009-12-13 10:27:33 +0000
commitef8cc767b201e4798a060282d4a6f280094bb8cc (patch)
tree4f19eae6870321f280959be4b7b24cd0e38d4c2a
parent7dd703c9af5f8b4a50f056c47588a9e51d4ea681 (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.c69
-rw-r--r--common/dict.h16
-rw-r--r--common/set.c20
-rw-r--r--common/set.h14
-rw-r--r--nslcd/group.c33
-rw-r--r--nslcd/myldap.c67
-rw-r--r--tests/test_dict.c51
-rw-r--r--tests/test_set.c17
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;
}