diff -r e617c9cf6dd3 -r 90073cbb535d lm_connection.c --- a/lm_connection.c Mon Feb 16 01:32:12 2009 +0200 +++ b/lm_connection.c Fri Feb 20 23:07:43 2009 +0200 @@ -4,6 +4,7 @@ #include // GDestroyNotify, GMainContext #include +#include "config.h" #include "util.h" #include "lm_types.h" #include "lm_message.h" @@ -62,16 +63,15 @@ { const char *server = luaL_checkstring (L, 1); LmConnection *connection; - if (lua_gettop (L) < 2) { + if (lua_gettop (L) < 2) connection = lm_connection_new (server); - lua_pop (L, 1); - } else { + else { luaL_argcheck (L, lua_islightuserdata (L, 2), 2, "glib main context lightuserdata expected"); connection = lm_connection_new_with_context (server, (GMainContext *) lua_touserdata (L, 2)); - lua_pop (L, 2); } llm_connection_bless (L, connection); lm_connection_unref (connection); + D ("Connection %X created", (int) connection); return 1; } @@ -84,7 +84,6 @@ { luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "loudmouth connection lightuserdata expected"); llm_connection_bless (L, (LmConnection *) lua_touserdata (L, 1)); - lua_remove (L, -2); return 1; } @@ -99,37 +98,41 @@ // XXX lm_connection_unref (connection); lua_pushboolean (cb->L, success); if (lua_pcall (cb->L, 2, 0, 0)) { - // XXX lua_error (cb->L); + E ("Connection callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); - return; } } /// connection:open /// Opens connection to the server and then calls callback function. /// A: connection callback function -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_open (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_callback_t *cb; luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected"); + GError *err; cb = luaL_malloc (L, sizeof (llm_callback_t)); cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); cb->L = L; - lua_pushboolean (L, lm_connection_open (object->connection, - (LmResultFunction)llm_connection_callback, cb, - (GDestroyNotify)llm_callback_destroy, NULL)); - lua_remove (L, -2); - return 1; + if (lm_connection_open (object->connection, (LmResultFunction) llm_connection_callback, + cb, (GDestroyNotify) llm_callback_destroy, &err)) + return 1; + else { + lua_pushnil (L); + lua_pushstring (L, err->message); + W ("Connection opening failed"); + return 2; + } } /// connection:authenticate /// Tries to authenticate against opened connection, then calls callback function. /// A: string (username), string (password), string (resource), connection callback function -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_authenticate (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -138,72 +141,72 @@ const char *resource = luaL_checkstring (L, 4); llm_callback_t *cb; int status; + GError *err = NULL; luaL_argcheck (L, lua_isfunction (L, 5), 5, "function expected"); cb = luaL_malloc (L, sizeof (llm_callback_t)); cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); cb->L = L; - status = lm_connection_authenticate (object->connection, username, password, resource, - (LmResultFunction)llm_connection_callback, cb, - (GDestroyNotify)llm_callback_destroy, NULL); - lua_pop (L, 4); - lua_pushboolean (L, status); - return 1; + if (lm_connection_authenticate (object->connection, username, password, resource, + (LmResultFunction) llm_connection_callback, cb, + (GDestroyNotify) llm_callback_destroy, &err)) { + lua_pop (L, 3); + return 1; + } else { + lua_pushnil (L); + lua_pushstring (L, err->message); + W ("Connection authentication failed: %s", err->message); + return 2; + } } /// connection:port /// Gets or sets server port to connect. /// A: integer (optional) -/// R: integer (when called with no args) +/// R: integer (when called with no args) or lm connection object static int llm_connection_port (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_port (object->connection, luaL_checkint (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushnumber (L, lm_connection_get_port (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:server /// Gets or sets server to connect to. /// A: string (optional, server name) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm connection object static int llm_connection_server (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_server (object->connection, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushstring (L, lm_connection_get_server (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:jid /// Gets or sets jid for connection. /// A: string (optional) -/// R: string (when called with no args) +/// R: string (when called with no args) or lm connection object static int llm_connection_jid (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_jid (object->connection, luaL_checkstring (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get lua_pushstring (L, lm_connection_get_jid (object->connection)); - lua_remove (L, -2); - return 1; } + return 1; } /// connection:keep_alive_rate @@ -211,39 +214,38 @@ /// Note, that on some platforms there is no get function even in /// loudmouth versions, that should have it according to documentation. /// integer (optional, seconds) -/// integer (when called with no args) +/// integer (when called with no args) or lm connection object or nil, string (error message, when get function is not available in loudmouth) static int llm_connection_keep_alive_rate (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set lm_connection_set_keep_alive_rate (object->connection, luaL_checkint (L, 2)); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); + return 1; } else { // Get #ifdef HAVE_LM_CONNECTION_GET_KEEP_ALIVE_RATE lua_pushnumber (L, lm_connection_get_keep_alive_rate (object->connection)); - lua_remove (L, -2); + return 1; #else - lua_pop (L, 1); - lua_pushstring (L, "Sorry, your loudmouth have no get_keep_alive_rate"); - lua_error (L); + E ("Sorry, your loudmouth have no get_keep_alive_rate ()"); + lua_pushnil (L); + lua_pushstring (L, "Sorry, your loudmouth have no get_keep_alive_rate ()"); + return 2; #endif - return 1; } } /// connection:proxy /// Gets or sets proxy server for connection. /// A: lm proxy object (optional) -/// R: lm proxy object or nil (when called with no args) +/// R: lm proxy object or nil (when called with no args) or lm connection object static int llm_connection_proxy (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set llm_proxy_t *proxy = luaL_checklm_proxy (L, 2); lm_connection_set_proxy (object->connection, proxy->proxy); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get LmProxy *proxy = lm_connection_get_proxy (object->connection); lua_pop (L, 1); @@ -252,22 +254,21 @@ // XXX lm_proxy_unref (proxy); } else lua_pushnil (L); - return 1; } + return 1; } /// connection:ssl /// Gets or sets ssl object for connection. /// A: lm ssl object (optional) -/// R: lm ssl object or nil (when called with no args) +/// R: lm ssl object or nil (when called with no args) or lm connection object static int llm_connection_ssl (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); if (lua_gettop (L) > 1) { // Set llm_ssl_t *ssl = luaL_checklm_ssl (L, 2); lm_connection_set_ssl (object->connection, ssl->ssl); - lua_pop (L, 2); - return 0; + lua_pop (L, 1); } else { // Get LmSSL *ssl = lm_connection_get_ssl (object->connection); lua_pop (L, 1); @@ -276,19 +277,25 @@ // XXX lm_ssl_unref (ssl); } else lua_pushnil (L); - return 1; } + return 1; } /// connection:close /// Close connection. -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_close (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); - lua_pushboolean (L, lm_connection_close (object->connection, NULL)); - lua_remove (L, -2); - return 1; + GError *err = NULL; + if (lm_connection_close (object->connection, &err)) + return 1; + else { + W ("Connection close failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:status @@ -298,7 +305,6 @@ { llm_connection_t *connection = luaL_checklm_connection (L, 1); luaL_pushenum (L, lm_connection_get_state (connection->connection), llm_connection_state); - lua_remove (L, -2); return 1; } @@ -307,14 +313,15 @@ /// receiving of response to that message. /// Handler function can be either message handler object or just a function. /// A: lm message object, message handler callback function or lm message handler object (optional) -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_send (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_message_t *message = luaL_checklm_message (L, 2); int status; + GError *err = NULL; if (lua_gettop (L) < 3) // Send - status = lm_connection_send (object->connection, message->message, NULL); + status = lm_connection_send (object->connection, message->message, &err); else if (lua_isfunction (L, 3)) { // Send w/reply, func llm_callback_t *cb = luaL_malloc (L, sizeof (llm_callback_t)); LmMessageHandler *handler; @@ -325,31 +332,43 @@ (LmHandleMessageFunction)llm_message_handler_callback, cb, (GDestroyNotify)llm_callback_destroy); status = lm_connection_send_with_reply (object->connection, - message->message, handler, NULL); + message->message, handler, &err); lm_message_handler_unref (handler); } else { // Send w/reply, handler llm_message_handler_t *handler = luaL_checklm_message_handler (L, 3); status = lm_connection_send_with_reply (object->connection, message->message, - handler->message_handler, NULL); + handler->message_handler, &err); lua_pop (L, 1); }; - lua_pop (L, 2); - lua_pushboolean (L, status); - return 1; + lua_pop (L, 1); + if (status) + return 1; + else { + W ("Message sending failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:send_raw /// Sends arbitrary string to opened connection. /// A: string -/// R: boolean (status) +/// R: lm connection object or nil, string (error message) static int llm_connection_send_raw (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); const char *string = luaL_checkstring (L, 2); - int status = lm_connection_send_raw (object->connection, string, NULL); - lua_pop (L, 2); - lua_pushboolean (L, status); - return 1; + GError *err = NULL; + if (lm_connection_send_raw (object->connection, string, NULL)) { + lua_pop (L, 1); + return 1; + } else { + W ("Raw message sending failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:handler @@ -358,6 +377,7 @@ /// Handler function can be specified as plain function or message handler object. /// Though, you can unregister only a message handler object. /// A: message handler callback function or lm message handler object, message type, handler priority (optional) +/// R: lm connection object static int llm_connection_handler (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -393,7 +413,7 @@ type); } lua_pop (L, 2); - return 0; + return 1; } /// disconnect callback function @@ -406,15 +426,15 @@ // XXX lm_connection_unref (connection); luaL_pushenum (cb->L, reason, llm_disconnect_reason); if (lua_pcall (cb->L, 2, 0, 0)) { - // XXX lua_error (cb->L); + E ("Disconnect callback error: %s", lua_tostring (cb->L, -1)); lua_pop (cb->L, 1); - return; } } /// connection:ondisconnect /// Sets callback, that will be called on connection disconnect. /// A: disconnect callback function +/// R: lm connection object static int llm_connection_ondisconnect (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); @@ -428,56 +448,69 @@ lm_connection_set_disconnect_function (object->connection, (LmDisconnectFunction)llm_disconnect_callback, cb, (GDestroyNotify)llm_callback_destroy); - lua_pop (L, 1); - return 0; + return 1; } /// connection:open_wait /// Synchronous open call, that will block until connection will be opened. -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_open_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); - lua_pushboolean (L, lm_connection_open_and_block (object->connection, NULL)); - lua_remove (L, -2); - return 1; + GError *err = NULL; + if (lm_connection_open_and_block (object->connection, &err)) + return 1; + else { + W ("Synchronous connection opening failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:authenticate_wait /// Synchronous authentication call, that will wait until the end of authentication. /// A: string (username), string (password), string (resource) -/// R: boolean (success) +/// R: lm connection object or nil, string (error message) static int llm_connection_authenticate_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); const char *username = luaL_checkstring (L, 2); const char *password = luaL_checkstring (L, 3); const char *resource = luaL_checkstring (L, 4); - int status = lm_connection_authenticate_and_block (object->connection, username, - password, resource, NULL); - lua_pop (L, 4); - lua_pushboolean (L, status); - return 1; + GError *err = NULL; + if (lm_connection_authenticate_and_block (object->connection, username, + password, resource, &err)) + return 1; + else { + W ("Synchronous authentication failed: %s", err->message); + lua_pushnil (L); + lua_pushstring (L, err->message); + return 2; + } } /// connection:send_wait /// Synchronous call, that will send message and wait for reply to it. /// A: lm message object -/// R: lm message object or nil +/// R: lm message object or nil, string (error message) static int llm_connection_send_wait (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); llm_message_t *message = luaL_checklm_message (L, 2); + GError *err = NULL; LmMessage *new = lm_connection_send_with_reply_and_block (object->connection, - message->message, NULL); - lua_pop (L, 2); - if (!new) + message->message, &err); + if (!new) { + W ("Synchronous message sending failed: %s", err->message); lua_pushnil (L); - else { + lua_pushstring (L, err->message); + return 2; + } else { llm_message_bless (L, new); lm_message_unref (new); // XXX + return 1; } - return 1; } /// connection:pointer @@ -494,8 +527,8 @@ static int llm_connection_gc (lua_State *L) { llm_connection_t *object = luaL_checklm_connection (L, 1); + D ("Connection %X gc called", (int) object); lm_connection_unref (object->connection); - lua_pop (L, 1); return 0; }