diff options
author | Tomas Guisasola <tomas@luaforge.net> | 2003-08-12 14:37:56 +0000 |
---|---|---|
committer | Tomas Guisasola <tomas@luaforge.net> | 2003-08-12 14:37:56 +0000 |
commit | 794e52554cdd015e265ace4202794181c8a92fc5 (patch) | |
tree | c94b7a46e2d42ac94f2f223aa1b1c93211b95ea9 /lualdap/src/lualdap.c | |
parent | Primeiros passos na remocao completa de malloc's e free's. (diff) | |
download | lualdap-794e52554cdd015e265ace4202794181c8a92fc5.tar.xz lualdap-794e52554cdd015e265ace4202794181c8a92fc5.zip |
Substituicao de toda alocacao dinamica por estatica.
O tipo attrs_data e' usado para agrupar um conjunto de vetores de
modificacoes de atributos de uma entrada.
Mudanca na API do metodo modify (que passa a receber varias tabelas de
modificacoes de atributos).
Diffstat (limited to 'lualdap/src/lualdap.c')
-rwxr-xr-x | lualdap/src/lualdap.c | 368 |
1 files changed, 168 insertions, 200 deletions
diff --git a/lualdap/src/lualdap.c b/lualdap/src/lualdap.c index 1a654c9..94f6743 100755 --- a/lualdap/src/lualdap.c +++ b/lualdap/src/lualdap.c @@ -1,6 +1,6 @@ /* ** LuaLDAP -** $Id: lualdap.c,v 1.7 2003-06-23 11:40:41 tomas Exp $ +** $Id: lualdap.c,v 1.8 2003-08-12 14:37:56 tomas Exp $ */ #include <stdlib.h> @@ -53,6 +53,18 @@ typedef struct { } search_data; +/* LDAP attribute modification structure */ +typedef struct { + LDAPMod *attrs[LUALDAP_MAX_ATTRS + 1]; + LDAPMod mods[LUALDAP_MAX_ATTRS]; + int ai; + BerValue *values[LUALDAP_ARRAY_VALUES_SIZE]; + int vi; + BerValue bvals[LUALDAP_MAX_VALUES]; + int bi; +} attrs_data; + + int lualdap_libopen (lua_State *L); @@ -98,72 +110,136 @@ static void lualdap_setmeta (lua_State *L, char *name) { /* +** Initialize attributes structure. +*/ +static void init_attrs (attrs_data *attrs) { + attrs->ai = 0; + attrs->attrs[0] = NULL; + attrs->vi = 0; + attrs->values[0] = NULL; + attrs->bi = 0; +} + + +/* +** Copy a string on top of the stack to the next berval array position. +*/ +static void str2bvals (lua_State *L, int str, attrs_data *attrs) { + attrs->bvals[attrs->bi].bv_len = lua_strlen (L, str); + attrs->bvals[attrs->bi].bv_val = (char *)lua_tostring (L, str); + attrs->bi++; +} + + +/* +** Store a pointer to new berval. +*/ +static void new_value (attrs_data *attrs) { + attrs->values[attrs->vi] = &attrs->bvals[attrs->bi]; + attrs->vi++; +} + + +/* +** Store a NULL pointer to end attributes list. +*/ +static void last_value (attrs_data *attrs) { + attrs->values[attrs->vi] = NULL; + attrs->vi++; +} + + +/* +** Create a NULL-terminated array of berval strings from a Lua table. +** It also works for one string (instead of a table with a unique value). +** @param tab stack index of the table (or string). +** @return NULL-terminated array of berval strings. +*/ +static int table2bervalarray (lua_State *L, int tab, attrs_data *attrs) { + if (lua_isstring (L, tab)) { + if (LUALDAP_ARRAY_VALUES_SIZE < (attrs->vi + 1) || + LUALDAP_MAX_VALUES < attrs->bi) + return faildirect (L, LUALDAP_PREFIX"too many attributes/values"); + /* store pointer to new berval */ + new_value (attrs); + str2bvals (L, -1, attrs); + } else if (lua_istable (L, tab)) { + int i; + int n = luaL_getn (L, tab); + if (LUALDAP_ARRAY_VALUES_SIZE < (attrs->vi + n + 1) || + LUALDAP_MAX_VALUES < (attrs->bi + n)) + return faildirect (L, LUALDAP_PREFIX"too many attributes/values"); + for (i = 1; i <= n; i++) { + new_value (attrs); + lua_rawgeti (L, tab, i); /* push table element */ + if (lua_isstring (L, -1)) + str2bvals (L, -1, attrs); + else + return luaL_error (L, LUALDAP_PREFIX"invalid value (string expected, got %s)", lua_typename(L, lua_type(L, -1))); + } + lua_pop (L, n); + } else + return luaL_error (L, LUALDAP_PREFIX"invalid argument #%d", tab); + last_value (attrs); + return 0; +} + + +/* +** Convert a Lua table into an array of modifications. +** An array of modifications is a NULL-terminated array of LDAPMod's. +*/ +static int table2attrarray (lua_State *L, int tab, int op, attrs_data *attrs) { + lua_pushnil (L); /* first key for lua_next */ + while (lua_next (L, tab) != 0) { + if ((!lua_isnumber (L, -2)) && (lua_isstring (L, -2))) { + if (LUALDAP_MAX_ATTRS < attrs->ai) + return faildirect (L, LUALDAP_PREFIX"too many attributes/values"); + attrs->mods[attrs->ai].mod_op = op; + attrs->mods[attrs->ai].mod_type = (char *)lua_tostring (L, -2); + attrs->mods[attrs->ai].mod_bvalues = &attrs->values[attrs->vi]; + if (table2bervalarray (L, lua_gettop(L), attrs)) + return 2; + attrs->attrs[attrs->ai] = &attrs->mods[attrs->ai]; + attrs->ai++; + } + lua_pop (L, 1); /* pop value and leave last key on top of the stack */ + } + attrs->attrs[attrs->ai] = NULL; + return 0; +} + +/* !!!!!!! */ + +/* ** Copy a string or a table of strings from Lua to a NULL-terminated array ** of C-strings. */ static int table2strarray (lua_State *L, int tab, char *array[], int limit) { if (lua_isstring (L, tab)) { if (limit < 2) - return 0; + return faildirect (L, LUALDAP_PREFIX"too many arguments"); array[0] = (char *)lua_tostring (L, tab); array[1] = NULL; } else if (lua_istable (L, tab)) { int i; int n = luaL_getn (L, tab); if (limit < (n+1)) - return 0; + return luaL_error (L, LUALDAP_PREFIX"too many arguments"); for (i = 0; i < n; i++) { lua_rawgeti (L, tab, i+1); /* push table element */ if (lua_isstring (L, -1)) array[i] = (char *)lua_tostring (L, -1); else { - luaL_error (L, LUALDAP_PREFIX"invalid value"); + return luaL_error (L, LUALDAP_PREFIX"invalid value #%d", i+1); } } array[n] = NULL; /*lua_pop (L, n);*/ - } - return 1; -} - - -/* -** Create a NULL-terminated array of berval strings from a Lua table. -** It also works for one string (instead of a table with a unique value). -** @param tab stack index of the table (or string). -** @return NULL-terminated array of berval strings. -*/ -static int table2bervalarray (lua_State *L, int tab, BerValue *values[], int *vi, BerValue bvals[], int *bi) { - if (lua_isstring (L, tab)) { - if (LUALDAP_ARRAY_VALUES_SIZE < ((*vi) + 1) || - LUALDAP_MAX_VALUES < *bi) - return 0; - values[(*vi)++] = &bvals[*bi]; /* store pointer to new berval */ - bvals[*bi].bv_len = lua_strlen (L, tab); - bvals[*bi].bv_val = (char *)lua_tostring (L, tab); - (*bi)++; - } else if (lua_istable (L, tab)) { - int i; - int n = luaL_getn (L, tab); - if (LUALDAP_ARRAY_VALUES_SIZE < ((*vi) + n + 1) || - LUALDAP_MAX_VALUES < ((*bi) + n)) - return 0; - for (i = 0; i < n; i++) { - values[(*vi)++] = &bvals[*bi]; /* store pointer to new berval */ - lua_rawgeti (L, tab, i+1); /* push table element */ - if (lua_isstring (L, -1)) { - bvals[*bi].bv_len = lua_strlen (L, tab); - bvals[*bi].bv_val = (char *)lua_tostring (L, tab); - (*bi)++; - } else { - luaL_error (L, LUALDAP_PREFIX"invalid value"); - } - } - lua_pop (L, n); - } - values[(*vi)++] = NULL; - return 1; + } else + return luaL_error (L, LUALDAP_PREFIX"bad argument #%d (table or string expected, got %s)", tab, lua_typename (L, tab)); + return 0; } @@ -187,33 +263,6 @@ static int lualdap_close (lua_State *L) { /* -** Convert a Lua table into an array of attributes. -** An array of attributes is a NULL-terminated array of LDAPMod's. -*/ -static int table2attrarray (lua_State *L, int tab, int op, LDAPMod *attrs[], LDAPMod mods[], BerValue *values[], BerValue bvals[]) { - int vi = 0, bi = 0; - int i = 0; - lua_pushnil (L); /* first key for lua_next */ - while (lua_next (L, tab) != 0) { - if (lua_isstring (L, -1)) { - if (LUALDAP_MAX_ATTRS < i) - return 0; - mods[i].mod_op = op; - mods[i].mod_type = (char *)lua_tostring (L, -2); - mods[i].mod_bvalues = &values[vi]; - if (!table2bervalarray (L, -1, values,&vi, bvals,&bi)) - return 0; - attrs[i] = &mods[i]; - i++; - } - lua_pop (L, 1); /* pop value and leave last key on top of the stack */ - } - attrs[i] = NULL; - return 1; -} - - -/* ** Add a new entry to the directory. ** @param #1 LDAP connection. ** @param #2 String with new entry's DN. @@ -223,14 +272,12 @@ static int table2attrarray (lua_State *L, int tab, int op, LDAPMod *attrs[], LDA static int lualdap_add (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); - LDAPMod *attrs[LUALDAP_MAX_ATTRS + 1]; - LDAPMod mods[LUALDAP_MAX_ATTRS]; - BerValue *values[LUALDAP_ARRAY_VALUES_SIZE]; - BerValue bvals[LUALDAP_MAX_VALUES]; + attrs_data attrs; + init_attrs (&attrs); if (lua_istable (L, 3)) - if (!table2attrarray (L, 3, LUALDAP_MOD_ADD, attrs, mods, values, bvals)) - return faildirect (L, LUALDAP_PREFIX"too many values/attributes"); - int rc = ldap_add_ext_s (conn->ld, dn, attrs, NULL, NULL); + if (table2attrarray(L, 3, LUALDAP_MOD_ADD, &attrs)) + return 2; + int rc = ldap_add_ext_s (conn->ld, dn, attrs.attrs, NULL, NULL); if (rc == LDAP_SUCCESS) { lua_pushboolean (L, 1); return 1; @@ -292,118 +339,15 @@ static int lualdap_delete (lua_State *L) { */ static int op2code (const char *s) { switch (*s) { - case 'a': + case '+': return LUALDAP_MOD_ADD; - case 'd': + case '-': return LUALDAP_MOD_DEL; - case 'r': + case '=': return LUALDAP_MOD_REP; default: - return 0; /* never reached */ - } -} - - -/* -** Convert a table into a NULL-terminated array of berval. -*/ -static BerValue **table2bervals (lua_State *L, int tab) { - BerValue **values; - int i; - int n = luaL_getn (L, tab); - values = (BerValue **)malloc ((n+1) * sizeof(BerValue *)); - for (i = 0; i < n; i++) { - const char *s; - size_t len; - lua_rawgeti (L, tab, i+1); - s = luaL_checklstring (L, -1, &len); - values[i]->bv_val = malloc (len); - memcpy (values[i]->bv_val, lua_tostring (L, -1), len); - values[i]->bv_len = len; - } - values[n] = NULL; - lua_pop (L, n); - return values; -} - - -/* -** Convert a table into an LDAPMod structure. -*/ -static LDAPMod *table2ldapmod (lua_State *L, int tab, int i) { - const char *s; - size_t len; - LDAPMod *mod; - /* check table */ - lua_rawgeti (L, tab, i); - luaL_checktype (L, -1, LUA_TTABLE); - tab = lua_gettop (L); - mod = (LDAPMod *)malloc (sizeof (LDAPMod)); - /* get modification operation */ - lua_pushstring (L, "op"); - lua_rawget (L, tab); - s = luaL_checklstring (L, -1, &len); - mod->mod_op = op2code (s); - /* get type of the attribute to modify */ - lua_pushstring (L, "type"); - lua_rawget (L, tab); - s = luaL_checklstring (L, -1, &len); - mod->mod_type = malloc (len); - memcpy (mod->mod_type, s, len); - /* get the values to add, delete or replace. */ - lua_pushstring (L, "values"); - lua_rawget (L, tab); - if (lua_istable (L, -1)) - /* a set of values */ - mod->mod_bvalues = table2bervals (L, lua_gettop (L)); - else { - /* just one value */ - size_t len; - const char *s = luaL_checklstring (L, -1, &len); - mod->mod_bvalues = (BerValue **)malloc (2 * sizeof (BerValue *)); - mod->mod_bvalues[0] = (BerValue *)malloc (sizeof (BerValue)); - mod->mod_bvalues[0]->bv_val = (char *)malloc (len * sizeof (char)); - memcpy (mod->mod_bvalues[0]->bv_val, s, len); - mod->mod_bvalues[0]->bv_len = len; - mod->mod_bvalues[1] = NULL; - } - lua_pop (L, 4); - return mod; -} - - -/* -** Build an array of modifications. -*/ -static LDAPMod **getmods (lua_State *L, int tab) { - LDAPMod **mods; - int i, n; - luaL_checktype (L, tab, LUA_TTABLE); - n = luaL_getn (L, tab); - mods = (LDAPMod **)malloc ((n+1) * sizeof (LDAPMod **)); - for (i = 0; i < n; i++) { - mods[i] = table2ldapmod (L, tab, i+1); - } - mods[n] = NULL; - return mods; -} - - -/* -** Free modifications array. -*/ -static void freemods (LDAPMod **mods) { - int i; - for (i = 0; mods[i] != NULL; i++) { - int j; - for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) - free (mods[i]->mod_bvalues[j]->bv_val); - free (mods[i]->mod_bvalues[j]); - free (mods[i]->mod_type); - free (mods[i]->mod_bvalues); - free (mods[i]); + return 0; } - free (mods); } @@ -417,14 +361,30 @@ static void freemods (LDAPMod **mods) { static int lualdap_modify (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); - LDAPMod **mods = getmods (L, 3); - int rc = ldap_modify_ext_s (conn->ld, dn, mods, NULL, NULL); - freemods (mods); - if (rc == LDAP_SUCCESS) { - lua_pushboolean (L, 1); - return 1; - } else - return faildirect (L, ldap_err2string (rc)); + attrs_data attrs; + int param = 3; + while (lua_istable (L, param)) { + int rc, op; + init_attrs (&attrs); + /* get operation ('+','-','=' operations allowed) */ + lua_rawgeti (L, param, 1); + if (lua_isstring (L, -1)) + op = op2code (lua_tostring (L, -1)); + else + op = 0; + if (!op) + return luaL_error (L, LUALDAP_PREFIX"forgotten operation on argument #%d", param); + if (table2attrarray (L, param, op, &attrs)) + return 2; + rc = ldap_modify_ext_s (conn->ld, dn, attrs.attrs, NULL, NULL); + if (rc != LDAP_SUCCESS) + return luaL_error (L, + LUALDAP_PREFIX"error while modification set #%d: %s", + param-2, ldap_err2string (rc)); + param++; + } + lua_pushboolean (L, 1); + return 1; } @@ -443,7 +403,7 @@ static int pushvalues (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) { lua_newtable (L); for (i = 0; i < n; i++) { lua_pushlstring (L, vals[i]->bv_val, vals[i]->bv_len); - lua_rawseti (L, -2, i); + lua_rawseti (L, -2, i+1); } } ldap_value_free_len (vals); @@ -525,17 +485,17 @@ static int next_message (lua_State *L) { } case LDAP_RES_SEARCH_REFERENCE: { /*LDAPMessage *ref = ldap_first_reference (conn->ld, msg);*/ + lua_pushnil (L); break; } case LDAP_RES_SEARCH_RESULT: lua_pushnil (L); break; default: - luaL_error (L, LUALDAP_PREFIX"error on search result chain"); + return luaL_error (L, LUALDAP_PREFIX"error on search result chain"); } - - ldap_msgfree (res); } + ldap_msgfree (res); return 1; } @@ -610,8 +570,11 @@ static int lualdap_search (lua_State *L) { struct timeval *timeout = NULL; /* ??? function parameter ??? */ int sizelimit = LDAP_NO_LIMIT; /* ??? function parameter ??? */ - if (lua_istable (L, 5)) - table2strarray (L, 5, attrs, LUALDAP_MAX_ATTRS); + if (lua_istable (L, 5)) { + if (table2strarray (L, 5, attrs, LUALDAP_MAX_ATTRS)) + return 2; + } else + attrs[0] = NULL; rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly, NULL, NULL, timeout, sizelimit, &msgid); if (rc != LDAP_SUCCESS) @@ -720,6 +683,11 @@ int lualdap_libopen (lua_State *L) { lua_pushcfunction (L, lualdap_open_simple); lua_rawset (L, -3); lua_setglobal (L, LUALDAP_TABLENAME); + +/* +lua_pushcfunction (L, lualdap_modify); +lua_setglobal (L, "modify"); +*/ return 0; } |