From 1adb39819e9f60ae466372e8d7de766d7ffd51e9 Mon Sep 17 00:00:00 2001 From: Tomas Guisasola Date: Fri, 29 Aug 2003 14:24:53 +0000 Subject: Implementacao dos "futuros", ou seja, as funcoes que recebem a resposta das operacoes assincronas. Pequenas correcoes de estilo. --- lualdap/src/lualdap.c | 288 +++++++++++++++++++++++++++++--------------------- 1 file changed, 166 insertions(+), 122 deletions(-) (limited to 'lualdap/src/lualdap.c') diff --git a/lualdap/src/lualdap.c b/lualdap/src/lualdap.c index 6ba272d..77166c5 100755 --- a/lualdap/src/lualdap.c +++ b/lualdap/src/lualdap.c @@ -1,6 +1,6 @@ /* ** LuaLDAP -** $Id: lualdap.c,v 1.18 2003-08-27 16:36:11 tomas Exp $ +** $Id: lualdap.c,v 1.19 2003-08-29 14:24:53 tomas Exp $ */ #include @@ -136,14 +136,11 @@ static const char *strtabparam (lua_State *L, char *name, char *def) { strgettable (L, name); if (lua_isnil (L, -1)) return def; + else if (lua_isstring (L, -1)) + return lua_tostring (L, -1); else { - const char *s = lua_tostring (L, -1); - if (!s) { - option_error (L, name, "string"); - return NULL; - } - else - return s; + option_error (L, name, "string"); + return NULL; } } @@ -156,13 +153,10 @@ static long longtabparam (lua_State *L, char *name, int def) { strgettable (L, name); if (lua_isnil (L, -1)) return def; - else { - long n = (long)lua_tonumber (L, -1); - if (n == 0 && !lua_isnumber (L, -1)) - return option_error (L, name, "number"); - else - return n; - } + else if (lua_isnumber (L, -1)) + return (long)lua_tonumber (L, -1); + else + return option_error (L, name, "number"); } @@ -174,13 +168,10 @@ static double numbertabparam (lua_State *L, char *name, double def) { strgettable (L, name); if (lua_isnil (L, -1)) return def; - else { - double n = lua_tonumber (L, -1); - if (n == 0 && !lua_isnumber (L, -1)) - return option_error (L, name, "number"); - else - return n; - } + else if (lua_isnumber (L, -1)) + return lua_tonumber (L, -1); + else + return option_error (L, name, "number"); } @@ -192,10 +183,10 @@ static int booltabparam (lua_State *L, char *name, int def) { strgettable (L, name); if (lua_isnil (L, -1)) return def; - else if (!lua_isboolean (L, -1)) - return option_error (L, name, "boolean"); - else + else if (lua_isboolean (L, -1)) return lua_toboolean (L, -1); + else + return option_error (L, name, "boolean"); } @@ -221,7 +212,7 @@ static void A_init (attrs_data *attrs) { /* -** Store a string on the attributes structure. +** Store the string on top of the stack on the attributes structure. ** Increment the bvals counter. */ static BerValue *A_setbval (lua_State *L, attrs_data *a, const char *n) { @@ -376,6 +367,69 @@ static int table2strarray (lua_State *L, int tab, char *array[], int limit) { } +/* +** Get the result message of an operation. +** #1 upvalue == connection +** #2 upvalue == msgid +*/ +static int result_message (lua_State *L) { + struct timeval *timeout = NULL; /* ??? function parameter ??? */ + LDAPMessage *res; + int rc; + conn_data *conn = (conn_data *)lua_touserdata (L, lua_upvalueindex (1)); + int msgid = (int)lua_tonumber (L, lua_upvalueindex (2)); + int res_code = (int)lua_tonumber (L, lua_upvalueindex (3)); + + luaL_argcheck (L,!conn->closed,1,LUALDAP_PREFIX"LDAP connection is closed"); + rc = ldap_result (conn->ld, msgid, LDAP_MSG_ONE, timeout, &res); + if (rc == 0) + return faildirect (L, LUALDAP_PREFIX"result timeout expired"); + else if (rc == -1) + return faildirect (L, LUALDAP_PREFIX"result error"); + else if (rc != res_code) + return faildirect (L, ldap_err2string (rc)); + else { + int err, ret = 1; + char *mdn, *msg; + rc = ldap_parse_result (conn->ld, res, &err, &mdn, &msg, NULL, NULL, 1); + if (rc != LDAP_SUCCESS) + return faildirect (L, ldap_err2string (rc)); + switch (err) { + case LDAP_SUCCESS: + case LDAP_COMPARE_TRUE: + lua_pushboolean (L, 1); + break; + case LDAP_COMPARE_FALSE: + lua_pushboolean (L, 0); + break; + default: + lua_pushnil (L); + lua_pushstring (L, LUALDAP_PREFIX); + lua_pushstring (L, msg); + lua_concat (L, 2); + ret = 2; + } + ldap_memfree (mdn); + ldap_memfree (msg); + return ret; + } +} + + +/* +** Push a function to process the LDAP result. +*/ +static int create_future (lua_State *L, int rc, int conn, int msgid, int code) { + if (rc != LDAP_SUCCESS) + return faildirect (L, ldap_err2string (rc)); + lua_pushvalue (L, conn); /* push connection as #1 upvalue */ + lua_pushnumber (L, msgid); /* push msgid as #2 upvalue */ + lua_pushnumber (L, code); /* push code as #3 upvalue */ + lua_pushcclosure (L, result_message, 3); + return 1; +} + + /* ** Unbind from the directory. ** @param #1 LDAP connection. @@ -401,23 +455,19 @@ static int lualdap_close (lua_State *L) { ** @param #1 LDAP connection. ** @param #2 String with new entry's DN. ** @param #3 Table with new entry's attributes and values. -** @return ?? +** @return Function to process the LDAP result. */ static int lualdap_add (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); attrs_data attrs; - int rc; + int rc, msgid; A_init (&attrs); if (lua_istable (L, 3)) A_tab2mod (L, &attrs, 3, LUALDAP_MOD_ADD); A_lastattr (L, &attrs); - rc = ldap_add_ext_s (conn->ld, dn, attrs.attrs, NULL, NULL); - if (rc == LDAP_SUCCESS) { - lua_pushboolean (L, 1); - return 1; - } else - return faildirect (L, ldap_err2string (rc)); + rc = ldap_add_ext (conn->ld, dn, attrs.attrs, NULL, NULL, &msgid); + return create_future (L, rc, 1, msgid, LDAP_RES_ADD); } @@ -427,25 +477,18 @@ static int lualdap_add (lua_State *L) { ** @param #2 String with entry's DN. ** @param #3 String with attribute's name. ** @param #4 String with attribute's value. -** @return Boolean. +** @return Function to process the LDAP result. */ static int lualdap_compare (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); const char *attr = luaL_check_string (L, 3); BerValue bvalue; - int rc; + int rc, msgid; bvalue.bv_val = (char *)luaL_check_string (L, 4); bvalue.bv_len = lua_strlen (L, 4); - rc = ldap_compare_ext_s (conn->ld, dn, attr, &bvalue, NULL, NULL); - if (rc == LDAP_COMPARE_TRUE) { - lua_pushboolean (L, 1); - return 1; - } else if (rc == LDAP_COMPARE_FALSE) { - lua_pushboolean (L, 0); - return 1; - } else - return faildirect (L, ldap_err2string (rc)); + rc = ldap_compare_ext (conn->ld, dn, attr, &bvalue, NULL, NULL, &msgid); + return create_future (L, rc, 1, msgid, LDAP_RES_COMPARE); } @@ -458,12 +501,9 @@ static int lualdap_compare (lua_State *L) { static int lualdap_delete (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); - int rc = ldap_delete_ext_s (conn->ld, dn, NULL, NULL); - if (rc == LDAP_SUCCESS) { - lua_pushboolean (L, 1); - return 1; - } else - return faildirect (L, ldap_err2string (rc)); + int rc, msgid; + rc = ldap_delete_ext (conn->ld, dn, NULL, NULL, &msgid); + return create_future (L, rc, 1, msgid, LDAP_RES_DELETE); } @@ -497,7 +537,7 @@ static int lualdap_modify (lua_State *L) { conn_data *conn = getconnection (L); const char *dn = luaL_check_string (L, 2); attrs_data attrs; - int rc, param = 3; + int rc, msgid, param = 3; A_init (&attrs); while (lua_istable (L, param)) { int op; @@ -512,12 +552,22 @@ static int lualdap_modify (lua_State *L) { } A_lastattr (L, &attrs); rc = ldap_modify_ext_s (conn->ld, dn, attrs.attrs, NULL, NULL); - if (rc != LDAP_SUCCESS) - return faildirect (L, ldap_err2string (rc)); - else { - lua_pushboolean (L, 1); - return 1; - } + return create_future (L, rc, 1, msgid, LDAP_RES_MODIFY); +} + + +/* +** Change the distinguished name of an entry. +*/ +static int lualdap_rename (lua_State *L) { + conn_data *conn = getconnection (L); + const char *dn = luaL_check_string (L, 2); + const char *rdn = luaL_check_string (L, 3); + const char *par = luaL_optlstring (L, 4, NULL, NULL); + const int del = luaL_optnumber (L, 5, 0); + int msgid; + int rc = ldap_rename (conn->ld, dn, rdn, par, del, NULL, NULL, &msgid); + return create_future (L, rc, 1, msgid, LDAP_RES_MODDN); } @@ -529,7 +579,7 @@ static int lualdap_modify (lua_State *L) { ** @param attr Name of entry's attribute to get values from. ** @return 1 in case of success. */ -static int pushvalues (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) { +static int push_values (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) { int i, n; BerValue **vals = ldap_get_values_len (ld, entry, attr); if ((n = ldap_count_values_len (vals)) == 1) /* just one value */ @@ -551,7 +601,7 @@ static int pushvalues (lua_State *L, LDAP *ld, LDAPMessage *entry, char *attr) { ** @param entry Current entry. ** @param tab Absolute stack index of the table. */ -static void setattribs (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) { +static void set_attribs (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) { char *attr; BerElement *ber = NULL; for (attr = ldap_first_attribute (ld, entry, &ber); @@ -559,12 +609,21 @@ static void setattribs (lua_State *L, LDAP *ld, LDAPMessage *entry, int tab) { attr = ldap_next_attribute (ld, entry, ber)) { lua_pushstring (L, attr); - pushvalues (L, ld, entry, attr); + push_values (L, ld, entry, attr); lua_rawset (L, tab); /* tab[attr] = vals */ ldap_memfree (attr); } - if (ber) - ber_free (ber, 0); + ber_free (ber, 0); /* don't need to test if (ber == NULL) */ +} + + +/* +** Get the distinguished name of the given entry and pushes it on the stack. +*/ +static void push_dn (lua_State *L, LDAP *ld, LDAPMessage *entry) { + char *dn = ldap_get_dn (ld, entry); + lua_pushstring (L, dn); + ldap_memfree (dn); } @@ -589,26 +648,22 @@ static int next_message (lua_State *L) { return faildirect (L, LUALDAP_PREFIX"result timeout expired"); else if (rc == -1) return faildirect (L, LUALDAP_PREFIX"result error"); - - if (rc == LDAP_RES_SEARCH_RESULT) /* last message => nil */ + else if (rc == LDAP_RES_SEARCH_RESULT) /* last message => nil */ lua_pushnil (L); else { LDAPMessage *msg = ldap_first_message (conn->ld, res); switch (ldap_msgtype (msg)) { case LDAP_RES_SEARCH_ENTRY: { - int tab; LDAPMessage *entry = ldap_first_entry (conn->ld, msg); - char *dn = ldap_get_dn (conn->ld, entry); - lua_pushstring (L, dn); - ldap_memfree (dn); + push_dn (L, conn->ld, entry); lua_newtable (L); - tab = lua_gettop (L); - setattribs (L, conn->ld, entry, tab); + set_attribs (L, conn->ld, entry, lua_gettop (L)); ret = 2; /* two return values */ break; } case LDAP_RES_SEARCH_REFERENCE: { - /*LDAPMessage *ref = ldap_first_reference (conn->ld, msg);*/ + LDAPMessage *ref = ldap_first_reference (conn->ld, msg); + push_dn (L, conn->ld, ref); /* is this supposed to work? */ lua_pushnil (L); break; } @@ -616,6 +671,7 @@ static int next_message (lua_State *L) { lua_pushnil (L); break; default: + ldap_msgfree (res); return luaL_error (L, LUALDAP_PREFIX"error on search result chain"); } } @@ -644,7 +700,7 @@ static int string2scope (lua_State *L, const char *s) { /* -** +** Close the search object. */ static int lualdap_search_close (lua_State *L) { search_data *search = (search_data *)luaL_checkudata (L, lua_upvalueindex (1), LUALDAP_SEARCH_METATABLE); @@ -671,6 +727,38 @@ static void create_search (lua_State *L, int conn_index, int msgid) { } +/* +** Fill in the attrs array, according to the attrs parameter. +*/ +static int get_attrs_param (lua_State *L, char *attrs[]) { + lua_pushstring (L, "attrs"); + lua_gettable (L, 2); + if (lua_isstring (L, -1)) { + attrs[0] = (char *)lua_tostring (L, -1); + attrs[1] = NULL; + } else if (!lua_istable (L, -1)) + attrs[0] = NULL; + else + if (table2strarray (L, lua_gettop (L), attrs, LUALDAP_MAX_ATTRS)) + return 0; + return 1; +} + + +/* +** Fill in the struct timeval, according to the timeout parameter. +*/ +static struct timeval *get_timeout_param (lua_State *L, struct timeval *st) { + double t = numbertabparam (L, "timeout", 0); + st->tv_sec = (long)t; + st->tv_usec = (long)(1000000 * (t - st->tv_sec)); + if (st->tv_sec == 0 && st->tv_usec == 0) + return NULL; + else + return st; +} + + /* ** Perform a search operation. ** @return #1 Function to iterate over the result entries. @@ -680,43 +768,22 @@ static void create_search (lua_State *L, int conn_index, int msgid) { */ static int lualdap_search (lua_State *L) { conn_data *conn = getconnection (L); - const char *base; - int scope; - const char *filter; + const char *base, *filter; char *attrs[LUALDAP_MAX_ATTRS]; - int attrsonly; - int msgid; - int rc; + int scope, attrsonly, msgid, rc, sizelimit; struct timeval st, *timeout; - int sizelimit; - double t; if (!lua_istable (L, 2)) return luaL_error (L, LUALDAP_PREFIX"no search specification"); - /* get attributes parameter */ - lua_pushstring (L, "attrs"); - lua_gettable (L, 2); - if (lua_isstring (L, -1)) { - attrs[0] = (char *)lua_tostring (L, -1); - attrs[1] = NULL; - } else if (!lua_istable (L, -1)) - attrs[0] = NULL; - else - if (table2strarray (L, lua_gettop (L), attrs, LUALDAP_MAX_ATTRS)) - return 2; + if (!get_attrs_param (L, attrs)) + return 2; /* get other parameters */ attrsonly = booltabparam (L, "attrsonly", 0); base = strtabparam (L, "base", NULL); filter = strtabparam (L, "filter", NULL); scope = string2scope (L, strtabparam (L, "scope", NULL)); sizelimit = longtabparam (L, "sizelimit", LDAP_NO_LIMIT); - t = numbertabparam (L, "timeout", 0); - st.tv_sec = (long)t; - st.tv_usec = (long)(1000000 * (t - st.tv_sec)); - if (st.tv_sec == 0 && st.tv_usec == 0) - timeout = NULL; - else - timeout = &st; + timeout = get_timeout_param (L, &st); rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly, NULL, NULL, timeout, sizelimit, &msgid); @@ -731,29 +798,6 @@ static int lualdap_search (lua_State *L) { } -/* -** Change the distinguished name of an entry. -*/ -static int lualdap_rename (lua_State *L) { - conn_data *conn = getconnection (L); - const char *dn = luaL_check_string (L, 2); - const char *rdn = luaL_check_string (L, 3); - const char *par = luaL_optlstring (L, 4, NULL, NULL); - const int del = luaL_optnumber (L, 5, 0); - int rc = ldap_rename_s (conn->ld, dn, rdn, par, del, NULL, NULL); - if (rc == LDAP_SUCCESS) { - lua_pushboolean (L, 1); - return 1; - } else { - lua_pushnil (L); - lua_pushstring (L, LUALDAP_PREFIX); - lua_pushstring (L, ldap_err2string (rc)); - lua_concat (L, 2); - return 2; - } -} - - /* ** Create a metatable. */ -- cgit v1.2.3-59-g8ed1b