From b07dba7b2c404fe11182f8a5f8c3e5ea92250bf6 Mon Sep 17 00:00:00 2001 From: Russell Zuck Date: Mon, 6 Aug 2012 10:49:47 -0400 Subject: [PATCH 01/65] fix memory leak in logging of large buffers --- src/ctx.c | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/ctx.c b/src/ctx.c index a2975dcb..5a246879 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -249,32 +249,38 @@ void xmpp_log(const xmpp_ctx_t * const ctx, { int oldret, ret; char smbuf[1024]; - char *buf; - va_list copy; + char *bigbuf = NULL; + va_list ap_copy; - buf = smbuf; - va_copy(copy, ap); - ret = xmpp_vsnprintf(buf, 1023, fmt, ap); + va_copy(ap_copy, ap); + ret = xmpp_vsnprintf(smbuf, 1023, fmt, ap_copy); + va_end(ap_copy); if (ret > 1023) { - buf = (char *)xmpp_alloc(ctx, ret + 1); - if (!buf) { - buf = NULL; - xmpp_error(ctx, "log", "Failed allocating memory for log message."); - va_end(copy); - return; - } - oldret = ret; - ret = xmpp_vsnprintf(buf, ret + 1, fmt, copy); - if (ret > oldret) { - xmpp_error(ctx, "log", "Unexpected error"); - return; - } + bigbuf = (char *)xmpp_alloc(ctx, ret + 1); + if (!bigbuf) { + bigbuf = NULL; + xmpp_error(ctx, "log", "Failed allocating memory for log message."); + return; + } + oldret = ret; + va_copy(ap_copy, ap); + ret = xmpp_vsnprintf(bigbuf, ret + 1, fmt, ap_copy); + va_end(ap_copy); + + if (ret > oldret) { + xmpp_error(ctx, "log", "Unexpected error"); + return; + } + + if (ctx->log->handler) { + ctx->log->handler(ctx->log->userdata, level, area, bigbuf); + } + xmpp_free(ctx, bigbuf); } else { - va_end(copy); + if (ctx->log->handler) { + ctx->log->handler(ctx->log->userdata, level, area, smbuf); + } } - - if (ctx->log->handler) - ctx->log->handler(ctx->log->userdata, level, area, buf); } /** Write to the log at the ERROR level. From 53cdc96a4b79558a2fb1afb1d388070a5cb8a8f1 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 8 Oct 2012 12:09:49 +0300 Subject: [PATCH 02/65] configure.ac: fix building without libxml2 Options --with-libxml2 and --without-libxml2 are broken. libstrophe is always built with libxml2 support. This patch fixes the problem and makes libstrophe be built with expat support by default. --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 97444e53..e170fc3b 100644 --- a/configure.ac +++ b/configure.ac @@ -9,11 +9,9 @@ AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([couldn't find openssl headers, PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])]) AC_ARG_WITH([libxml2], - [AS_HELP_STRING([--with-libxml2], [use libxml2 for XML parsing])], - [with_libxml2=check], - [with_libxml2=no]) + [AS_HELP_STRING([--with-libxml2], [use libxml2 for XML parsing])]) -if test "x$with_libxml2" != xno; then +if test "x$with_libxml2" = xyes; then PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7], [with_libxml2=yes], [AC_MSG_ERROR([couldn't find libxml2])]) From 9088383aebb8f166677247464bd80a17cfc08723 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 10 Oct 2012 17:37:19 +0300 Subject: [PATCH 03/65] build shared library --- Makefile.am | 13 +++++++------ bootstrap.sh | 1 + configure.ac | 1 + 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 788d37c9..b09ee583 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,15 +6,16 @@ PARSER_CFLAGS=@PARSER_CFLAGS@ PARSER_LIBS=@PARSER_LIBS@ SSL_LIBS = -lssl -lcrypto -lz +LIBS += $(SSL_LIBS) $(PARSER_LIBS) STROPHE_FLAGS = -I$(top_srcdir) -STROPHE_LIBS = libstrophe.a $(PARSER_LIBS) $(SSL_LIBS) +STROPHE_LIBS = libstrophe.la ## Main build targets -lib_LIBRARIES = libstrophe.a +lib_LTLIBRARIES = libstrophe.la -libstrophe_a_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS) -libstrophe_a_SOURCES = src/auth.c src/conn.c src/ctx.c \ +libstrophe_la_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS) +libstrophe_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/event.c src/handler.c src/hash.c \ src/jid.c src/md5.c src/sasl.c src/sha1.c \ src/snprintf.c src/sock.c src/stanza.c src/thread.c \ @@ -23,9 +24,9 @@ libstrophe_a_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/sasl.h src/sha1.h src/sock.h src/thread.h src/tls.h src/util.h if PARSER_EXPAT -libstrophe_a_SOURCES += src/parser_expat.c +libstrophe_la_SOURCES += src/parser_expat.c else -libstrophe_a_SOURCES += src/parser_libxml2.c +libstrophe_la_SOURCES += src/parser_libxml2.c endif include_HEADERS = strophe.h diff --git a/bootstrap.sh b/bootstrap.sh index 473f746b..3b72d881 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -5,6 +5,7 @@ if [ -d /usr/local/share/aclocal ]; then ACFLAGS="-I /usr/local/share/aclocal" fi +libtoolize aclocal ${ACFLAGS} automake --add-missing --foreign --copy autoconf diff --git a/configure.ac b/configure.ac index e170fc3b..9ad2c1b8 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,7 @@ AM_INIT_AUTOMAKE AC_PROG_CC AC_PROG_RANLIB +AC_PROG_LIBTOOL AM_PROG_CC_C_O AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([couldn't find openssl headers, openssl required])]) From d0515b070b30e074f2d96cedc106801ab35f523b Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 10 Oct 2012 20:00:26 +0300 Subject: [PATCH 04/65] add libstrophe.pc file --- Makefile.am | 4 ++++ configure.ac | 2 +- libstrophe.pc.in | 11 +++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 libstrophe.pc.in diff --git a/Makefile.am b/Makefile.am index b09ee583..d6c534e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,8 @@ AUTOMAKE_OPTIONS = subdir-objects CFLAGS = -g -Wall +pkgconfigdir = $(libdir)/pkgconfig + PARSER_CFLAGS=@PARSER_CFLAGS@ PARSER_LIBS=@PARSER_LIBS@ @@ -34,6 +36,8 @@ noinst_HEADERS = strophepp.h EXTRA_DIST = docs +pkgconfig_DATA = libstrophe.pc + ## Examples noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot examples_active_SOURCES = examples/active.c diff --git a/configure.ac b/configure.ac index 9ad2c1b8..1496990e 100644 --- a/configure.ac +++ b/configure.ac @@ -43,5 +43,5 @@ AM_CONDITIONAL([PARSER_EXPAT], [test x$with_parser != xlibxml2]) AC_SUBST(PARSER_NAME) AC_SUBST(PARSER_CFLAGS) AC_SUBST(PARSER_LIBS) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile libstrophe.pc]) AC_OUTPUT diff --git a/libstrophe.pc.in b/libstrophe.pc.in new file mode 100644 index 00000000..9ab13d47 --- /dev/null +++ b/libstrophe.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libstrophe +Description: A simple, lightweight C library for writing XMPP clients +Requires: +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lstrophe +Cflags: -I${includedir} From 71000f22b094084475b4f0cdfa0e803e6c3d335c Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 10:52:46 +0300 Subject: [PATCH 05/65] update .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 70d9cf39..e7b5e215 100644 --- a/.gitignore +++ b/.gitignore @@ -7,18 +7,25 @@ compile aclocal.m4 config.log config.status +config.guess +config.sub depcomp autom4te.cache +libtool +ltmain.sh .dirstamp .deps .sconsign* +src/*.lo src/*.o examples/*.o tests/*.o tests/check_parser +*.la *.a *.tar.gz *.zip +*.pc docs/html TAGS examples/basic @@ -33,3 +40,6 @@ tests/test_hash tests/test_jid tests/test_sasl tests/test_sock +.libs/ +examples/.libs/ +src/.libs/ From 84672567fd43ff6b73118af86745b255af097929 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 10:53:53 +0300 Subject: [PATCH 06/65] Makefile.am: preserve system defined CFLAGS --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index d6c534e1..0a1a12f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = subdir-objects -CFLAGS = -g -Wall +CFLAGS += -g -Wall pkgconfigdir = $(libdir)/pkgconfig From bb9cff012f1d166e0f853a1a13122bfcba910cae Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 14:06:40 +0300 Subject: [PATCH 07/65] base64_decode: avoid null pointer dereference --- src/sasl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sasl.c b/src/sasl.c index 73fbbc9b..6e024140 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -494,9 +494,8 @@ unsigned char *base64_decode(xmpp_ctx_t *ctx, if (len & 0x03) return NULL; dlen = base64_decoded_len(ctx, buffer, len); - dbuf = xmpp_alloc(ctx, dlen + 1); + d = dbuf = xmpp_alloc(ctx, dlen + 1); if (dbuf != NULL) { - d = dbuf; /* loop over each set of 4 characters, decoding 3 bytes */ for (i = 0; i < len - 3; i += 4) { hextet = _base64_invcharmap[(int)buffer[i]]; @@ -553,7 +552,8 @@ unsigned char *base64_decode(xmpp_ctx_t *ctx, break; } } - *d = '\0'; + if (d) + *d = '\0'; return dbuf; _base64_decode_error: From e54723378adaf6b511f005385d67466be5f406db Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 14:22:58 +0300 Subject: [PATCH 08/65] base64_decode: handle zero-length buffers zero-length buffer will cause problem within 'base64_decoded_len' and with use of uninitialized 'hextet' --- src/sasl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sasl.c b/src/sasl.c index 6e024140..cc70a6be 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -490,6 +490,8 @@ unsigned char *base64_decode(xmpp_ctx_t *ctx, uint32_t word, hextet; int i; + /* handle zero-length buffers */ + if (!len) return NULL; /* len must be a multiple of 4 */ if (len & 0x03) return NULL; From c1facb1a3ff6e369b03999a0c2ef227ed5cf873c Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 16:45:04 +0300 Subject: [PATCH 09/65] xmpp_log: free memory before exit --- src/ctx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ctx.c b/src/ctx.c index 5a246879..9732e786 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -269,6 +269,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, if (ret > oldret) { xmpp_error(ctx, "log", "Unexpected error"); + xmpp_free(ctx, bigbuf); return; } From 89b712e7c38f751a12adc1859c75ee5a53914dc4 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 17:24:09 +0300 Subject: [PATCH 10/65] _log_open_tag: size_t can never be less then 0 size_t is unsigned type. We should declare len as either ssize_t or int --- src/conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conn.c b/src/conn.c index 26df4186..e35a7356 100644 --- a/src/conn.c +++ b/src/conn.c @@ -681,7 +681,8 @@ void xmpp_conn_disable_tls(xmpp_conn_t * const conn) static void _log_open_tag(xmpp_conn_t *conn, char **attrs) { char buf[4096]; - size_t len, pos; + size_t pos; + int len; int i; if (!attrs) return; From a5d5986074c6297c94a683d8965ea33099368c76 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 18:01:00 +0300 Subject: [PATCH 11/65] base64_decode: shut up compiler --- src/sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sasl.c b/src/sasl.c index cc70a6be..0859e8dc 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -487,7 +487,7 @@ unsigned char *base64_decode(xmpp_ctx_t *ctx, { int dlen; unsigned char *dbuf, *d; - uint32_t word, hextet; + uint32_t word, hextet = 0; int i; /* handle zero-length buffers */ From 387483eb6648a5e0a6982342fde20bcf3d1beb5b Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 18:01:40 +0300 Subject: [PATCH 12/65] auth.c: remove unused declaration --- src/auth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/auth.c b/src/auth.c index 23719256..4656711b 100644 --- a/src/auth.c +++ b/src/auth.c @@ -56,7 +56,6 @@ #endif static void _auth(xmpp_conn_t * const conn); -static void _handle_open_tls(xmpp_conn_t * const conn); static void _handle_open_sasl(xmpp_conn_t * const conn); static int _handle_missing_legacy(xmpp_conn_t * const conn, void * const userdata); From 2ccdf4e83f3dd33df100de9f72c1c01a37254516 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 11 Oct 2012 18:40:15 +0300 Subject: [PATCH 13/65] thread.c: fix memory leak within mutex_destroy --- src/thread.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/thread.c b/src/thread.c index 5a7e8c3d..d0ca3d8d 100644 --- a/src/thread.c +++ b/src/thread.c @@ -71,16 +71,22 @@ mutex_t *mutex_create(const xmpp_ctx_t * ctx) int mutex_destroy(mutex_t *mutex) { int ret = 1; - const xmpp_ctx_t *ctx; + const xmpp_ctx_t *ctx = NULL; + + if (mutex) + ctx = mutex->ctx; + if (!ctx) + return XMPP_EMEM; #ifdef _WIN32 if (mutex->mutex) ret = CloseHandle(mutex->mutex); #else - if (mutex->mutex) + if (mutex->mutex) { ret = pthread_mutex_destroy(mutex->mutex) == 0; + xmpp_free(ctx, mutex->mutex); + } #endif - ctx = mutex->ctx; xmpp_free(ctx, mutex); return ret; From a9c4a0834b7bfb18329c3d63de400e696d6aa354 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 15:32:39 +0300 Subject: [PATCH 14/65] ctx.c: spacing --- src/ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctx.c b/src/ctx.c index 9732e786..0a7993a4 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -263,7 +263,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, return; } oldret = ret; - va_copy(ap_copy, ap); + va_copy(ap_copy, ap); ret = xmpp_vsnprintf(bigbuf, ret + 1, fmt, ap_copy); va_end(ap_copy); From 5e87552250066426071a922a999422a1f40f7d4b Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 16:04:03 +0300 Subject: [PATCH 15/65] update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e7b5e215..a1a39b74 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ tests/check_parser *.tar.gz *.zip *.pc +*~ +*.swp docs/html TAGS examples/basic From a4164acad5eb7853ca63f610d4f23ca1c8501b4d Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 16:08:40 +0300 Subject: [PATCH 16/65] xmpp_log: do not process when handler is NULL --- src/ctx.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ctx.c b/src/ctx.c index 0a7993a4..91c80ddd 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -252,6 +252,9 @@ void xmpp_log(const xmpp_ctx_t * const ctx, char *bigbuf = NULL; va_list ap_copy; + if (!ctx || !ctx->log || !ctx->log->handler) + return; + va_copy(ap_copy, ap); ret = xmpp_vsnprintf(smbuf, 1023, fmt, ap_copy); va_end(ap_copy); @@ -273,15 +276,10 @@ void xmpp_log(const xmpp_ctx_t * const ctx, return; } - if (ctx->log->handler) { - ctx->log->handler(ctx->log->userdata, level, area, bigbuf); - } + ctx->log->handler(ctx->log->userdata, level, area, bigbuf); xmpp_free(ctx, bigbuf); - } else { - if (ctx->log->handler) { - ctx->log->handler(ctx->log->userdata, level, area, smbuf); - } - } + } else + ctx->log->handler(ctx->log->userdata, level, area, smbuf); } /** Write to the log at the ERROR level. From 0bd52cecf72aecf7c695cf75e65ae59219013349 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 22:20:01 +0300 Subject: [PATCH 17/65] rename fork to libcouplet --- Makefile.am | 18 +++++++++--------- README.markdown | 25 ++++++++----------------- configure.ac | 12 ++++++------ strophe.h => couplet.h | 2 +- strophepp.h => coupletpp.h | 4 ++-- examples/active.c | 2 +- examples/basic.c | 2 +- examples/bot.c | 2 +- examples/roster.c | 2 +- libstrophe.pc.in => libcouplet.pc.in | 6 +++--- src/auth.c | 2 +- src/common.h | 2 +- src/conn.c | 2 +- src/ctx.c | 2 +- src/event.c | 2 +- src/handler.c | 2 +- src/hash.c | 2 +- src/jid.c | 2 +- src/oocontext.cpp | 4 ++-- src/oostanza.cpp | 4 ++-- src/parser.h | 2 +- src/parser_expat.c | 2 +- src/parser_libxml2.c | 2 +- src/sasl.c | 2 +- src/sasl.h | 2 +- src/stanza.c | 2 +- src/thread.c | 2 +- src/thread.h | 2 +- src/util.c | 2 +- tests/check_parser.c | 2 +- tests/test_base64.c | 2 +- tests/test_ctx.c | 2 +- tests/test_hash.c | 2 +- tests/test_jid.c | 2 +- tests/test_sasl.c | 2 +- 35 files changed, 60 insertions(+), 69 deletions(-) rename strophe.h => couplet.h (99%) rename strophepp.h => coupletpp.h (98%) rename libstrophe.pc.in => libcouplet.pc.in (51%) diff --git a/Makefile.am b/Makefile.am index 0a1a12f3..db3afd78 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,13 +11,13 @@ SSL_LIBS = -lssl -lcrypto -lz LIBS += $(SSL_LIBS) $(PARSER_LIBS) STROPHE_FLAGS = -I$(top_srcdir) -STROPHE_LIBS = libstrophe.la +STROPHE_LIBS = libcouplet.la ## Main build targets -lib_LTLIBRARIES = libstrophe.la +lib_LTLIBRARIES = libcouplet.la -libstrophe_la_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS) -libstrophe_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ +libcouplet_la_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS) +libcouplet_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/event.c src/handler.c src/hash.c \ src/jid.c src/md5.c src/sasl.c src/sha1.c \ src/snprintf.c src/sock.c src/stanza.c src/thread.c \ @@ -26,17 +26,17 @@ libstrophe_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/sasl.h src/sha1.h src/sock.h src/thread.h src/tls.h src/util.h if PARSER_EXPAT -libstrophe_la_SOURCES += src/parser_expat.c +libcouplet_la_SOURCES += src/parser_expat.c else -libstrophe_la_SOURCES += src/parser_libxml2.c +libcouplet_la_SOURCES += src/parser_libxml2.c endif -include_HEADERS = strophe.h -noinst_HEADERS = strophepp.h +include_HEADERS = couplet.h +noinst_HEADERS = coupletpp.h EXTRA_DIST = docs -pkgconfig_DATA = libstrophe.pc +pkgconfig_DATA = libcouplet.pc ## Examples noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot diff --git a/README.markdown b/README.markdown index 4c0b3f83..4745147b 100644 --- a/README.markdown +++ b/README.markdown @@ -1,14 +1,8 @@ -# libstrophe +# libcouplet -libstrophe is a lightweight XMPP client library written in C. It has -minimal dependencies and is configurable for various environments. It -runs well on both Linux, Unix, and Windows based platforms. - -Its goals are: - -- usable quickly -- well documented -- reliable +libcouplet is a fork of libstrophe - a lightweight XMPP client library +written in C. Goal of the fork is make library suitable for multi-thread +applications. ## Build Instructions @@ -23,27 +17,24 @@ From the top-level directory, run the following commands: ./configure make -This will create a static library, also in the top-level -directory, which can be linked into other programs. The -public API is defined in `strophe.h` which is also in the -top-level directory. - The `examples` directory contains some examples of how to use the library; these may be helpful in addition to the API documentation ## Requirements -libstrophe requires: +libcouplet requires: - expat or libxml2 - expat is the default; use --with-libxml2 to switch - libresolv on UNIX systems - make sure you include -lresolv - if you are compiling by hand. + if you are compiling by hand. In addition, if you wish to run the unit tests, you will need the check package. +Windows systems aren't supported for now. + ### OS X (with Homebrew package manager) You can install the requirements with: diff --git a/configure.ac b/configure.ac index 1496990e..f42aeae3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libstrophe], [0.8-snapshot], [jack@metajack.im]) +AC_INIT([libcouplet], [0.8-snapshot], [pasis.ua@gmail.com]) AM_INIT_AUTOMAKE AC_PROG_CC @@ -6,7 +6,7 @@ AC_PROG_RANLIB AC_PROG_LIBTOOL AM_PROG_CC_C_O -AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([couldn't find openssl headers, openssl required])]) +AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([could not find openssl headers, openssl required])]) PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])]) AC_ARG_WITH([libxml2], @@ -15,9 +15,9 @@ AC_ARG_WITH([libxml2], if test "x$with_libxml2" = xyes; then PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7], [with_libxml2=yes], - [AC_MSG_ERROR([couldn't find libxml2])]) + [AC_MSG_ERROR([could not find libxml2])]) else - AC_CHECK_HEADER(expat.h, [], [AC_MSG_ERROR([couldn't find expat headers; expat required])]) + AC_CHECK_HEADER(expat.h, [], [AC_MSG_ERROR([could not find expat headers; expat required])]) fi if test "x$with_libxml2" = xyes; then @@ -32,7 +32,7 @@ else PARSER_LIBS=-lexpat fi -AC_MSG_NOTICE([libstrophe will use the $with_parser XML parser]) +AC_MSG_NOTICE([libcouplet will use the $with_parser XML parser]) AC_SEARCH_LIBS([socket], [socket]) AC_LINK_IFELSE([AC_LANG_CALL([#include ], [res_query])], [],[LIBS="$LIBS -lresolv"]) @@ -43,5 +43,5 @@ AM_CONDITIONAL([PARSER_EXPAT], [test x$with_parser != xlibxml2]) AC_SUBST(PARSER_NAME) AC_SUBST(PARSER_CFLAGS) AC_SUBST(PARSER_LIBS) -AC_CONFIG_FILES([Makefile libstrophe.pc]) +AC_CONFIG_FILES([Makefile libcouplet.pc]) AC_OUTPUT diff --git a/strophe.h b/couplet.h similarity index 99% rename from strophe.h rename to couplet.h index e3a2f4df..ac8e7abd 100644 --- a/strophe.h +++ b/couplet.h @@ -1,4 +1,4 @@ -/* strophe.h +/* couplet.h ** strophe XMPP client library C API ** ** Copyright (C) 2005-2009 Collecta, Inc. diff --git a/strophepp.h b/coupletpp.h similarity index 98% rename from strophepp.h rename to coupletpp.h index 00431366..5fba7612 100644 --- a/strophepp.h +++ b/coupletpp.h @@ -1,4 +1,4 @@ -/* strophepp.h +/* coupletpp.h ** strophe XMPP client library C++ API ** ** Copyright (C) 2005-2009 Collecta, Inc. @@ -19,7 +19,7 @@ #ifndef __LIBSTROPHE_STROPHEPP_H__ #define __LIBSTROPHE_STROPHEPP_H__ -#include "strophe.h" +#include "couplet.h" namespace XMPP { class Context { diff --git a/examples/active.c b/examples/active.c index 8fdde725..4695c210 100644 --- a/examples/active.c +++ b/examples/active.c @@ -20,7 +20,7 @@ #include #include -#include +#include int handle_reply(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, diff --git a/examples/basic.c b/examples/basic.c index 0a317ee8..0acc73ac 100644 --- a/examples/basic.c +++ b/examples/basic.c @@ -14,7 +14,7 @@ #include -#include +#include /* define a handler for connection events */ diff --git a/examples/bot.c b/examples/bot.c index 03ba9c81..534ad40e 100644 --- a/examples/bot.c +++ b/examples/bot.c @@ -23,7 +23,7 @@ #include #include -#include +#include int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) diff --git a/examples/roster.c b/examples/roster.c index 379a998f..13651cd4 100644 --- a/examples/roster.c +++ b/examples/roster.c @@ -19,7 +19,7 @@ #include #include -#include +#include int handle_reply(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, diff --git a/libstrophe.pc.in b/libcouplet.pc.in similarity index 51% rename from libstrophe.pc.in rename to libcouplet.pc.in index 9ab13d47..d6db556e 100644 --- a/libstrophe.pc.in +++ b/libcouplet.pc.in @@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -Name: libstrophe -Description: A simple, lightweight C library for writing XMPP clients +Name: libcouplet +Description: Fork of libstrophe - a simple, lightweight C library for writing XMPP clients Requires: Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lstrophe +Libs: -L${libdir} -lcouplet Cflags: -I${includedir} diff --git a/src/auth.c b/src/auth.c index 4656711b..d744f85a 100644 --- a/src/auth.c +++ b/src/auth.c @@ -20,7 +20,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "sasl.h" diff --git a/src/common.h b/src/common.h index 9434e6ff..e6eda6d2 100644 --- a/src/common.h +++ b/src/common.h @@ -26,7 +26,7 @@ #endif -#include "strophe.h" +#include "couplet.h" #include "sock.h" #include "tls.h" #include "hash.h" diff --git a/src/conn.c b/src/conn.c index e35a7356..95216c66 100644 --- a/src/conn.c +++ b/src/conn.c @@ -23,7 +23,7 @@ #include #include -#include +#include "couplet.h" #include "common.h" #include "util.h" diff --git a/src/ctx.c b/src/ctx.c index 91c80ddd..4a8e430e 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -48,7 +48,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "util.h" diff --git a/src/event.c b/src/event.c index 1eaa643c..ffbd9f6b 100644 --- a/src/event.c +++ b/src/event.c @@ -47,7 +47,7 @@ #define ECONNABORTED WSAECONNABORTED #endif -#include +#include "couplet.h" #include "common.h" #include "parser.h" diff --git a/src/handler.c b/src/handler.c index d382ca89..05fb7de3 100644 --- a/src/handler.c +++ b/src/handler.c @@ -29,7 +29,7 @@ #include "ostypes.h" #endif -#include "strophe.h" +#include "couplet.h" #include "common.h" /** Fire off all stanza handlers that match. diff --git a/src/hash.c b/src/hash.c index 3acbc151..225a1ed6 100644 --- a/src/hash.c +++ b/src/hash.c @@ -19,7 +19,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "hash.h" diff --git a/src/jid.c b/src/jid.c index 53b2c484..14de4463 100644 --- a/src/jid.c +++ b/src/jid.c @@ -18,7 +18,7 @@ #include -#include "strophe.h" +#include "couplet.h" #include "common.h" /** Create a JID string from component parts node, domain, and resource. diff --git a/src/oocontext.cpp b/src/oocontext.cpp index 50717e45..dc2dd2e2 100644 --- a/src/oocontext.cpp +++ b/src/oocontext.cpp @@ -14,8 +14,8 @@ #include -#include "strophe.h" -#include "strophepp.h" +#include "couplet.h" +#include "coupletpp.h" XMPP::Context::Context() { diff --git a/src/oostanza.cpp b/src/oostanza.cpp index 178bfbf4..74924ee3 100644 --- a/src/oostanza.cpp +++ b/src/oostanza.cpp @@ -12,8 +12,8 @@ ** distribution. */ -#include "strophe.h" -#include "strophepp.h" +#include "couplet.h" +#include "coupletpp.h" using namespace XMPP; diff --git a/src/parser.h b/src/parser.h index 89ff71b1..9cb80883 100644 --- a/src/parser.h +++ b/src/parser.h @@ -19,7 +19,7 @@ #ifndef __LIBSTROPHE_PARSER_H__ #define __LIBSTROPHE_PARSER_H__ -#include "strophe.h" +#include "couplet.h" typedef struct _parser_t parser_t; diff --git a/src/parser_expat.c b/src/parser_expat.c index 9ab4e38f..e3490979 100644 --- a/src/parser_expat.c +++ b/src/parser_expat.c @@ -22,7 +22,7 @@ #include -#include +#include "couplet.h" #include "common.h" #include "parser.h" diff --git a/src/parser_libxml2.c b/src/parser_libxml2.c index ab10a4b3..68cfd9bb 100644 --- a/src/parser_libxml2.c +++ b/src/parser_libxml2.c @@ -23,7 +23,7 @@ #include #include -#include +#include "couplet.h" #include "common.h" #include "parser.h" diff --git a/src/sasl.c b/src/sasl.c index 0859e8dc..9f93cb6a 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -18,7 +18,7 @@ #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "sasl.h" #include "md5.h" diff --git a/src/sasl.h b/src/sasl.h index 09d5b8d0..3709dfea 100644 --- a/src/sasl.h +++ b/src/sasl.h @@ -19,7 +19,7 @@ #ifndef __LIBSTROPHE_SASL_H__ #define __LIBSTROPHE_SASL_H__ -#include "strophe.h" +#include "couplet.h" /** low-level sasl routines */ diff --git a/src/stanza.c b/src/stanza.c index 6bf11b80..af667f77 100644 --- a/src/stanza.c +++ b/src/stanza.c @@ -22,7 +22,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "hash.h" diff --git a/src/thread.c b/src/thread.c index d0ca3d8d..793cc9f0 100644 --- a/src/thread.c +++ b/src/thread.c @@ -26,7 +26,7 @@ #include #endif -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "thread.h" diff --git a/src/thread.h b/src/thread.h index 6dc155ab..564c3a88 100644 --- a/src/thread.h +++ b/src/thread.h @@ -28,7 +28,7 @@ #include #endif -#include "strophe.h" +#include "couplet.h" typedef struct _mutex_t mutex_t; diff --git a/src/util.c b/src/util.c index c442fe71..a1e69acd 100644 --- a/src/util.c +++ b/src/util.c @@ -27,7 +27,7 @@ #include #endif -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "util.h" diff --git a/tests/check_parser.c b/tests/check_parser.c index 902d9e1a..5c332232 100644 --- a/tests/check_parser.c +++ b/tests/check_parser.c @@ -16,7 +16,7 @@ #include -#include +#include #include "parser.h" #include "test.h" diff --git a/tests/test_base64.c b/tests/test_base64.c index dd158c7a..6899ae1b 100644 --- a/tests/test_base64.c +++ b/tests/test_base64.c @@ -15,7 +15,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "sasl.h" diff --git a/tests/test_ctx.c b/tests/test_ctx.c index 011b9141..1bbb44ab 100644 --- a/tests/test_ctx.c +++ b/tests/test_ctx.c @@ -16,7 +16,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" static int log_called = 0; diff --git a/tests/test_hash.c b/tests/test_hash.c index e4906e7f..3c007411 100644 --- a/tests/test_hash.c +++ b/tests/test_hash.c @@ -16,7 +16,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "hash.h" diff --git a/tests/test_jid.c b/tests/test_jid.c index 6b921694..f40f0f17 100644 --- a/tests/test_jid.c +++ b/tests/test_jid.c @@ -15,7 +15,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" static const char jid1[] = "foo@bar.com"; diff --git a/tests/test_sasl.c b/tests/test_sasl.c index 829e5f81..3017224e 100644 --- a/tests/test_sasl.c +++ b/tests/test_sasl.c @@ -15,7 +15,7 @@ #include #include -#include "strophe.h" +#include "couplet.h" #include "common.h" #include "sasl.h" From 6e48d261351567d0aaa465903bb2166d30c5a076 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 22:22:09 +0300 Subject: [PATCH 18/65] remove expat dir --- expat | 1 - 1 file changed, 1 deletion(-) delete mode 160000 expat diff --git a/expat b/expat deleted file mode 160000 index adf19a31..00000000 --- a/expat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit adf19a31860c5b439c84f2ec1fde245b4815529a From 7c171597b5bb1e4dfcd91f067eb5effff64be630 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 23:05:44 +0300 Subject: [PATCH 19/65] Makefile.am: rename variables --- Makefile.am | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/Makefile.am b/Makefile.am index db3afd78..eebaace5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,22 +1,19 @@ AUTOMAKE_OPTIONS = subdir-objects -CFLAGS += -g -Wall - -pkgconfigdir = $(libdir)/pkgconfig - +AM_CFLAGS = -I$(top_srcdir) -g -Wall PARSER_CFLAGS=@PARSER_CFLAGS@ -PARSER_LIBS=@PARSER_LIBS@ +PARSER_LIBS=@PARSER_LIBS@ SSL_LIBS = -lssl -lcrypto -lz +COUPLET_LIBS = libcouplet.la LIBS += $(SSL_LIBS) $(PARSER_LIBS) -STROPHE_FLAGS = -I$(top_srcdir) -STROPHE_LIBS = libcouplet.la +pkgconfigdir = $(libdir)/pkgconfig ## Main build targets lib_LTLIBRARIES = libcouplet.la -libcouplet_la_CFLAGS=$(STROPHE_FLAGS) $(PARSER_CFLAGS) +libcouplet_la_CFLAGS=$(AM_CFLAGS) $(PARSER_CFLAGS) libcouplet_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/event.c src/handler.c src/hash.c \ src/jid.c src/md5.c src/sasl.c src/sha1.c \ @@ -41,23 +38,23 @@ pkgconfig_DATA = libcouplet.pc ## Examples noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot examples_active_SOURCES = examples/active.c -examples_active_CFLAGS = $(STROPHE_FLAGS) -examples_active_LDADD = $(STROPHE_LIBS) +examples_active_CFLAGS = $(AM_CFLAGS) +examples_active_LDADD = $(COUPLET_LIBS) examples_roster_SOURCES = examples/roster.c -examples_roster_CFLAGS = $(STROPHE_FLAGS) -examples_roster_LDADD = $(STROPHE_LIBS) +examples_roster_CFLAGS = $(AM_CFLAGS) +examples_roster_LDADD = $(COUPLET_LIBS) examples_basic_SOURCES = examples/basic.c -examples_basic_CFLAGS = $(STROPHE_FLAGS) -examples_basic_LDADD = $(STROPHE_LIBS) +examples_basic_CFLAGS = $(AM_CFLAGS) +examples_basic_LDADD = $(COUPLET_LIBS) examples_bot_SOURCES = examples/bot.c -examples_bot_CFLAGS = $(STROPHE_FLAGS) -examples_bot_LDADD = $(STROPHE_LIBS) +examples_bot_CFLAGS = $(AM_CFLAGS) +examples_bot_LDADD = $(COUPLET_LIBS) ## Tests TESTS = tests/check_parser check_PROGRAMS = tests/check_parser tests_check_parser_SOURCES = tests/check_parser.c tests/test.h -tests_check_parser_CFLAGS = @check_CFLAGS@ $(PARSER_CFLAGS) $(STROPHE_FLAGS) \ +tests_check_parser_CFLAGS = @check_CFLAGS@ $(PARSER_CFLAGS) $(AM_CFLAGS) \ -I$(top_srcdir)/src -tests_check_parser_LDADD = @check_LIBS@ $(STROPHE_LIBS) +tests_check_parser_LDADD = @check_LIBS@ $(COUPLET_LIBS) From 2f0ba0cbe23010cdf65a323f3d09d2f21649a62a Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 12 Oct 2012 23:42:50 +0300 Subject: [PATCH 20/65] autotools: replace AC_PROG_RANLIB and AC_PROG_LIBTOOL with LT_INIT --- configure.ac | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f42aeae3..1a4185ea 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,8 @@ AC_INIT([libcouplet], [0.8-snapshot], [pasis.ua@gmail.com]) AM_INIT_AUTOMAKE AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_LIBTOOL AM_PROG_CC_C_O +LT_INIT AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([could not find openssl headers, openssl required])]) PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])]) From 91084792c93cac7aeac4ce7c5ab509d6f43cc6d5 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 01:00:59 +0300 Subject: [PATCH 21/65] ctx.c: spacing --- src/ctx.c | 225 +++++++++++++++++++++++++++--------------------------- 1 file changed, 112 insertions(+), 113 deletions(-) diff --git a/src/ctx.c b/src/ctx.c index 4a8e430e..3a0ebbfa 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -1,9 +1,9 @@ /* ctx.c ** strophe XMPP client library -- run-time context implementation ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** -** This software is provided AS-IS with no warranty, either express +** This software is provided AS-IS with no warranty, either express ** or implied. ** ** This software is distributed under license and may not be copied, @@ -39,7 +39,7 @@ * result in strange (and platform dependent) behavior. * * Specifically, the socket library on Win32 platforms must be initialized - * before use (although this is not the case on POSIX systems). The TLS + * before use (although this is not the case on POSIX systems). The TLS * subsystem must also seed the random number generator. */ @@ -58,10 +58,10 @@ * * @ingroup Init */ - void xmpp_initialize(void) +void xmpp_initialize(void) { - sock_initialize(); - tls_initialize(); + sock_initialize(); + tls_initialize(); } /** Shutdown the Strophe library. @@ -70,8 +70,8 @@ */ void xmpp_shutdown(void) { - tls_shutdown(); - sock_shutdown(); + tls_shutdown(); + sock_shutdown(); } /* version information */ @@ -100,36 +100,36 @@ void xmpp_shutdown(void) */ int xmpp_version_check(int major, int minor) { - return (major == LIBXMPP_VERSION_MAJOR) && - (minor >= LIBXMPP_VERSION_MINOR); + return (major == LIBXMPP_VERSION_MAJOR) && + (minor >= LIBXMPP_VERSION_MINOR); } /* We define the global default allocator, logger, and context here. */ -/* Wrap stdlib routines malloc, free, and realloc for default memory - * management. +/* Wrap stdlib routines malloc, free, and realloc for default memory + * management. */ static void *_malloc(const size_t size, void * const userdata) { - return malloc(size); + return malloc(size); } static void _free(void *p, void * const userdata) { - free(p); + free(p); } static void *_realloc(void *p, const size_t size, void * const userdata) { - return realloc(p, size); + return realloc(p, size); } /* default memory function map */ static xmpp_mem_t xmpp_default_mem = { - _malloc, /* use the thinly wrapped stdlib routines by default */ - _free, - _realloc, - NULL + _malloc, /* use the thinly wrapped stdlib routines by default */ + _free, + _realloc, + NULL }; /* log levels and names */ @@ -153,9 +153,9 @@ void xmpp_default_logger(void * const userdata, const char * const area, const char * const msg) { - xmpp_log_level_t filter_level = * (xmpp_log_level_t*)userdata; - if (level >= filter_level) - fprintf(stderr, "%s %s %s\n", area, _xmpp_log_level_name[level], msg); + xmpp_log_level_t filter_level = * (xmpp_log_level_t*)userdata; + if (level >= filter_level) + fprintf(stderr, "%s %s %s\n", area, _xmpp_log_level_name[level], msg); } static const xmpp_log_t _xmpp_default_loggers[] = { @@ -178,11 +178,11 @@ static const xmpp_log_t _xmpp_default_loggers[] = { */ xmpp_log_t *xmpp_get_default_logger(xmpp_log_level_t level) { - /* clamp to the known range */ - if (level > XMPP_LEVEL_ERROR) level = XMPP_LEVEL_ERROR; - if (level < XMPP_LEVEL_DEBUG) level = XMPP_LEVEL_DEBUG; + /* clamp to the known range */ + if (level > XMPP_LEVEL_ERROR) level = XMPP_LEVEL_ERROR; + if (level < XMPP_LEVEL_DEBUG) level = XMPP_LEVEL_DEBUG; - return (xmpp_log_t*)&_xmpp_default_loggers[level]; + return (xmpp_log_t*)&_xmpp_default_loggers[level]; } static xmpp_log_t xmpp_default_log = { NULL, NULL }; @@ -190,7 +190,7 @@ static xmpp_log_t xmpp_default_log = { NULL, NULL }; /* convenience functions for accessing the context */ /** Allocate memory in a Strophe context. - * All Strophe functions will use this to allocate memory. + * All Strophe functions will use this to allocate memory. * * @param ctx a Strophe context object * @param size the number of bytes to allocate @@ -199,7 +199,7 @@ static xmpp_log_t xmpp_default_log = { NULL, NULL }; */ void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size) { - return ctx->mem->alloc(size, ctx->mem->userdata); + return ctx->mem->alloc(size, ctx->mem->userdata); } /** Free memory in a Strophe context. @@ -210,7 +210,7 @@ void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size) */ void xmpp_free(const xmpp_ctx_t * const ctx, void *p) { - ctx->mem->free(p, ctx->mem->userdata); + ctx->mem->free(p, ctx->mem->userdata); } /** Reallocate memory in a Strophe context. @@ -225,14 +225,14 @@ void xmpp_free(const xmpp_ctx_t * const ctx, void *p) void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p, const size_t size) { - return ctx->mem->realloc(p, size, ctx->mem->userdata); + return ctx->mem->realloc(p, size, ctx->mem->userdata); } /** Write a log message to the logger. * Write a log message to the logger for the context for the specified * level and area. This function takes a printf-style format string and a * variable argument list (in va_list) format. This function is not meant - * to be called directly, but is used via xmpp_error, xmpp_warn, xmpp_info, + * to be called directly, but is used via xmpp_error, xmpp_warn, xmpp_info, * and xmpp_debug. * * @param ctx a Strophe context object @@ -247,44 +247,44 @@ void xmpp_log(const xmpp_ctx_t * const ctx, const char * const fmt, va_list ap) { - int oldret, ret; - char smbuf[1024]; - char *bigbuf = NULL; - va_list ap_copy; - - if (!ctx || !ctx->log || !ctx->log->handler) - return; - - va_copy(ap_copy, ap); - ret = xmpp_vsnprintf(smbuf, 1023, fmt, ap_copy); - va_end(ap_copy); - if (ret > 1023) { - bigbuf = (char *)xmpp_alloc(ctx, ret + 1); - if (!bigbuf) { - bigbuf = NULL; - xmpp_error(ctx, "log", "Failed allocating memory for log message."); - return; - } - oldret = ret; + int oldret, ret; + char smbuf[1024]; + char *bigbuf = NULL; + va_list ap_copy; + + if (!ctx || !ctx->log || !ctx->log->handler) + return; + va_copy(ap_copy, ap); - ret = xmpp_vsnprintf(bigbuf, ret + 1, fmt, ap_copy); - va_end(ap_copy); - - if (ret > oldret) { - xmpp_error(ctx, "log", "Unexpected error"); - xmpp_free(ctx, bigbuf); - return; - } - - ctx->log->handler(ctx->log->userdata, level, area, bigbuf); - xmpp_free(ctx, bigbuf); - } else - ctx->log->handler(ctx->log->userdata, level, area, smbuf); + ret = xmpp_vsnprintf(smbuf, 1023, fmt, ap_copy); + va_end(ap_copy); + if (ret > 1023) { + bigbuf = (char *)xmpp_alloc(ctx, ret + 1); + if (!bigbuf) { + bigbuf = NULL; + xmpp_error(ctx, "log", "Failed allocating memory for log message."); + return; + } + oldret = ret; + va_copy(ap_copy, ap); + ret = xmpp_vsnprintf(bigbuf, ret + 1, fmt, ap_copy); + va_end(ap_copy); + + if (ret > oldret) { + xmpp_error(ctx, "log", "Unexpected error"); + xmpp_free(ctx, bigbuf); + return; + } + + ctx->log->handler(ctx->log->userdata, level, area, bigbuf); + xmpp_free(ctx, bigbuf); + } else + ctx->log->handler(ctx->log->userdata, level, area, smbuf); } /** Write to the log at the ERROR level. * This is a convenience function for writing to the log at the - * ERROR level. It takes a printf-style format string followed by a + * ERROR level. It takes a printf-style format string followed by a * variable list of arguments for formatting. * * @param ctx a Strophe context object @@ -293,15 +293,15 @@ void xmpp_log(const xmpp_ctx_t * const ctx, * arguments to format */ void xmpp_error(const xmpp_ctx_t * const ctx, - const char * const area, - const char * const fmt, - ...) + const char * const area, + const char * const fmt, + ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - xmpp_log(ctx, XMPP_LEVEL_ERROR, area, fmt, ap); - va_end(ap); + va_start(ap, fmt); + xmpp_log(ctx, XMPP_LEVEL_ERROR, area, fmt, ap); + va_end(ap); } /** Write to the log at the WARN level. @@ -315,15 +315,15 @@ void xmpp_error(const xmpp_ctx_t * const ctx, * arguments to format */ void xmpp_warn(const xmpp_ctx_t * const ctx, - const char * const area, - const char * const fmt, - ...) + const char * const area, + const char * const fmt, + ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - xmpp_log(ctx, XMPP_LEVEL_WARN, area, fmt, ap); - va_end(ap); + va_start(ap, fmt); + xmpp_log(ctx, XMPP_LEVEL_WARN, area, fmt, ap); + va_end(ap); } /** Write to the log at the INFO level. @@ -337,15 +337,15 @@ void xmpp_warn(const xmpp_ctx_t * const ctx, * arguments to format */ void xmpp_info(const xmpp_ctx_t * const ctx, - const char * const area, - const char * const fmt, - ...) + const char * const area, + const char * const fmt, + ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - xmpp_log(ctx, XMPP_LEVEL_INFO, area, fmt, ap); - va_end(ap); + va_start(ap, fmt); + xmpp_log(ctx, XMPP_LEVEL_INFO, area, fmt, ap); + va_end(ap); } /** Write to the log at the DEBUG level. @@ -359,15 +359,15 @@ void xmpp_info(const xmpp_ctx_t * const ctx, * arguments to format */ void xmpp_debug(const xmpp_ctx_t * const ctx, - const char * const area, - const char * const fmt, - ...) + const char * const area, + const char * const fmt, + ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - xmpp_log(ctx, XMPP_LEVEL_DEBUG, area, fmt, ap); - va_end(ap); + va_start(ap, fmt); + xmpp_log(ctx, XMPP_LEVEL_DEBUG, area, fmt, ap); + va_end(ap); } /** Create and initialize a Strophe context object. @@ -387,29 +387,29 @@ void xmpp_debug(const xmpp_ctx_t * const ctx, xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, const xmpp_log_t * const log) { - xmpp_ctx_t *ctx = NULL; + xmpp_ctx_t *ctx = NULL; - if (mem == NULL) - ctx = xmpp_default_mem.alloc(sizeof(xmpp_ctx_t), NULL); - else - ctx = mem->alloc(sizeof(xmpp_ctx_t), mem->userdata); + if (mem == NULL) + ctx = xmpp_default_mem.alloc(sizeof(xmpp_ctx_t), NULL); + else + ctx = mem->alloc(sizeof(xmpp_ctx_t), mem->userdata); - if (ctx != NULL) { - if (mem != NULL) - ctx->mem = mem; - else - ctx->mem = &xmpp_default_mem; + if (ctx != NULL) { + if (mem != NULL) + ctx->mem = mem; + else + ctx->mem = &xmpp_default_mem; - if (log == NULL) - ctx->log = &xmpp_default_log; - else - ctx->log = log; + if (log == NULL) + ctx->log = &xmpp_default_log; + else + ctx->log = log; - ctx->connlist = NULL; - ctx->loop_status = XMPP_LOOP_NOTSTARTED; - } + ctx->connlist = NULL; + ctx->loop_status = XMPP_LOOP_NOTSTARTED; + } - return ctx; + return ctx; } /** Free a Strophe context object that is no longer in use. @@ -420,7 +420,6 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, */ void xmpp_ctx_free(xmpp_ctx_t * const ctx) { - /* mem and log are owned by their suppliers */ - xmpp_free(ctx, ctx); /* pull the hole in after us */ + /* mem and log are owned by their suppliers */ + xmpp_free(ctx, ctx); /* pull the hole in after us */ } - From 6eb60189c74aa3234fa4371fc94545d9e4b582ae Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 01:04:28 +0300 Subject: [PATCH 22/65] ctx.c: update todo list --- src/ctx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ctx.c b/src/ctx.c index 3a0ebbfa..c65e0b11 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -262,6 +262,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, bigbuf = (char *)xmpp_alloc(ctx, ret + 1); if (!bigbuf) { bigbuf = NULL; + /* @TODO avoid recursive calls */ xmpp_error(ctx, "log", "Failed allocating memory for log message."); return; } @@ -271,6 +272,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, va_end(ap_copy); if (ret > oldret) { + /* @TODO avoid recursive calls */ xmpp_error(ctx, "log", "Unexpected error"); xmpp_free(ctx, bigbuf); return; From bded0196db41a473fad2627df2f2c9d833f51871 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 01:20:04 +0300 Subject: [PATCH 23/65] common.h: spacing --- src/common.h | 244 +++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/src/common.h b/src/common.h index e6eda6d2..00d6fb7d 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,7 @@ /* common.h ** strophe XMPP client library -- internal common structures ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express or ** implied. @@ -36,35 +36,35 @@ /** run-time context **/ typedef enum { - XMPP_LOOP_NOTSTARTED, - XMPP_LOOP_RUNNING, - XMPP_LOOP_QUIT + XMPP_LOOP_NOTSTARTED, + XMPP_LOOP_RUNNING, + XMPP_LOOP_QUIT } xmpp_loop_status_t; typedef struct _xmpp_connlist_t { - xmpp_conn_t *conn; - struct _xmpp_connlist_t *next; + xmpp_conn_t *conn; + struct _xmpp_connlist_t *next; } xmpp_connlist_t; struct _xmpp_ctx_t { - const xmpp_mem_t *mem; - const xmpp_log_t *log; + const xmpp_mem_t *mem; + const xmpp_log_t *log; - xmpp_loop_status_t loop_status; - xmpp_connlist_t *connlist; + xmpp_loop_status_t loop_status; + xmpp_connlist_t *connlist; }; /* convenience functions for accessing the context */ void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size); -void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p, +void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p, const size_t size); char *xmpp_strdup(const xmpp_ctx_t * const ctx, const char * const s); -void xmpp_log(const xmpp_ctx_t * const ctx, +void xmpp_log(const xmpp_ctx_t * const ctx, const xmpp_log_level_t level, const char * const area, - const char * const fmt, + const char * const fmt, va_list ap); /* wrappers for xmpp_log at specific levels */ @@ -88,8 +88,8 @@ void xmpp_debug(const xmpp_ctx_t * const ctx, /** jid */ /* these return new strings that must be xmpp_free()'d */ char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node, - const char *domain, - const char *resource); + const char *domain, + const char *resource); char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid); char *xmpp_jid_node(xmpp_ctx_t *ctx, const char *jid); char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid); @@ -100,118 +100,118 @@ char *xmpp_jid_resource(xmpp_ctx_t *ctx, const char *jid); /* opaque connection object */ typedef enum { - XMPP_STATE_DISCONNECTED, - XMPP_STATE_CONNECTING, - XMPP_STATE_CONNECTED + XMPP_STATE_DISCONNECTED, + XMPP_STATE_CONNECTING, + XMPP_STATE_CONNECTED } xmpp_conn_state_t; typedef struct _xmpp_send_queue_t xmpp_send_queue_t; struct _xmpp_send_queue_t { - char *data; - size_t len; - size_t written; + char *data; + size_t len; + size_t written; - xmpp_send_queue_t *next; + xmpp_send_queue_t *next; }; typedef struct _xmpp_handlist_t xmpp_handlist_t; struct _xmpp_handlist_t { - /* common members */ - int user_handler; - void *handler; - void *userdata; - int enabled; /* handlers are added disabled and enabled after the - * handler chain is processed to prevent stanzas from - * getting processed by newly added handlers */ - xmpp_handlist_t *next; - - union { - /* timed handlers */ - struct { - unsigned long period; - uint64_t last_stamp; + /* common members */ + int user_handler; + void *handler; + void *userdata; + int enabled; /* handlers are added disabled and enabled after the + * handler chain is processed to prevent stanzas from + * getting processed by newly added handlers */ + xmpp_handlist_t *next; + + union { + /* timed handlers */ + struct { + unsigned long period; + uint64_t last_stamp; + }; + /* id handlers */ + struct { + char *id; + }; + /* normal handlers */ + struct { + char *ns; + char *name; + char *type; + }; }; - /* id handlers */ - struct { - char *id; - }; - /* normal handlers */ - struct { - char *ns; - char *name; - char *type; - }; - }; }; -#define SASL_MASK_PLAIN 0x01 -#define SASL_MASK_DIGESTMD5 0x02 -#define SASL_MASK_ANONYMOUS 0x04 +#define SASL_MASK_PLAIN 0x01 +#define SASL_MASK_DIGESTMD5 0x02 +#define SASL_MASK_ANONYMOUS 0x04 typedef void (*xmpp_open_handler)(xmpp_conn_t * const conn); struct _xmpp_conn_t { - unsigned int ref; - xmpp_ctx_t *ctx; - xmpp_conn_type_t type; - - xmpp_conn_state_t state; - uint64_t timeout_stamp; - int error; - xmpp_stream_error_t *stream_error; - sock_t sock; - tls_t *tls; - - int tls_support; - int tls_disabled; - int tls_failed; /* set when tls fails, so we don't try again */ - int sasl_support; /* if true, field is a bitfield of supported - mechanisms */ - int secured; /* set when stream is secured with TLS */ - - /* if server returns or we must do them */ - int bind_required; - int session_required; - - char *lang; - char *domain; - char *connectdomain; - char *connectport; - char *jid; - char *pass; - char *bound_jid; - char *stream_id; - - /* send queue and parameters */ - int blocking_send; - int send_queue_max; - int send_queue_len; - xmpp_send_queue_t *send_queue_head; - xmpp_send_queue_t *send_queue_tail; - - /* xml parser */ - int reset_parser; - parser_t *parser; - - /* timeouts */ - unsigned int connect_timeout; - - /* event handlers */ - - /* stream open handler */ - xmpp_open_handler open_handler; - - /* user handlers only get called after authentication */ - int authenticated; + unsigned int ref; + xmpp_ctx_t *ctx; + xmpp_conn_type_t type; + + xmpp_conn_state_t state; + uint64_t timeout_stamp; + int error; + xmpp_stream_error_t *stream_error; + sock_t sock; + tls_t *tls; + + int tls_support; + int tls_disabled; + int tls_failed; /* set when tls fails, so we don't try again */ + int sasl_support; /* if true, field is a bitfield of supported + * mechanisms */ + int secured; /* set when stream is secured with TLS */ + + /* if server returns or we must do them */ + int bind_required; + int session_required; + + char *lang; + char *domain; + char *connectdomain; + char *connectport; + char *jid; + char *pass; + char *bound_jid; + char *stream_id; + + /* send queue and parameters */ + int blocking_send; + int send_queue_max; + int send_queue_len; + xmpp_send_queue_t *send_queue_head; + xmpp_send_queue_t *send_queue_tail; + + /* xml parser */ + int reset_parser; + parser_t *parser; + + /* timeouts */ + unsigned int connect_timeout; + + /* event handlers */ + + /* stream open handler */ + xmpp_open_handler open_handler; + + /* user handlers only get called after authentication */ + int authenticated; - /* connection events handler */ - xmpp_conn_handler conn_handler; - void *userdata; - - /* other handlers */ - xmpp_handlist_t *timed_handlers; - hash_t *id_handlers; - xmpp_handlist_t *handlers; + /* connection events handler */ + xmpp_conn_handler conn_handler; + void *userdata; + + /* other handlers */ + xmpp_handlist_t *timed_handlers; + hash_t *id_handlers; + xmpp_handlist_t *handlers; }; void conn_disconnect(xmpp_conn_t * const conn); @@ -222,25 +222,25 @@ void conn_parser_reset(xmpp_conn_t * const conn); typedef enum { - XMPP_STANZA_UNKNOWN, - XMPP_STANZA_TEXT, - XMPP_STANZA_TAG + XMPP_STANZA_UNKNOWN, + XMPP_STANZA_TEXT, + XMPP_STANZA_TAG } xmpp_stanza_type_t; struct _xmpp_stanza_t { - int ref; - xmpp_ctx_t *ctx; + int ref; + xmpp_ctx_t *ctx; - xmpp_stanza_type_t type; + xmpp_stanza_type_t type; - xmpp_stanza_t *prev; - xmpp_stanza_t *next; - xmpp_stanza_t *children; - xmpp_stanza_t *parent; + xmpp_stanza_t *prev; + xmpp_stanza_t *next; + xmpp_stanza_t *children; + xmpp_stanza_t *parent; - char *data; + char *data; - hash_t *attributes; + hash_t *attributes; }; /* handler management */ From b986f8cb48e05cd9d85c570b0b10b3dd8752993a Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 02:13:10 +0300 Subject: [PATCH 24/65] conn.c: spacing --- src/conn.c | 881 +++++++++++++++++++++++++++-------------------------- 1 file changed, 447 insertions(+), 434 deletions(-) diff --git a/src/conn.c b/src/conn.c index 95216c66..8a5a2d56 100644 --- a/src/conn.c +++ b/src/conn.c @@ -1,7 +1,7 @@ /* conn.c ** strophe XMPP client library -- connection object functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -12,7 +12,7 @@ ** distribution. */ -/** @file +/** @file * Connection management. */ @@ -36,7 +36,7 @@ #define DEFAULT_SEND_QUEUE_MAX 64 #endif #ifndef DISCONNECT_TIMEOUT -/** @def DISCONNECT_TIMEOUT +/** @def DISCONNECT_TIMEOUT * The time to wait (in milliseconds) for graceful disconnection to * complete before the connection is reset. The default is 2 seconds. */ @@ -44,21 +44,21 @@ #endif #ifndef CONNECT_TIMEOUT /** @def CONNECT_TIMEOUT - * The time to wait (in milliseconds) for a connection attempt to succeed + * The time to wait (in milliseconds) for a connection attempt to succeed * or error. The default is 5 seconds. */ #define CONNECT_TIMEOUT 5000 /* 5 seconds */ #endif -static int _disconnect_cleanup(xmpp_conn_t * const conn, +static int _disconnect_cleanup(xmpp_conn_t * const conn, void * const userdata); -static void _handle_stream_start(char *name, char **attrs, - void * const userdata); +static void _handle_stream_start(char *name, char **attrs, + void * const userdata); static void _handle_stream_end(char *name, - void * const userdata); + void * const userdata); static void _handle_stream_stanza(xmpp_stanza_t *stanza, - void * const userdata); + void * const userdata); /** Create a new Strophe connection object. * @@ -70,97 +70,101 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza, */ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) { - xmpp_conn_t *conn = NULL; - xmpp_connlist_t *tail, *item; + xmpp_conn_t *conn = NULL; + xmpp_connlist_t *tail, *item; - if (ctx == NULL) return NULL; + if (ctx == NULL) + return NULL; conn = xmpp_alloc(ctx, sizeof(xmpp_conn_t)); - - if (conn != NULL) { - conn->ctx = ctx; - - conn->type = XMPP_UNKNOWN; - conn->state = XMPP_STATE_DISCONNECTED; - conn->sock = -1; - conn->tls = NULL; - conn->timeout_stamp = 0; - conn->error = 0; - conn->stream_error = NULL; - - /* default send parameters */ - conn->blocking_send = 0; - conn->send_queue_max = DEFAULT_SEND_QUEUE_MAX; - conn->send_queue_len = 0; - conn->send_queue_head = NULL; - conn->send_queue_tail = NULL; - - /* default timeouts */ - conn->connect_timeout = CONNECT_TIMEOUT; - - conn->lang = xmpp_strdup(conn->ctx, "en"); - if (!conn->lang) { - xmpp_free(conn->ctx, conn); - return NULL; - } - conn->domain = NULL; - conn->jid = NULL; - conn->pass = NULL; - conn->stream_id = NULL; - conn->bound_jid = NULL; - - conn->tls_support = 0; - conn->tls_disabled = 0; - conn->tls_failed = 0; - conn->sasl_support = 0; - conn->secured = 0; - - conn->bind_required = 0; - conn->session_required = 0; - - conn->parser = parser_new(conn->ctx, - _handle_stream_start, - _handle_stream_end, - _handle_stream_stanza, - conn); - conn->reset_parser = 0; - conn_prepare_reset(conn, auth_handle_open); - - conn->authenticated = 0; - conn->conn_handler = NULL; - conn->userdata = NULL; - conn->timed_handlers = NULL; - /* we own (and will free) the hash values */ - conn->id_handlers = hash_new(conn->ctx, 32, NULL); - conn->handlers = NULL; - - /* give the caller a reference to connection */ - conn->ref = 1; - - /* add connection to ctx->connlist */ - tail = conn->ctx->connlist; - while (tail && tail->next) tail = tail->next; - - item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t)); - if (!item) { - xmpp_error(conn->ctx, "xmpp", "failed to allocate memory"); - xmpp_free(conn->ctx, conn->lang); - parser_free(conn->parser); - xmpp_free(conn->ctx, conn); - conn = NULL; - } else { - item->conn = conn; - item->next = NULL; - if (tail) tail->next = item; - else conn->ctx->connlist = item; + if (conn != NULL) { + conn->ctx = ctx; + + conn->type = XMPP_UNKNOWN; + conn->state = XMPP_STATE_DISCONNECTED; + conn->sock = -1; + conn->tls = NULL; + conn->timeout_stamp = 0; + conn->error = 0; + conn->stream_error = NULL; + + /* default send parameters */ + conn->blocking_send = 0; + conn->send_queue_max = DEFAULT_SEND_QUEUE_MAX; + conn->send_queue_len = 0; + conn->send_queue_head = NULL; + conn->send_queue_tail = NULL; + + /* default timeouts */ + conn->connect_timeout = CONNECT_TIMEOUT; + + conn->lang = xmpp_strdup(conn->ctx, "en"); + if (!conn->lang) { + xmpp_free(conn->ctx, conn); + return NULL; + } + conn->domain = NULL; + conn->jid = NULL; + conn->pass = NULL; + conn->stream_id = NULL; + conn->bound_jid = NULL; + + conn->tls_support = 0; + conn->tls_disabled = 0; + conn->tls_failed = 0; + conn->sasl_support = 0; + conn->secured = 0; + + conn->bind_required = 0; + conn->session_required = 0; + + conn->parser = parser_new(conn->ctx, + _handle_stream_start, + _handle_stream_end, + _handle_stream_stanza, + conn); + conn->reset_parser = 0; + conn_prepare_reset(conn, auth_handle_open); + + conn->authenticated = 0; + conn->conn_handler = NULL; + conn->userdata = NULL; + conn->timed_handlers = NULL; + /* we own (and will free) the hash values */ + conn->id_handlers = hash_new(conn->ctx, 32, NULL); + conn->handlers = NULL; + + /* give the caller a reference to connection */ + conn->ref = 1; + + /* add connection to ctx->connlist */ + tail = conn->ctx->connlist; + while (tail && tail->next) + tail = tail->next; + + item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t)); + if (!item) { + xmpp_error(conn->ctx, "xmpp", "failed to allocate memory"); + xmpp_free(conn->ctx, conn->lang); + parser_free(conn->parser); + xmpp_free(conn->ctx, conn); + conn = NULL; + } else { + item->conn = conn; + item->next = NULL; + + if (tail) + tail->next = item; + else + conn->ctx->connlist = item; + } } - } - - return conn; + + return conn; } /** Clone a Strophe connection object. - * + * * @param conn a Strophe connection object * * @return the same conn object passed in with its reference count @@ -170,12 +174,12 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) */ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) { - conn->ref++; - return conn; + conn->ref++; + return conn; } /** Release a Strophe connection object. - * Decrement the reference count by one for a connection, freeing the + * Decrement the reference count by one for a connection, freeing the * connection object if the count reaches 0. * * @param conn a Strophe connection object @@ -186,103 +190,105 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) */ int xmpp_conn_release(xmpp_conn_t * const conn) { - xmpp_ctx_t *ctx; - xmpp_connlist_t *item, *prev; - xmpp_handlist_t *hlitem, *thli; - hash_iterator_t *iter; - const char *key; - int released = 0; - - if (conn->ref > 1) - conn->ref--; - else { - ctx = conn->ctx; - - /* remove connection from context's connlist */ - if (ctx->connlist->conn == conn) { - item = ctx->connlist; - ctx->connlist = item->next; - xmpp_free(ctx, item); - } else { - prev = NULL; - item = ctx->connlist; - while (item && item->conn != conn) { - prev = item; - item = item->next; - } - - if (!item) { - xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); - } else { - prev->next = item->next; - xmpp_free(ctx, item); - } + xmpp_ctx_t *ctx; + xmpp_connlist_t *item, *prev; + xmpp_handlist_t *hlitem, *thli; + hash_iterator_t *iter; + const char *key; + int released = 0; + + if (conn->ref > 1) + conn->ref--; + else { + ctx = conn->ctx; + + /* remove connection from context's connlist */ + if (ctx->connlist->conn == conn) { + item = ctx->connlist; + ctx->connlist = item->next; + xmpp_free(ctx, item); + } else { + prev = NULL; + item = ctx->connlist; + while (item && item->conn != conn) { + prev = item; + item = item->next; + } + + if (item) { + prev->next = item->next; + xmpp_free(ctx, item); + } else + xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); + } + + /* free handler stuff + * note that userdata is the responsibility of the client + * and the handler pointers don't need to be freed since they + * are pointers to functions */ + + hlitem = conn->timed_handlers; + while (hlitem) { + thli = hlitem; + hlitem = hlitem->next; + + xmpp_free(ctx, thli); + } + + /* id handlers + * we have to traverse the hash table freeing list elements + * then release the hash table */ + iter = hash_iter_new(conn->id_handlers); + while ((key = hash_iter_next(iter))) { + hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key); + while (hlitem) { + thli = hlitem; + hlitem = hlitem->next; + xmpp_free(conn->ctx, thli->id); + xmpp_free(conn->ctx, thli); + } + } + hash_iter_release(iter); + hash_release(conn->id_handlers); + + hlitem = conn->handlers; + while (hlitem) { + thli = hlitem; + hlitem = hlitem->next; + + if (thli->ns) + xmpp_free(ctx, thli->ns); + if (thli->name) + xmpp_free(ctx, thli->name); + if (thli->type) + xmpp_free(ctx, thli->type); + xmpp_free(ctx, thli); + } + + if (conn->stream_error) { + xmpp_stanza_release(conn->stream_error->stanza); + if (conn->stream_error->text) + xmpp_free(ctx, conn->stream_error->text); + xmpp_free(ctx, conn->stream_error); + } + + parser_free(conn->parser); + + if (conn->domain) xmpp_free(ctx, conn->domain); + if (conn->jid) xmpp_free(ctx, conn->jid); + if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); + if (conn->pass) xmpp_free(ctx, conn->pass); + if (conn->stream_id) xmpp_free(ctx, conn->stream_id); + if (conn->lang) xmpp_free(ctx, conn->lang); + xmpp_free(ctx, conn); + released = 1; } - /* free handler stuff - * note that userdata is the responsibility of the client - * and the handler pointers don't need to be freed since they - * are pointers to functions */ - - hlitem = conn->timed_handlers; - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - - xmpp_free(ctx, thli); - } - - /* id handlers - * we have to traverse the hash table freeing list elements - * then release the hash table */ - iter = hash_iter_new(conn->id_handlers); - while ((key = hash_iter_next(iter))) { - hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key); - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - xmpp_free(conn->ctx, thli->id); - xmpp_free(conn->ctx, thli); - } - } - hash_iter_release(iter); - hash_release(conn->id_handlers); - - hlitem = conn->handlers; - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - - if (thli->ns) xmpp_free(ctx, thli->ns); - if (thli->name) xmpp_free(ctx, thli->name); - if (thli->type) xmpp_free(ctx, thli->type); - xmpp_free(ctx, thli); - } - - if (conn->stream_error) { - xmpp_stanza_release(conn->stream_error->stanza); - if (conn->stream_error->text) - xmpp_free(ctx, conn->stream_error->text); - xmpp_free(ctx, conn->stream_error); - } - - parser_free(conn->parser); - - if (conn->domain) xmpp_free(ctx, conn->domain); - if (conn->jid) xmpp_free(ctx, conn->jid); - if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); - if (conn->pass) xmpp_free(ctx, conn->pass); - if (conn->stream_id) xmpp_free(ctx, conn->stream_id); - if (conn->lang) xmpp_free(ctx, conn->lang); - xmpp_free(ctx, conn); - released = 1; - } - - return released; + return released; } /** Get the JID which is or will be bound to the connection. - * + * * @param conn a Strophe connection object * * @return a string containing the full JID or NULL if it has not been set @@ -291,7 +297,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn) */ const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn) { - return conn->jid; + return conn->jid; } /** @@ -309,11 +315,11 @@ const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn) */ const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn) { - return conn->bound_jid; + return conn->bound_jid; } /** Set the JID of the user that will be bound to the connection. - * If any JID was previously set, it will be discarded. This should not be + * If any JID was previously set, it will be discarded. This should not be * be used after a connection is created. The function will make a copy of * the JID string. If the supllied JID is missing the node, SASL * ANONYMOUS authentication will be used. @@ -325,8 +331,9 @@ const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn) */ void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid) { - if (conn->jid) xmpp_free(conn->ctx, conn->jid); - conn->jid = xmpp_strdup(conn->ctx, jid); + if (conn->jid) + xmpp_free(conn->ctx, conn->jid); + conn->jid = xmpp_strdup(conn->ctx, jid); } /** Get the password used for authentication of a connection. @@ -339,13 +346,13 @@ void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid) */ const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn) { - return conn->pass; + return conn->pass; } /** Set the password used to authenticate the connection. * If any password was previously set, it will be discarded. The function * will make a copy of the password string. - * + * * @param conn a Strophe connection object * @param pass the password * @@ -353,15 +360,16 @@ const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn) */ void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass) { - if (conn->pass) xmpp_free(conn->ctx, conn->pass); - conn->pass = xmpp_strdup(conn->ctx, pass); + if (conn->pass) + xmpp_free(conn->ctx, conn->pass); + conn->pass = xmpp_strdup(conn->ctx, pass); } /** Get the strophe context that the connection is associated with. * @param conn a Strophe connection object -* +* * @return a Strophe context -* +* * @ingroup Connections */ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn) @@ -374,7 +382,7 @@ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn) * process to the XMPP server, and notifiations of connection state changes * will be sent to the callback function. The domain and port to connect to * are usually determined by an SRV lookup for the xmpp-client service at - * the domain specified in the JID. If SRV lookup fails, altdomain and + * the domain specified in the JID. If SRV lookup fails, altdomain and * altport will be used instead if specified. * * @param conn a Strophe connection object @@ -390,56 +398,58 @@ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn) * * @ingroup Connections */ -int xmpp_connect_client(xmpp_conn_t * const conn, +int xmpp_connect_client(xmpp_conn_t * const conn, const char * const altdomain, unsigned short altport, xmpp_conn_handler callback, void * const userdata) { - char connectdomain[2048]; - int connectport; - const char * domain; - - conn->type = XMPP_CLIENT; - - conn->domain = xmpp_jid_domain(conn->ctx, conn->jid); - if (!conn->domain) return -1; - - if (altdomain) { - xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); - strcpy(connectdomain, altdomain); - connectport = altport ? altport : 5222; - } else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain, - connectdomain, 2048, &connectport)) { - xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed."); - if (!altdomain) - domain = conn->domain; - else - domain = altdomain; - xmpp_debug(conn->ctx, "xmpp", "Using alternate domain %s, port %d", - altdomain, altport); - strcpy(connectdomain, domain); - connectport = altport ? altport : 5222; - } - conn->sock = sock_connect(connectdomain, connectport); - xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d", - connectdomain, connectport, conn->sock); - if (conn->sock == -1) return -1; - - /* setup handler */ - conn->conn_handler = callback; - conn->userdata = userdata; - - /* FIXME: it could happen that the connect returns immediately as - * successful, though this is pretty unlikely. This would be a little - * hard to fix, since we'd have to detect and fire off the callback - * from within the event loop */ - - conn->state = XMPP_STATE_CONNECTING; - conn->timeout_stamp = time_stamp(); - xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", connectdomain); - - return 0; + char connectdomain[2048]; + int connectport; + const char * domain; + + conn->type = XMPP_CLIENT; + + conn->domain = xmpp_jid_domain(conn->ctx, conn->jid); + if (!conn->domain) + return -1; + + if (altdomain) { + xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); + strcpy(connectdomain, altdomain); + connectport = altport ? altport : 5222; + } else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain, + connectdomain, 2048, &connectport)) { + xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed."); + if (!altdomain) + domain = conn->domain; + else + domain = altdomain; + xmpp_debug(conn->ctx, "xmpp", "Using alternate domain %s, port %d", + altdomain, altport); + strcpy(connectdomain, domain); + connectport = altport ? altport : 5222; + } + conn->sock = sock_connect(connectdomain, connectport); + xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d", + connectdomain, connectport, conn->sock); + if (conn->sock == -1) + return -1; + + /* setup handler */ + conn->conn_handler = callback; + conn->userdata = userdata; + + /* FIXME: it could happen that the connect returns immediately as + * successful, though this is pretty unlikely. This would be a little + * hard to fix, since we'd have to detect and fire off the callback + * from within the event loop */ + + conn->state = XMPP_STATE_CONNECTING; + conn->timeout_stamp = time_stamp(); + xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", connectdomain); + + return 0; } /** Cleanly disconnect the connection. @@ -450,10 +460,10 @@ int xmpp_connect_client(xmpp_conn_t * const conn, */ void conn_disconnect_clean(xmpp_conn_t * const conn) { - /* remove the timed handler */ - xmpp_timed_handler_delete(conn, _disconnect_cleanup); + /* remove the timed handler */ + xmpp_timed_handler_delete(conn, _disconnect_cleanup); - conn_disconnect(conn); + conn_disconnect(conn); } /** Disconnect from the XMPP server. @@ -462,47 +472,45 @@ void conn_disconnect_clean(xmpp_conn_t * const conn) * * @param conn a Strophe connection object */ -void conn_disconnect(xmpp_conn_t * const conn) +void conn_disconnect(xmpp_conn_t * const conn) { - xmpp_debug(conn->ctx, "xmpp", "Closing socket."); - conn->state = XMPP_STATE_DISCONNECTED; - if (conn->tls) { - tls_stop(conn->tls); - tls_free(conn->tls); - conn->tls = NULL; - } - sock_close(conn->sock); - - /* fire off connection handler */ - conn->conn_handler(conn, XMPP_CONN_DISCONNECT, conn->error, - conn->stream_error, conn->userdata); + xmpp_debug(conn->ctx, "xmpp", "Closing socket."); + conn->state = XMPP_STATE_DISCONNECTED; + if (conn->tls) { + tls_stop(conn->tls); + tls_free(conn->tls); + conn->tls = NULL; + } + sock_close(conn->sock); + + /* fire off connection handler */ + conn->conn_handler(conn, XMPP_CONN_DISCONNECT, conn->error, + conn->stream_error, conn->userdata); } /* prepares a parser reset. this is called from handlers. we can't * reset the parser immediately as it is not re-entrant. */ void conn_prepare_reset(xmpp_conn_t * const conn, xmpp_open_handler handler) { - conn->reset_parser = 1; - conn->open_handler = handler; + conn->reset_parser = 1; + conn->open_handler = handler; } /* reset the parser */ void conn_parser_reset(xmpp_conn_t * const conn) { - conn->reset_parser = 0; - parser_reset(conn->parser); + conn->reset_parser = 0; + parser_reset(conn->parser); } /* timed handler for cleanup if normal disconnect procedure takes too long */ -static int _disconnect_cleanup(xmpp_conn_t * const conn, +static int _disconnect_cleanup(xmpp_conn_t * const conn, void * const userdata) { - xmpp_debug(conn->ctx, "xmpp", - "disconnection forced by cleanup timeout"); - - conn_disconnect(conn); + xmpp_debug(conn->ctx, "xmpp", "disconnection forced by cleanup timeout"); + conn_disconnect(conn); - return 0; + return 0; } /** Initiate termination of the connection to the XMPP server. @@ -516,20 +524,20 @@ static int _disconnect_cleanup(xmpp_conn_t * const conn, */ void xmpp_disconnect(xmpp_conn_t * const conn) { - if (conn->state != XMPP_STATE_CONNECTING && - conn->state != XMPP_STATE_CONNECTED) - return; + if (conn->state != XMPP_STATE_CONNECTING && + conn->state != XMPP_STATE_CONNECTED) + return; - /* close the stream */ - xmpp_send_raw_string(conn, ""); + /* close the stream */ + xmpp_send_raw_string(conn, ""); - /* setup timed handler in case disconnect takes too long */ - handler_add_timed(conn, _disconnect_cleanup, - DISCONNECT_TIMEOUT, NULL); + /* setup timed handler in case disconnect takes too long */ + handler_add_timed(conn, _disconnect_cleanup, + DISCONNECT_TIMEOUT, NULL); } /** Send a raw string to the XMPP server. - * This function is a convenience function to send raw string data to the + * This function is a convenience function to send raw string data to the * XMPP server. It is used by Strophe to send short messages instead of * building up an XML stanza with DOM methods. This should be used with care * as it does not validate the data; invalid data may result in immediate @@ -539,47 +547,46 @@ void xmpp_disconnect(xmpp_conn_t * const conn) * @param fmt a printf-style format string followed by a variable list of * arguments to format */ -void xmpp_send_raw_string(xmpp_conn_t * const conn, +void xmpp_send_raw_string(xmpp_conn_t * const conn, const char * const fmt, ...) { - va_list ap; - size_t len; - char buf[1024]; /* small buffer for common case */ - char *bigbuf; - - va_start(ap, fmt); - len = xmpp_vsnprintf(buf, 1024, fmt, ap); - va_end(ap); - - if (len >= 1024) { - /* we need more space for this data, so we allocate a big - * enough buffer and print to that */ - len++; /* account for trailing \0 */ - bigbuf = xmpp_alloc(conn->ctx, len); - if (!bigbuf) { - xmpp_debug(conn->ctx, "xmpp", "Could not allocate memory for send_raw_string"); - return; - } + va_list ap; + size_t len; + char buf[1024]; /* small buffer for common case */ + char *bigbuf; + va_start(ap, fmt); - xmpp_vsnprintf(bigbuf, len, fmt, ap); + len = xmpp_vsnprintf(buf, 1024, fmt, ap); va_end(ap); - xmpp_debug(conn->ctx, "conn", "SENT: %s", bigbuf); - - /* len - 1 so we don't send trailing \0 */ - xmpp_send_raw(conn, bigbuf, len - 1); - - xmpp_free(conn->ctx, bigbuf); - } else { - xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); - - xmpp_send_raw(conn, buf, len); - } + if (len >= 1024) { + /* we need more space for this data, so we allocate a big + * enough buffer and print to that */ + len++; /* account for trailing \0 */ + bigbuf = xmpp_alloc(conn->ctx, len); + if (!bigbuf) { + xmpp_debug(conn->ctx, "xmpp", + "Could not allocate memory for send_raw_string"); + return; + } + va_start(ap, fmt); + xmpp_vsnprintf(bigbuf, len, fmt, ap); + va_end(ap); + + xmpp_debug(conn->ctx, "conn", "SENT: %s", bigbuf); + /* len - 1 so we don't send trailing \0 */ + xmpp_send_raw(conn, bigbuf, len - 1); + + xmpp_free(conn->ctx, bigbuf); + } else { + xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); + xmpp_send_raw(conn, buf, len); + } } /** Send raw bytes to the XMPP server. - * This function is a convenience function to send raw bytes to the - * XMPP server. It is usedly primarly by xmpp_send_raw_string. This + * This function is a convenience function to send raw bytes to the + * XMPP server. It is usedly primarly by xmpp_send_raw_string. This * function should be used with care as it does not validate the bytes and * invalid data may result in stream termination by the XMPP server. * @@ -590,35 +597,37 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn, void xmpp_send_raw(xmpp_conn_t * const conn, const char * const data, const size_t len) { - xmpp_send_queue_t *item; - - if (conn->state != XMPP_STATE_CONNECTED) return; - - /* create send queue item for queue */ - item = xmpp_alloc(conn->ctx, sizeof(xmpp_send_queue_t)); - if (!item) return; - - item->data = xmpp_alloc(conn->ctx, len); - if (!item->data) { - xmpp_free(conn->ctx, item); - return; - } - memcpy(item->data, data, len); - item->len = len; - item->next = NULL; - item->written = 0; - - /* add item to the send queue */ - if (!conn->send_queue_tail) { - /* first item, set head and tail */ - conn->send_queue_head = item; - conn->send_queue_tail = item; - } else { - /* add to the tail */ - conn->send_queue_tail->next = item; - conn->send_queue_tail = item; - } - conn->send_queue_len++; + xmpp_send_queue_t *item; + + if (conn->state != XMPP_STATE_CONNECTED) + return; + + /* create send queue item for queue */ + item = xmpp_alloc(conn->ctx, sizeof(xmpp_send_queue_t)); + if (!item) + return; + + item->data = xmpp_alloc(conn->ctx, len); + if (!item->data) { + xmpp_free(conn->ctx, item); + return; + } + memcpy(item->data, data, len); + item->len = len; + item->next = NULL; + item->written = 0; + + /* add item to the send queue */ + if (!conn->send_queue_tail) { + /* first item, set head and tail */ + conn->send_queue_head = item; + conn->send_queue_tail = item; + } else { + /* add to the tail */ + conn->send_queue_tail->next = item; + conn->send_queue_tail = item; + } + conn->send_queue_len++; } /** Send an XML stanza to the XMPP server. @@ -633,17 +642,15 @@ void xmpp_send_raw(xmpp_conn_t * const conn, void xmpp_send(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza) { - char *buf; - size_t len; - int ret; - - if (conn->state == XMPP_STATE_CONNECTED) { - if ((ret = xmpp_stanza_to_text(stanza, &buf, &len)) == 0) { - xmpp_send_raw(conn, buf, len); - xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); - xmpp_free(conn->ctx, buf); + char *buf; + size_t len; + + if (conn->state == XMPP_STATE_CONNECTED && + xmpp_stanza_to_text(stanza, &buf, &len) == 0) { + xmpp_send_raw(conn, buf, len); + xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); + xmpp_free(conn->ctx, buf); } - } } /** Send the opening <stream:stream> tag to the server. @@ -654,17 +661,17 @@ void xmpp_send(xmpp_conn_t * const conn, */ void conn_open_stream(xmpp_conn_t * const conn) { - xmpp_send_raw_string(conn, - "" \ - "", - conn->domain, - conn->lang, - conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT, - XMPP_NS_STREAMS); + xmpp_send_raw_string(conn, + "" \ + "", + conn->domain, + conn->lang, + conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT, + XMPP_NS_STREAMS); } /** Disable TLS for this connection, called by users of the library. @@ -675,100 +682,106 @@ void conn_open_stream(xmpp_conn_t * const conn) */ void xmpp_conn_disable_tls(xmpp_conn_t * const conn) { - conn->tls_disabled = 1; + conn->tls_disabled = 1; } static void _log_open_tag(xmpp_conn_t *conn, char **attrs) { - char buf[4096]; - size_t pos; - int len; - int i; - - if (!attrs) return; - - pos = 0; - len = xmpp_snprintf(buf, 4096, ""); - if (len < 0) return; - - xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf); + char buf[4096]; + size_t pos; + int len; + int i; + + if (!attrs) + return; + + pos = 0; + len = xmpp_snprintf(buf, 4096, ""); + if (len < 0) + return; + + xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf); } static char *_get_stream_attribute(char **attrs, char *name) { - int i; + int i; - if (!attrs) return NULL; + if (!attrs) + return NULL; - for (i = 0; attrs[i]; i += 2) - if (strcmp(name, attrs[i]) == 0) - return attrs[i+1]; + for (i = 0; attrs[i]; i += 2) + if (strcmp(name, attrs[i]) == 0) + return attrs[i+1]; - return NULL; + return NULL; } -static void _handle_stream_start(char *name, char **attrs, - void * const userdata) +static void _handle_stream_start(char *name, char **attrs, + void * const userdata) { - xmpp_conn_t *conn = (xmpp_conn_t *)userdata; - char *id; - - if (strcmp(name, "stream:stream") != 0) { - printf("name = %s\n", name); - xmpp_error(conn->ctx, "conn", "Server did not open valid stream."); - conn_disconnect(conn); - } else { - _log_open_tag(conn, attrs); - - if (conn->stream_id) xmpp_free(conn->ctx, conn->stream_id); - - id = _get_stream_attribute(attrs, "id"); - if (id) - conn->stream_id = xmpp_strdup(conn->ctx, id); - - if (!conn->stream_id) { - xmpp_error(conn->ctx, "conn", "Memory allocation failed."); - conn_disconnect(conn); - } - } - - /* call stream open handler */ - conn->open_handler(conn); + xmpp_conn_t *conn = (xmpp_conn_t *)userdata; + char *id; + + if (strcmp(name, "stream:stream") != 0) { + printf("name = %s\n", name); + xmpp_error(conn->ctx, "conn", "Server did not open valid stream."); + conn_disconnect(conn); + } else { + _log_open_tag(conn, attrs); + + if (conn->stream_id) + xmpp_free(conn->ctx, conn->stream_id); + + id = _get_stream_attribute(attrs, "id"); + if (id) + conn->stream_id = xmpp_strdup(conn->ctx, id); + + if (!conn->stream_id) { + xmpp_error(conn->ctx, "conn", "Memory allocation failed."); + conn_disconnect(conn); + } + } + + /* call stream open handler */ + conn->open_handler(conn); } static void _handle_stream_end(char *name, - void * const userdata) + void * const userdata) { - xmpp_conn_t *conn = (xmpp_conn_t *)userdata; + xmpp_conn_t *conn = (xmpp_conn_t *)userdata; - /* stream is over */ - xmpp_debug(conn->ctx, "xmpp", "RECV: "); - conn_disconnect_clean(conn); + /* stream is over */ + xmpp_debug(conn->ctx, "xmpp", "RECV: "); + conn_disconnect_clean(conn); } static void _handle_stream_stanza(xmpp_stanza_t *stanza, - void * const userdata) + void * const userdata) { - xmpp_conn_t *conn = (xmpp_conn_t *)userdata; - char *buf; - size_t len; + xmpp_conn_t *conn = (xmpp_conn_t *)userdata; + char *buf; + size_t len; - if (xmpp_stanza_to_text(stanza, &buf, &len) == 0) { - xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf); - xmpp_free(conn->ctx, buf); - } + if (xmpp_stanza_to_text(stanza, &buf, &len) == 0) { + xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf); + xmpp_free(conn->ctx, buf); + } - handler_fire_stanza(conn, stanza); + handler_fire_stanza(conn, stanza); } From 57c28e0c0c7970778d333c7e5ad8c8a10c166c26 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 14:21:24 +0300 Subject: [PATCH 25/65] event.c: spacing --- src/event.c | 440 ++++++++++++++++++++++++++-------------------------- 1 file changed, 219 insertions(+), 221 deletions(-) diff --git a/src/event.c b/src/event.c index ffbd9f6b..1546907a 100644 --- a/src/event.c +++ b/src/event.c @@ -74,244 +74,242 @@ */ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) { - xmpp_connlist_t *connitem; - xmpp_conn_t *conn; - fd_set rfds, wfds; - sock_t max = 0; - int ret; - struct timeval tv; - xmpp_send_queue_t *sq, *tsq; - int towrite; - char buf[4096]; - uint64_t next; - long usec; - int tls_read_bytes = 0; - - if (ctx->loop_status == XMPP_LOOP_QUIT) return; - ctx->loop_status = XMPP_LOOP_RUNNING; - - /* send queued data */ - connitem = ctx->connlist; - while (connitem) { - conn = connitem->conn; - if (conn->state != XMPP_STATE_CONNECTED) { - connitem = connitem->next; - continue; - } + xmpp_connlist_t *connitem; + xmpp_conn_t *conn; + fd_set rfds, wfds; + sock_t max = 0; + int ret; + struct timeval tv; + xmpp_send_queue_t *sq, *tsq; + int towrite; + char buf[4096]; + uint64_t next; + long usec; + int tls_read_bytes = 0; + + if (ctx->loop_status == XMPP_LOOP_QUIT) + return; + ctx->loop_status = XMPP_LOOP_RUNNING; + + /* send queued data */ + connitem = ctx->connlist; + while (connitem) { + conn = connitem->conn; + if (conn->state != XMPP_STATE_CONNECTED) { + connitem = connitem->next; + continue; + } - /* if we're running tls, there may be some remaining data waiting to - * be sent, so push that out */ - if (conn->tls) { - ret = tls_clear_pending_write(conn->tls); - - if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) { - /* an error occured */ - xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting."); - conn->error = ECONNABORTED; - conn_disconnect(conn); - } - } + /* if we're running tls, there may be some remaining data waiting to + * be sent, so push that out */ + if (conn->tls) { + ret = tls_clear_pending_write(conn->tls); - /* write all data from the send queue to the socket */ - sq = conn->send_queue_head; - while (sq) { - towrite = sq->len - sq->written; - - if (conn->tls) { - ret = tls_write(conn->tls, &sq->data[sq->written], towrite); - - if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) { - /* an error occured */ - conn->error = tls_error(conn->tls); - break; - } else if (ret < towrite) { - /* not all data could be sent now */ - if (ret >= 0) sq->written += ret; - break; + if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) { + /* an error occured */ + xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting."); + conn->error = ECONNABORTED; + conn_disconnect(conn); + } } - } else { - ret = sock_write(conn->sock, &sq->data[sq->written], towrite); - - if (ret < 0 && !sock_is_recoverable(sock_error())) { - /* an error occured */ - conn->error = sock_error(); - break; - } else if (ret < towrite) { - /* not all data could be sent now */ - if (ret >= 0) sq->written += ret; - break; + /* write all data from the send queue to the socket */ + sq = conn->send_queue_head; + while (sq) { + towrite = sq->len - sq->written; + + if (conn->tls) { + ret = tls_write(conn->tls, &sq->data[sq->written], towrite); + + if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) { + /* an error occured */ + conn->error = tls_error(conn->tls); + break; + } else if (ret < towrite) { + /* not all data could be sent now */ + if (ret >= 0) + sq->written += ret; + break; + } + + } else { + ret = sock_write(conn->sock, &sq->data[sq->written], towrite); + + if (ret < 0 && !sock_is_recoverable(sock_error())) { + /* an error occured */ + conn->error = sock_error(); + break; + } else if (ret < towrite) { + /* not all data could be sent now */ + if (ret >= 0) + sq->written += ret; + break; + } + } + + /* all data for this queue item written, delete and move on */ + xmpp_free(ctx, sq->data); + tsq = sq; + sq = sq->next; + xmpp_free(ctx, tsq); + + /* pop the top item */ + conn->send_queue_head = sq; + /* if we've sent everything update the tail */ + if (!sq) + conn->send_queue_tail = NULL; } - } - - /* all data for this queue item written, delete and move on */ - xmpp_free(ctx, sq->data); - tsq = sq; - sq = sq->next; - xmpp_free(ctx, tsq); - - /* pop the top item */ - conn->send_queue_head = sq; - /* if we've sent everything update the tail */ - if (!sq) conn->send_queue_tail = NULL; - } - /* tear down connection on error */ - if (conn->error) { - /* FIXME: need to tear down send queues and random other things - * maybe this should be abstracted */ - xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting."); - conn->error = ECONNABORTED; - conn_disconnect(conn); - } + /* tear down connection on error */ + if (conn->error) { + /* FIXME: need to tear down send queues and random other things + * maybe this should be abstracted */ + xmpp_debug(ctx, "xmpp", "Send error occured, disconnecting."); + conn->error = ECONNABORTED; + conn_disconnect(conn); + } - connitem = connitem->next; - } - - /* reset parsers if needed */ - for (connitem = ctx->connlist; connitem; connitem = connitem->next) { - if (connitem->conn->reset_parser) - conn_parser_reset(connitem->conn); - } + connitem = connitem->next; + } + /* reset parsers if needed */ + for (connitem = ctx->connlist; connitem; connitem = connitem->next) + if (connitem->conn->reset_parser) + conn_parser_reset(connitem->conn); - /* fire any ready timed handlers, then - make sure we don't wait past the time when timed handlers need - to be called */ - next = handler_fire_timed(ctx); + /* fire any ready timed handlers, then + * make sure we don't wait past the time when timed handlers need + * to be called */ + next = handler_fire_timed(ctx); - usec = ((next < timeout) ? next : timeout) * 1000; - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; + usec = ((next < timeout) ? next : timeout) * 1000; + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; - FD_ZERO(&rfds); - FD_ZERO(&wfds); + FD_ZERO(&rfds); + FD_ZERO(&wfds); - /* find events to watch */ - connitem = ctx->connlist; - while (connitem) { - conn = connitem->conn; + /* find events to watch */ + connitem = ctx->connlist; + while (connitem) { + conn = connitem->conn; - switch (conn->state) { - case XMPP_STATE_CONNECTING: - /* connect has been called and we're waiting for it to complete */ - /* connection will give us write or error events */ + switch (conn->state) { + case XMPP_STATE_CONNECTING: + /* connect has been called and we're waiting for it to complete */ + /* connection will give us write or error events */ - /* make sure the timeout hasn't expired */ - if (time_elapsed(conn->timeout_stamp, time_stamp()) <= - conn->connect_timeout) - FD_SET(conn->sock, &wfds); - else { - conn->error = ETIMEDOUT; - xmpp_info(ctx, "xmpp", "Connection attempt timed out."); - conn_disconnect(conn); - } - break; - case XMPP_STATE_CONNECTED: - FD_SET(conn->sock, &rfds); - break; - case XMPP_STATE_DISCONNECTED: - /* do nothing */ - default: - break; - } + /* make sure the timeout hasn't expired */ + if (time_elapsed(conn->timeout_stamp, time_stamp()) <= + conn->connect_timeout) + FD_SET(conn->sock, &wfds); + else { + conn->error = ETIMEDOUT; + xmpp_info(ctx, "xmpp", "Connection attempt timed out."); + conn_disconnect(conn); + } + break; + case XMPP_STATE_CONNECTED: + FD_SET(conn->sock, &rfds); + break; + case XMPP_STATE_DISCONNECTED: + /* do nothing */ + default: + break; + } - /* Check if there is something in the SSL buffer. */ - if (conn->tls) { - tls_read_bytes += tls_pending(conn->tls); - } + /* Check if there is something in the SSL buffer. */ + if (conn->tls) + tls_read_bytes += tls_pending(conn->tls); - if (conn->sock > max) max = conn->sock; + if (conn->sock > max) + max = conn->sock; - connitem = connitem->next; - } + connitem = connitem->next; + } - /* check for events */ - ret = select(max + 1, &rfds, &wfds, NULL, &tv); + /* check for events */ + ret = select(max + 1, &rfds, &wfds, NULL, &tv); - /* select errored */ - if (ret < 0) { - if (!sock_is_recoverable(sock_error())) - xmpp_error(ctx, "xmpp", "event watcher internal error %d", - sock_error()); - return; - } + /* select errored */ + if (ret < 0) { + if (!sock_is_recoverable(sock_error())) + xmpp_error(ctx, "xmpp", "event watcher internal error %d", + sock_error()); + return; + } - /* no events happened */ - if (ret == 0 && tls_read_bytes == 0) return; - - /* process events */ - connitem = ctx->connlist; - while (connitem) { - conn = connitem->conn; - - switch (conn->state) { - case XMPP_STATE_CONNECTING: - if (FD_ISSET(conn->sock, &wfds)) { - /* connection complete */ - - /* check for error */ - if (sock_connect_error(conn->sock) != 0) { - /* connection failed */ - xmpp_debug(ctx, "xmpp", "connection failed"); - conn_disconnect(conn); - break; - } - - conn->state = XMPP_STATE_CONNECTED; - xmpp_debug(ctx, "xmpp", "connection successful"); - - - /* send stream init */ - conn_open_stream(conn); - } - - break; - case XMPP_STATE_CONNECTED: - if (FD_ISSET(conn->sock, &rfds) || (conn->tls && tls_pending(conn->tls))) { - if (conn->tls) { - ret = tls_read(conn->tls, buf, 4096); - } else { - ret = sock_read(conn->sock, buf, 4096); - } + /* no events happened */ + if (ret == 0 && tls_read_bytes == 0) + return; + + /* process events */ + connitem = ctx->connlist; + while (connitem) { + conn = connitem->conn; + + switch (conn->state) { + case XMPP_STATE_CONNECTING: + if (FD_ISSET(conn->sock, &wfds)) { + /* connection complete */ + + /* check for error */ + if (sock_connect_error(conn->sock) != 0) { + /* connection failed */ + xmpp_debug(ctx, "xmpp", "connection failed"); + conn_disconnect(conn); + break; + } + + conn->state = XMPP_STATE_CONNECTED; + xmpp_debug(ctx, "xmpp", "connection successful"); + + /* send stream init */ + conn_open_stream(conn); + } - if (ret > 0) { - ret = parser_feed(conn->parser, buf, ret); - if (!ret) { - /* parse error, we need to shut down */ - /* FIXME */ - xmpp_debug(ctx, "xmpp", "parse error, disconnecting"); - conn_disconnect(conn); - } - } else { - if (conn->tls) { - if (!tls_is_recoverable(tls_error(conn->tls))) - { - xmpp_debug(ctx, "xmpp", "Unrecoverable TLS error, %d.", tls_error(conn->tls)); - conn->error = tls_error(conn->tls); - conn_disconnect(conn); + break; + case XMPP_STATE_CONNECTED: + if (FD_ISSET(conn->sock, &rfds) || (conn->tls && tls_pending(conn->tls))) { + if (conn->tls) + ret = tls_read(conn->tls, buf, 4096); + else + ret = sock_read(conn->sock, buf, 4096); + + if (ret > 0) { + ret = parser_feed(conn->parser, buf, ret); + if (!ret) { + /* parse error, we need to shut down */ + /* FIXME */ + xmpp_debug(ctx, "xmpp", "parse error, disconnecting"); + conn_disconnect(conn); + } + } else if (conn->tls) { + if (!tls_is_recoverable(tls_error(conn->tls))) { + xmpp_debug(ctx, "xmpp", "Unrecoverable TLS error, %d.", tls_error(conn->tls)); + conn->error = tls_error(conn->tls); + conn_disconnect(conn); + } + } else { + /* return of 0 means socket closed by server */ + xmpp_debug(ctx, "xmpp", "Socket closed by remote host."); + conn->error = ECONNRESET; + conn_disconnect(conn); + } } - } else { - /* return of 0 means socket closed by server */ - xmpp_debug(ctx, "xmpp", "Socket closed by remote host."); - conn->error = ECONNRESET; - conn_disconnect(conn); - } + + break; + case XMPP_STATE_DISCONNECTED: + /* do nothing */ + default: + break; } - } - break; - case XMPP_STATE_DISCONNECTED: - /* do nothing */ - default: - break; + connitem = connitem->next; } - connitem = connitem->next; - } - - /* fire any ready handlers */ - handler_fire_timed(ctx); + /* fire any ready handlers */ + handler_fire_timed(ctx); } /** Start the event loop. @@ -324,14 +322,14 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) */ void xmpp_run(xmpp_ctx_t *ctx) { - if (ctx->loop_status != XMPP_LOOP_NOTSTARTED) return; + if (ctx->loop_status != XMPP_LOOP_NOTSTARTED) + return; - ctx->loop_status = XMPP_LOOP_RUNNING; - while (ctx->loop_status == XMPP_LOOP_RUNNING) { - xmpp_run_once(ctx, DEFAULT_TIMEOUT); - } + ctx->loop_status = XMPP_LOOP_RUNNING; + while (ctx->loop_status == XMPP_LOOP_RUNNING) + xmpp_run_once(ctx, DEFAULT_TIMEOUT); - xmpp_debug(ctx, "event", "Event loop completed."); + xmpp_debug(ctx, "event", "Event loop completed."); } /** Stop the event loop. @@ -344,8 +342,8 @@ void xmpp_run(xmpp_ctx_t *ctx) */ void xmpp_stop(xmpp_ctx_t *ctx) { - xmpp_debug(ctx, "event", "Stopping event loop."); + xmpp_debug(ctx, "event", "Stopping event loop."); - if (ctx->loop_status == XMPP_LOOP_RUNNING) - ctx->loop_status = XMPP_LOOP_QUIT; + if (ctx->loop_status == XMPP_LOOP_RUNNING) + ctx->loop_status = XMPP_LOOP_QUIT; } From 103e7be4fbc6b04aa30118fa3c4db52c0a7dd700 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 17:22:55 +0300 Subject: [PATCH 26/65] event, conn: lock send_queue with mutex --- src/common.h | 2 ++ src/conn.c | 34 ++++++++++++++++++++++------- src/event.c | 60 +++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/common.h b/src/common.h index 00d6fb7d..29025209 100644 --- a/src/common.h +++ b/src/common.h @@ -32,6 +32,7 @@ #include "hash.h" #include "util.h" #include "parser.h" +#include "thread.h" /** run-time context **/ @@ -188,6 +189,7 @@ struct _xmpp_conn_t { int send_queue_len; xmpp_send_queue_t *send_queue_head; xmpp_send_queue_t *send_queue_tail; + mutex_t *send_queue_mutex; /* xml parser */ int reset_parser; diff --git a/src/conn.c b/src/conn.c index 8a5a2d56..f0d6394c 100644 --- a/src/conn.c +++ b/src/conn.c @@ -28,6 +28,7 @@ #include "common.h" #include "util.h" #include "parser.h" +#include "thread.h" #ifndef DEFAULT_SEND_QUEUE_MAX /** @def DEFAULT_SEND_QUEUE_MAX @@ -94,15 +95,17 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->send_queue_len = 0; conn->send_queue_head = NULL; conn->send_queue_tail = NULL; + conn->send_queue_mutex = mutex_create(ctx); + if (!conn->send_queue_mutex) + goto out_free_conn; /* default timeouts */ conn->connect_timeout = CONNECT_TIMEOUT; conn->lang = xmpp_strdup(conn->ctx, "en"); - if (!conn->lang) { - xmpp_free(conn->ctx, conn); - return NULL; - } + if (!conn->lang) + goto out_free_mutex; + conn->domain = NULL; conn->jid = NULL; conn->pass = NULL; @@ -123,6 +126,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) _handle_stream_end, _handle_stream_stanza, conn); + if (!conn->parser) + goto out_free_lang; conn->reset_parser = 0; conn_prepare_reset(conn, auth_handle_open); @@ -145,10 +150,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t)); if (!item) { xmpp_error(conn->ctx, "xmpp", "failed to allocate memory"); - xmpp_free(conn->ctx, conn->lang); - parser_free(conn->parser); - xmpp_free(conn->ctx, conn); - conn = NULL; + goto out_free_parser; } else { item->conn = conn; item->next = NULL; @@ -161,6 +163,16 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) } return conn; + +out_free_parser: + parser_free(conn->parser); +out_free_lang: + xmpp_free(conn->ctx, conn->lang); +out_free_mutex: + mutex_destroy(conn->send_queue_mutex); +out_free_conn: + xmpp_free(conn->ctx, conn); + return NULL; } /** Clone a Strophe connection object. @@ -274,6 +286,10 @@ int xmpp_conn_release(xmpp_conn_t * const conn) parser_free(conn->parser); + /* free send_queue */ + /* @TODO release send_queue */ + mutex_destroy(conn->send_queue_mutex); + if (conn->domain) xmpp_free(ctx, conn->domain); if (conn->jid) xmpp_free(ctx, conn->jid); if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); @@ -618,6 +634,7 @@ void xmpp_send_raw(xmpp_conn_t * const conn, item->written = 0; /* add item to the send queue */ + mutex_lock(conn->send_queue_mutex); if (!conn->send_queue_tail) { /* first item, set head and tail */ conn->send_queue_head = item; @@ -628,6 +645,7 @@ void xmpp_send_raw(xmpp_conn_t * const conn, conn->send_queue_tail = item; } conn->send_queue_len++; + mutex_unlock(conn->send_queue_mutex); } /** Send an XML stanza to the XMPP server. diff --git a/src/event.c b/src/event.c index 1546907a..997ce9a1 100644 --- a/src/event.c +++ b/src/event.c @@ -50,6 +50,7 @@ #include "couplet.h" #include "common.h" #include "parser.h" +#include "thread.h" #ifndef DEFAULT_TIMEOUT /** @def DEFAULT_TIMEOUT @@ -59,6 +60,34 @@ #define DEFAULT_TIMEOUT 1 #endif +static xmpp_send_queue_t * +xmpp_send_queue_next(xmpp_ctx_t *ctx, xmpp_conn_t *conn) +{ + xmpp_send_queue_t *sq; + mutex_lock(conn->send_queue_mutex); + sq = conn->send_queue_head; + if (sq) { + conn->send_queue_head = sq->next; + if (!sq->next) + conn->send_queue_tail = NULL; + conn->send_queue_len--; + } + mutex_unlock(conn->send_queue_mutex); + return sq; +} + +static void +xmpp_send_queue_ins(xmpp_ctx_t *ctx, xmpp_conn_t *conn, xmpp_send_queue_t *sq) +{ + mutex_lock(conn->send_queue_mutex); + sq->next = conn->send_queue_head; + conn->send_queue_head = sq; + if (!sq->next) + conn->send_queue_tail = sq; + conn->send_queue_len++; + mutex_unlock(conn->send_queue_mutex); +} + /** Run the event loop once. * This function will run send any data that has been queued by * xmpp_send and related functions and run through the Strophe even @@ -80,8 +109,9 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) sock_t max = 0; int ret; struct timeval tv; - xmpp_send_queue_t *sq, *tsq; + xmpp_send_queue_t *sq; int towrite; + int sent; char buf[4096]; uint64_t next; long usec; @@ -114,8 +144,9 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) } /* write all data from the send queue to the socket */ - sq = conn->send_queue_head; + sq = xmpp_send_queue_next(ctx, conn); while (sq) { + sent = 1; towrite = sq->len - sq->written; if (conn->tls) { @@ -124,12 +155,12 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) if (ret < 0 && !tls_is_recoverable(tls_error(conn->tls))) { /* an error occured */ conn->error = tls_error(conn->tls); - break; + sent = 0; } else if (ret < towrite) { /* not all data could be sent now */ if (ret >= 0) sq->written += ret; - break; + sent = 0; } } else { @@ -138,26 +169,25 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) if (ret < 0 && !sock_is_recoverable(sock_error())) { /* an error occured */ conn->error = sock_error(); - break; + sent = 0; } else if (ret < towrite) { /* not all data could be sent now */ if (ret >= 0) sq->written += ret; - break; + sent = 0; } } + if (!sent) { + /* insert sq to the head of send queue */ + xmpp_send_queue_ins(ctx, conn, sq); + break; + } + /* all data for this queue item written, delete and move on */ xmpp_free(ctx, sq->data); - tsq = sq; - sq = sq->next; - xmpp_free(ctx, tsq); - - /* pop the top item */ - conn->send_queue_head = sq; - /* if we've sent everything update the tail */ - if (!sq) - conn->send_queue_tail = NULL; + xmpp_free(ctx, sq); + sq = xmpp_send_queue_next(ctx, conn); } /* tear down connection on error */ From 7e406676ac6bcbac9badafe8bfe560dfb1789a21 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 21:27:51 +0300 Subject: [PATCH 27/65] conn.c: spacing --- src/conn.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/conn.c b/src/conn.c index f0d6394c..1d0fe11b 100644 --- a/src/conn.c +++ b/src/conn.c @@ -51,15 +51,12 @@ #define CONNECT_TIMEOUT 5000 /* 5 seconds */ #endif -static int _disconnect_cleanup(xmpp_conn_t * const conn, - void * const userdata); +static int _disconnect_cleanup(xmpp_conn_t * const conn, void * const userdata); static void _handle_stream_start(char *name, char **attrs, void * const userdata); -static void _handle_stream_end(char *name, - void * const userdata); -static void _handle_stream_stanza(xmpp_stanza_t *stanza, - void * const userdata); +static void _handle_stream_end(char *name, void * const userdata); +static void _handle_stream_stanza(xmpp_stanza_t *stanza, void * const userdata); /** Create a new Strophe connection object. * @@ -290,12 +287,18 @@ int xmpp_conn_release(xmpp_conn_t * const conn) /* @TODO release send_queue */ mutex_destroy(conn->send_queue_mutex); - if (conn->domain) xmpp_free(ctx, conn->domain); - if (conn->jid) xmpp_free(ctx, conn->jid); - if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); - if (conn->pass) xmpp_free(ctx, conn->pass); - if (conn->stream_id) xmpp_free(ctx, conn->stream_id); - if (conn->lang) xmpp_free(ctx, conn->lang); + if (conn->domain) + xmpp_free(ctx, conn->domain); + if (conn->jid) + xmpp_free(ctx, conn->jid); + if (conn->bound_jid) + xmpp_free(ctx, conn->bound_jid); + if (conn->pass) + xmpp_free(ctx, conn->pass); + if (conn->stream_id) + xmpp_free(ctx, conn->stream_id); + if (conn->lang) + xmpp_free(ctx, conn->lang); xmpp_free(ctx, conn); released = 1; } From a8e6ec7c8b4a241051dfacb483fb452ee0591330 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 21:58:45 +0300 Subject: [PATCH 28/65] conn.c: little code refactoring --- src/conn.c | 346 ++++++++++++++++++++++++++--------------------------- 1 file changed, 172 insertions(+), 174 deletions(-) diff --git a/src/conn.c b/src/conn.c index 1d0fe11b..b738dd12 100644 --- a/src/conn.c +++ b/src/conn.c @@ -68,95 +68,96 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza, void * const userdata); */ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) { - xmpp_conn_t *conn = NULL; + xmpp_conn_t *conn; xmpp_connlist_t *tail, *item; - if (ctx == NULL) + if (!ctx) return NULL; conn = xmpp_alloc(ctx, sizeof(xmpp_conn_t)); - if (conn != NULL) { - conn->ctx = ctx; + if (!conn) + return NULL; - conn->type = XMPP_UNKNOWN; - conn->state = XMPP_STATE_DISCONNECTED; - conn->sock = -1; - conn->tls = NULL; - conn->timeout_stamp = 0; - conn->error = 0; - conn->stream_error = NULL; - - /* default send parameters */ - conn->blocking_send = 0; - conn->send_queue_max = DEFAULT_SEND_QUEUE_MAX; - conn->send_queue_len = 0; - conn->send_queue_head = NULL; - conn->send_queue_tail = NULL; - conn->send_queue_mutex = mutex_create(ctx); - if (!conn->send_queue_mutex) - goto out_free_conn; - - /* default timeouts */ - conn->connect_timeout = CONNECT_TIMEOUT; - - conn->lang = xmpp_strdup(conn->ctx, "en"); - if (!conn->lang) - goto out_free_mutex; - - conn->domain = NULL; - conn->jid = NULL; - conn->pass = NULL; - conn->stream_id = NULL; - conn->bound_jid = NULL; - - conn->tls_support = 0; - conn->tls_disabled = 0; - conn->tls_failed = 0; - conn->sasl_support = 0; - conn->secured = 0; - - conn->bind_required = 0; - conn->session_required = 0; - - conn->parser = parser_new(conn->ctx, - _handle_stream_start, - _handle_stream_end, - _handle_stream_stanza, - conn); - if (!conn->parser) - goto out_free_lang; - conn->reset_parser = 0; - conn_prepare_reset(conn, auth_handle_open); - - conn->authenticated = 0; - conn->conn_handler = NULL; - conn->userdata = NULL; - conn->timed_handlers = NULL; - /* we own (and will free) the hash values */ - conn->id_handlers = hash_new(conn->ctx, 32, NULL); - conn->handlers = NULL; - - /* give the caller a reference to connection */ - conn->ref = 1; - - /* add connection to ctx->connlist */ - tail = conn->ctx->connlist; - while (tail && tail->next) - tail = tail->next; - - item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t)); - if (!item) { - xmpp_error(conn->ctx, "xmpp", "failed to allocate memory"); - goto out_free_parser; - } else { - item->conn = conn; - item->next = NULL; - - if (tail) - tail->next = item; - else - conn->ctx->connlist = item; - } + conn->ctx = ctx; + + conn->type = XMPP_UNKNOWN; + conn->state = XMPP_STATE_DISCONNECTED; + conn->sock = -1; + conn->tls = NULL; + conn->timeout_stamp = 0; + conn->error = 0; + conn->stream_error = NULL; + + /* default send parameters */ + conn->blocking_send = 0; + conn->send_queue_max = DEFAULT_SEND_QUEUE_MAX; + conn->send_queue_len = 0; + conn->send_queue_head = NULL; + conn->send_queue_tail = NULL; + conn->send_queue_mutex = mutex_create(ctx); + if (!conn->send_queue_mutex) + goto out_free_conn; + + /* default timeouts */ + conn->connect_timeout = CONNECT_TIMEOUT; + + conn->lang = xmpp_strdup(ctx, "en"); + if (!conn->lang) + goto out_free_mutex; + + conn->domain = NULL; + conn->jid = NULL; + conn->pass = NULL; + conn->stream_id = NULL; + conn->bound_jid = NULL; + + conn->tls_support = 0; + conn->tls_disabled = 0; + conn->tls_failed = 0; + conn->sasl_support = 0; + conn->secured = 0; + + conn->bind_required = 0; + conn->session_required = 0; + + conn->parser = parser_new(ctx, + _handle_stream_start, + _handle_stream_end, + _handle_stream_stanza, + conn); + if (!conn->parser) + goto out_free_lang; + conn->reset_parser = 0; + conn_prepare_reset(conn, auth_handle_open); + + conn->authenticated = 0; + conn->conn_handler = NULL; + conn->userdata = NULL; + conn->timed_handlers = NULL; + /* we own (and will free) the hash values */ + conn->id_handlers = hash_new(ctx, 32, NULL); + conn->handlers = NULL; + + /* give the caller a reference to connection */ + conn->ref = 1; + + /* add connection to ctx->connlist */ + tail = ctx->connlist; + while (tail && tail->next) + tail = tail->next; + + item = xmpp_alloc(ctx, sizeof(xmpp_connlist_t)); + if (!item) { + xmpp_error(ctx, "xmpp", "failed to allocate memory"); + goto out_free_parser; + } else { + item->conn = conn; + item->next = NULL; + + if (tail) + tail->next = item; + else + ctx->connlist = item; } return conn; @@ -164,11 +165,11 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) out_free_parser: parser_free(conn->parser); out_free_lang: - xmpp_free(conn->ctx, conn->lang); + xmpp_free(ctx, conn->lang); out_free_mutex: mutex_destroy(conn->send_queue_mutex); out_free_conn: - xmpp_free(conn->ctx, conn); + xmpp_free(ctx, conn); return NULL; } @@ -204,106 +205,104 @@ int xmpp_conn_release(xmpp_conn_t * const conn) xmpp_handlist_t *hlitem, *thli; hash_iterator_t *iter; const char *key; - int released = 0; - if (conn->ref > 1) + if (conn->ref > 1) { conn->ref--; - else { - ctx = conn->ctx; + return 0; + } - /* remove connection from context's connlist */ - if (ctx->connlist->conn == conn) { - item = ctx->connlist; - ctx->connlist = item->next; - xmpp_free(ctx, item); - } else { - prev = NULL; - item = ctx->connlist; - while (item && item->conn != conn) { - prev = item; - item = item->next; - } - - if (item) { - prev->next = item->next; - xmpp_free(ctx, item); - } else - xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); - } + ctx = conn->ctx; - /* free handler stuff - * note that userdata is the responsibility of the client - * and the handler pointers don't need to be freed since they - * are pointers to functions */ + /* remove connection from context's connlist */ + if (ctx->connlist->conn == conn) { + item = ctx->connlist; + ctx->connlist = item->next; + xmpp_free(ctx, item); + } else { + prev = NULL; + item = ctx->connlist; + while (item && item->conn != conn) { + prev = item; + item = item->next; + } - hlitem = conn->timed_handlers; - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; + if (item) { + prev->next = item->next; + xmpp_free(ctx, item); + } else + xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); + } - xmpp_free(ctx, thli); - } + /* free handler stuff + * note that userdata is the responsibility of the client + * and the handler pointers don't need to be freed since they + * are pointers to functions */ - /* id handlers - * we have to traverse the hash table freeing list elements - * then release the hash table */ - iter = hash_iter_new(conn->id_handlers); - while ((key = hash_iter_next(iter))) { - hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key); - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - xmpp_free(conn->ctx, thli->id); - xmpp_free(conn->ctx, thli); - } - } - hash_iter_release(iter); - hash_release(conn->id_handlers); + hlitem = conn->timed_handlers; + while (hlitem) { + thli = hlitem; + hlitem = hlitem->next; + xmpp_free(ctx, thli); + } - hlitem = conn->handlers; + /* id handlers + * we have to traverse the hash table freeing list elements + * then release the hash table */ + iter = hash_iter_new(conn->id_handlers); + while ((key = hash_iter_next(iter))) { + hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key); while (hlitem) { thli = hlitem; hlitem = hlitem->next; - - if (thli->ns) - xmpp_free(ctx, thli->ns); - if (thli->name) - xmpp_free(ctx, thli->name); - if (thli->type) - xmpp_free(ctx, thli->type); + xmpp_free(ctx, thli->id); xmpp_free(ctx, thli); } + } + hash_iter_release(iter); + hash_release(conn->id_handlers); + + hlitem = conn->handlers; + while (hlitem) { + thli = hlitem; + hlitem = hlitem->next; + + if (thli->ns) + xmpp_free(ctx, thli->ns); + if (thli->name) + xmpp_free(ctx, thli->name); + if (thli->type) + xmpp_free(ctx, thli->type); + xmpp_free(ctx, thli); + } - if (conn->stream_error) { - xmpp_stanza_release(conn->stream_error->stanza); - if (conn->stream_error->text) - xmpp_free(ctx, conn->stream_error->text); - xmpp_free(ctx, conn->stream_error); - } - - parser_free(conn->parser); + if (conn->stream_error) { + xmpp_stanza_release(conn->stream_error->stanza); + if (conn->stream_error->text) + xmpp_free(ctx, conn->stream_error->text); + xmpp_free(ctx, conn->stream_error); + } - /* free send_queue */ - /* @TODO release send_queue */ - mutex_destroy(conn->send_queue_mutex); + parser_free(conn->parser); - if (conn->domain) - xmpp_free(ctx, conn->domain); - if (conn->jid) - xmpp_free(ctx, conn->jid); - if (conn->bound_jid) - xmpp_free(ctx, conn->bound_jid); - if (conn->pass) - xmpp_free(ctx, conn->pass); - if (conn->stream_id) - xmpp_free(ctx, conn->stream_id); - if (conn->lang) - xmpp_free(ctx, conn->lang); - xmpp_free(ctx, conn); - released = 1; - } + /* free send_queue */ + /* @TODO release send_queue */ + mutex_destroy(conn->send_queue_mutex); - return released; + if (conn->domain) + xmpp_free(ctx, conn->domain); + if (conn->jid) + xmpp_free(ctx, conn->jid); + if (conn->bound_jid) + xmpp_free(ctx, conn->bound_jid); + if (conn->pass) + xmpp_free(ctx, conn->pass); + if (conn->stream_id) + xmpp_free(ctx, conn->stream_id); + if (conn->lang) + xmpp_free(ctx, conn->lang); + xmpp_free(ctx, conn); + + return 1; } /** Get the JID which is or will be bound to the connection. @@ -660,14 +659,13 @@ void xmpp_send_raw(xmpp_conn_t * const conn, * * @ingroup Connections */ -void xmpp_send(xmpp_conn_t * const conn, - xmpp_stanza_t * const stanza) +void xmpp_send(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza) { char *buf; size_t len; if (conn->state == XMPP_STATE_CONNECTED && - xmpp_stanza_to_text(stanza, &buf, &len) == 0) { + !xmpp_stanza_to_text(stanza, &buf, &len)) { xmpp_send_raw(conn, buf, len); xmpp_debug(conn->ctx, "conn", "SENT: %s", buf); xmpp_free(conn->ctx, buf); @@ -746,7 +744,7 @@ static char *_get_stream_attribute(char **attrs, char *name) return NULL; for (i = 0; attrs[i]; i += 2) - if (strcmp(name, attrs[i]) == 0) + if (!strcmp(name, attrs[i])) return attrs[i+1]; return NULL; @@ -758,7 +756,7 @@ static void _handle_stream_start(char *name, char **attrs, xmpp_conn_t *conn = (xmpp_conn_t *)userdata; char *id; - if (strcmp(name, "stream:stream") != 0) { + if (strcmp(name, "stream:stream")) { printf("name = %s\n", name); xmpp_error(conn->ctx, "conn", "Server did not open valid stream."); conn_disconnect(conn); @@ -799,7 +797,7 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza, char *buf; size_t len; - if (xmpp_stanza_to_text(stanza, &buf, &len) == 0) { + if (!xmpp_stanza_to_text(stanza, &buf, &len)) { xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf); xmpp_free(conn->ctx, buf); } From 0ba86a09a2e9eed5558f252da9c6dee81c95ac1d Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sat, 13 Oct 2012 22:04:09 +0300 Subject: [PATCH 29/65] conn.c: update todo list --- src/conn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/conn.c b/src/conn.c index b738dd12..fe0cfda9 100644 --- a/src/conn.c +++ b/src/conn.c @@ -432,6 +432,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn, if (!conn->domain) return -1; + /* @TODO replace port 5222 with a marco */ if (altdomain) { xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); strcpy(connectdomain, altdomain); From abec656fe11d32a62ff19a1de6db0c119dc5b4e2 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sun, 14 Oct 2012 13:20:35 +0300 Subject: [PATCH 30/65] thread.c: spacing --- src/thread.c | 80 +++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/src/thread.c b/src/thread.c index 793cc9f0..131ba668 100644 --- a/src/thread.c +++ b/src/thread.c @@ -31,12 +31,12 @@ #include "thread.h" struct _mutex_t { - const xmpp_ctx_t *ctx; + const xmpp_ctx_t *ctx; #ifdef _WIN32 - HANDLE mutex; + HANDLE mutex; #else - pthread_mutex_t *mutex; + pthread_mutex_t *mutex; #endif }; @@ -44,82 +44,84 @@ struct _mutex_t { mutex_t *mutex_create(const xmpp_ctx_t * ctx) { - mutex_t *mutex; + mutex_t *mutex; + + mutex = xmpp_alloc(ctx, sizeof(mutex_t)); + if (!mutex) + return NULL; - mutex = xmpp_alloc(ctx, sizeof(mutex_t)); - if (mutex) { - mutex->ctx = ctx; #ifdef _WIN32 mutex->mutex = CreateMutex(NULL, FALSE, NULL); #else mutex->mutex = xmpp_alloc(ctx, sizeof(pthread_mutex_t)); - if (mutex->mutex) - if (pthread_mutex_init(mutex->mutex, NULL) != 0) { + if (mutex->mutex && pthread_mutex_init(mutex->mutex, NULL)) { + /* mutex is allocated but not initialized */ xmpp_free(ctx, mutex->mutex); mutex->mutex = NULL; - } + } #endif + if (!mutex->mutex) { - xmpp_free(ctx, mutex); - mutex = NULL; - } - } + xmpp_free(ctx, mutex); + mutex = NULL; + } else + mutex->ctx = ctx; - return mutex; + return mutex; } int mutex_destroy(mutex_t *mutex) { - int ret = 1; - const xmpp_ctx_t *ctx = NULL; + int ret = 1; + const xmpp_ctx_t *ctx = NULL; - if (mutex) - ctx = mutex->ctx; - if (!ctx) - return XMPP_EMEM; + if (mutex) + ctx = mutex->ctx; + if (!ctx) + return XMPP_EMEM; #ifdef _WIN32 - if (mutex->mutex) - ret = CloseHandle(mutex->mutex); + if (mutex->mutex) + ret = CloseHandle(mutex->mutex); #else - if (mutex->mutex) { - ret = pthread_mutex_destroy(mutex->mutex) == 0; - xmpp_free(ctx, mutex->mutex); - } + if (mutex->mutex) { + ret = pthread_mutex_destroy(mutex->mutex) == 0; + xmpp_free(ctx, mutex->mutex); + } #endif - xmpp_free(ctx, mutex); + xmpp_free(ctx, mutex); - return ret; + return ret; } int mutex_lock(mutex_t *mutex) { - int ret; + int ret; #ifdef _WIN32 - ret = WaitForSingleObject(mutex->mutex, INFINITE) == 0; + ret = WaitForSingleObject(mutex->mutex, INFINITE) == 0; #else - ret = pthread_mutex_lock(mutex->mutex) == 0; + ret = pthread_mutex_lock(mutex->mutex) == 0; #endif - return ret; + return ret; } int mutex_trylock(mutex_t *mutex) { - /* TODO */ - return 0; + /* TODO */ + return 0; } int mutex_unlock(mutex_t *mutex) { - int ret; + int ret; #ifdef _WIN32 - ret = ReleaseMutex(mutex->mutex); + ret = ReleaseMutex(mutex->mutex); #else - ret = pthread_mutex_unlock(mutex->mutex) == 0; + ret = pthread_mutex_unlock(mutex->mutex) == 0; #endif - return ret; + return ret; } From fa77c207579a2c72b6fd086dbbf8f8905c894c19 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 15 Oct 2012 00:05:39 +0300 Subject: [PATCH 31/65] move sending loop to a separated thread --- configure.ac | 2 + couplet.h | 1 + src/common.h | 2 + src/conn.c | 86 +++++++++++++++++++++++++++---------------- src/ctx.c | 41 +++++++++++++++------ src/event.c | 97 ++++++++++++++++++++++++++++++++++++------------ src/thread.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/thread.h | 16 ++++++++ 8 files changed, 279 insertions(+), 68 deletions(-) diff --git a/configure.ac b/configure.ac index 1a4185ea..d7c81a39 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,8 @@ PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not foun AC_ARG_WITH([libxml2], [AS_HELP_STRING([--with-libxml2], [use libxml2 for XML parsing])]) +AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([pthread support is required])]) + if test "x$with_libxml2" = xyes; then PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7], [with_libxml2=yes], diff --git a/couplet.h b/couplet.h index ac8e7abd..aa6eeee7 100644 --- a/couplet.h +++ b/couplet.h @@ -363,6 +363,7 @@ void xmpp_presence_new(); */ /** event loop **/ +void xmpp_run_send_queue_once(xmpp_ctx_t *ctx); void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout); void xmpp_run(xmpp_ctx_t *ctx); void xmpp_stop(xmpp_ctx_t *ctx); diff --git a/src/common.h b/src/common.h index 29025209..6982eb7f 100644 --- a/src/common.h +++ b/src/common.h @@ -53,6 +53,8 @@ struct _xmpp_ctx_t { xmpp_loop_status_t loop_status; xmpp_connlist_t *connlist; + mutex_t *connlist_mutex; + xmpp_sem_t *send_queue_sem; }; diff --git a/src/conn.c b/src/conn.c index fe0cfda9..671f6ac1 100644 --- a/src/conn.c +++ b/src/conn.c @@ -58,6 +58,48 @@ static void _handle_stream_start(char *name, char **attrs, static void _handle_stream_end(char *name, void * const userdata); static void _handle_stream_stanza(xmpp_stanza_t *stanza, void * const userdata); +/* insert connlist item to the tail */ +static void _xmpp_connlist_ins(xmpp_ctx_t *ctx, xmpp_connlist_t *item) +{ + xmpp_connlist_t *tail; + + mutex_lock(ctx->connlist_mutex); + tail = ctx->connlist; + while (tail && tail->next) + tail = tail->next; + if (!tail) + ctx->connlist = item; + else + tail->next = item; + mutex_unlock(ctx->connlist_mutex); +} + +/* delete connlist item specified by conn + * return TRUE if conn is found within connlist and FALSE otherwise + */ +static int _xmpp_connlist_del(xmpp_ctx_t *ctx, xmpp_conn_t *conn) +{ + xmpp_connlist_t *item, *prev; + + prev = NULL; + mutex_lock(ctx->connlist_mutex); + item = ctx->connlist; + while (item && item->conn != conn) { + prev = item; + item = item->next; + } + if (item) { + if (!prev) + ctx->connlist = item->next; + else + prev->next = item->next; + xmpp_free(ctx, item); + } + mutex_unlock(ctx->connlist_mutex); + + return !item; +} + /** Create a new Strophe connection object. * * @param ctx a Strophe context object @@ -69,7 +111,7 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza, void * const userdata); xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) { xmpp_conn_t *conn; - xmpp_connlist_t *tail, *item; + xmpp_connlist_t *item; if (!ctx) return NULL; @@ -142,10 +184,6 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->ref = 1; /* add connection to ctx->connlist */ - tail = ctx->connlist; - while (tail && tail->next) - tail = tail->next; - item = xmpp_alloc(ctx, sizeof(xmpp_connlist_t)); if (!item) { xmpp_error(ctx, "xmpp", "failed to allocate memory"); @@ -153,11 +191,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) } else { item->conn = conn; item->next = NULL; - - if (tail) - tail->next = item; - else - ctx->connlist = item; + _xmpp_connlist_ins(ctx, item); } return conn; @@ -201,7 +235,6 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) int xmpp_conn_release(xmpp_conn_t * const conn) { xmpp_ctx_t *ctx; - xmpp_connlist_t *item, *prev; xmpp_handlist_t *hlitem, *thli; hash_iterator_t *iter; const char *key; @@ -214,24 +247,8 @@ int xmpp_conn_release(xmpp_conn_t * const conn) ctx = conn->ctx; /* remove connection from context's connlist */ - if (ctx->connlist->conn == conn) { - item = ctx->connlist; - ctx->connlist = item->next; - xmpp_free(ctx, item); - } else { - prev = NULL; - item = ctx->connlist; - while (item && item->conn != conn) { - prev = item; - item = item->next; - } - - if (item) { - prev->next = item->next; - xmpp_free(ctx, item); - } else - xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); - } + if (!_xmpp_connlist_del(ctx, conn)) + xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); /* free handler stuff * note that userdata is the responsibility of the client @@ -616,19 +633,22 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn, void xmpp_send_raw(xmpp_conn_t * const conn, const char * const data, const size_t len) { + xmpp_ctx_t *ctx; xmpp_send_queue_t *item; if (conn->state != XMPP_STATE_CONNECTED) return; + ctx = conn->ctx; + /* create send queue item for queue */ - item = xmpp_alloc(conn->ctx, sizeof(xmpp_send_queue_t)); + item = xmpp_alloc(ctx, sizeof(xmpp_send_queue_t)); if (!item) return; - item->data = xmpp_alloc(conn->ctx, len); + item->data = xmpp_alloc(ctx, len); if (!item->data) { - xmpp_free(conn->ctx, item); + xmpp_free(ctx, item); return; } memcpy(item->data, data, len); @@ -649,6 +669,8 @@ void xmpp_send_raw(xmpp_conn_t * const conn, } conn->send_queue_len++; mutex_unlock(conn->send_queue_mutex); + /* unlock send_queue_thread */ + xmpp_sem_post(ctx->send_queue_sem); } /** Send an XML stanza to the XMPP server. diff --git a/src/ctx.c b/src/ctx.c index c65e0b11..fa636825 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -51,6 +51,7 @@ #include "couplet.h" #include "common.h" #include "util.h" +#include "thread.h" /** Initialize the Strophe library. * This function initializes subcomponents of the Strophe library and must @@ -396,22 +397,35 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, else ctx = mem->alloc(sizeof(xmpp_ctx_t), mem->userdata); - if (ctx != NULL) { - if (mem != NULL) - ctx->mem = mem; - else - ctx->mem = &xmpp_default_mem; + if (!ctx) + return NULL; - if (log == NULL) - ctx->log = &xmpp_default_log; - else - ctx->log = log; + if (!mem) + ctx->mem = &xmpp_default_mem; + else + ctx->mem = mem; - ctx->connlist = NULL; - ctx->loop_status = XMPP_LOOP_NOTSTARTED; - } + if (!log) + ctx->log = &xmpp_default_log; + else + ctx->log = log; + + ctx->connlist = NULL; + ctx->loop_status = XMPP_LOOP_NOTSTARTED; + ctx->connlist_mutex = mutex_create(ctx); + if (!ctx->connlist_mutex) + goto out_free_ctx; + ctx->send_queue_sem = xmpp_sem_create(ctx); + if (!ctx->send_queue_sem) + goto out_free_mutex; return ctx; + +out_free_mutex: + mutex_destroy(ctx->connlist_mutex); +out_free_ctx: + xmpp_free(ctx, ctx); + return NULL; } /** Free a Strophe context object that is no longer in use. @@ -422,6 +436,9 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, */ void xmpp_ctx_free(xmpp_ctx_t * const ctx) { + mutex_destroy(ctx->connlist_mutex); + /** @TODO destroy ctx->send_queue_sem */ + /* mem and log are owned by their suppliers */ xmpp_free(ctx, ctx); /* pull the hole in after us */ } diff --git a/src/event.c b/src/event.c index 997ce9a1..79ea3ca2 100644 --- a/src/event.c +++ b/src/event.c @@ -88,38 +88,22 @@ xmpp_send_queue_ins(xmpp_ctx_t *ctx, xmpp_conn_t *conn, xmpp_send_queue_t *sq) mutex_unlock(conn->send_queue_mutex); } -/** Run the event loop once. - * This function will run send any data that has been queued by - * xmpp_send and related functions and run through the Strophe even - * loop a single time, and will not wait more than timeout - * milliseconds for events. This is provided to support integration - * with event loops outside the library, and if used, should be - * called regularly to achieve low latency event handling. +/** Run send loop once. + * This function will run send any data that has been queued by xmpp_send + * and related functions. * * @param ctx a Strophe context object - * @param timeout time to wait for events in milliseconds * * @ingroup EventLoop */ -void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) +void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) { xmpp_connlist_t *connitem; xmpp_conn_t *conn; - fd_set rfds, wfds; - sock_t max = 0; - int ret; - struct timeval tv; xmpp_send_queue_t *sq; - int towrite; int sent; - char buf[4096]; - uint64_t next; - long usec; - int tls_read_bytes = 0; - - if (ctx->loop_status == XMPP_LOOP_QUIT) - return; - ctx->loop_status = XMPP_LOOP_RUNNING; + int ret; + int towrite; /* send queued data */ connitem = ctx->connlist; @@ -201,6 +185,64 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) connitem = connitem->next; } +} + +/** Start the sending loop. + * This function is start routine for a separated thread. It continuously + * calls xmpp_run_send_queue_once. + * + * @param data is a pointer to a Strophe context object + * + * @return always NULL + * + * @ingroup EventLoop + */ +void *xmpp_send_queue_thread(void *data) +{ + xmpp_ctx_t *ctx = (xmpp_ctx_t *)data; + + if (!ctx) + return NULL; + + /** @TODO make condition for break */ + /* infinite loop */ + while (1) { + /* lock thread if nothing to be sent */ + xmpp_sem_wait(ctx->send_queue_sem); + xmpp_run_send_queue_once(ctx); + } + + return NULL; +} + +/** Run the event loop once. + * This function will run through the Strophe event + * loop a single time, and will not wait more than timeout + * milliseconds for events. This is provided to support integration + * with event loops outside the library, and if used, should be + * called regularly to achieve low latency event handling. + * + * @param ctx a Strophe context object + * @param timeout time to wait for events in milliseconds + * + * @ingroup EventLoop + */ +void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) +{ + xmpp_connlist_t *connitem; + xmpp_conn_t *conn; + fd_set rfds, wfds; + sock_t max = 0; + int ret; + struct timeval tv; + char buf[4096]; + uint64_t next; + long usec; + int tls_read_bytes = 0; + + if (ctx->loop_status == XMPP_LOOP_QUIT) + return; + ctx->loop_status = XMPP_LOOP_RUNNING; /* reset parsers if needed */ for (connitem = ctx->connlist; connitem; connitem = connitem->next) @@ -343,8 +385,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) } /** Start the event loop. - * This function continuously calls xmpp_run_once and does not return - * until xmpp_stop has been called. + * This function starts sending loop thread and continuously calls + * xmpp_run_once. Loop does not stop until xmpp_stop has been called. * * @param ctx a Strophe context object * @@ -352,13 +394,20 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) */ void xmpp_run(xmpp_ctx_t *ctx) { + thread_t *thread; + if (ctx->loop_status != XMPP_LOOP_NOTSTARTED) return; + thread = thread_create(ctx, &xmpp_send_queue_thread, ctx); + /** @TODO check return value */ + ctx->loop_status = XMPP_LOOP_RUNNING; while (ctx->loop_status == XMPP_LOOP_RUNNING) xmpp_run_once(ctx, DEFAULT_TIMEOUT); + /** @TODO stop sending thread */ + xmpp_debug(ctx, "event", "Event loop completed."); } diff --git a/src/thread.c b/src/thread.c index 131ba668..8d596889 100644 --- a/src/thread.c +++ b/src/thread.c @@ -40,6 +40,108 @@ struct _mutex_t { #endif }; +struct _thread_t { + const xmpp_ctx_t *ctx; + +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + pthread_t *thread; +#endif +}; + +struct _xmpp_sem_t { + const xmpp_ctx_t *ctx; + +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + sem_t *sem; +#endif +}; + +/* semaphore functions */ + +xmpp_sem_t *xmpp_sem_create(const xmpp_ctx_t *ctx) +{ + xmpp_sem_t *sem; + + sem = xmpp_alloc(ctx, sizeof(xmpp_sem_t)); + if (!sem) + return NULL; + +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + sem->sem = xmpp_alloc(ctx, sizeof(*sem->sem)); + if (sem->sem && sem_init(sem->sem, 0, 0)) { + /* semaphore is allocated but not initialized */ + xmpp_free(ctx, sem->sem); + sem->sem = NULL; + } +#endif + + if (!sem->sem) { + xmpp_free(ctx, sem); + sem = NULL; + } else + sem->ctx = ctx; + + return sem; +} + +void xmpp_sem_wait(xmpp_sem_t *sem) +{ +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + sem_wait(sem->sem); +#endif +} + +void xmpp_sem_post(xmpp_sem_t *sem) +{ +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + sem_post(sem->sem); +#endif +} + +/* thread functions */ + +thread_t *thread_create(const xmpp_ctx_t *ctx, thread_func_t start_func, void *arg) +{ + thread_t *thread; + + if (!ctx) + return NULL; + + thread = xmpp_alloc(ctx, sizeof(thread_t)); + if (!thread) + return NULL; + +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + thread->thread = xmpp_alloc(ctx, sizeof(*thread->thread)); + if (thread->thread && + pthread_create(thread->thread, NULL, start_func, arg)) { + /* thread is allocated but not initialized */ + xmpp_free(ctx, thread->thread); + thread->thread = NULL; + } +#endif + + if (!thread->thread) { + xmpp_free(ctx, thread); + thread = NULL; + } else + thread->ctx = ctx; + + return thread; +} + /* mutex functions */ mutex_t *mutex_create(const xmpp_ctx_t * ctx) diff --git a/src/thread.h b/src/thread.h index 564c3a88..cae51a58 100644 --- a/src/thread.h +++ b/src/thread.h @@ -26,11 +26,27 @@ #include #else #include +#include #endif #include "couplet.h" typedef struct _mutex_t mutex_t; +typedef struct _thread_t thread_t; +typedef struct _xmpp_sem_t xmpp_sem_t; + +typedef void *(*thread_func_t) (void *); + +/* semaphore functions */ + +xmpp_sem_t *xmpp_sem_create(const xmpp_ctx_t *ctx); +void xmpp_sem_wait(xmpp_sem_t *sem); +void xmpp_sem_post(xmpp_sem_t *sem); +/** @TODO create xmpp_sem_destroy() */ + +/* thread functions */ + +thread_t *thread_create(const xmpp_ctx_t *ctx, thread_func_t start_func, void *arg); /* mutex functions */ From 2f02910211e83eb4302e30efa7ace6613b59696c Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 15 Oct 2012 00:12:31 +0300 Subject: [PATCH 32/65] event.c: update todo list --- src/event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/event.c b/src/event.c index 79ea3ca2..e302112e 100644 --- a/src/event.c +++ b/src/event.c @@ -105,6 +105,7 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) int ret; int towrite; + /** @TODO lock connlist with ctx->connlist_mutex */ /* send queued data */ connitem = ctx->connlist; while (connitem) { From 5b48a241328c36f845dfde8e4a1bea87bb7fd1eb Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 15 Oct 2012 14:23:14 +0300 Subject: [PATCH 33/65] thread: introduce xmpp_sem_destroy --- src/thread.c | 23 +++++++++++++++++++++++ src/thread.h | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index 8d596889..475242fc 100644 --- a/src/thread.c +++ b/src/thread.c @@ -108,6 +108,29 @@ void xmpp_sem_post(xmpp_sem_t *sem) #endif } +int xmpp_sem_destroy(xmpp_sem_t *sem) +{ + const xmpp_ctx_t *ctx = NULL; + int ret; + + if (sem) + ctx = sem->ctx; + if (!ctx) + return 0; + +#ifdef _WIN32 +# error "win32 is not supported for now" +#else + if (sem->sem) { + ret = sem_destoy(sem->sem) == 0; + xmpp_free(ctx, sem->sem); + } +#endif + xmpp_free(ctx, sem); + + return ret; +} + /* thread functions */ thread_t *thread_create(const xmpp_ctx_t *ctx, thread_func_t start_func, void *arg) diff --git a/src/thread.h b/src/thread.h index cae51a58..df00b30e 100644 --- a/src/thread.h +++ b/src/thread.h @@ -42,7 +42,7 @@ typedef void *(*thread_func_t) (void *); xmpp_sem_t *xmpp_sem_create(const xmpp_ctx_t *ctx); void xmpp_sem_wait(xmpp_sem_t *sem); void xmpp_sem_post(xmpp_sem_t *sem); -/** @TODO create xmpp_sem_destroy() */ +int xmpp_sem_destroy(xmpp_sem_t *sem); /* thread functions */ From 419c0d4f90a78697612572d8c2ca4de2be1e11b6 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 15 Oct 2012 14:28:14 +0300 Subject: [PATCH 34/65] thread.c: fix typo --- src/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index 475242fc..890489e5 100644 --- a/src/thread.c +++ b/src/thread.c @@ -122,7 +122,7 @@ int xmpp_sem_destroy(xmpp_sem_t *sem) # error "win32 is not supported for now" #else if (sem->sem) { - ret = sem_destoy(sem->sem) == 0; + ret = sem_destroy(sem->sem) == 0; xmpp_free(ctx, sem->sem); } #endif From 39f1d532bbffe3145b5ecb110f784df008608317 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Mon, 15 Oct 2012 14:28:52 +0300 Subject: [PATCH 35/65] thread.c: initialize ret in xmpp_sem_destroy --- src/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index 890489e5..e2996408 100644 --- a/src/thread.c +++ b/src/thread.c @@ -111,7 +111,7 @@ void xmpp_sem_post(xmpp_sem_t *sem) int xmpp_sem_destroy(xmpp_sem_t *sem) { const xmpp_ctx_t *ctx = NULL; - int ret; + int ret = 1; if (sem) ctx = sem->ctx; From b2a19c122678c6d231f29486c7c7582dc995e29e Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 16 Oct 2012 09:47:03 +0300 Subject: [PATCH 36/65] rename and document send queue helpers --- src/event.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/event.c b/src/event.c index e302112e..f7527a5c 100644 --- a/src/event.c +++ b/src/event.c @@ -60,8 +60,11 @@ #define DEFAULT_TIMEOUT 1 #endif +/* Get the next item from the send queue. + * This function removes returned item from the queue + */ static xmpp_send_queue_t * -xmpp_send_queue_next(xmpp_ctx_t *ctx, xmpp_conn_t *conn) +_xmpp_send_queue_next(xmpp_ctx_t *ctx, xmpp_conn_t *conn) { xmpp_send_queue_t *sq; mutex_lock(conn->send_queue_mutex); @@ -76,8 +79,9 @@ xmpp_send_queue_next(xmpp_ctx_t *ctx, xmpp_conn_t *conn) return sq; } +/* Insert item to the head of the send queue */ static void -xmpp_send_queue_ins(xmpp_ctx_t *ctx, xmpp_conn_t *conn, xmpp_send_queue_t *sq) +_xmpp_send_queue_ins(xmpp_ctx_t *ctx, xmpp_conn_t *conn, xmpp_send_queue_t *sq) { mutex_lock(conn->send_queue_mutex); sq->next = conn->send_queue_head; @@ -129,7 +133,7 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) } /* write all data from the send queue to the socket */ - sq = xmpp_send_queue_next(ctx, conn); + sq = _xmpp_send_queue_next(ctx, conn); while (sq) { sent = 1; towrite = sq->len - sq->written; @@ -165,14 +169,14 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) if (!sent) { /* insert sq to the head of send queue */ - xmpp_send_queue_ins(ctx, conn, sq); + _xmpp_send_queue_ins(ctx, conn, sq); break; } /* all data for this queue item written, delete and move on */ xmpp_free(ctx, sq->data); xmpp_free(ctx, sq); - sq = xmpp_send_queue_next(ctx, conn); + sq = _xmpp_send_queue_next(ctx, conn); } /* tear down connection on error */ From a90f09ecd9454beeb692d60953e7c7e1c0ae2b10 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 16 Oct 2012 10:30:40 +0300 Subject: [PATCH 37/65] conn: set maximum domain length to 255 --- couplet.h | 5 +++++ src/conn.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/couplet.h b/couplet.h index aa6eeee7..d534625b 100644 --- a/couplet.h +++ b/couplet.h @@ -99,6 +99,11 @@ extern "C" { */ #define XMPP_EINT -3 +/** @def XMPP_FQDN_MAX_LEN + * Maximum length of FQDN. Should be set to 255 according to RFC2181. + */ +#define XMPP_FQDN_MAX_LEN 255 + /* initialization and shutdown */ void xmpp_initialize(void); void xmpp_shutdown(void); diff --git a/src/conn.c b/src/conn.c index 671f6ac1..0c0209e7 100644 --- a/src/conn.c +++ b/src/conn.c @@ -439,7 +439,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn, xmpp_conn_handler callback, void * const userdata) { - char connectdomain[2048]; + char connectdomain[XMPP_FQDN_MAX_LEN + 1]; int connectport; const char * domain; @@ -455,7 +455,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn, strcpy(connectdomain, altdomain); connectport = altport ? altport : 5222; } else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain, - connectdomain, 2048, &connectport)) { + connectdomain, XMPP_FQDN_MAX_LEN + 1, &connectport)) { xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed."); if (!altdomain) domain = conn->domain; From 115836913a19c13cc15ce94f03910ca562a88a0e Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 16 Oct 2012 11:00:01 +0300 Subject: [PATCH 38/65] conn: check for domain length before call strcpy --- couplet.h | 4 ++++ src/conn.c | 13 ++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/couplet.h b/couplet.h index d534625b..0b9307ab 100644 --- a/couplet.h +++ b/couplet.h @@ -98,6 +98,10 @@ extern "C" { * Internal failure error code. */ #define XMPP_EINT -3 +/** @def XMPP_EINVAL + * Invalid argument. + */ +#define XMPP_EINVAL -4 /** @def XMPP_FQDN_MAX_LEN * Maximum length of FQDN. Should be set to 255 according to RFC2181. diff --git a/src/conn.c b/src/conn.c index 0c0209e7..eb95f2e7 100644 --- a/src/conn.c +++ b/src/conn.c @@ -441,7 +441,6 @@ int xmpp_connect_client(xmpp_conn_t * const conn, { char connectdomain[XMPP_FQDN_MAX_LEN + 1]; int connectport; - const char * domain; conn->type = XMPP_CLIENT; @@ -451,19 +450,19 @@ int xmpp_connect_client(xmpp_conn_t * const conn, /* @TODO replace port 5222 with a marco */ if (altdomain) { + if (strlen(altdomain) > XMPP_FQDN_MAX_LEN) + return XMPP_EINVAL; xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); strcpy(connectdomain, altdomain); connectport = altport ? altport : 5222; } else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain, connectdomain, XMPP_FQDN_MAX_LEN + 1, &connectport)) { xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed."); - if (!altdomain) - domain = conn->domain; - else - domain = altdomain; - xmpp_debug(conn->ctx, "xmpp", "Using alternate domain %s, port %d", + if (strlen(conn->domain) > XMPP_FQDN_MAX_LEN) + return XMPP_EINVAL; + xmpp_debug(conn->ctx, "xmpp", "Using domain %s, port %d", altdomain, altport); - strcpy(connectdomain, domain); + strcpy(connectdomain, conn->domain); connectport = altport ? altport : 5222; } conn->sock = sock_connect(connectdomain, connectport); From ccb6e969315b09a7039f1284c7f61c355ec1401a Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 16 Oct 2012 11:05:33 +0300 Subject: [PATCH 39/65] replace port number 5222 with a macro --- couplet.h | 10 +++++++++- src/conn.c | 5 ++--- src/sock.c | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/couplet.h b/couplet.h index 0b9307ab..6422a6ba 100644 --- a/couplet.h +++ b/couplet.h @@ -104,9 +104,17 @@ extern "C" { #define XMPP_EINVAL -4 /** @def XMPP_FQDN_MAX_LEN - * Maximum length of FQDN. Should be set to 255 according to RFC2181. + * Maximum length of FQDN. + * + * Should be set to 255 according to RFC2181. */ #define XMPP_FQDN_MAX_LEN 255 +/** @def XMPP_CLIENT_PORT + * Default xmpp-client TCP port. + * + * The recomended port is 5222 according to RFC3920. + */ +#define XMPP_CLIENT_PORT 5222 /* initialization and shutdown */ void xmpp_initialize(void); diff --git a/src/conn.c b/src/conn.c index eb95f2e7..d1a16c46 100644 --- a/src/conn.c +++ b/src/conn.c @@ -448,13 +448,12 @@ int xmpp_connect_client(xmpp_conn_t * const conn, if (!conn->domain) return -1; - /* @TODO replace port 5222 with a marco */ if (altdomain) { if (strlen(altdomain) > XMPP_FQDN_MAX_LEN) return XMPP_EINVAL; xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain."); strcpy(connectdomain, altdomain); - connectport = altport ? altport : 5222; + connectport = altport ? altport : XMPP_CLIENT_PORT; } else if (!sock_srv_lookup("xmpp-client", "tcp", conn->domain, connectdomain, XMPP_FQDN_MAX_LEN + 1, &connectport)) { xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed."); @@ -463,7 +462,7 @@ int xmpp_connect_client(xmpp_conn_t * const conn, xmpp_debug(conn->ctx, "xmpp", "Using domain %s, port %d", altdomain, altport); strcpy(connectdomain, conn->domain); - connectport = altport ? altport : 5222; + connectport = altport ? altport : XMPP_CLIENT_PORT; } conn->sock = sock_connect(connectdomain, connectport); xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d", diff --git a/src/sock.c b/src/sock.c index d3f2798b..1a76b670 100644 --- a/src/sock.c +++ b/src/sock.c @@ -905,7 +905,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, if (!set) { snprintf(resulttarget, resulttargetlength, "%s", domain); - *resultport = 5222; + *resultport = XMPP_CLIENT_PORT; return 0; } From b6496f8cdc2b4e0102a101c63bb44f134945d52f Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 16 Oct 2012 11:13:54 +0300 Subject: [PATCH 40/65] sock.c: add missing couplet.h --- src/sock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sock.c b/src/sock.c index 1a76b670..a49c3f79 100644 --- a/src/sock.c +++ b/src/sock.c @@ -42,6 +42,7 @@ #endif #include "sock.h" +#include "couplet.h" void sock_initialize(void) { From eb52f457ff0308c5d6199eb4c0a7381f79ebe720 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 17 Oct 2012 17:17:39 +0300 Subject: [PATCH 41/65] sasl: spacing Also fixed possible null pointer dereference in _add_key. --- src/sasl.c | 991 ++++++++++++++++++++++++++--------------------------- src/sasl.h | 6 +- 2 files changed, 488 insertions(+), 509 deletions(-) diff --git a/src/sasl.c b/src/sasl.c index 9f93cb6a..872e5c6a 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -1,7 +1,7 @@ /* sasl.c ** strophe XMPP client library -- SASL authentication helpers -** -** Copyright (C) 2005-2009 Collecta, Inc. +** +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -25,15 +25,15 @@ /* make sure the stdint.h types are available */ #if defined(_MSC_VER) /* Microsoft Visual C++ */ - typedef signed char int8_t; - typedef short int int16_t; - typedef int int32_t; - typedef __int64 int64_t; - - typedef unsigned char uint8_t; - typedef unsigned short int uint16_t; - typedef unsigned int uint32_t; - /* no uint64_t */ +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef __int64 int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +/* no uint64_t */ #else #include #endif @@ -41,26 +41,26 @@ /** generate authentication string for the SASL PLAIN mechanism */ char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) { - int idlen, passlen; - char *result = NULL; - char *msg; - - /* our message is Base64(authzid,\0,authid,\0,password) - if there is no authzid, that field is left empty */ - - idlen = strlen(authid); - passlen = strlen(password); - msg = xmpp_alloc(ctx, 2 + idlen + passlen); - if (msg != NULL) { - msg[0] = '\0'; - memcpy(msg+1, authid, idlen); - msg[1+idlen] = '\0'; - memcpy(msg+1+idlen+1, password, passlen); - result = base64_encode(ctx, (unsigned char *)msg, 2 + idlen + passlen); - xmpp_free(ctx, msg); - } - - return result; + int idlen, passlen; + char *result = NULL; + char *msg; + + /* our message is Base64(authzid,\0,authid,\0,password) + * if there is no authzid, that field is left empty */ + + idlen = strlen(authid); + passlen = strlen(password); + msg = xmpp_alloc(ctx, 2 + idlen + passlen); + if (msg) { + msg[0] = '\0'; + memcpy(msg+1, authid, idlen); + msg[1+idlen] = '\0'; + memcpy(msg+1+idlen+1, password, passlen); + result = base64_encode(ctx, (unsigned char *)msg, 2 + idlen + passlen); + xmpp_free(ctx, msg); + } + + return result; } /** helpers for digest auth */ @@ -68,296 +68,307 @@ char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) { /* create a new, null-terminated string from a substring */ static char *_make_string(xmpp_ctx_t *ctx, const char *s, const unsigned len) { - char *result; - - result = xmpp_alloc(ctx, len + 1); - if (result != NULL) { - memcpy(result, s, len); - result[len] = '\0'; - } - return result; + char *result; + + result = xmpp_alloc(ctx, len + 1); + if (result != NULL) { + memcpy(result, s, len); + result[len] = '\0'; + } + + return result; } /* create a new, null-terminated string quoting another string */ static char *_make_quoted(xmpp_ctx_t *ctx, const char *s) { - char *result; - int len = strlen(s); - - result = xmpp_alloc(ctx, len + 3); - if (result != NULL) { - result[0] = '"'; - memcpy(result+1, s, len); - result[len+1] = '"'; - result[len+2] = '\0'; - } - return result; + char *result; + int len = strlen(s); + + result = xmpp_alloc(ctx, len + 3); + if (result != NULL) { + result[0] = '"'; + memcpy(result+1, s, len); + result[len+1] = '"'; + result[len+2] = '\0'; + } + + return result; } /* split key, value pairs into a hash */ static hash_t *_parse_digest_challenge(xmpp_ctx_t *ctx, const char *msg) { - hash_t *result; - unsigned char *text; - char *key, *value; - unsigned char *s, *t; - - text = base64_decode(ctx, msg, strlen(msg)); - if (text == NULL) { - xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!"); - return NULL; - } - - result = hash_new(ctx, 10, xmpp_free); - if (result != NULL) { - s = text; - while (*s != '\0') { - /* skip any leading commas and spaces */ - while ((*s == ',') || (*s == ' ')) s++; - /* accumulate a key ending at '=' */ - t = s; - while ((*t != '=') && (*t != '\0')) t++; - if (*t == '\0') break; /* bad string */ - key = _make_string(ctx, (char *)s, (t-s)); - if (key == NULL) break; - /* advance our start pointer past the key */ - s = t + 1; - t = s; - /* if we see quotes, grab the string in between */ - if ((*s == '\'') || (*s == '"')) { - t++; - while ((*t != *s) && (*t != '\0')) - t++; - value = _make_string(ctx, (char *)s+1, (t-s-1)); - if (*t == *s) { - s = t + 1; - } else { - s = t; + hash_t *result; + unsigned char *text; + char *key, *value; + unsigned char *s, *t; + + text = base64_decode(ctx, msg, strlen(msg)); + if (!text) { + xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!"); + return NULL; + } + + result = hash_new(ctx, 10, xmpp_free); + if (result) { + s = text; + while (*s != '\0') { + /* skip any leading commas and spaces */ + while ((*s == ',') || (*s == ' ')) + s++; + /* accumulate a key ending at '=' */ + t = s; + while ((*t != '=') && (*t != '\0')) + t++; + if (*t == '\0') /* bad string */ + break; + key = _make_string(ctx, (char *)s, (t-s)); + if (!key) + break; + /* advance our start pointer past the key */ + s = t + 1; + t = s; + /* if we see quotes, grab the string in between */ + if ((*s == '\'') || (*s == '"')) { + t++; + while ((*t != *s) && (*t != '\0')) + t++; + value = _make_string(ctx, (char *)s+1, (t-s-1)); + if (*t == *s) + s = t + 1; + else + s = t; + /* otherwise, accumulate a value ending in ',' or '\0' */ + } else { + while ((*t != ',') && (*t != '\0')) + t++; + value = _make_string(ctx, (char *)s, (t-s)); + s = t; + } + if (!value) { + xmpp_free(ctx, key); + break; + } + /* TODO: check for collisions per spec */ + hash_add(result, key, value); + /* hash table now owns the value, free the key */ + xmpp_free(ctx, key); } - /* otherwise, accumulate a value ending in ',' or '\0' */ - } else { - while ((*t != ',') && (*t != '\0')) t++; - value = _make_string(ctx, (char *)s, (t-s)); - s = t; - } - if (value == NULL) { - xmpp_free(ctx, key); - break; - } - /* TODO: check for collisions per spec */ - hash_add(result, key, value); - /* hash table now owns the value, free the key */ - xmpp_free(ctx, key); } - } - xmpp_free(ctx, text); + xmpp_free(ctx, text); - return result; + return result; } /** expand a 16 byte MD5 digest to a 32 byte hex representation */ static void _digest_to_hex(const char *digest, char *hex) { - int i; - const char hexdigit[] = "0123456789abcdef"; + int i; + const char hexdigit[] = "0123456789abcdef"; - for (i = 0; i < 16; i++) { - *hex++ = hexdigit[ (digest[i] >> 4) & 0x0F ]; - *hex++ = hexdigit[ digest[i] & 0x0F ]; - } + for (i = 0; i < 16; i++) { + *hex++ = hexdigit[ (digest[i] >> 4) & 0x0F ]; + *hex++ = hexdigit[ digest[i] & 0x0F ]; + } } /** append 'key="value"' to a buffer, growing as necessary */ -static char *_add_key(xmpp_ctx_t *ctx, hash_t *table, const char *key, +static char *_add_key(xmpp_ctx_t *ctx, hash_t *table, const char *key, char *buf, int *len, int quote) { - int olen,nlen; - int keylen, valuelen; - const char *value, *qvalue; - char *c; - - /* allocate a zero-length string if necessary */ - if (buf == NULL) { - buf = xmpp_alloc(ctx, 1); - buf[0] = '\0'; - } - if (buf == NULL) return NULL; - - /* get current string length */ - olen = strlen(buf); - value = hash_get(table, key); - if (value == NULL) { - xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key); - value = ""; - } - if (quote) { - qvalue = _make_quoted(ctx, value); - } else { - qvalue = value; - } - /* added length is key + '=' + value */ - /* (+ ',' if we're not the first entry */ - keylen = strlen(key); - valuelen = strlen(qvalue); - nlen = (olen ? 1 : 0) + keylen + 1 + valuelen + 1; - buf = xmpp_realloc(ctx, buf, olen+nlen); - - if (buf != NULL) { - c = buf + olen; - if (olen) *c++ = ','; - memcpy(c, key, keylen); c += keylen; - *c++ = '='; - memcpy(c, qvalue, valuelen); c += valuelen; - *c++ = '\0'; - } - - if (quote) xmpp_free(ctx, (char *)qvalue); - - return buf; + int olen,nlen; + int keylen, valuelen; + const char *value, *qvalue; + char *c; + + /* allocate a zero-length string if necessary */ + if (!buf) { + buf = xmpp_alloc(ctx, 1); + if (!buf) + return NULL; + buf[0] = '\0'; + } + + /* get current string length */ + olen = strlen(buf); + value = hash_get(table, key); + if (!value) { + xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key); + value = ""; + } + if (quote) + qvalue = _make_quoted(ctx, value); + else + qvalue = value; + + /* added length is key + '=' + value */ + /* (+ ',' if we're not the first entry */ + keylen = strlen(key); + valuelen = strlen(qvalue); + nlen = (olen ? 1 : 0) + keylen + 1 + valuelen + 1; + buf = xmpp_realloc(ctx, buf, olen+nlen); + + if (buf) { + c = buf + olen; + if (olen) + *c++ = ','; + memcpy(c, key, keylen); c += keylen; + *c++ = '='; + memcpy(c, qvalue, valuelen); c += valuelen; + *c++ = '\0'; + } + + if (quote) + xmpp_free(ctx, (char *)qvalue); + + return buf; } /** generate auth response string for the SASL DIGEST-MD5 mechanism */ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge, - const char *jid, const char *password) { - hash_t *table; - char *result = NULL; - char *node, *domain, *realm; - char *value; - char *response; - int rlen; - struct MD5Context MD5; - unsigned char digest[16], HA1[16], HA2[16]; - char hex[32]; - - /* our digest response is - Hex( KD( HEX(MD5(A1)), - nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2)) - )) - - where KD(k, s) = MD5(k ':' s), - A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce - A2 = "AUTHENTICATE" ':' "xmpp/" domain - - If there is an authzid it is ':'-appended to A1 */ - - /* parse the challenge */ - table = _parse_digest_challenge(ctx, challenge); - if (table == NULL) { - xmpp_error(ctx, "SASL", "couldn't parse digest challenge"); - return NULL; - } + const char *jid, const char *password) +{ + hash_t *table; + char *result = NULL; + char *node, *domain, *realm; + char *value; + char *response; + int rlen; + struct MD5Context MD5; + unsigned char digest[16], HA1[16], HA2[16]; + char hex[32]; + + /* our digest response is + * Hex( KD( HEX(MD5(A1)), + * nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2)) + * )) + * + * where KD(k, s) = MD5(k ':' s), + * A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce + * A2 = "AUTHENTICATE" ':' "xmpp/" domain + * + * If there is an authzid it is ':'-appended to A1 + */ + + /* parse the challenge */ + table = _parse_digest_challenge(ctx, challenge); + if (!table) { + xmpp_error(ctx, "SASL", "couldn't parse digest challenge"); + return NULL; + } - node = xmpp_jid_node(ctx, jid); - domain = xmpp_jid_domain(ctx, jid); + node = xmpp_jid_node(ctx, jid); + domain = xmpp_jid_domain(ctx, jid); - /* generate default realm of domain if one didn't come from the - server */ - realm = hash_get(table, "realm"); - if (realm == NULL || strlen(realm) == 0) { - hash_add(table, "realm", xmpp_strdup(ctx, domain)); + /* generate default realm of domain if one didn't come from the + * server */ realm = hash_get(table, "realm"); - } - - /* add our response fields */ - hash_add(table, "username", xmpp_strdup(ctx, node)); - /* TODO: generate a random cnonce */ - hash_add(table, "cnonce", xmpp_strdup(ctx, "00DEADBEEF00")); - hash_add(table, "nc", xmpp_strdup(ctx, "00000001")); - hash_add(table, "qop", xmpp_strdup(ctx, "auth")); - value = xmpp_alloc(ctx, 5 + strlen(domain) + 1); - memcpy(value, "xmpp/", 5); - memcpy(value+5, domain, strlen(domain)); - value[5+strlen(domain)] = '\0'; - hash_add(table, "digest-uri", value); - - /* generate response */ - - /* construct MD5(node : realm : password) */ - MD5Init(&MD5); - MD5Update(&MD5, (unsigned char *)node, strlen(node)); - MD5Update(&MD5, (unsigned char *)":", 1); - MD5Update(&MD5, (unsigned char *)realm, strlen(realm)); - MD5Update(&MD5, (unsigned char *)":", 1); - MD5Update(&MD5, (unsigned char *)password, strlen(password)); - MD5Final(digest, &MD5); - - /* digest now contains the first field of A1 */ - - MD5Init(&MD5); - MD5Update(&MD5, digest, 16); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "nonce"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "cnonce"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Final(digest, &MD5); - - /* now digest is MD5(A1) */ - memcpy(HA1, digest, 16); - - /* construct MD5(A2) */ - MD5Init(&MD5); - MD5Update(&MD5, (unsigned char *)"AUTHENTICATE:", 13); - value = hash_get(table, "digest-uri"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - if (strcmp(hash_get(table, "qop"), "auth") != 0) { - MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000", - 33); - } - MD5Final(digest, &MD5); - - memcpy(HA2, digest, 16); - - /* construct response */ - MD5Init(&MD5); - _digest_to_hex((char *)HA1, hex); - MD5Update(&MD5, (unsigned char *)hex, 32); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "nonce"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "nc"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "cnonce"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Update(&MD5, (unsigned char *)":", 1); - value = hash_get(table, "qop"); - MD5Update(&MD5, (unsigned char *)value, strlen(value)); - MD5Update(&MD5, (unsigned char *)":", 1); - _digest_to_hex((char *)HA2, hex); - MD5Update(&MD5, (unsigned char *)hex, 32); - MD5Final(digest, &MD5); - - response = xmpp_alloc(ctx, 32+1); - _digest_to_hex((char *)digest, hex); - memcpy(response, hex, 32); - response[32] = '\0'; - hash_add(table, "response", response); - - /* construct reply */ - result = NULL; - rlen = 0; - result = _add_key(ctx, table, "username", result, &rlen, 1); - result = _add_key(ctx, table, "realm", result, &rlen, 1); - result = _add_key(ctx, table, "nonce", result, &rlen, 1); - result = _add_key(ctx, table, "cnonce", result, &rlen, 1); - result = _add_key(ctx, table, "nc", result, &rlen, 0); - result = _add_key(ctx, table, "qop", result, &rlen, 0); - result = _add_key(ctx, table, "digest-uri", result, &rlen, 1); - result = _add_key(ctx, table, "response", result, &rlen, 0); - result = _add_key(ctx, table, "charset", result, &rlen, 0); + if (!realm || !strlen(realm)) { + hash_add(table, "realm", xmpp_strdup(ctx, domain)); + realm = hash_get(table, "realm"); + } + + /* add our response fields */ + hash_add(table, "username", xmpp_strdup(ctx, node)); + /* TODO: generate a random cnonce */ + hash_add(table, "cnonce", xmpp_strdup(ctx, "00DEADBEEF00")); + hash_add(table, "nc", xmpp_strdup(ctx, "00000001")); + hash_add(table, "qop", xmpp_strdup(ctx, "auth")); + value = xmpp_alloc(ctx, 5 + strlen(domain) + 1); + memcpy(value, "xmpp/", 5); + memcpy(value+5, domain, strlen(domain)); + value[5+strlen(domain)] = '\0'; + hash_add(table, "digest-uri", value); + + /* generate response */ + + /* construct MD5(node : realm : password) */ + MD5Init(&MD5); + MD5Update(&MD5, (unsigned char *)node, strlen(node)); + MD5Update(&MD5, (unsigned char *)":", 1); + MD5Update(&MD5, (unsigned char *)realm, strlen(realm)); + MD5Update(&MD5, (unsigned char *)":", 1); + MD5Update(&MD5, (unsigned char *)password, strlen(password)); + MD5Final(digest, &MD5); + + /* digest now contains the first field of A1 */ + + MD5Init(&MD5); + MD5Update(&MD5, digest, 16); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "nonce"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "cnonce"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Final(digest, &MD5); + + /* now digest is MD5(A1) */ + memcpy(HA1, digest, 16); + + /* construct MD5(A2) */ + MD5Init(&MD5); + MD5Update(&MD5, (unsigned char *)"AUTHENTICATE:", 13); + value = hash_get(table, "digest-uri"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + if (strcmp(hash_get(table, "qop"), "auth")) { + MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000", 33); + } + MD5Final(digest, &MD5); + + memcpy(HA2, digest, 16); + + /* construct response */ + MD5Init(&MD5); + _digest_to_hex((char *)HA1, hex); + MD5Update(&MD5, (unsigned char *)hex, 32); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "nonce"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "nc"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "cnonce"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Update(&MD5, (unsigned char *)":", 1); + value = hash_get(table, "qop"); + MD5Update(&MD5, (unsigned char *)value, strlen(value)); + MD5Update(&MD5, (unsigned char *)":", 1); + _digest_to_hex((char *)HA2, hex); + MD5Update(&MD5, (unsigned char *)hex, 32); + MD5Final(digest, &MD5); + + response = xmpp_alloc(ctx, 32 + 1); + /** @TODO check 'response' for NULL */ + _digest_to_hex((char *)digest, hex); + memcpy(response, hex, 32); + response[32] = '\0'; + hash_add(table, "response", response); + + /* construct reply */ + result = NULL; + rlen = 0; + result = _add_key(ctx, table, "username", result, &rlen, 1); + result = _add_key(ctx, table, "realm", result, &rlen, 1); + result = _add_key(ctx, table, "nonce", result, &rlen, 1); + result = _add_key(ctx, table, "cnonce", result, &rlen, 1); + result = _add_key(ctx, table, "nc", result, &rlen, 0); + result = _add_key(ctx, table, "qop", result, &rlen, 0); + result = _add_key(ctx, table, "digest-uri", result, &rlen, 1); + result = _add_key(ctx, table, "response", result, &rlen, 0); + result = _add_key(ctx, table, "charset", result, &rlen, 0); - xmpp_free(ctx, node); - xmpp_free(ctx, domain); - hash_release(table); /* also frees value strings */ + xmpp_free(ctx, node); + xmpp_free(ctx, domain); + hash_release(table); /* also frees value strings */ - /* reuse response for the base64 encode of our result */ - response = base64_encode(ctx, (unsigned char *)result, strlen(result)); - xmpp_free(ctx, result); + /* reuse response for the base64 encode of our result */ + response = base64_encode(ctx, (unsigned char *)result, strlen(result)); + xmpp_free(ctx, result); - return response; + return response; } @@ -366,252 +377,220 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge, /** map of all byte values to the base64 values, or to '65' which indicates an invalid character. '=' is '64' */ static const char _base64_invcharmap[256] = { - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,62, 65,65,65,63, - 52,53,54,55, 56,57,58,59, 60,61,65,65, 65,64,65,65, - 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,65, 65,65,65,65, - 65,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, - 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65 + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,62, 65,65,65,63, + 52,53,54,55, 56,57,58,59, 60,61,65,65, 65,64,65,65, + 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,65, 65,65,65,65, + 65,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65, + 65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65 }; /** map of all 6-bit values to their corresponding byte in the base64 alphabet. Padding char is the value '64' */ static const char _base64_charmap[65] = { - 'A','B','C','D', 'E','F','G','H', - 'I','J','K','L', 'M','N','O','P', - 'Q','R','S','T', 'U','V','W','X', - 'Y','Z','a','b', 'c','d','e','f', - 'g','h','i','j', 'k','l','m','n', - 'o','p','q','r', 's','t','u','v', - 'w','x','y','z', '0','1','2','3', - '4','5','6','7', '8','9','+','/', - '=' + 'A','B','C','D', 'E','F','G','H', + 'I','J','K','L', 'M','N','O','P', + 'Q','R','S','T', 'U','V','W','X', + 'Y','Z','a','b', 'c','d','e','f', + 'g','h','i','j', 'k','l','m','n', + 'o','p','q','r', 's','t','u','v', + 'w','x','y','z', '0','1','2','3', + '4','5','6','7', '8','9','+','/', + '=' }; int base64_encoded_len(xmpp_ctx_t *ctx, const unsigned len) { - /* encoded steam is 4 bytes for every three, rounded up */ - return ((len + 2)/3) << 2; + /* encoded steam is 4 bytes for every three, rounded up */ + return ((len + 2)/3) << 2; } -char *base64_encode(xmpp_ctx_t *ctx, +char *base64_encode(xmpp_ctx_t *ctx, const unsigned char * const buffer, const unsigned len) { - int clen; - char *cbuf, *c; - uint32_t word, hextet; - int i; - - clen = base64_encoded_len(ctx, len); - cbuf = xmpp_alloc(ctx, clen + 1); - if (cbuf != NULL) { - c = cbuf; - /* loop over data, turning every 3 bytes into 4 characters */ - for (i = 0; i < len - 2; i += 3) { - word = buffer[i] << 16 | buffer[i+1] << 8 | buffer[i+2]; - hextet = (word & 0x00FC0000) >> 18; - *c++ = _base64_charmap[hextet]; - hextet = (word & 0x0003F000) >> 12; - *c++ = _base64_charmap[hextet]; - hextet = (word & 0x00000FC0) >> 6; - *c++ = _base64_charmap[hextet]; - hextet = (word & 0x000003F); - *c++ = _base64_charmap[hextet]; - } - /* zero, one or two bytes left */ - switch (len - i) { - case 0: - break; - case 1: - hextet = (buffer[len-1] & 0xFC) >> 2; - *c++ = _base64_charmap[hextet]; - hextet = (buffer[len-1] & 0x03) << 4; - *c++ = _base64_charmap[hextet]; - *c++ = _base64_charmap[64]; /* pad */ - *c++ = _base64_charmap[64]; /* pad */ - break; - case 2: - hextet = (buffer[len-2] & 0xFC) >> 2; - *c++ = _base64_charmap[hextet]; - hextet = ((buffer[len-2] & 0x03) << 4) | - ((buffer[len-1] & 0xF0) >> 4); - *c++ = _base64_charmap[hextet]; - hextet = (buffer[len-1] & 0x0F) << 2; - *c++ = _base64_charmap[hextet]; - *c++ = _base64_charmap[64]; /* pad */ - break; + int clen; + char *cbuf, *c; + uint32_t word, hextet; + int i; + + clen = base64_encoded_len(ctx, len); + cbuf = xmpp_alloc(ctx, clen + 1); + if (cbuf) { + c = cbuf; + /* loop over data, turning every 3 bytes into 4 characters */ + for (i = 0; i < len - 2; i += 3) { + word = buffer[i] << 16 | buffer[i+1] << 8 | buffer[i+2]; + hextet = (word & 0x00FC0000) >> 18; + *c++ = _base64_charmap[hextet]; + hextet = (word & 0x0003F000) >> 12; + *c++ = _base64_charmap[hextet]; + hextet = (word & 0x00000FC0) >> 6; + *c++ = _base64_charmap[hextet]; + hextet = (word & 0x000003F); + *c++ = _base64_charmap[hextet]; + } + /* zero, one or two bytes left */ + switch (len - i) { + case 0: + break; + case 1: + hextet = (buffer[len-1] & 0xFC) >> 2; + *c++ = _base64_charmap[hextet]; + hextet = (buffer[len-1] & 0x03) << 4; + *c++ = _base64_charmap[hextet]; + *c++ = _base64_charmap[64]; /* pad */ + *c++ = _base64_charmap[64]; /* pad */ + break; + case 2: + hextet = (buffer[len-2] & 0xFC) >> 2; + *c++ = _base64_charmap[hextet]; + hextet = ((buffer[len-2] & 0x03) << 4) | + ((buffer[len-1] & 0xF0) >> 4); + *c++ = _base64_charmap[hextet]; + hextet = (buffer[len-1] & 0x0F) << 2; + *c++ = _base64_charmap[hextet]; + *c++ = _base64_charmap[64]; /* pad */ + break; + } + /* add a terminal null */ + *c = '\0'; } - /* add a terminal null */ - *c = '\0'; - } - return cbuf; + return cbuf; } int base64_decoded_len(xmpp_ctx_t *ctx, const char * const buffer, const unsigned len) { - int nudge; - int c; - - /* count the padding characters for the remainder */ - nudge = -1; - c = _base64_invcharmap[(int)buffer[len-1]]; - if (c < 64) nudge = 0; - else if (c == 64) { - c = _base64_invcharmap[(int)buffer[len-2]]; - if (c < 64) nudge = 1; + int nudge; + int c; + + /* count the padding characters for the remainder */ + nudge = -1; + c = _base64_invcharmap[(int)buffer[len-1]]; + if (c < 64) + nudge = 0; else if (c == 64) { - c = _base64_invcharmap[(int)buffer[len-3]]; - if (c < 64) nudge = 2; - } - } - if (nudge < 0) return 0; /* reject bad coding */ - - /* decoded steam is 3 bytes for every four */ - return 3 * (len >> 2) - nudge; + c = _base64_invcharmap[(int)buffer[len-2]]; + if (c < 64) + nudge = 1; + else if (c == 64) { + c = _base64_invcharmap[(int)buffer[len-3]]; + if (c < 64) + nudge = 2; + } + } + if (nudge < 0) + return 0; /* reject bad coding */ + + /* decoded steam is 3 bytes for every four */ + return 3 * (len >> 2) - nudge; } unsigned char *base64_decode(xmpp_ctx_t *ctx, const char * const buffer, const unsigned len) { - int dlen; - unsigned char *dbuf, *d; - uint32_t word, hextet = 0; - int i; - - /* handle zero-length buffers */ - if (!len) return NULL; - /* len must be a multiple of 4 */ - if (len & 0x03) return NULL; - - dlen = base64_decoded_len(ctx, buffer, len); - d = dbuf = xmpp_alloc(ctx, dlen + 1); - if (dbuf != NULL) { - /* loop over each set of 4 characters, decoding 3 bytes */ - for (i = 0; i < len - 3; i += 4) { - hextet = _base64_invcharmap[(int)buffer[i]]; - if (hextet & 0xC0) break; - word = hextet << 18; - hextet = _base64_invcharmap[(int)buffer[i+1]]; - if (hextet & 0xC0) break; - word |= hextet << 12; - hextet = _base64_invcharmap[(int)buffer[i+2]]; - if (hextet & 0xC0) break; - word |= hextet << 6; - hextet = _base64_invcharmap[(int)buffer[i+3]]; - if (hextet & 0xC0) break; - word |= hextet; - *d++ = (word & 0x00FF0000) >> 16; - *d++ = (word & 0x0000FF00) >> 8; - *d++ = (word & 0x000000FF); - } - if (hextet > 64) goto _base64_decode_error; - /* handle the remainder */ - switch (dlen % 3) { - case 0: - /* nothing to do */ - break; - case 1: - /* redo the last quartet, checking for correctness */ - hextet = _base64_invcharmap[(int)buffer[len-4]]; - if (hextet & 0xC0) goto _base64_decode_error; - word = hextet << 2; - hextet = _base64_invcharmap[(int)buffer[len-3]]; - if (hextet & 0xC0) goto _base64_decode_error; - word |= hextet >> 4; - *d++ = word & 0xFF; - hextet = _base64_invcharmap[(int)buffer[len-2]]; - if (hextet != 64) goto _base64_decode_error; - hextet = _base64_invcharmap[(int)buffer[len-1]]; - if (hextet != 64) goto _base64_decode_error; - break; - case 2: - /* redo the last quartet, checking for correctness */ - hextet = _base64_invcharmap[(int)buffer[len-4]]; - if (hextet & 0xC0) goto _base64_decode_error; - word = hextet << 10; - hextet = _base64_invcharmap[(int)buffer[len-3]]; - if (hextet & 0xC0) goto _base64_decode_error; - word |= hextet << 4; - hextet = _base64_invcharmap[(int)buffer[len-2]]; - if (hextet & 0xC0) goto _base64_decode_error; - word |= hextet >> 2; - *d++ = (word & 0xFF00) >> 8; - *d++ = (word & 0x00FF); - hextet = _base64_invcharmap[(int)buffer[len-1]]; - if (hextet != 64) goto _base64_decode_error; - break; + int dlen; + unsigned char *dbuf, *d; + uint32_t word, hextet = 0; + int i; + + /* handle zero-length buffers */ + if (!len) + return NULL; + /* len must be a multiple of 4 */ + if (len & 0x03) + return NULL; + + dlen = base64_decoded_len(ctx, buffer, len); + d = dbuf = xmpp_alloc(ctx, dlen + 1); + if (dbuf) { + /* loop over each set of 4 characters, decoding 3 bytes */ + for (i = 0; i < len - 3; i += 4) { + hextet = _base64_invcharmap[(int)buffer[i]]; + if (hextet & 0xC0) + break; + word = hextet << 18; + hextet = _base64_invcharmap[(int)buffer[i+1]]; + if (hextet & 0xC0) + break; + word |= hextet << 12; + hextet = _base64_invcharmap[(int)buffer[i+2]]; + if (hextet & 0xC0) + break; + word |= hextet << 6; + hextet = _base64_invcharmap[(int)buffer[i+3]]; + if (hextet & 0xC0) + break; + word |= hextet; + *d++ = (word & 0x00FF0000) >> 16; + *d++ = (word & 0x0000FF00) >> 8; + *d++ = (word & 0x000000FF); + } + if (hextet > 64) + goto _base64_decode_error; + /* handle the remainder */ + switch (dlen % 3) { + case 0: + /* nothing to do */ + break; + case 1: + /* redo the last quartet, checking for correctness */ + hextet = _base64_invcharmap[(int)buffer[len-4]]; + if (hextet & 0xC0) + goto _base64_decode_error; + word = hextet << 2; + hextet = _base64_invcharmap[(int)buffer[len-3]]; + if (hextet & 0xC0) + goto _base64_decode_error; + word |= hextet >> 4; + *d++ = word & 0xFF; + hextet = _base64_invcharmap[(int)buffer[len-2]]; + if (hextet != 64) + goto _base64_decode_error; + hextet = _base64_invcharmap[(int)buffer[len-1]]; + if (hextet != 64) + goto _base64_decode_error; + break; + case 2: + /* redo the last quartet, checking for correctness */ + hextet = _base64_invcharmap[(int)buffer[len-4]]; + if (hextet & 0xC0) + goto _base64_decode_error; + word = hextet << 10; + hextet = _base64_invcharmap[(int)buffer[len-3]]; + if (hextet & 0xC0) + goto _base64_decode_error; + word |= hextet << 4; + hextet = _base64_invcharmap[(int)buffer[len-2]]; + if (hextet & 0xC0) + goto _base64_decode_error; + word |= hextet >> 2; + *d++ = (word & 0xFF00) >> 8; + *d++ = (word & 0x00FF); + hextet = _base64_invcharmap[(int)buffer[len-1]]; + if (hextet != 64) + goto _base64_decode_error; + break; + } } - } - if (d) - *d = '\0'; - return dbuf; - -_base64_decode_error: - /* invalid character; abort decoding! */ - xmpp_free(ctx, dbuf); - return NULL; -} - -/*** self tests ***/ -#ifdef TEST - -#include + if (d) + *d = '\0'; -int test_charmap_identity(void) -{ - int i, v, u; - - for (i = 0; i < 65; i++) { - v = _base64_charmap[i]; - if (v > 255) return 1; - u = _base64_invcharmap[v]; -/* printf("map: %d -> %d -> %d\n", i, v, u); */ - if (u != i) return 1; - } + return dbuf; - return 0; -} - -int test_charmap_range(void) -{ - int i, v; - - for (i = 64; i < 256; i++) { - v = _base64_invcharmap[i]; - if (i < 64) return 1; - } - - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret = 0; - - printf("testing charmap identity..."); - ret = test_charmap_identity(); - if (ret) return ret; - printf(" ok.\n"); - - printf("testing charmap range..."); - ret = test_charmap_range(); - if (ret) return ret; - printf(" ok.\n"); - - printf("no error\n"); - return 0; +_base64_decode_error: + /* invalid character; abort decoding! */ + xmpp_free(ctx, dbuf); + return NULL; } - -#endif /* TEST */ diff --git a/src/sasl.h b/src/sasl.h index 3709dfea..5cc1e7b2 100644 --- a/src/sasl.h +++ b/src/sasl.h @@ -1,7 +1,7 @@ /* sasl.h ** strophe XMPP client library -- SASL authentication helpers -** -** Copyright (C) 2005-2009 Collecta, Inc. +** +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -32,7 +32,7 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge, int base64_encoded_len(xmpp_ctx_t *ctx, const unsigned len); -char *base64_encode(xmpp_ctx_t *ctx, +char *base64_encode(xmpp_ctx_t *ctx, const unsigned char * const buffer, const unsigned len); int base64_decoded_len(xmpp_ctx_t *ctx, From 943bd62f1ebcf1f58b635ff022654a286df27cef Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 17 Oct 2012 19:30:24 +0300 Subject: [PATCH 42/65] ctx.c: update todo list --- src/ctx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ctx.c b/src/ctx.c index fa636825..6d1823fe 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -263,7 +263,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, bigbuf = (char *)xmpp_alloc(ctx, ret + 1); if (!bigbuf) { bigbuf = NULL; - /* @TODO avoid recursive calls */ + /** @TODO avoid recursive calls */ xmpp_error(ctx, "log", "Failed allocating memory for log message."); return; } @@ -273,7 +273,7 @@ void xmpp_log(const xmpp_ctx_t * const ctx, va_end(ap_copy); if (ret > oldret) { - /* @TODO avoid recursive calls */ + /** @TODO avoid recursive calls */ xmpp_error(ctx, "log", "Unexpected error"); xmpp_free(ctx, bigbuf); return; From a1c6745a9e867ff379733187ca2111626ff732dc Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Wed, 17 Oct 2012 20:16:57 +0300 Subject: [PATCH 43/65] ctx: destroy send_queeu_sem on destroying ctx --- src/ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ctx.c b/src/ctx.c index 6d1823fe..01e91946 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -437,7 +437,7 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, void xmpp_ctx_free(xmpp_ctx_t * const ctx) { mutex_destroy(ctx->connlist_mutex); - /** @TODO destroy ctx->send_queue_sem */ + xmpp_sem_destroy(ctx->send_queue_sem); /* mem and log are owned by their suppliers */ xmpp_free(ctx, ctx); /* pull the hole in after us */ From 226f59c166bafb3c238d34dae5f5e47282557a88 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 18 Oct 2012 20:56:27 +0300 Subject: [PATCH 44/65] doc: update README --- README.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.markdown b/README.markdown index 4745147b..683eae8d 100644 --- a/README.markdown +++ b/README.markdown @@ -35,6 +35,14 @@ check package. Windows systems aren't supported for now. +### Gentoo + +libcouplet can be installed from Gentoo overlay 'stuff': + + layman -a stuff + echo =dev-libs/libcouplet-9999 ** >> /etc/portage/package.keywords + emerge libcouplet + ### OS X (with Homebrew package manager) You can install the requirements with: From 349c1aaa622e2c3e0316711c6473265e923e5c51 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Thu, 18 Oct 2012 23:58:57 +0300 Subject: [PATCH 45/65] introduce api for general lists --- src/list.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/list.h | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/list.c create mode 100644 src/list.h diff --git a/src/list.c b/src/list.c new file mode 100644 index 00000000..1bb89381 --- /dev/null +++ b/src/list.c @@ -0,0 +1,62 @@ +/* list.c + * libcouplet - fork of libstrophe, XMPP client library + * General list routines + * + * Copyright (C) 2012 Dmitry Podgorny + * + * This software is provided AS-IS with no warranty + * + * You can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, either version + * 3 of the License, or any later version. + */ + +/** @file + * General list routines + */ + +#include "list.h" + +list_head_t *list_init(const xmpp_ctx_t * const ctx) +{ +} + +list_t *list_init_item(const xmpp_ctx_t * const ctx) +{ +} + +list_t *list_get_first(const list_head_t * const list) +{ +} + +list_t *list_get_next(const list_head_t * const list, const list_t * const item) +{ +} + +list_t *list_get_last(const list_head_t * const list) +{ +} + +list_t *list_pull_first(const list_head_t * const list) +{ +} + +list_t *list_pull_last(const list_head_t * const list) +{ +} + +void list_insert(list_head_t * const list, list_t * const item) +{ +} + +void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after) +{ +} + +void list_append(list_head_t * const list, list_t * const item) +{ +} + +void list_update(list_head_t * const list, list_t * const item, const void * const data) +{ +} diff --git a/src/list.h b/src/list.h new file mode 100644 index 00000000..b8009b65 --- /dev/null +++ b/src/list.h @@ -0,0 +1,52 @@ +/* list.h + * libcouplet - fork of libstrophe, XMPP client library + * General list routines + * + * Copyright (C) 2012 Dmitry Podgorny + * + * This software is provided AS-IS with no warranty + * + * You can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, either version + * 3 of the License, or any later version. + */ + +/** @file + * General list routines header + */ + +#ifndef __LIBCOUPLET_LIST_H__ +#define __LIBCOUPLET_LIST_H__ + +#include "couplet.h" +#include "thread.h" + +struct _list_t { + void *data; + struct _list_t *next; +}; + +typedef struct _list_t list_t; + +struct _list_head_t { + xmpp_ctx_t *ctx; + mutex_t *mutex; + list_t *head; + list_t *tail; +}; + +typedef struct _list_head_t list_head_t; + +list_head_t *list_init(const xmpp_ctx_t * const ctx); +list_t *list_init_item(const xmpp_ctx_t * const ctx); +list_t *list_get_first(const list_head_t * const list); +list_t *list_get_next(const list_head_t * const list, const list_t * const item); +list_t *list_get_last(const list_head_t * const list); +list_t *list_pull_first(const list_head_t * const list); +list_t *list_pull_last(const list_head_t * const list); +void list_insert(list_head_t * const list, list_t * const item); +void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after); +void list_append(list_head_t * const list, list_t * const item); +void list_update(list_head_t * const list, list_t * const item, const void * const data); + +#endif From 76e52343e667070a2baa50c2da6945295a3cd386 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 00:18:09 +0300 Subject: [PATCH 46/65] list: update api --- src/list.c | 12 ++++++++++-- src/list.h | 16 ++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/list.c b/src/list.c index 1bb89381..2063c03b 100644 --- a/src/list.c +++ b/src/list.c @@ -21,6 +21,10 @@ list_head_t *list_init(const xmpp_ctx_t * const ctx) { } +void list_destroy(list_head_t *list) +{ +} + list_t *list_init_item(const xmpp_ctx_t * const ctx) { } @@ -37,11 +41,15 @@ list_t *list_get_last(const list_head_t * const list) { } -list_t *list_pull_first(const list_head_t * const list) +list_t *list_pull_first(list_head_t * const list) +{ +} + +list_t *list_pull_next(list_head_t * const list, list_t * const item) { } -list_t *list_pull_last(const list_head_t * const list) +list_t *list_pull_last(list_head_t * const list) { } diff --git a/src/list.h b/src/list.h index b8009b65..5b2a3e5a 100644 --- a/src/list.h +++ b/src/list.h @@ -38,15 +38,27 @@ struct _list_head_t { typedef struct _list_head_t list_head_t; list_head_t *list_init(const xmpp_ctx_t * const ctx); +void list_destroy(list_head_t *list); list_t *list_init_item(const xmpp_ctx_t * const ctx); list_t *list_get_first(const list_head_t * const list); list_t *list_get_next(const list_head_t * const list, const list_t * const item); list_t *list_get_last(const list_head_t * const list); -list_t *list_pull_first(const list_head_t * const list); -list_t *list_pull_last(const list_head_t * const list); +list_t *list_pull_first(list_head_t * const list); +list_t *list_pull_next(list_head_t * const list, list_t * const item); +list_t *list_pull_last(list_head_t * const list); void list_insert(list_head_t * const list, list_t * const item); void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after); void list_append(list_head_t * const list, list_t * const item); void list_update(list_head_t * const list, list_t * const item, const void * const data); +inline void list_lock(const list_head_t * const list) +{ + mutex_lock(list->mutex); +} + +inline void list_unlock(const list_head_t * const list) +{ + mutex_unlock(list->mutex); +} + #endif From 0c00ae82df6c44547de185c30c656e312ff3bab3 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 10:43:28 +0300 Subject: [PATCH 47/65] list: implement some functions implement list_init implement list_init_item implement list_pull_first implement list_insert implememt list_append --- src/list.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/list.c b/src/list.c index 2063c03b..67960897 100644 --- a/src/list.c +++ b/src/list.c @@ -17,16 +17,58 @@ #include "list.h" +/** Create new list. + * + * @param ctx a context object + * + * @return a pointer to allocated list_head_t structure or NULL pointer + */ list_head_t *list_init(const xmpp_ctx_t * const ctx) { + list_head_t *list; + + if (!ctx) + return NULL; + + list = (list_head_t *)xmpp_alloc(ctx, sizeof(*list)); + if (list) { + list->mutex = mutex_create(ctx); + if (!list->mutex) { + xmpp_free(ctx, list); + return NULL; + } + list->ctx = ctx; + list->head = NULL; + list->tail = NULL; + } + + return list; } void list_destroy(list_head_t *list) { } +/** Create new list item + * + * @param ctx a context object + * + * @return a pointer to allocated list_t structure or NULL pointer + */ list_t *list_init_item(const xmpp_ctx_t * const ctx) { + list_t *item; + + if (!ctx) + return NULL; + + item = (list_t *)xmpp_alloc(ctx, sizeof(*item)); + if (item) { + item->data = NULL; + item->next = NULL; + } + + return item; } list_t *list_get_first(const list_head_t * const list) @@ -41,8 +83,26 @@ list_t *list_get_last(const list_head_t * const list) { } +/** Get the first element of the list and remove it + * + * @param list a list object + * + * @return pointer to the first element or NULL pointer if such doesn't exist + */ list_t *list_pull_first(list_head_t * const list) { + list_t *item; + + mutex_lock(list->mutex); + item = list->head; + if (item) { + list->head = item->next; + if (!list->head) + list->tail = NULL; + } + mutex_unlock(list->mutex); + + return item; } list_t *list_pull_next(list_head_t * const list, list_t * const item) @@ -53,16 +113,45 @@ list_t *list_pull_last(list_head_t * const list) { } +/** Insert the element to the head of the list + * + * @param list a list object + * @param item an element for insertion + */ void list_insert(list_head_t * const list, list_t * const item) { + if (!item) + return; + + mutex_lock(list->mutex); + item->next = list->head; + list->head = item; + if (!item->next) + list->tail = item; + mutex_unlock(list->mutex); } void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after) { } +/** Append the element to the end of the list + * + * @param list a list object + * @param item an element + */ void list_append(list_head_t * const list, list_t * const item) { + if (!item) + return; + + mutex_lock(list->mutex); + if (!list->tail) + list->head = item; + else + list->tail->next = item; + list->tail = item; + mutex_unlock(list->mutex); } void list_update(list_head_t * const list, list_t * const item, const void * const data) From 4d554b96a7a6abc8c3b69ee730704b2b2b1eb82d Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 11:28:00 +0300 Subject: [PATCH 48/65] list: rename some functions rename list_pull_first rename list_pull_next rename list_pull_last rename list_append --- src/list.c | 8 ++++---- src/list.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/list.c b/src/list.c index 67960897..7940d804 100644 --- a/src/list.c +++ b/src/list.c @@ -89,7 +89,7 @@ list_t *list_get_last(const list_head_t * const list) * * @return pointer to the first element or NULL pointer if such doesn't exist */ -list_t *list_pull_first(list_head_t * const list) +list_t *list_shift(list_head_t * const list) { list_t *item; @@ -105,11 +105,11 @@ list_t *list_pull_first(list_head_t * const list) return item; } -list_t *list_pull_next(list_head_t * const list, list_t * const item) +list_t *list_shift_next(list_head_t * const list, list_t * const item) { } -list_t *list_pull_last(list_head_t * const list) +list_t *list_pop(list_head_t * const list) { } @@ -140,7 +140,7 @@ void list_insert_after(list_head_t * const list, list_t * const item, list_t * c * @param list a list object * @param item an element */ -void list_append(list_head_t * const list, list_t * const item) +void list_push(list_head_t * const list, list_t * const item) { if (!item) return; diff --git a/src/list.h b/src/list.h index 5b2a3e5a..a3df14d0 100644 --- a/src/list.h +++ b/src/list.h @@ -43,12 +43,12 @@ list_t *list_init_item(const xmpp_ctx_t * const ctx); list_t *list_get_first(const list_head_t * const list); list_t *list_get_next(const list_head_t * const list, const list_t * const item); list_t *list_get_last(const list_head_t * const list); -list_t *list_pull_first(list_head_t * const list); -list_t *list_pull_next(list_head_t * const list, list_t * const item); -list_t *list_pull_last(list_head_t * const list); +list_t *list_shift(list_head_t * const list); +list_t *list_shift_next(list_head_t * const list, list_t * const item); +list_t *list_pop(list_head_t * const list); void list_insert(list_head_t * const list, list_t * const item); void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after); -void list_append(list_head_t * const list, list_t * const item); +void list_push(list_head_t * const list, list_t * const item); void list_update(list_head_t * const list, list_t * const item, const void * const data); inline void list_lock(const list_head_t * const list) From 1e58cd3eacbfdbfbdf66eb29ba7b09ededfc82bb Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 21:33:29 +0300 Subject: [PATCH 49/65] conn: use general list for send queue --- Makefile.am | 5 ++-- src/common.h | 8 ++----- src/conn.c | 64 ++++++++++++++++++++++++---------------------------- src/event.c | 43 ++++++----------------------------- src/list.c | 4 +++- src/list.h | 6 ++--- 6 files changed, 48 insertions(+), 82 deletions(-) diff --git a/Makefile.am b/Makefile.am index eebaace5..6b512958 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,9 +18,10 @@ libcouplet_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/event.c src/handler.c src/hash.c \ src/jid.c src/md5.c src/sasl.c src/sha1.c \ src/snprintf.c src/sock.c src/stanza.c src/thread.c \ - src/tls_openssl.c src/util.c \ + src/tls_openssl.c src/util.c src/list.c \ src/common.h src/hash.h src/md5.h src/ostypes.h src/parser.h \ - src/sasl.h src/sha1.h src/sock.h src/thread.h src/tls.h src/util.h + src/sasl.h src/sha1.h src/sock.h src/thread.h src/tls.h src/util.h \ + src/list.h if PARSER_EXPAT libcouplet_la_SOURCES += src/parser_expat.c diff --git a/src/common.h b/src/common.h index 6982eb7f..dbabe4ae 100644 --- a/src/common.h +++ b/src/common.h @@ -33,6 +33,7 @@ #include "util.h" #include "parser.h" #include "thread.h" +#include "list.h" /** run-time context **/ @@ -113,8 +114,6 @@ struct _xmpp_send_queue_t { char *data; size_t len; size_t written; - - xmpp_send_queue_t *next; }; typedef struct _xmpp_handlist_t xmpp_handlist_t; @@ -188,10 +187,7 @@ struct _xmpp_conn_t { /* send queue and parameters */ int blocking_send; int send_queue_max; - int send_queue_len; - xmpp_send_queue_t *send_queue_head; - xmpp_send_queue_t *send_queue_tail; - mutex_t *send_queue_mutex; + list_head_t *send_queue; /* xml parser */ int reset_parser; diff --git a/src/conn.c b/src/conn.c index d1a16c46..45956cb2 100644 --- a/src/conn.c +++ b/src/conn.c @@ -133,11 +133,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) /* default send parameters */ conn->blocking_send = 0; conn->send_queue_max = DEFAULT_SEND_QUEUE_MAX; - conn->send_queue_len = 0; - conn->send_queue_head = NULL; - conn->send_queue_tail = NULL; - conn->send_queue_mutex = mutex_create(ctx); - if (!conn->send_queue_mutex) + conn->send_queue = list_init(ctx); + if (!conn->send_queue) goto out_free_conn; /* default timeouts */ @@ -145,7 +142,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->lang = xmpp_strdup(ctx, "en"); if (!conn->lang) - goto out_free_mutex; + goto out_free_send_queue; conn->domain = NULL; conn->jid = NULL; @@ -200,8 +197,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) parser_free(conn->parser); out_free_lang: xmpp_free(ctx, conn->lang); -out_free_mutex: - mutex_destroy(conn->send_queue_mutex); +out_free_send_queue: + list_destroy(conn->send_queue); out_free_conn: xmpp_free(ctx, conn); return NULL; @@ -302,8 +299,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn) parser_free(conn->parser); /* free send_queue */ - /* @TODO release send_queue */ - mutex_destroy(conn->send_queue_mutex); + list_destroy(conn->send_queue); if (conn->domain) xmpp_free(ctx, conn->domain); @@ -632,7 +628,8 @@ void xmpp_send_raw(xmpp_conn_t * const conn, const char * const data, const size_t len) { xmpp_ctx_t *ctx; - xmpp_send_queue_t *item; + xmpp_send_queue_t *sq; + list_t *item; if (conn->state != XMPP_STATE_CONNECTED) return; @@ -640,35 +637,34 @@ void xmpp_send_raw(xmpp_conn_t * const conn, ctx = conn->ctx; /* create send queue item for queue */ - item = xmpp_alloc(ctx, sizeof(xmpp_send_queue_t)); - if (!item) + sq = xmpp_alloc(ctx, sizeof(xmpp_send_queue_t)); + if (!sq) return; - item->data = xmpp_alloc(ctx, len); - if (!item->data) { - xmpp_free(ctx, item); - return; - } - memcpy(item->data, data, len); - item->len = len; - item->next = NULL; - item->written = 0; + sq->data = xmpp_alloc(ctx, len); + if (!sq->data) + goto out_free_sq; + + item = list_init_item(ctx); + if (!item) + goto out_free_data; + + memcpy(sq->data, data, len); + sq->len = len; + sq->written = 0; + item->data = (void *)sq; /* add item to the send queue */ - mutex_lock(conn->send_queue_mutex); - if (!conn->send_queue_tail) { - /* first item, set head and tail */ - conn->send_queue_head = item; - conn->send_queue_tail = item; - } else { - /* add to the tail */ - conn->send_queue_tail->next = item; - conn->send_queue_tail = item; - } - conn->send_queue_len++; - mutex_unlock(conn->send_queue_mutex); + list_push(conn->send_queue, item); /* unlock send_queue_thread */ xmpp_sem_post(ctx->send_queue_sem); + + return; + +out_free_data: + xmpp_free(ctx, sq->data); +out_free_sq: + xmpp_free(ctx, sq); } /** Send an XML stanza to the XMPP server. diff --git a/src/event.c b/src/event.c index f7527a5c..9d3b664c 100644 --- a/src/event.c +++ b/src/event.c @@ -60,38 +60,6 @@ #define DEFAULT_TIMEOUT 1 #endif -/* Get the next item from the send queue. - * This function removes returned item from the queue - */ -static xmpp_send_queue_t * -_xmpp_send_queue_next(xmpp_ctx_t *ctx, xmpp_conn_t *conn) -{ - xmpp_send_queue_t *sq; - mutex_lock(conn->send_queue_mutex); - sq = conn->send_queue_head; - if (sq) { - conn->send_queue_head = sq->next; - if (!sq->next) - conn->send_queue_tail = NULL; - conn->send_queue_len--; - } - mutex_unlock(conn->send_queue_mutex); - return sq; -} - -/* Insert item to the head of the send queue */ -static void -_xmpp_send_queue_ins(xmpp_ctx_t *ctx, xmpp_conn_t *conn, xmpp_send_queue_t *sq) -{ - mutex_lock(conn->send_queue_mutex); - sq->next = conn->send_queue_head; - conn->send_queue_head = sq; - if (!sq->next) - conn->send_queue_tail = sq; - conn->send_queue_len++; - mutex_unlock(conn->send_queue_mutex); -} - /** Run send loop once. * This function will run send any data that has been queued by xmpp_send * and related functions. @@ -105,6 +73,7 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) xmpp_connlist_t *connitem; xmpp_conn_t *conn; xmpp_send_queue_t *sq; + list_t *item; int sent; int ret; int towrite; @@ -133,9 +102,10 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) } /* write all data from the send queue to the socket */ - sq = _xmpp_send_queue_next(ctx, conn); - while (sq) { + item = list_shift(conn->send_queue); + while (item) { sent = 1; + sq = (xmpp_send_queue_t *)item->data; towrite = sq->len - sq->written; if (conn->tls) { @@ -169,14 +139,15 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) if (!sent) { /* insert sq to the head of send queue */ - _xmpp_send_queue_ins(ctx, conn, sq); + list_insert(conn->send_queue, item); break; } /* all data for this queue item written, delete and move on */ xmpp_free(ctx, sq->data); xmpp_free(ctx, sq); - sq = _xmpp_send_queue_next(ctx, conn); + xmpp_free(ctx, item); + item = list_shift(conn->send_queue); } /* tear down connection on error */ diff --git a/src/list.c b/src/list.c index 7940d804..de4b9a48 100644 --- a/src/list.c +++ b/src/list.c @@ -16,6 +16,8 @@ */ #include "list.h" +#include "couplet.h" +#include "common.h" /** Create new list. * @@ -23,7 +25,7 @@ * * @return a pointer to allocated list_head_t structure or NULL pointer */ -list_head_t *list_init(const xmpp_ctx_t * const ctx) +list_head_t *list_init(xmpp_ctx_t * const ctx) { list_head_t *list; diff --git a/src/list.h b/src/list.h index a3df14d0..6cf01eb7 100644 --- a/src/list.h +++ b/src/list.h @@ -37,7 +37,7 @@ struct _list_head_t { typedef struct _list_head_t list_head_t; -list_head_t *list_init(const xmpp_ctx_t * const ctx); +list_head_t *list_init(xmpp_ctx_t * const ctx); void list_destroy(list_head_t *list); list_t *list_init_item(const xmpp_ctx_t * const ctx); list_t *list_get_first(const list_head_t * const list); @@ -51,12 +51,12 @@ void list_insert_after(list_head_t * const list, list_t * const item, list_t * c void list_push(list_head_t * const list, list_t * const item); void list_update(list_head_t * const list, list_t * const item, const void * const data); -inline void list_lock(const list_head_t * const list) +static inline void list_lock_mutex(const list_head_t * const list) { mutex_lock(list->mutex); } -inline void list_unlock(const list_head_t * const list) +static inline void list_unlock_mutex(const list_head_t * const list) { mutex_unlock(list->mutex); } From 1ca7d8f10615ee9f5b39ea46d40013347408b6ef Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 21:42:52 +0300 Subject: [PATCH 50/65] list: implement list_destroy --- src/list.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/list.c b/src/list.c index de4b9a48..f0f36319 100644 --- a/src/list.c +++ b/src/list.c @@ -47,8 +47,15 @@ list_head_t *list_init(xmpp_ctx_t * const ctx) return list; } +/** Destroy the list + * + * @param list a list object + */ void list_destroy(list_head_t *list) { + /** @TODO avoid memory leak issue when the list isn't empty */ + mutex_destroy(list->mutex); + xmpp_free(list->ctx, list); } /** Create new list item From 8442c4df4e72a0ad938d48aebe66a2ea6714e1de Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 23:12:51 +0300 Subject: [PATCH 51/65] list: update api, implement some functions implement list_get_first implement list_get_next implement list_pop_by_data --- src/list.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/list.h | 2 +- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/list.c b/src/list.c index f0f36319..eda5af89 100644 --- a/src/list.c +++ b/src/list.c @@ -80,12 +80,40 @@ list_t *list_init_item(const xmpp_ctx_t * const ctx) return item; } +/** Get the first element of the list + * Function just returns head of the list + * + * @param list a list object + * + * @return pointer to head of the list or NULL pointer if the list is empty + */ list_t *list_get_first(const list_head_t * const list) { + list_t *item; + + mutex_lock(list->mutex); + item = list->head; + mutex_unlock(list->mutex); + + return item; } +/** Get element that follows the item + * + * @param list a list object + * @param item s list item object + * + * @return pointer to the next element if exists or NULL pointer otherwise + */ list_t *list_get_next(const list_head_t * const list, const list_t * const item) { + list_t *next; + + mutex_lock(list->mutex); + next = item->next; + mutex_unlock(list->mutex); + + return next; } list_t *list_get_last(const list_head_t * const list) @@ -114,8 +142,37 @@ list_t *list_shift(list_head_t * const list) return item; } -list_t *list_shift_next(list_head_t * const list, list_t * const item) +/** Remove the item if exists + * Function searches the item within the list and removes it if exists + * + * @param list a list object + * @param item list element for search + * + * @return pointer to the item if it was removed and NULL pointer otherwise + */ +list_t *list_pop_by_data(list_head_t * const list, const void * const data) { + list_t *prev = NULL; + list_t *cur; + + mutex_lock(list->mutex); + cur = list->head; + while (cur) { + if (cur->data == data) { + if (prev) + prev->next = cur->next; + else + list->head = cur->next; + if (!cur->next) + list->tail = prev; + break; + } + prev = cur; + cur = cur->next; + } + mutex_unlock(list->mutex); + + return cur; } list_t *list_pop(list_head_t * const list) diff --git a/src/list.h b/src/list.h index 6cf01eb7..a6fce72f 100644 --- a/src/list.h +++ b/src/list.h @@ -44,7 +44,7 @@ list_t *list_get_first(const list_head_t * const list); list_t *list_get_next(const list_head_t * const list, const list_t * const item); list_t *list_get_last(const list_head_t * const list); list_t *list_shift(list_head_t * const list); -list_t *list_shift_next(list_head_t * const list, list_t * const item); +list_t *list_pop_by_data(list_head_t * const list, const void * const data); list_t *list_pop(list_head_t * const list); void list_insert(list_head_t * const list, list_t * const item); void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after); From 46d3629a9871388782560cda0f6a13dce3f3f67f Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Fri, 19 Oct 2012 23:15:22 +0300 Subject: [PATCH 52/65] ctx: use general list for connlist --- src/common.h | 8 +--- src/conn.c | 63 +++++---------------------- src/ctx.c | 14 +++--- src/event.c | 57 ++++++++++++------------ src/handler.c | 106 +++++++++++++++++++++++---------------------- src/tls_schannel.c | 6 +-- 6 files changed, 108 insertions(+), 146 deletions(-) diff --git a/src/common.h b/src/common.h index dbabe4ae..3f0d4cb0 100644 --- a/src/common.h +++ b/src/common.h @@ -43,18 +43,12 @@ typedef enum { XMPP_LOOP_QUIT } xmpp_loop_status_t; -typedef struct _xmpp_connlist_t { - xmpp_conn_t *conn; - struct _xmpp_connlist_t *next; -} xmpp_connlist_t; - struct _xmpp_ctx_t { const xmpp_mem_t *mem; const xmpp_log_t *log; xmpp_loop_status_t loop_status; - xmpp_connlist_t *connlist; - mutex_t *connlist_mutex; + list_head_t *connlist; xmpp_sem_t *send_queue_sem; }; diff --git a/src/conn.c b/src/conn.c index 45956cb2..f355ab63 100644 --- a/src/conn.c +++ b/src/conn.c @@ -29,6 +29,7 @@ #include "util.h" #include "parser.h" #include "thread.h" +#include "list.h" #ifndef DEFAULT_SEND_QUEUE_MAX /** @def DEFAULT_SEND_QUEUE_MAX @@ -58,48 +59,6 @@ static void _handle_stream_start(char *name, char **attrs, static void _handle_stream_end(char *name, void * const userdata); static void _handle_stream_stanza(xmpp_stanza_t *stanza, void * const userdata); -/* insert connlist item to the tail */ -static void _xmpp_connlist_ins(xmpp_ctx_t *ctx, xmpp_connlist_t *item) -{ - xmpp_connlist_t *tail; - - mutex_lock(ctx->connlist_mutex); - tail = ctx->connlist; - while (tail && tail->next) - tail = tail->next; - if (!tail) - ctx->connlist = item; - else - tail->next = item; - mutex_unlock(ctx->connlist_mutex); -} - -/* delete connlist item specified by conn - * return TRUE if conn is found within connlist and FALSE otherwise - */ -static int _xmpp_connlist_del(xmpp_ctx_t *ctx, xmpp_conn_t *conn) -{ - xmpp_connlist_t *item, *prev; - - prev = NULL; - mutex_lock(ctx->connlist_mutex); - item = ctx->connlist; - while (item && item->conn != conn) { - prev = item; - item = item->next; - } - if (item) { - if (!prev) - ctx->connlist = item->next; - else - prev->next = item->next; - xmpp_free(ctx, item); - } - mutex_unlock(ctx->connlist_mutex); - - return !item; -} - /** Create a new Strophe connection object. * * @param ctx a Strophe context object @@ -111,7 +70,7 @@ static int _xmpp_connlist_del(xmpp_ctx_t *ctx, xmpp_conn_t *conn) xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) { xmpp_conn_t *conn; - xmpp_connlist_t *item; + list_t *item; if (!ctx) return NULL; @@ -181,14 +140,12 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->ref = 1; /* add connection to ctx->connlist */ - item = xmpp_alloc(ctx, sizeof(xmpp_connlist_t)); - if (!item) { - xmpp_error(ctx, "xmpp", "failed to allocate memory"); + item = list_init_item(ctx); + if (!item) goto out_free_parser; - } else { - item->conn = conn; - item->next = NULL; - _xmpp_connlist_ins(ctx, item); + else { + item->data = (void *)conn; + list_push(ctx->connlist, item); } return conn; @@ -232,6 +189,7 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn) int xmpp_conn_release(xmpp_conn_t * const conn) { xmpp_ctx_t *ctx; + list_t *item; xmpp_handlist_t *hlitem, *thli; hash_iterator_t *iter; const char *key; @@ -244,7 +202,10 @@ int xmpp_conn_release(xmpp_conn_t * const conn) ctx = conn->ctx; /* remove connection from context's connlist */ - if (!_xmpp_connlist_del(ctx, conn)) + item = list_pop_by_data(ctx->connlist, (void *)conn); + if (item) + xmpp_free(ctx, item); + else xmpp_error(ctx, "xmpp", "Connection not in context's list\n"); /* free handler stuff diff --git a/src/ctx.c b/src/ctx.c index 01e91946..ba202d58 100644 --- a/src/ctx.c +++ b/src/ctx.c @@ -52,6 +52,7 @@ #include "common.h" #include "util.h" #include "thread.h" +#include "list.h" /** Initialize the Strophe library. * This function initializes subcomponents of the Strophe library and must @@ -410,19 +411,18 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, else ctx->log = log; - ctx->connlist = NULL; ctx->loop_status = XMPP_LOOP_NOTSTARTED; - ctx->connlist_mutex = mutex_create(ctx); - if (!ctx->connlist_mutex) + ctx->connlist = list_init(ctx); + if (!ctx->connlist) goto out_free_ctx; ctx->send_queue_sem = xmpp_sem_create(ctx); if (!ctx->send_queue_sem) - goto out_free_mutex; + goto out_free_connlist; return ctx; -out_free_mutex: - mutex_destroy(ctx->connlist_mutex); +out_free_connlist: + list_destroy(ctx->connlist); out_free_ctx: xmpp_free(ctx, ctx); return NULL; @@ -436,7 +436,7 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, */ void xmpp_ctx_free(xmpp_ctx_t * const ctx) { - mutex_destroy(ctx->connlist_mutex); + list_destroy(ctx->connlist); xmpp_sem_destroy(ctx->send_queue_sem); /* mem and log are owned by their suppliers */ diff --git a/src/event.c b/src/event.c index 9d3b664c..fba6ae4e 100644 --- a/src/event.c +++ b/src/event.c @@ -51,6 +51,7 @@ #include "common.h" #include "parser.h" #include "thread.h" +#include "list.h" #ifndef DEFAULT_TIMEOUT /** @def DEFAULT_TIMEOUT @@ -70,23 +71,20 @@ */ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) { - xmpp_connlist_t *connitem; + list_t *connitem; + list_t *sqitem; xmpp_conn_t *conn; xmpp_send_queue_t *sq; - list_t *item; int sent; int ret; int towrite; - /** @TODO lock connlist with ctx->connlist_mutex */ /* send queued data */ - connitem = ctx->connlist; + connitem = list_get_first(ctx->connlist); while (connitem) { - conn = connitem->conn; - if (conn->state != XMPP_STATE_CONNECTED) { - connitem = connitem->next; - continue; - } + conn = (xmpp_conn_t *)connitem->data; + if (conn->state != XMPP_STATE_CONNECTED) + goto loop_next; /* if we're running tls, there may be some remaining data waiting to * be sent, so push that out */ @@ -102,10 +100,10 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) } /* write all data from the send queue to the socket */ - item = list_shift(conn->send_queue); - while (item) { + sqitem = list_shift(conn->send_queue); + while (sqitem) { sent = 1; - sq = (xmpp_send_queue_t *)item->data; + sq = (xmpp_send_queue_t *)sqitem->data; towrite = sq->len - sq->written; if (conn->tls) { @@ -139,15 +137,15 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) if (!sent) { /* insert sq to the head of send queue */ - list_insert(conn->send_queue, item); + list_insert(conn->send_queue, sqitem); break; } /* all data for this queue item written, delete and move on */ xmpp_free(ctx, sq->data); xmpp_free(ctx, sq); - xmpp_free(ctx, item); - item = list_shift(conn->send_queue); + xmpp_free(ctx, sqitem); + sqitem = list_shift(conn->send_queue); } /* tear down connection on error */ @@ -158,8 +156,9 @@ void xmpp_run_send_queue_once(xmpp_ctx_t *ctx) conn->error = ECONNABORTED; conn_disconnect(conn); } - - connitem = connitem->next; + +loop_next: + connitem = list_get_next(ctx->connlist, connitem); } } @@ -205,7 +204,7 @@ void *xmpp_send_queue_thread(void *data) */ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) { - xmpp_connlist_t *connitem; + list_t *connitem; xmpp_conn_t *conn; fd_set rfds, wfds; sock_t max = 0; @@ -221,9 +220,13 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) ctx->loop_status = XMPP_LOOP_RUNNING; /* reset parsers if needed */ - for (connitem = ctx->connlist; connitem; connitem = connitem->next) - if (connitem->conn->reset_parser) - conn_parser_reset(connitem->conn); + connitem = list_get_first(ctx->connlist); + while (connitem) { + conn = (xmpp_conn_t *)connitem->data; + if (conn->reset_parser) + conn_parser_reset(conn); + connitem = list_get_next(ctx->connlist, connitem); + } /* fire any ready timed handlers, then * make sure we don't wait past the time when timed handlers need @@ -238,9 +241,9 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) FD_ZERO(&wfds); /* find events to watch */ - connitem = ctx->connlist; + connitem = list_get_first(ctx->connlist); while (connitem) { - conn = connitem->conn; + conn = (xmpp_conn_t *)connitem->data; switch (conn->state) { case XMPP_STATE_CONNECTING: @@ -273,7 +276,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) if (conn->sock > max) max = conn->sock; - connitem = connitem->next; + connitem = list_get_next(ctx->connlist, connitem); } /* check for events */ @@ -292,9 +295,9 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) return; /* process events */ - connitem = ctx->connlist; + connitem = list_get_first(ctx->connlist); while (connitem) { - conn = connitem->conn; + conn = (xmpp_conn_t *)connitem->data; switch (conn->state) { case XMPP_STATE_CONNECTING: @@ -353,7 +356,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) break; } - connitem = connitem->next; + connitem = list_get_next(ctx->connlist, connitem); } /* fire any ready handlers */ diff --git a/src/handler.c b/src/handler.c index 05fb7de3..fec1666a 100644 --- a/src/handler.c +++ b/src/handler.c @@ -31,6 +31,7 @@ #include "couplet.h" #include "common.h" +#include "list.h" /** Fire off all stanza handlers that match. * This function is called internally by the event loop whenever stanzas @@ -138,61 +139,64 @@ void handler_fire_stanza(xmpp_conn_t * const conn, */ uint64_t handler_fire_timed(xmpp_ctx_t * const ctx) { - xmpp_connlist_t *connitem; - xmpp_handlist_t *handitem, *temp; - int ret, fired; - uint64_t elapsed, min; - - min = (uint64_t)(-1); - - connitem = ctx->connlist; - while (connitem) { - if (connitem->conn->state != XMPP_STATE_CONNECTED) { - connitem = connitem->next; - continue; - } - - /* enable all handlers that were added */ - for (handitem = connitem->conn->timed_handlers; handitem; - handitem = handitem->next) - handitem->enabled = 1; - - handitem = connitem->conn->timed_handlers; - while (handitem) { - /* skip newly added handlers */ - if (!handitem->enabled) { - handitem = handitem->next; - continue; - } + list_t *connitem; + xmpp_handlist_t *handitem, *temp; + xmpp_conn_t *conn; + int ret, fired; + uint64_t elapsed, min; + + min = (uint64_t)(-1); + + connitem = list_get_first(ctx->connlist); + while (connitem) { + conn = (xmpp_conn_t *)connitem->data; + if (conn->state != XMPP_STATE_CONNECTED) + goto loop_connitem_next; + + /* enable all handlers that were added */ + handitem = conn->timed_handlers; + while (handitem) { + handitem->enabled = 1; + handitem = handitem->next; + } - /* only fire user handlers after authentication */ - if (handitem->user_handler && !connitem->conn->authenticated) { - handitem = handitem->next; - continue; - } + handitem = conn->timed_handlers; + while (handitem) { + /* skip newly added handlers */ + if (!handitem->enabled) { + handitem = handitem->next; + continue; + } + + /* only fire user handlers after authentication */ + if (handitem->user_handler && !conn->authenticated) { + handitem = handitem->next; + continue; + } + + fired = 0; + elapsed = time_elapsed(handitem->last_stamp, time_stamp()); + if (elapsed >= handitem->period) { + /* fire! */ + fired = 1; + handitem->last_stamp = time_stamp(); + ret = ((xmpp_timed_handler)handitem->handler)(conn, handitem->userdata); + } else if (min > (handitem->period - elapsed)) + min = handitem->period - elapsed; + + temp = handitem; + handitem = handitem->next; + + /* delete handler if it returned false */ + if (fired && !ret) + xmpp_timed_handler_delete(conn, temp->handler); + } - fired = 0; - elapsed = time_elapsed(handitem->last_stamp, time_stamp()); - if (elapsed >= handitem->period) { - /* fire! */ - fired = 1; - handitem->last_stamp = time_stamp(); - ret = ((xmpp_timed_handler)handitem->handler)(connitem->conn, handitem->userdata); - } else if (min > (handitem->period - elapsed)) - min = handitem->period - elapsed; - - temp = handitem; - handitem = handitem->next; - - /* delete handler if it returned false */ - if (fired && !ret) - xmpp_timed_handler_delete(connitem->conn, temp->handler); +loop_connitem_next: + connitem = list_get_next(ctx->connlist, connitem); } - connitem = connitem->next; - } - - return min; + return min; } /** Reset all timed handlers. diff --git a/src/tls_schannel.c b/src/tls_schannel.c index c1db394e..ebbcbe56 100644 --- a/src/tls_schannel.c +++ b/src/tls_schannel.c @@ -218,16 +218,16 @@ int tls_start(tls_t *tls) /* search the ctx's conns for our sock, and use the domain there as our * name */ { - xmpp_connlist_t *listentry = tls->ctx->connlist; + list_t *listentry = list_get_first(tls->ctx->connlist); while (listentry) { - xmpp_conn_t *conn = listentry->conn; + xmpp_conn_t *conn = (xmpp_conn_t *)listentry->data; if (conn->sock == tls->sock) { name = strdup(conn->domain); listentry = NULL; } else { - listentry = listentry->next; + listentry = list_get_next(tls->ctx->connlist, listentry); } } } From 0a7849474f4f2f8c874c5b54a0bd001bbe6c51aa Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sun, 21 Oct 2012 23:28:23 +0300 Subject: [PATCH 53/65] remove trailing whitespaces --- couplet.h | 28 +++++----- coupletpp.h | 6 +-- src/auth.c | 68 ++++++++++++------------ src/common.h | 4 +- src/conn.c | 2 +- src/ctx.c | 6 +-- src/event.c | 24 ++++----- src/handler.c | 28 +++++----- src/hash.c | 10 ++-- src/hash.h | 4 +- src/jid.c | 8 +-- src/md5.c | 4 +- src/ostypes.h | 6 +-- src/parser.h | 4 +- src/parser_expat.c | 8 +-- src/parser_libxml2.c | 12 ++--- src/sasl.c | 6 +-- src/sha1.c | 28 +++++----- src/snprintf.c | 122 +++++++++++++++++++++---------------------- src/sock.c | 34 ++++++------ src/sock.h | 2 +- src/stanza.c | 58 ++++++++++---------- src/thread.c | 2 +- src/thread.h | 2 +- src/tls.h | 2 +- src/tls_dummy.c | 2 +- src/tls_gnutls.c | 6 +-- src/tls_openssl.c | 6 +-- src/tls_schannel.c | 20 +++---- src/util.c | 4 +- src/util.h | 2 +- 31 files changed, 259 insertions(+), 259 deletions(-) diff --git a/couplet.h b/couplet.h index 6422a6ba..1f32a30e 100644 --- a/couplet.h +++ b/couplet.h @@ -82,7 +82,7 @@ extern "C" { #define XMPP_EOK 0 /** @def XMPP_EMEM * Memory related failure error code. - * + * * This is returned on allocation errors and signals that the host may * be out of memory. */ @@ -134,7 +134,7 @@ typedef struct _xmpp_log_t xmpp_log_t; /* opaque run time context containing the above hooks */ typedef struct _xmpp_ctx_t xmpp_ctx_t; -xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, +xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem, const xmpp_log_t * const log); void xmpp_ctx_free(xmpp_ctx_t * const ctx); @@ -158,7 +158,7 @@ typedef enum { XMPP_COMPONENT } xmpp_conn_type_t; -typedef void (*xmpp_log_handler)(void * const userdata, +typedef void (*xmpp_log_handler)(void * const userdata, const xmpp_log_level_t level, const char * const area, const char * const msg); @@ -218,7 +218,7 @@ typedef struct { xmpp_stanza_t *stanza; } xmpp_stream_error_t; -typedef void (*xmpp_conn_handler)(xmpp_conn_t * const conn, +typedef void (*xmpp_conn_handler)(xmpp_conn_t * const conn, const xmpp_conn_event_t event, const int error, xmpp_stream_error_t * const stream_error, @@ -236,7 +236,7 @@ void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass); xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn); void xmpp_conn_disable_tls(xmpp_conn_t * const conn); -int xmpp_connect_client(xmpp_conn_t * const conn, +int xmpp_connect_client(xmpp_conn_t * const conn, const char * const altdomain, unsigned short altport, xmpp_conn_handler callback, @@ -250,16 +250,16 @@ void xmpp_disconnect(xmpp_conn_t * const conn); void xmpp_send(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza); -void xmpp_send_raw_string(xmpp_conn_t * const conn, +void xmpp_send_raw_string(xmpp_conn_t * const conn, const char * const fmt, ...); -void xmpp_send_raw(xmpp_conn_t * const conn, +void xmpp_send_raw(xmpp_conn_t * const conn, const char * const data, const size_t len); /* handlers */ /* if the handle returns false it is removed */ -typedef int (*xmpp_timed_handler)(xmpp_conn_t * const conn, +typedef int (*xmpp_timed_handler)(xmpp_conn_t * const conn, void * const userdata); void xmpp_timed_handler_add(xmpp_conn_t * const conn, @@ -318,11 +318,11 @@ int xmpp_stanza_is_text(xmpp_stanza_t * const stanza); int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza); /** marshall a stanza into text for transmission or display **/ -int xmpp_stanza_to_text(xmpp_stanza_t *stanza, +int xmpp_stanza_to_text(xmpp_stanza_t *stanza, char ** const buf, size_t * const buflen); xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza); -xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, +xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, const char * const name); xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza, const char * const ns); @@ -340,7 +340,7 @@ char *xmpp_stanza_get_name(xmpp_stanza_t * const stanza); int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child); int xmpp_stanza_set_ns(xmpp_stanza_t * const stanza, const char * const ns); /* set_attribute adds/replaces attributes */ -int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza, +int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza, const char * const key, const char * const value); int xmpp_stanza_set_name(xmpp_stanza_t *stanza, @@ -348,15 +348,15 @@ int xmpp_stanza_set_name(xmpp_stanza_t *stanza, int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char * const text); int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza, - const char * const text, + const char * const text, const size_t size); /* common stanza helpers */ char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza); char *xmpp_stanza_get_id(xmpp_stanza_t * const stanza); -int xmpp_stanza_set_id(xmpp_stanza_t * const stanza, +int xmpp_stanza_set_id(xmpp_stanza_t * const stanza, const char * const id); -int xmpp_stanza_set_type(xmpp_stanza_t * const stanza, +int xmpp_stanza_set_type(xmpp_stanza_t * const stanza, const char * const type); /* unimplemented diff --git a/coupletpp.h b/coupletpp.h index 5fba7612..121ec638 100644 --- a/coupletpp.h +++ b/coupletpp.h @@ -43,10 +43,10 @@ namespace XMPP { private: static void *callAlloc(const size_t size, void * const userdata); - static void *callRealloc(void *p, const size_t size, + static void *callRealloc(void *p, const size_t size, void * const userdata); static void callFree(void *p, void * const userdata); - static void callLog(void * const userdata, + static void callLog(void * const userdata, const xmpp_log_level_t level, const char * const area, const char * const msg); @@ -67,7 +67,7 @@ namespace XMPP { void release(); Stanza *clone(); Stanza *copy(); - + int toText(const char ** const buf, size_t * const buflen); Stanza *getChildren(); Stanza *getChildByName(const char * const name); diff --git a/src/auth.c b/src/auth.c index d744f85a..c6408503 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1,7 +1,7 @@ /* auth.c ** strophe XMPP client library -- auth functions and handlers ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express or ** implied. @@ -12,7 +12,7 @@ ** distribution. */ -/** @file +/** @file * Authentication function and handlers. */ @@ -99,7 +99,7 @@ static int _handle_error(xmpp_conn_t * const conn, /* free old stream error if it's still there */ if (conn->stream_error) { xmpp_stanza_release(conn->stream_error->stanza); - if (conn->stream_error->text) + if (conn->stream_error->text) xmpp_free(conn->ctx, conn->stream_error->text); xmpp_free(conn->ctx, conn->stream_error); } @@ -220,7 +220,7 @@ static int _handle_features(xmpp_conn_t * const conn, /* check for SASL */ child = xmpp_stanza_get_child_by_name(stanza, "mechanisms"); if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) { - for (mech = xmpp_stanza_get_children(child); mech; + for (mech = xmpp_stanza_get_children(child); mech; mech = xmpp_stanza_get_next(mech)) { if (strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) { text = xmpp_stanza_get_text(mech); @@ -237,7 +237,7 @@ static int _handle_features(xmpp_conn_t * const conn, } _auth(conn); - + return 0; } @@ -262,7 +262,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn, { char *name; name = xmpp_stanza_get_name(stanza); - xmpp_debug(conn->ctx, "xmpp", + xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name); if (strcmp(name, "proceed") == 0) { @@ -276,7 +276,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn, tls_free(conn->tls); conn->tls = NULL; conn->tls_failed = 1; - + /* failed tls spoils the connection, so disconnect */ xmpp_disconnect(conn); } @@ -302,14 +302,14 @@ static int _handle_sasl_result(xmpp_conn_t * const conn, /* the server should send a or stanza */ if (strcmp(name, "failure") == 0) { - xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed", + xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed", (char *)userdata); - + /* fall back to next auth method */ _auth(conn); } else if (strcmp(name, "success") == 0) { /* SASL PLAIN auth successful, we need to restart the stream */ - xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful", + xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful", (char *)userdata); /* reset parser */ @@ -354,10 +354,10 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn, if (!auth) { disconnect_mem_error(conn); return 0; - } + } xmpp_stanza_set_name(auth, "response"); xmpp_stanza_set_ns(auth, XMPP_NS_SASL); - + authdata = xmpp_stanza_new(conn->ctx); if (!authdata) { disconnect_mem_error(conn); @@ -370,7 +370,7 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn, xmpp_stanza_add_child(auth, authdata); xmpp_stanza_release(authdata); - handler_add(conn, _handle_digestmd5_rspauth, + handler_add(conn, _handle_digestmd5_rspauth, XMPP_NS_SASL, NULL, NULL, NULL); xmpp_send(conn, auth); @@ -403,7 +403,7 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn, if (!auth) { disconnect_mem_error(conn); return 0; - } + } xmpp_stanza_set_name(auth, "response"); xmpp_stanza_set_ns(auth, XMPP_NS_SASL); xmpp_send(conn, auth); @@ -425,7 +425,7 @@ static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn) xmpp_stanza_set_name(starttls, "starttls"); xmpp_stanza_set_ns(starttls, XMPP_NS_TLS); } - + return starttls; } @@ -441,14 +441,14 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t * const conn, xmpp_stanza_set_ns(auth, XMPP_NS_SASL); xmpp_stanza_set_attribute(auth, "mechanism", mechanism); } - + return auth; } -/* authenticate the connection - * this may get called multiple times. if any auth method fails, +/* authenticate the connection + * this may get called multiple times. if any auth method fails, * this will get called again until one auth method succeeds or every - * method fails + * method fails */ static void _auth(xmpp_conn_t * const conn) { @@ -488,7 +488,7 @@ static void _auth(xmpp_conn_t * const conn) return; } - handler_add(conn, _handle_proceedtls_default, + handler_add(conn, _handle_proceedtls_default, XMPP_NS_TLS, NULL, NULL, NULL); xmpp_send(conn, auth); @@ -513,7 +513,7 @@ static void _auth(xmpp_conn_t * const conn) /* SASL ANONYMOUS was tried, unset flag */ conn->sasl_support &= ~SASL_MASK_ANONYMOUS; } else if (anonjid) { - xmpp_error(conn->ctx, "auth", + xmpp_error(conn->ctx, "auth", "No node in JID, and SASL ANONYMOUS unsupported."); xmpp_disconnect(conn); } else if (conn->sasl_support & SASL_MASK_DIGESTMD5) { @@ -524,7 +524,7 @@ static void _auth(xmpp_conn_t * const conn) } - handler_add(conn, _handle_digestmd5_challenge, + handler_add(conn, _handle_digestmd5_challenge, XMPP_NS_SASL, NULL, NULL, NULL); xmpp_send(conn, auth); @@ -542,7 +542,7 @@ static void _auth(xmpp_conn_t * const conn) if (!authdata) { disconnect_mem_error(conn); return; - } + } authid = _get_authid(conn); if (!authid) { disconnect_mem_error(conn); @@ -569,7 +569,7 @@ static void _auth(xmpp_conn_t * const conn) conn->sasl_support &= ~SASL_MASK_PLAIN; } else if (conn->type == XMPP_CLIENT) { /* legacy client authentication */ - + iq = xmpp_stanza_new(conn->ctx); if (!iq) { disconnect_mem_error(conn); @@ -655,7 +655,7 @@ static void _auth(xmpp_conn_t * const conn) } else { xmpp_stanza_release(authdata); xmpp_stanza_release(iq); - xmpp_error(conn->ctx, "auth", + xmpp_error(conn->ctx, "auth", "Cannot authenticate without resource"); xmpp_disconnect(conn); return; @@ -664,7 +664,7 @@ static void _auth(xmpp_conn_t * const conn) xmpp_stanza_release(authdata); handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL); - handler_add_timed(conn, _handle_missing_legacy, + handler_add_timed(conn, _handle_missing_legacy, LEGACY_TIMEOUT, NULL); xmpp_send(conn, iq); @@ -676,7 +676,7 @@ static void _auth(xmpp_conn_t * const conn) /** Set up handlers at stream start. * This function is called internally to Strophe for handling the opening * of an XMPP stream. It's called by the parser when a stream is opened - * or reset, and adds the initial handlers for and + * or reset, and adds the initial handlers for and * . This function is not intended for use outside * of Strophe. * @@ -738,7 +738,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn, /* if bind is required, go ahead and start it */ if (conn->bind_required) { /* bind resource */ - + /* setup response handlers */ handler_add_id(conn, _handle_bind, "_xmpp_bind1", NULL); handler_add_timed(conn, _handle_missing_bind, @@ -770,7 +770,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn, resource = NULL; } - /* if we have a resource to request, do it. otherwise the + /* if we have a resource to request, do it. otherwise the server will assign us one */ if (resource) { res = xmpp_stanza_new(conn->ctx); @@ -821,7 +821,7 @@ static int _handle_missing_features_sasl(xmpp_conn_t * const conn, xmpp_disconnect(conn); return 0; } - + static int _handle_bind(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) @@ -853,7 +853,7 @@ static int _handle_bind(xmpp_conn_t * const conn, if (conn->session_required) { /* setup response handlers */ handler_add_id(conn, _handle_session, "_xmpp_session1", NULL); - handler_add_timed(conn, _handle_missing_session, + handler_add_timed(conn, _handle_missing_session, SESSION_TIMEOUT, NULL); /* send session request */ @@ -884,9 +884,9 @@ static int _handle_bind(xmpp_conn_t * const conn, xmpp_stanza_release(iq); } else { conn->authenticated = 1; - + /* call connection handler */ - conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, + conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } } else { @@ -923,7 +923,7 @@ static int _handle_session(xmpp_conn_t * const conn, xmpp_debug(conn->ctx, "xmpp", "Session establishment successful."); conn->authenticated = 1; - + /* call connection handler */ conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } else { diff --git a/src/common.h b/src/common.h index 3f0d4cb0..63f35ecf 100644 --- a/src/common.h +++ b/src/common.h @@ -197,7 +197,7 @@ struct _xmpp_conn_t { /* user handlers only get called after authentication */ int authenticated; - + /* connection events handler */ xmpp_conn_handler conn_handler; void *userdata; @@ -226,7 +226,7 @@ struct _xmpp_stanza_t { xmpp_ctx_t *ctx; xmpp_stanza_type_t type; - + xmpp_stanza_t *prev; xmpp_stanza_t *next; xmpp_stanza_t *children; diff --git a/src/conn.c b/src/conn.c index f355ab63..98e6d041 100644 --- a/src/conn.c +++ b/src/conn.c @@ -658,7 +658,7 @@ void xmpp_send(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza) */ void conn_open_stream(xmpp_conn_t * const conn) { - xmpp_send_raw_string(conn, + xmpp_send_raw_string(conn, "" \ "mem = &xmpp_default_mem; - else + else ctx->mem = mem; if (!log) diff --git a/src/event.c b/src/event.c index fba6ae4e..388fc1db 100644 --- a/src/event.c +++ b/src/event.c @@ -1,7 +1,7 @@ /* event.c ** strophe XMPP client library -- event loop and management ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -17,15 +17,15 @@ */ /** @defgroup EventLoop Event loop - * These functions manage the Strophe event loop. - * + * These functions manage the Strophe event loop. + * * Simple tools can use xmpp_run() and xmpp_stop() to manage the life * cycle of the program. A common idiom is to set up a few initial * event handers, call xmpp_run(), and then respond and react to * events as they come in. At some point, one of the handlers will * call xmpp_stop() to quit the event loop which leads to the program * terminating. - * + * * More complex programs will have their own event loops, and should * ensure that xmpp_run_once() is called regularly from there. For * example, a GUI program will already include an event loop to @@ -229,7 +229,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) } /* fire any ready timed handlers, then - * make sure we don't wait past the time when timed handlers need + * make sure we don't wait past the time when timed handlers need * to be called */ next = handler_fire_timed(ctx); @@ -237,19 +237,19 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) tv.tv_sec = usec / 1000000; tv.tv_usec = usec % 1000000; - FD_ZERO(&rfds); + FD_ZERO(&rfds); FD_ZERO(&wfds); /* find events to watch */ connitem = list_get_first(ctx->connlist); while (connitem) { conn = (xmpp_conn_t *)connitem->data; - + switch (conn->state) { case XMPP_STATE_CONNECTING: /* connect has been called and we're waiting for it to complete */ /* connection will give us write or error events */ - + /* make sure the timeout hasn't expired */ if (time_elapsed(conn->timeout_stamp, time_stamp()) <= conn->connect_timeout) @@ -268,11 +268,11 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) default: break; } - + /* Check if there is something in the SSL buffer. */ if (conn->tls) tls_read_bytes += tls_pending(conn->tls); - + if (conn->sock > max) max = conn->sock; @@ -285,11 +285,11 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) /* select errored */ if (ret < 0) { if (!sock_is_recoverable(sock_error())) - xmpp_error(ctx, "xmpp", "event watcher internal error %d", + xmpp_error(ctx, "xmpp", "event watcher internal error %d", sock_error()); return; } - + /* no events happened */ if (ret == 0 && tls_read_bytes == 0) return; diff --git a/src/handler.c b/src/handler.c index fec1666a..6b63043b 100644 --- a/src/handler.c +++ b/src/handler.c @@ -1,7 +1,7 @@ /* handler.c ** strophe XMPP client library -- event handler management ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -45,7 +45,7 @@ void handler_fire_stanza(xmpp_conn_t * const conn, { xmpp_handlist_t *item, *prev; char *id, *ns, *name, *type; - + /* call id handlers */ id = xmpp_stanza_get_id(stanza); if (id) { @@ -76,12 +76,12 @@ void handler_fire_stanza(xmpp_conn_t * const conn, item = next; } } - + /* call handlers */ ns = xmpp_stanza_get_ns(stanza); name = xmpp_stanza_get_name(stanza); type = xmpp_stanza_get_type(stanza); - + /* enable all added handlers */ for (item = conn->handlers; item; item = item->next) item->enabled = 1; @@ -119,7 +119,7 @@ void handler_fire_stanza(xmpp_conn_t * const conn, xmpp_free(conn->ctx, item); item = NULL; } - + if (item) { prev = item; item = item->next; @@ -213,7 +213,7 @@ void handler_reset_timed(xmpp_conn_t *conn, int user_only) while (handitem) { if ((user_only && handitem->user_handler) || !user_only) handitem->last_stamp = time_stamp(); - + handitem = handitem->next; } } @@ -221,7 +221,7 @@ void handler_reset_timed(xmpp_conn_t *conn, int user_only) static void _timed_handler_add(xmpp_conn_t * const conn, xmpp_timed_handler handler, const unsigned long period, - void * const userdata, + void * const userdata, const int user_handler) { xmpp_handlist_t *item, *tail; @@ -251,7 +251,7 @@ static void _timed_handler_add(xmpp_conn_t * const conn, conn->timed_handlers = item; else { tail = conn->timed_handlers; - while (tail->next) + while (tail->next) tail = tail->next; tail->next = item; } @@ -285,7 +285,7 @@ void xmpp_timed_handler_delete(xmpp_conn_t * const conn, prev->next = item->next; else conn->timed_handlers = item->next; - + xmpp_free(conn->ctx, item); } } @@ -327,7 +327,7 @@ static void _id_handler_add(xmpp_conn_t * const conn, if (!tail) hash_add(conn->id_handlers, id, item); else { - while (tail->next) + while (tail->next) tail = tail->next; tail->next = item; } @@ -397,7 +397,7 @@ static void _handler_add(xmpp_conn_t * const conn, item->userdata = userdata; item->enabled = 0; item->next = NULL; - + if (ns) { item->ns = xmpp_strdup(conn->ctx, ns); if (!item->ns) { @@ -430,7 +430,7 @@ static void _handler_add(xmpp_conn_t * const conn, conn->handlers = item; else { tail = conn->handlers; - while (tail->next) + while (tail->next) tail = tail->next; tail->next = item; } @@ -455,7 +455,7 @@ void xmpp_handler_delete(xmpp_conn_t * const conn, while (item) { if (item->handler == (void *)handler) break; - + prev = item; item = item->next; } @@ -478,7 +478,7 @@ void xmpp_handler_delete(xmpp_conn_t * const conn, * and continue firing regularly after that. Strophe will try its best * to fire handlers as close to the period times as it can, but accuracy * will vary depending on the resolution of the event loop. - * + * * If the handler function returns true, it will be kept, and if it * returns false, it will be deleted from the list of handlers. * diff --git a/src/hash.c b/src/hash.c index 225a1ed6..27d27562 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1,7 +1,7 @@ /* hash.c ** strophe XMPP client library -- hash table implementation -** -** Copyright (C) 2005-2009 Collecta, Inc. +** +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -47,7 +47,7 @@ struct _hash_iterator_t { hashentry_t *entry; int index; }; - + /** allocate and initialize a new hash table */ hash_t *hash_new(xmpp_ctx_t * const ctx, const int size, hash_free_func free) @@ -70,7 +70,7 @@ hash_t *hash_new(xmpp_ctx_t * const ctx, const int size, /* give the caller a reference */ result->ref = 1; } - + return result; } @@ -87,7 +87,7 @@ void hash_release(hash_t * const table) xmpp_ctx_t *ctx = table->ctx; hashentry_t *entry, *next; int i; - + if (table->ref > 1) table->ref--; else { diff --git a/src/hash.h b/src/hash.h index 94c0b14e..e069ec90 100644 --- a/src/hash.h +++ b/src/hash.h @@ -1,7 +1,7 @@ /* hash.h ** strophe XMPP client library -- hash table interface -** -** Copyright (C) 2005-2009 Collecta, Inc. +** +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/jid.c b/src/jid.c index 14de4463..67635445 100644 --- a/src/jid.c +++ b/src/jid.c @@ -1,7 +1,7 @@ /* jid.c ** strophe XMPP client library -- helper functions for parsing JIDs ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -66,7 +66,7 @@ char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node, } /** Create a bare JID from a JID. - * + * * @param ctx the Strophe context object * @param jid the JID * @@ -90,7 +90,7 @@ char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid) } /** Create a node string from a JID. - * + * * @param ctx a Strophe context object * @param jid the JID * @@ -153,7 +153,7 @@ char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid) * @param ctx a Strophe context object * @param jid the JID * - * @return an allocated string with the resource or NULL if no resource + * @return an allocated string with the resource or NULL if no resource * is found or an error occurs */ char *xmpp_jid_resource(xmpp_ctx_t *ctx, const char *jid) diff --git a/src/md5.c b/src/md5.c index c4ac4ac4..94e5b3ea 100644 --- a/src/md5.c +++ b/src/md5.c @@ -107,7 +107,7 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, uint32_t len) } /* - * Final wrapup - pad to 64-byte boundary with the bit pattern + * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) @@ -184,7 +184,7 @@ void MD5Transform(uint32_t buf[4], const unsigned char inext[64], { register uint32_t a, b, c, d, i; uint32_t in[16]; - + for (i = 0; i < 16; i++) in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i); diff --git a/src/ostypes.h b/src/ostypes.h index 0794b2ba..3be371e6 100644 --- a/src/ostypes.h +++ b/src/ostypes.h @@ -1,8 +1,8 @@ /* ostypes.h -** strophe XMPP client library -- type definitions for platforms +** strophe XMPP client library -- type definitions for platforms ** without stdint.h ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -21,7 +21,7 @@ #define __LIBSTROPHE_OSTYPES_H__ #ifdef _WIN32 -typedef unsigned __int64 uint64_t; +typedef unsigned __int64 uint64_t; #endif #endif /* __LIBSTROPHE_OSTYPES_H__ */ diff --git a/src/parser.h b/src/parser.h index 9cb80883..8e580b50 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,7 +1,7 @@ /* parser.h ** strophe XMPP client library -- parser structures and functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express or ** implied. @@ -31,7 +31,7 @@ typedef void (*parser_stanza_callback)(xmpp_stanza_t *stanza, void * const userdata); -parser_t *parser_new(xmpp_ctx_t *ctx, +parser_t *parser_new(xmpp_ctx_t *ctx, parser_start_callback startcb, parser_end_callback endcb, parser_stanza_callback stanzacb, diff --git a/src/parser_expat.c b/src/parser_expat.c index e3490979..dce475bc 100644 --- a/src/parser_expat.c +++ b/src/parser_expat.c @@ -1,7 +1,7 @@ /* parser.c ** strophe XMPP client library -- xml parser handlers and utility functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -58,7 +58,7 @@ static void _start_element(void *userdata, if (parser->depth == 0) { /* notify the owner */ if (parser->startcb) - parser->startcb((char *)name, (char **)attrs, + parser->startcb((char *)name, (char **)attrs, parser->userdata); } else { /* build stanzas at depth 1 */ @@ -85,7 +85,7 @@ static void _start_element(void *userdata, /* add child to parent */ xmpp_stanza_add_child(parser->stanza, child); - + /* the child is owned by the toplevel stanza now */ xmpp_stanza_release(child); @@ -180,7 +180,7 @@ int parser_reset(parser_t *parser) if (parser->expat) XML_ParserFree(parser->expat); - if (parser->stanza) + if (parser->stanza) xmpp_stanza_release(parser->stanza); parser->expat = XML_ParserCreate(NULL); diff --git a/src/parser_libxml2.c b/src/parser_libxml2.c index 68cfd9bb..500c07d4 100644 --- a/src/parser_libxml2.c +++ b/src/parser_libxml2.c @@ -1,7 +1,7 @@ /* parser.c ** strophe XMPP client library -- xml parser handlers and utility functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -50,7 +50,7 @@ static void _set_attributes(xmpp_stanza_t *stanza, const xmlChar **attrs) } } -static void _start_element(void *userdata, +static void _start_element(void *userdata, const xmlChar *name, const xmlChar **attrs) { parser_t *parser = (parser_t *)userdata; @@ -59,7 +59,7 @@ static void _start_element(void *userdata, if (parser->depth == 0) { /* notify the owner */ if (parser->startcb) - parser->startcb((char *)name, (char **)attrs, + parser->startcb((char *)name, (char **)attrs, parser->userdata); } else { /* build stanzas at depth 1 */ @@ -86,7 +86,7 @@ static void _start_element(void *userdata, /* add child to parent */ xmpp_stanza_add_child(parser->stanza, child); - + /* the child is owned by the toplevel stanza now */ xmpp_stanza_release(child); @@ -186,10 +186,10 @@ int parser_reset(parser_t *parser) if (parser->xmlctx) xmlFreeParserCtxt(parser->xmlctx); - if (parser->stanza) + if (parser->stanza) xmpp_stanza_release(parser->stanza); - parser->xmlctx = xmlCreatePushParserCtxt(&parser->handlers, + parser->xmlctx = xmlCreatePushParserCtxt(&parser->handlers, parser, NULL, 0, NULL); if (!parser->xmlctx) return 0; diff --git a/src/sasl.c b/src/sasl.c index 872e5c6a..3e301b58 100644 --- a/src/sasl.c +++ b/src/sasl.c @@ -359,7 +359,7 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge, result = _add_key(ctx, table, "digest-uri", result, &rlen, 1); result = _add_key(ctx, table, "response", result, &rlen, 0); result = _add_key(ctx, table, "charset", result, &rlen, 0); - + xmpp_free(ctx, node); xmpp_free(ctx, domain); hash_release(table); /* also frees value strings */ @@ -469,7 +469,7 @@ char *base64_encode(xmpp_ctx_t *ctx, return cbuf; } -int base64_decoded_len(xmpp_ctx_t *ctx, +int base64_decoded_len(xmpp_ctx_t *ctx, const char * const buffer, const unsigned len) { int nudge; @@ -488,7 +488,7 @@ int base64_decoded_len(xmpp_ctx_t *ctx, c = _base64_invcharmap[(int)buffer[len-3]]; if (c < 64) nudge = 2; - } + } } if (nudge < 0) return 0; /* reject bad coding */ diff --git a/src/sha1.c b/src/sha1.c index ec4cb6c7..9001edd5 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -8,7 +8,7 @@ By Steve Reid 100% Public Domain ----------------- -Modified 7/98 +Modified 7/98 By James H. Brown Still 100% Public Domain @@ -30,7 +30,7 @@ Since the file IO in main() reads 16K at a time, any file 8K or larger would be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million "a"s). -I also changed the declaration of variables i & j in SHA1Update to +I also changed the declaration of variables i & j in SHA1Update to unsigned long from unsigned int for the same reason. These changes should make no difference to any 32 bit implementations since @@ -57,7 +57,7 @@ Still 100% public domain Modified 4/01 By Saul Kravitz Still 100% PD -Modified to run on Compaq Alpha hardware. +Modified to run on Compaq Alpha hardware. ----------------- Modified 07/2002 @@ -91,7 +91,7 @@ A million repetitions of "a" typedef short int int16_t; typedef int int32_t; typedef __int64 int64_t; - + typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; @@ -130,7 +130,7 @@ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); void SHAPrintContext(SHA1_CTX *context, char *msg){ printf("%s (%d,%d) %x %x %x %x %x\n", msg, - context->count[0], context->count[1], + context->count[0], context->count[1], context->state[0], context->state[1], context->state[2], @@ -259,7 +259,7 @@ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) digest[i] = (uint8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } - + /* Wipe variables */ i = 0; memset(context->buffer, 0, 64); @@ -271,7 +271,7 @@ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) SHA1_Transform(context->state, context->buffer); #endif } - + /*************************************************************/ #if 0 @@ -296,7 +296,7 @@ FILE* file; fputs("Unable to open file.", stderr); return(-1); } - } + } SHA1_Init(&context); while (!feof(file)) { /* note: what if ferror(file) */ i = fread(buffer, 1, 16384, file); @@ -327,13 +327,13 @@ static char *test_results[] = { "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"}; - + void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output) { int i,j; char *c = output; - + for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { for (j = 0; j < 4; j++) { sprintf(c,"%02X", digest[i*4+j]); @@ -344,7 +344,7 @@ void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output) } *(c - 1) = '\0'; } - + int main(int argc, char** argv) { int k; @@ -353,8 +353,8 @@ int main(int argc, char** argv) char output[80]; fprintf(stdout, "verifying SHA-1 implementation... "); - - for (k = 0; k < 2; k++){ + + for (k = 0; k < 2; k++){ SHA1_Init(&context); SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k])); SHA1_Final(&context, digest); @@ -366,7 +366,7 @@ int main(int argc, char** argv) fprintf(stderr,"\t%s returned\n", output); fprintf(stderr,"\t%s is correct\n", test_results[k]); return (1); - } + } } /* million 'a' vector we feed separately */ SHA1_Init(&context); diff --git a/src/snprintf.c b/src/snprintf.c index bd1cdc3b..35531988 100644 --- a/src/snprintf.c +++ b/src/snprintf.c @@ -35,9 +35,9 @@ * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. - * + * * Thomas Roessler 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. + * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 @@ -107,7 +107,7 @@ int xmpp_snprintf (char *str, size_t count, const char *fmt, ...); int xmpp_vsnprintf (char *str, size_t count, const char *fmt, va_list arg); -static int dopr (char *buffer, size_t maxlen, const char *format, +static int dopr (char *buffer, size_t maxlen, const char *format, va_list args); static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); @@ -162,7 +162,7 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) int cflags; int total; size_t currlen; - + state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; @@ -174,17 +174,17 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) if (ch == '\0') state = DP_S_DONE; - switch(state) + switch(state) { case DP_S_DEFAULT: - if (ch == '%') + if (ch == '%') state = DP_S_FLAGS; - else + else total += dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: - switch (ch) + switch (ch) { case '-': flags |= DP_F_MINUS; @@ -212,49 +212,49 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) } break; case DP_S_MIN: - if (isdigit(ch)) + if (isdigit(ch)) { min = 10*min + char_to_int (ch); ch = *format++; - } - else if (ch == '*') + } + else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; - } - else + } + else state = DP_S_DOT; break; case DP_S_DOT: - if (ch == '.') + if (ch == '.') { state = DP_S_MAX; ch = *format++; - } - else + } + else state = DP_S_MOD; break; case DP_S_MAX: - if (isdigit(ch)) + if (isdigit(ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; - } - else if (ch == '*') + } + else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; - } - else + } + else state = DP_S_MOD; break; case DP_S_MOD: /* Currently, we don't support Long Long, bummer */ - switch (ch) + switch (ch) { case 'h': cflags = DP_C_SHORT; @@ -274,11 +274,11 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_CONV; break; case DP_S_CONV: - switch (ch) + switch (ch) { case 'd': case 'i': - if (cflags == DP_C_SHORT) + if (cflags == DP_C_SHORT) value = va_arg (args, int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); @@ -355,19 +355,19 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) max, flags); break; case 'n': - if (cflags == DP_C_SHORT) + if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; - } - else if (cflags == DP_C_LONG) + } + else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = currlen; - } - else + } + else { int *num; num = va_arg (args, int *); @@ -399,9 +399,9 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) } if (buffer != NULL) { - if (currlen < maxlen - 1) + if (currlen < maxlen - 1) buffer[currlen] = '\0'; - else + else buffer[maxlen - 1] = '\0'; } return total; @@ -413,7 +413,7 @@ static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, int padlen, strln; /* amount to pad */ int cnt = 0; int total = 0; - + if (value == 0) { value = ""; @@ -423,9 +423,9 @@ static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, if (max >= 0 && max < strln) strln = max; padlen = min - strln; - if (padlen < 0) + if (padlen < 0) padlen = 0; - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ while (padlen > 0) @@ -459,7 +459,7 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen, int zpadlen = 0; /* amount to zero pad */ int caps = 0; int total = 0; - + if (max < 0) max = 0; @@ -478,7 +478,7 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_SPACE) signvalue = ' '; } - + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { @@ -499,7 +499,7 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen, zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF @@ -508,18 +508,18 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen, #endif /* Spaces */ - while (spadlen > 0) + while (spadlen > 0) { total += dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ - if (signvalue) + if (signvalue) total += dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ - if (zpadlen > 0) + if (zpadlen > 0) { while (zpadlen > 0) { @@ -529,9 +529,9 @@ static int fmtint (char *buffer, size_t *currlen, size_t maxlen, } /* Digits */ - while (place > 0) + while (place > 0) total += dopr_outch (buffer, currlen, maxlen, convert[--place]); - + /* Left Justified spaces */ while (spadlen < 0) { total += dopr_outch (buffer, currlen, maxlen, ' '); @@ -560,7 +560,7 @@ static LDOUBLE _snp_pow10 (int exp) result *= 10; exp--; } - + return result; } @@ -586,13 +586,13 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ - int zpadlen = 0; + int zpadlen = 0; int caps = 0; int total = 0; long intpart; long fracpart; - - /* + + /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ @@ -616,8 +616,8 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, intpart = ufvalue; - /* - * Sorry, we only support 9 digits past the decimal because of our + /* + * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) @@ -657,18 +657,18 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; - if (padlen < 0) + if (padlen < 0) padlen = 0; - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ - if ((flags & DP_F_ZERO) && (padlen > 0)) + if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) + if (signvalue) { total += dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; @@ -685,10 +685,10 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, total += dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } - if (signvalue) + if (signvalue) total += dopr_outch (buffer, currlen, maxlen, signvalue); - while (iplace > 0) + while (iplace > 0) total += dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); /* @@ -699,7 +699,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, { total += dopr_outch (buffer, currlen, maxlen, '.'); - while (fplace > 0) + while (fplace > 0) total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); } @@ -709,7 +709,7 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, --zpadlen; } - while (padlen < 0) + while (padlen < 0) { total += dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; @@ -749,7 +749,7 @@ int xmpp_snprintf (va_alist) va_dcl #endif VA_LOCAL_DECL; int total; - + VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); @@ -784,7 +784,7 @@ int main (void) "%.1f", NULL }; - double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 0}; char *int_fmt[] = { "%-1.5d", @@ -812,7 +812,7 @@ int main (void) sprintf (buf2, fp_fmt[x], fp_nums[y]); if (strcmp (buf1, buf2)) { - printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n", + printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n", fp_fmt[x], buf1, buf2); fail++; } @@ -826,7 +826,7 @@ int main (void) sprintf (buf2, int_fmt[x], int_nums[y]); if (strcmp (buf1, buf2)) { - printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n", + printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n", int_fmt[x], buf1, buf2); fail++; } diff --git a/src/sock.c b/src/sock.c index a49c3f79..f9b42b3d 100644 --- a/src/sock.c +++ b/src/sock.c @@ -1,7 +1,7 @@ /* sock.c ** strophe XMPP client library -- socket abstraction implementation ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -83,7 +83,7 @@ sock_t sock_connect(const char * const host, const unsigned int port) char service[6]; struct addrinfo *res, *ainfo, hints; int err; - + sock = -1; snprintf(service, 6, "%u", port); @@ -98,7 +98,7 @@ sock_t sock_connect(const char * const host, const unsigned int port) ainfo = res; while (ainfo) { - if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, + if ((sock = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol)) >= 0) { sock_set_nonblocking(sock); @@ -158,7 +158,7 @@ int sock_write(const sock_t sock, const void * const buff, const size_t len) int sock_is_recoverable(const int error) { #ifdef _WIN32 - return (error == WSAEINTR || error == WSAEWOULDBLOCK || + return (error == WSAEINTR || error == WSAEWOULDBLOCK || error == WSAEINPROGRESS); #else return (error == EAGAIN || error == EINTR); @@ -293,7 +293,7 @@ void netbuf_get_16bitnum(unsigned char *buf, int buflen, int *offset, unsigned s *offset += 2; } -void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset, +void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset, char *name) { unsigned char *start = buf + *offset; @@ -301,7 +301,7 @@ void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset, unsigned char *wordstart, *wordend; wordstart = (unsigned char *)name; - + while (*wordstart) { int len; @@ -427,7 +427,7 @@ int netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char *na } partlen = *p++; - + for (i=0; i < partlen; i++) { *p2++ = *p++; @@ -452,7 +452,7 @@ void netbuf_add_dnsquery_header(unsigned char *buf, int buflen, int *offset, str unsigned char *p; netbuf_add_16bitnum(buf, buflen, offset, header->id); - + p = buf + *offset; *p++ = ((header->qr & 0x01) << 7) | ((header->opcode & 0x0F) << 3) @@ -473,7 +473,7 @@ void netbuf_add_dnsquery_header(unsigned char *buf, int buflen, int *offset, str void netbuf_get_dnsquery_header(unsigned char *buf, int buflen, int *offset, struct dnsquery_header *header) { unsigned char *p; - + netbuf_get_16bitnum(buf, buflen, offset, &(header->id)); p = buf + *offset; @@ -545,7 +545,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, if (!set) { HINSTANCE hdnsapi = NULL; - + DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, PDNS_RECORD*, PVOID*); void (WINAPI * pDnsRecordListFree)(PDNS_RECORD, DNS_FREE_TYPE); @@ -578,7 +578,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, pDnsRecordListFree(dnsrecords, DnsFreeRecordList); } - + FreeLibrary(hdnsapi); } } @@ -656,7 +656,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, { error = RegQueryValueEx(search, "DhcpNameServer", NULL, NULL, (LPBYTE)name, &len); } - + if (error == ERROR_SUCCESS) { char *parse = "0123456789.", *start, *end; @@ -868,24 +868,24 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, if (!set) { unsigned char buf[65535]; int len; - + if ((len = res_query(fulldomain, C_IN, T_SRV, buf, 65535)) > 0) { int offset; int i; struct dnsquery_header header; struct dnsquery_question question; struct dnsquery_resourcerecord rr; - + offset = 0; netbuf_get_dnsquery_header(buf, 65536, &offset, &header); - + for (i = 0; i < header.qdcount; i++) { netbuf_get_dnsquery_question(buf, 65536, &offset, &question); } for (i = 0; i < header.ancount; i++) { netbuf_get_dnsquery_resourcerecord(buf, 65536, &offset, &rr); - + if (rr.type == 33) { struct dnsquery_srvrdata *srvrdata = &(rr.rdata); @@ -898,7 +898,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain, for (i = 0; i < header.ancount; i++) { netbuf_get_dnsquery_resourcerecord(buf, 65536, &offset, &rr); - } + } } } #endif diff --git a/src/sock.h b/src/sock.h index 4fd98ba4..0291f3a4 100644 --- a/src/sock.h +++ b/src/sock.h @@ -1,7 +1,7 @@ /* sock.h ** strophe XMPP client library -- socket abstraction header ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/stanza.c b/src/stanza.c index af667f77..135e9980 100644 --- a/src/stanza.c +++ b/src/stanza.c @@ -1,7 +1,7 @@ /* stanza.c ** strophe XMPP client library -- XMPP stanza object and utilities ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -58,12 +58,12 @@ xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx) stanza->attributes = NULL; } - return stanza; + return stanza; } /** Clone a stanza object. * This function increments the reference count of the stanza object. - * + * * @param stanza a Strophe stanza object * * @return the stanza object with it's reference count incremented @@ -115,7 +115,7 @@ xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza) val = xmpp_strdup(stanza->ctx, (char *)hash_get(stanza->attributes, key)); if (!val) goto copy_error; - + if (hash_add(copy->attributes, key, val)) goto copy_error; } @@ -145,7 +145,7 @@ xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza) } /** Release a stanza object and all of its children. - * This function releases a stanza object and potentially all of its + * This function releases a stanza object and potentially all of its * children, which may cause the object(s) to be freed. * * @param stanza a Strophe stanza object @@ -181,11 +181,11 @@ int xmpp_stanza_release(xmpp_stanza_t * const stanza) } /** Determine if a stanza is a text node. - * + * * @param stanza a Strophe stanza object * * @return TRUE if the stanza is a text node, FALSE otherwise - * + * * @ingroup Stanza */ int xmpp_stanza_is_text(xmpp_stanza_t * const stanza) @@ -194,11 +194,11 @@ int xmpp_stanza_is_text(xmpp_stanza_t * const stanza) } /** Determine if a stanza is a tag node. - * + * * @param stanza a Strophe stanza object * * @return TRUE if the stanza is a tag node, FALSE otherwise - * + * * @ingroup Stanza */ int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza) @@ -278,7 +278,7 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza, ret = xmpp_snprintf(ptr, left, ">"); if (ret < 0) return XMPP_EMEM; _render_update(&written, buflen, ret, &left, &ptr); - + /* iterate and recurse over child stanzas */ child = stanza->children; while (child) { @@ -293,7 +293,7 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza, /* write end tag */ ret = xmpp_snprintf(ptr, left, "", stanza->data); if (ret < 0) return XMPP_EMEM; - + _render_update(&written, buflen, ret, &left, &ptr); } } @@ -350,7 +350,7 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza, ret = _render_stanza_recursive(stanza, buffer, length); if (ret > length - 1) return XMPP_EMEM; } - + buffer[length - 1] = 0; *buf = buffer; @@ -360,7 +360,7 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza, } /** Set the name of a stanza. - * + * * @param stanza a Strophe stanza object * @param name a string with the name of the stanza * @@ -369,7 +369,7 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza, * * @ingroup Stanza */ -int xmpp_stanza_set_name(xmpp_stanza_t *stanza, +int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char * const name) { if (stanza->type == XMPP_STANZA_TEXT) return XMPP_EINVOP; @@ -417,14 +417,14 @@ int xmpp_stanza_get_attribute_count(xmpp_stanza_t * const stanza) /** Get all attributes for a stanza object. * This function populates the array with attributes from the stanza. The - * attr array will be in the format: attr[i] = attribute name, + * attr array will be in the format: attr[i] = attribute name, * attr[i+1] = attribute value. * * @param stanza a Strophe stanza object * @param attr the string array to populate * @param attrlen the size of the array * - * @return the number of slots used in the array, which will be 2 times the + * @return the number of slots used in the array, which will be 2 times the * number of attributes in the stanza * * @ingroup Stanza @@ -461,7 +461,7 @@ int xmpp_stanza_get_attributes(xmpp_stanza_t * const stanza, } /** Set an attribute for a stanza object. - * + * * @param stanza a Strophe stanza object * @param key a string with the attribute name * @param value a string with the attribute value @@ -557,7 +557,7 @@ int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char * const text) { if (stanza->type == XMPP_STANZA_TAG) return XMPP_EINVOP; - + stanza->type = XMPP_STANZA_TEXT; if (stanza->data) xmpp_free(stanza->ctx, stanza->data); @@ -577,7 +577,7 @@ int xmpp_stanza_set_text(xmpp_stanza_t *stanza, * @param size the length of the text * * @return XMPP_EOK (0) on success and a number less than 0 on failure - * + * * @ingroup Stanza */ int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza, @@ -654,7 +654,7 @@ char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza) { if (stanza->type != XMPP_STANZA_TAG) return NULL; - + if (!stanza->attributes) return NULL; @@ -664,7 +664,7 @@ char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza) /** Get the first child of stanza with name. * This function searches all the immediate children of stanza for a child * stanza that matches the name. The first matching child is returned. - * + * * @param stanza a Strophe stanza object * @param name a string with the name to match * @@ -672,11 +672,11 @@ char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza) * * @ingroup Stanza */ -xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, +xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, const char * const name) { xmpp_stanza_t *child; - + for (child = stanza->children; child; child = child->next) { if (child->type == XMPP_STANZA_TAG && (strcmp(name, xmpp_stanza_get_name(child)) == 0)) @@ -690,7 +690,7 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, * This function searches all the immediate children of a stanza for a child * stanza that matches the namespace provided. The first matching child * is returned. - * + * * @param stanza a Strophe stanza object * @param ns a string with the namespace to match * @@ -708,7 +708,7 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza, strcmp(ns, xmpp_stanza_get_ns(child)) == 0) break; } - + return child; } @@ -723,13 +723,13 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza, * * @ingroup Stanza */ -xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza) +xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza) { return stanza->children; } /** Get the next sibling of a stanza. - * + * * @param stanza a Strophe stanza object * * @return the next sibling stanza or NULL if there are no more siblings @@ -790,7 +790,7 @@ char *xmpp_stanza_get_text(xmpp_stanza_t * const stanza) /** Get the text data pointer for a text stanza. * This function copies returns the raw pointer to the text data in the - * stanza. This should only be used in very special cases where the + * stanza. This should only be used in very special cases where the * caller needs to translate the datatype as this will save a double * allocation. The caller should not hold onto this pointer, and is * responsible for allocating a copy if it needs one. @@ -859,7 +859,7 @@ char *xmpp_stanza_get_attribute(xmpp_stanza_t * const stanza, { if (stanza->type != XMPP_STANZA_TAG) return NULL; - + if (!stanza->attributes) return NULL; diff --git a/src/thread.c b/src/thread.c index e2996408..4cd437e9 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1,7 +1,7 @@ /* thread.c ** strophe XMPP client library -- thread abstraction ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/thread.h b/src/thread.h index df00b30e..41917a4d 100644 --- a/src/thread.h +++ b/src/thread.h @@ -1,7 +1,7 @@ /* thread.h ** strophe XMPP client library -- thread abstraction header ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/tls.h b/src/tls.h index fa670b91..5fd283e8 100644 --- a/src/tls.h +++ b/src/tls.h @@ -1,7 +1,7 @@ /* tls.h ** strophe XMPP client library -- TLS abstraction header ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/tls_dummy.c b/src/tls_dummy.c index 00505fe5..e4843ee7 100644 --- a/src/tls_dummy.c +++ b/src/tls_dummy.c @@ -1,7 +1,7 @@ /* tls_dummy.c ** strophe XMPP client library -- TLS abstraction dummy impl. ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. diff --git a/src/tls_gnutls.c b/src/tls_gnutls.c index 7841331f..6ca019eb 100644 --- a/src/tls_gnutls.c +++ b/src/tls_gnutls.c @@ -1,7 +1,7 @@ /* tls.c ** strophe XMPP client library -- TLS abstraction header ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -62,7 +62,7 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock) gnutls_certificate_type_set_priority(tls->session, cert_type_priority); /* fixme: this may require setting a callback on win32? */ - gnutls_transport_set_ptr(tls->session, + gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)sock); } @@ -85,7 +85,7 @@ int tls_set_credentials(tls_t *tls, const char *cafilename) cafilename, GNUTLS_X509_FMT_PEM); if (err < 0) return err; - err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, + err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, tls->cred); return err; diff --git a/src/tls_openssl.c b/src/tls_openssl.c index e0874680..5754d712 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -1,7 +1,7 @@ /* tls_openssl.c ** strophe XMPP client library -- TLS abstraction openssl impl. ** -** Copyright (C) 2005-008 Collecta, Inc. +** Copyright (C) 2005-008 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -115,9 +115,9 @@ int tls_start(tls_t *tls) tv.tv_sec = 0; tv.tv_usec = 1000; - FD_ZERO(&fds); + FD_ZERO(&fds); FD_SET(tls->sock, &fds); - + select(tls->sock + 1, &fds, &fds, NULL, &tv); } } diff --git a/src/tls_schannel.c b/src/tls_schannel.c index ebbcbe56..2e356067 100644 --- a/src/tls_schannel.c +++ b/src/tls_schannel.c @@ -1,7 +1,7 @@ /* tls_schannel.c ** strophe XMPP client library -- TLS abstraction schannel impl. ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -102,7 +102,7 @@ tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock) return NULL; } - if (!(pInitSecurityInterface = + if (!(pInitSecurityInterface = (void *)GetProcAddress(tls->hsec32, "InitSecurityInterfaceA"))) { tls_free(tls); return NULL; @@ -196,7 +196,7 @@ void tls_free(tls_t *tls) FreeLibrary(tls->hsec32); tls->hsec32 = NULL; } - + xmpp_free(tls->ctx, tls); return; } @@ -297,7 +297,7 @@ int tls_start(tls_t *tls) FD_ZERO(&fds); FD_SET(tls->sock, &fds); - + select(tls->sock, &fds, NULL, NULL, &tv); } @@ -310,7 +310,7 @@ int tls_start(tls_t *tls) FD_ZERO(&fds); FD_SET(tls->sock, &fds); - + select(tls->sock, &fds, NULL, NULL, &tv); inbytes = sock_read(tls->sock, p, tls->spi->cbMaxToken - len); @@ -360,7 +360,7 @@ int tls_start(tls_t *tls) return 0; } - tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES, + tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES, &(tls->spcss)); tls->recvbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage @@ -401,7 +401,7 @@ int tls_is_recoverable(int error) int tls_pending(tls_t *tls) { // There are 3 cases: // - there is data in ready buffer, so it is by default pending - // - there is data in recv buffer. If it is not decrypted yet, means it + // - there is data in recv buffer. If it is not decrypted yet, means it // was incomplete. This should be processed again only if there is data // on the physical connection // - there is data on the physical connection. This case is treated @@ -494,7 +494,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len) ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL); if (ret == SEC_E_OK) { - memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer); + memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer); tls->readybufferpos = 0; tls->readybufferlen = sbdec[1].cbBuffer; /* have we got some data left over? If so, copy it to the start @@ -626,8 +626,8 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len) if (ret == -1 && !tls_is_recoverable(tls_error(tls))) { return -1; - } - + } + if (remain > tls->spcss.cbMaximumMessage) { sent += tls->spcss.cbMaximumMessage; remain -= tls->spcss.cbMaximumMessage; diff --git a/src/util.c b/src/util.c index a1e69acd..1cef0a40 100644 --- a/src/util.c +++ b/src/util.c @@ -1,7 +1,7 @@ /* util.c ** strophe XMPP client library -- various utility functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. @@ -95,7 +95,7 @@ uint64_t time_elapsed(uint64_t t1, uint64_t t2) /** Disconnect the stream with a memory error. * This is a convenience function used internally by various parts of - * the Strophe library for terminating the connection because of a + * the Strophe library for terminating the connection because of a * memory error. * * @param conn a Strophe connection object diff --git a/src/util.h b/src/util.h index dc00381a..8ba11db2 100644 --- a/src/util.h +++ b/src/util.h @@ -1,7 +1,7 @@ /* util.h ** strophe XMPP client library -- various utility functions ** -** Copyright (C) 2005-2009 Collecta, Inc. +** Copyright (C) 2005-2009 Collecta, Inc. ** ** This software is provided AS-IS with no warranty, either express ** or implied. From 39abc3cf6d4bfd0833dcb45d3c25ea9a2f95fa14 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sun, 21 Oct 2012 23:36:16 +0300 Subject: [PATCH 54/65] list: implement list_get_last --- src/list.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/list.c b/src/list.c index eda5af89..63100d33 100644 --- a/src/list.c +++ b/src/list.c @@ -116,8 +116,22 @@ list_t *list_get_next(const list_head_t * const list, const list_t * const item) return next; } +/** Get the last element of the list + * Function just returns tail of the list + * + * @param list a list object + * + * @return pointer to tail of the list or NULL pointer if the list is empty + */ list_t *list_get_last(const list_head_t * const list) { + list_t *last; + + mutex_lock(list->mutex); + last = list->tail; + mutex_unlock(list->mutex); + + return last; } /** Get the first element of the list and remove it From 677f500b2de1de675a2c5e77ab2415f96a12f23f Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 00:09:33 +0300 Subject: [PATCH 55/65] update list api, implement list_pop_next --- src/list.c | 31 ++++++++++++++++++++++--------- src/list.h | 4 +--- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/list.c b/src/list.c index 63100d33..325cd216 100644 --- a/src/list.c +++ b/src/list.c @@ -189,8 +189,29 @@ list_t *list_pop_by_data(list_head_t * const list, const void * const data) return cur; } -list_t *list_pop(list_head_t * const list) +/** Get next element and remove it from the list + * + * @param list a list object + * @param item a list item object + * + * @return pointer to the next element + */ +list_t *list_pop_next(list_head_t * const list, list_t * const item) { + list_t *next; + + if (!item) + return NULL; + + mutex_lock(list->mutex); + next = item->next; + if (next) + item->next = next->next; + if (!item->next) + list->last = item; + mutex_unlock(list->mutex); + + return next; } /** Insert the element to the head of the list @@ -211,10 +232,6 @@ void list_insert(list_head_t * const list, list_t * const item) mutex_unlock(list->mutex); } -void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after) -{ -} - /** Append the element to the end of the list * * @param list a list object @@ -233,7 +250,3 @@ void list_push(list_head_t * const list, list_t * const item) list->tail = item; mutex_unlock(list->mutex); } - -void list_update(list_head_t * const list, list_t * const item, const void * const data) -{ -} diff --git a/src/list.h b/src/list.h index a6fce72f..643d888c 100644 --- a/src/list.h +++ b/src/list.h @@ -45,11 +45,9 @@ list_t *list_get_next(const list_head_t * const list, const list_t * const item) list_t *list_get_last(const list_head_t * const list); list_t *list_shift(list_head_t * const list); list_t *list_pop_by_data(list_head_t * const list, const void * const data); -list_t *list_pop(list_head_t * const list); +list_t *list_pop_next(list_head_t * const list, list_t * const item); void list_insert(list_head_t * const list, list_t * const item); -void list_insert_after(list_head_t * const list, list_t * const item, list_t * const after); void list_push(list_head_t * const list, list_t * const item); -void list_update(list_head_t * const list, list_t * const item, const void * const data); static inline void list_lock_mutex(const list_head_t * const list) { From 6b28ba2ef1c59603bcf3b9d4c68de1ee26209583 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 00:36:51 +0300 Subject: [PATCH 56/65] event.c: replace 4096 with XMPP_RCV_BUF macro --- src/event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/event.c b/src/event.c index 388fc1db..1c65b705 100644 --- a/src/event.c +++ b/src/event.c @@ -210,7 +210,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) sock_t max = 0; int ret; struct timeval tv; - char buf[4096]; + char buf[XMPP_RCV_BUF]; uint64_t next; long usec; int tls_read_bytes = 0; @@ -323,9 +323,9 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout) case XMPP_STATE_CONNECTED: if (FD_ISSET(conn->sock, &rfds) || (conn->tls && tls_pending(conn->tls))) { if (conn->tls) - ret = tls_read(conn->tls, buf, 4096); + ret = tls_read(conn->tls, buf, XMPP_RCV_BUF); else - ret = sock_read(conn->sock, buf, 4096); + ret = sock_read(conn->sock, buf, XMPP_RCV_BUF); if (ret > 0) { ret = parser_feed(conn->parser, buf, ret); From b91aea0ff315a75095cb0ef61becf444033db117 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 00:37:27 +0300 Subject: [PATCH 57/65] common.h: add XMPP_RCV_BUF macro --- src/common.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common.h b/src/common.h index 63f35ecf..4e8fe9fc 100644 --- a/src/common.h +++ b/src/common.h @@ -35,6 +35,11 @@ #include "thread.h" #include "list.h" +/** @def XMPP_RCV_BUF + * Receive buffer size + */ +#define XMPP_RCV_BUF 4096 + /** run-time context **/ typedef enum { From 2830789fda29723e734deb19cc9a5cdb5f0554b0 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 00:40:58 +0300 Subject: [PATCH 58/65] list.c: fix typo --- src/list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/list.c b/src/list.c index 325cd216..4b86f2c5 100644 --- a/src/list.c +++ b/src/list.c @@ -208,7 +208,7 @@ list_t *list_pop_next(list_head_t * const list, list_t * const item) if (next) item->next = next->next; if (!item->next) - list->last = item; + list->tail = item; mutex_unlock(list->mutex); return next; From 99407fbb0e4b2dcf7a0852ea95324da2be085a27 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 17:11:44 +0300 Subject: [PATCH 59/65] doc: update README --- README.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/README.markdown b/README.markdown index 683eae8d..9a68b77e 100644 --- a/README.markdown +++ b/README.markdown @@ -27,6 +27,7 @@ libcouplet requires: - expat or libxml2 - expat is the default; use --with-libxml2 to switch +- openssl - libresolv on UNIX systems - make sure you include -lresolv if you are compiling by hand. From bc566b1689a5da1413600b8312e3c796f2f8fc2e Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 21:35:58 +0300 Subject: [PATCH 60/65] list: init next field when add new item --- src/list.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/list.c b/src/list.c index 4b86f2c5..e21eee0c 100644 --- a/src/list.c +++ b/src/list.c @@ -224,6 +224,7 @@ void list_insert(list_head_t * const list, list_t * const item) if (!item) return; + item->next = NULL; mutex_lock(list->mutex); item->next = list->head; list->head = item; @@ -242,6 +243,7 @@ void list_push(list_head_t * const list, list_t * const item) if (!item) return; + item->next = NULL; mutex_lock(list->mutex); if (!list->tail) list->head = item; From 6f50b7cec75f628ae6d64664506ef5d5468ea326 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Tue, 23 Oct 2012 21:38:06 +0300 Subject: [PATCH 61/65] use generic list for handlers and timed_handlers --- src/common.h | 28 ++- src/conn.c | 48 ++--- src/handler.c | 487 +++++++++++++++++++++++++------------------------- 3 files changed, 289 insertions(+), 274 deletions(-) diff --git a/src/common.h b/src/common.h index 4e8fe9fc..b0243938 100644 --- a/src/common.h +++ b/src/common.h @@ -115,16 +115,12 @@ struct _xmpp_send_queue_t { size_t written; }; -typedef struct _xmpp_handlist_t xmpp_handlist_t; -struct _xmpp_handlist_t { +typedef struct _xmpp_handler_t xmpp_handler_t; +struct _xmpp_handler_t { /* common members */ int user_handler; void *handler; void *userdata; - int enabled; /* handlers are added disabled and enabled after the - * handler chain is processed to prevent stanzas from - * getting processed by newly added handlers */ - xmpp_handlist_t *next; union { /* timed handlers */ @@ -145,6 +141,22 @@ struct _xmpp_handlist_t { }; }; +/** @TODO This is still used by id_handlers + * It should be removed after rewriting id handlers with generic lists + */ +typedef struct _xmpp_handlist_t xmpp_handlist_t; +struct _xmpp_handlist_t { + /* common members */ + int user_handler; + void *handler; + void *userdata; + + int enabled; + xmpp_handlist_t *next; + + char *id; +}; + #define SASL_MASK_PLAIN 0x01 #define SASL_MASK_DIGESTMD5 0x02 #define SASL_MASK_ANONYMOUS 0x04 @@ -208,9 +220,9 @@ struct _xmpp_conn_t { void *userdata; /* other handlers */ - xmpp_handlist_t *timed_handlers; + list_head_t *timed_handlers; hash_t *id_handlers; - xmpp_handlist_t *handlers; + list_head_t *handlers; }; void conn_disconnect(xmpp_conn_t * const conn); diff --git a/src/conn.c b/src/conn.c index 98e6d041..e0cd299e 100644 --- a/src/conn.c +++ b/src/conn.c @@ -131,10 +131,14 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) conn->authenticated = 0; conn->conn_handler = NULL; conn->userdata = NULL; - conn->timed_handlers = NULL; /* we own (and will free) the hash values */ conn->id_handlers = hash_new(ctx, 32, NULL); - conn->handlers = NULL; + conn->timed_handlers = list_init(ctx); + if (!conn->timed_handlers) + goto out_free_parser; + conn->handlers = list_init(ctx); + if (!conn->handlers) + goto out_free_timed_handlers; /* give the caller a reference to connection */ conn->ref = 1; @@ -142,7 +146,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) /* add connection to ctx->connlist */ item = list_init_item(ctx); if (!item) - goto out_free_parser; + goto out_free_handlers; else { item->data = (void *)conn; list_push(ctx->connlist, item); @@ -150,6 +154,10 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx) return conn; +out_free_handlers: + list_destroy(conn->handlers); +out_free_timed_handlers: + list_destroy(conn->timed_handlers); out_free_parser: parser_free(conn->parser); out_free_lang: @@ -190,6 +198,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn) { xmpp_ctx_t *ctx; list_t *item; + xmpp_handler_t *temp; xmpp_handlist_t *hlitem, *thli; hash_iterator_t *iter; const char *key; @@ -213,12 +222,11 @@ int xmpp_conn_release(xmpp_conn_t * const conn) * and the handler pointers don't need to be freed since they * are pointers to functions */ - hlitem = conn->timed_handlers; - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - xmpp_free(ctx, thli); + while ((item = list_shift(conn->timed_handlers))) { + xmpp_free(ctx, item->data); + xmpp_free(ctx, item); } + list_destroy(conn->timed_handlers); /* id handlers * we have to traverse the hash table freeing list elements @@ -236,19 +244,19 @@ int xmpp_conn_release(xmpp_conn_t * const conn) hash_iter_release(iter); hash_release(conn->id_handlers); - hlitem = conn->handlers; - while (hlitem) { - thli = hlitem; - hlitem = hlitem->next; - - if (thli->ns) - xmpp_free(ctx, thli->ns); - if (thli->name) - xmpp_free(ctx, thli->name); - if (thli->type) - xmpp_free(ctx, thli->type); - xmpp_free(ctx, thli); + while ((item = list_shift(conn->handlers))) { + temp = (xmpp_handler_t *)item->data; + + if (temp->ns) + xmpp_free(ctx, temp->ns); + if (temp->name) + xmpp_free(ctx, temp->name); + if (temp->type) + xmpp_free(ctx, temp->type); + xmpp_free(ctx, temp); + xmpp_free(ctx, item); } + list_destroy(conn->handlers); if (conn->stream_error) { xmpp_stanza_release(conn->stream_error->stanza); diff --git a/src/handler.c b/src/handler.c index 6b63043b..43ef843a 100644 --- a/src/handler.c +++ b/src/handler.c @@ -43,91 +43,82 @@ void handler_fire_stanza(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza) { - xmpp_handlist_t *item, *prev; - char *id, *ns, *name, *type; + list_t *hlistitem, *tail; + xmpp_handler_t *item; + xmpp_handlist_t *hitem, *prev; + char *id, *ns, *name, *type; + xmpp_ctx_t *ctx = conn->ctx; + + /* call id handlers */ + id = xmpp_stanza_get_id(stanza); + if (id) { + prev = NULL; + hitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, id); + while (hitem) { + xmpp_handlist_t *next = hitem->next; + + if (hitem->user_handler && !conn->authenticated) { + hitem = next; + continue; + } - /* call id handlers */ - id = xmpp_stanza_get_id(stanza); - if (id) { - prev = NULL; - item = (xmpp_handlist_t *)hash_get(conn->id_handlers, id); - while (item) { - xmpp_handlist_t *next = item->next; - - if (item->user_handler && !conn->authenticated) { - item = next; - continue; - } - - if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) { - /* handler is one-shot, so delete it */ - if (prev) - prev->next = next; - else { - hash_drop(conn->id_handlers, id); - hash_add(conn->id_handlers, id, next); + if (!((xmpp_handler)(hitem->handler))(conn, stanza, hitem->userdata)) { + /* handler is one-shot, so delete it */ + if (prev) + prev->next = next; + else { + hash_drop(conn->id_handlers, id); + hash_add(conn->id_handlers, id, next); + } + xmpp_free(ctx, hitem->id); + xmpp_free(ctx, hitem); + hitem = NULL; + } + if (hitem) + prev = hitem; + hitem = next; } - xmpp_free(conn->ctx, item->id); - xmpp_free(conn->ctx, item); - item = NULL; - } - if (item) - prev = item; - item = next; } - } - - /* call handlers */ - ns = xmpp_stanza_get_ns(stanza); - name = xmpp_stanza_get_name(stanza); - type = xmpp_stanza_get_type(stanza); - /* enable all added handlers */ - for (item = conn->handlers; item; item = item->next) - item->enabled = 1; + /* call handlers */ + ns = xmpp_stanza_get_ns(stanza); + name = xmpp_stanza_get_name(stanza); + type = xmpp_stanza_get_type(stanza); + + tail = list_get_last(conn->handlers); + while ((hlistitem = list_shift(conn->handlers))) { + item = (xmpp_handler_t *)hlistitem->data; + + /* don't call user handlers until authentication succeeds */ + if (item->user_handler && !conn->authenticated) + goto loop_handlers_continue; + + if ((!item->ns || (ns && strcmp(ns, item->ns) == 0) || + xmpp_stanza_get_child_by_ns(stanza, item->ns)) && + (!item->name || (name && strcmp(name, item->name) == 0)) && + (!item->type || (type && strcmp(type, item->type) == 0))) + if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) { + /* handler is one-shot, so delete it */ + if (item->ns) + xmpp_free(ctx, item->ns); + if (item->name) + xmpp_free(ctx, item->name); + if (item->type) + xmpp_free(ctx, item->type); + xmpp_free(ctx, item); + xmpp_free(ctx, hlistitem); + /* don't put hlistitem back to list */ + goto loop_handlers_continue; + } - prev = NULL; - item = conn->handlers; - while (item) { - /* skip newly added handlers */ - if (!item->enabled) { - prev = item; - item = item->next; - continue; - } + /* handler hasn't been deleted, put it back to list */ + list_push(conn->handlers, hlistitem); - /* don't call user handlers until authentication succeeds */ - if (item->user_handler && !conn->authenticated) { - prev = item; - item = item->next; - continue; +loop_handlers_continue: + /* skip newly added and watched handlers */ + if (hlistitem == tail) + break; } - - if ((!item->ns || (ns && strcmp(ns, item->ns) == 0) || - xmpp_stanza_get_child_by_ns(stanza, item->ns)) && - (!item->name || (name && strcmp(name, item->name) == 0)) && - (!item->type || (type && strcmp(type, item->type) == 0))) - if (!((xmpp_handler)(item->handler))(conn, stanza, item->userdata)) { - /* handler is one-shot, so delete it */ - if (prev) - prev->next = item->next; - else - conn->handlers = item->next; - if (item->ns) xmpp_free(conn->ctx, item->ns); - if (item->name) xmpp_free(conn->ctx, item->name); - if (item->type) xmpp_free(conn->ctx, item->type); - xmpp_free(conn->ctx, item); - item = NULL; - } - - if (item) { - prev = item; - item = item->next; - } else if (prev) - item = prev->next; - else - item = conn->handlers; - } } /** Fire off all timed handlers that are ready. @@ -140,7 +131,8 @@ void handler_fire_stanza(xmpp_conn_t * const conn, uint64_t handler_fire_timed(xmpp_ctx_t * const ctx) { list_t *connitem; - xmpp_handlist_t *handitem, *temp; + list_t *hlistitem, *tail; + xmpp_handler_t *handitem; xmpp_conn_t *conn; int ret, fired; uint64_t elapsed, min; @@ -151,30 +143,17 @@ uint64_t handler_fire_timed(xmpp_ctx_t * const ctx) while (connitem) { conn = (xmpp_conn_t *)connitem->data; if (conn->state != XMPP_STATE_CONNECTED) - goto loop_connitem_next; + goto loop_conn_continue; - /* enable all handlers that were added */ - handitem = conn->timed_handlers; - while (handitem) { - handitem->enabled = 1; - handitem = handitem->next; - } - - handitem = conn->timed_handlers; - while (handitem) { - /* skip newly added handlers */ - if (!handitem->enabled) { - handitem = handitem->next; - continue; - } + tail = list_get_last(conn->timed_handlers); + while ((hlistitem = list_shift(conn->timed_handlers))) { + fired = 0; + handitem = (xmpp_handler_t *)hlistitem->data; /* only fire user handlers after authentication */ - if (handitem->user_handler && !conn->authenticated) { - handitem = handitem->next; - continue; - } + if (handitem->user_handler && !conn->authenticated) + goto loop_handlers_continue; - fired = 0; elapsed = time_elapsed(handitem->last_stamp, time_stamp()); if (elapsed >= handitem->period) { /* fire! */ @@ -184,15 +163,20 @@ uint64_t handler_fire_timed(xmpp_ctx_t * const ctx) } else if (min > (handitem->period - elapsed)) min = handitem->period - elapsed; - temp = handitem; - handitem = handitem->next; - +loop_handlers_continue: /* delete handler if it returned false */ - if (fired && !ret) - xmpp_timed_handler_delete(conn, temp->handler); + if (fired && !ret) { + xmpp_free(ctx, handitem); + xmpp_free(ctx, hlistitem); + } else + list_push(conn->timed_handlers, hlistitem); + + /* skip newly added and watched handlers */ + if (hlistitem == tail) + break; } -loop_connitem_next: +loop_conn_continue: connitem = list_get_next(ctx->connlist, connitem); } @@ -207,15 +191,17 @@ uint64_t handler_fire_timed(xmpp_ctx_t * const ctx) */ void handler_reset_timed(xmpp_conn_t *conn, int user_only) { - xmpp_handlist_t *handitem; + list_t *hlistitem; + xmpp_handler_t *handitem; - handitem = conn->timed_handlers; - while (handitem) { - if ((user_only && handitem->user_handler) || !user_only) - handitem->last_stamp = time_stamp(); + hlistitem = list_get_first(conn->timed_handlers); + while (hlistitem) { + handitem = (xmpp_handler_t *)hlistitem->data; + if ((user_only && handitem->user_handler) || !user_only) + handitem->last_stamp = time_stamp(); - handitem = handitem->next; - } + hlistitem = list_get_next(conn->timed_handlers, hlistitem); + } } static void _timed_handler_add(xmpp_conn_t * const conn, @@ -224,37 +210,38 @@ static void _timed_handler_add(xmpp_conn_t * const conn, void * const userdata, const int user_handler) { - xmpp_handlist_t *item, *tail; - - /* check if handler is already in the list */ - for (item = conn->timed_handlers; item; item = item->next) { - if (item->handler == (void *)handler) - break; - } - if (item) return; - - /* build new item */ - item = xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t)); - if (!item) return; - - item->user_handler = user_handler; - item->handler = (void *)handler; - item->userdata = userdata; - item->enabled = 0; - item->next = NULL; - - item->period = period; - item->last_stamp = time_stamp(); - - /* append item to list */ - if (!conn->timed_handlers) - conn->timed_handlers = item; - else { - tail = conn->timed_handlers; - while (tail->next) - tail = tail->next; - tail->next = item; - } + list_t *hlistitem; + xmpp_handler_t *item; + + /* check if handler is already in the list */ + hlistitem = list_get_first(conn->timed_handlers); + while (hlistitem) { + item = (xmpp_handler_t *)hlistitem->data; + if (item->handler == (void *)handler) + break; + hlistitem = list_get_next(conn->timed_handlers, hlistitem); + } + if (hlistitem) + return; + + /* build new item */ + item = (xmpp_handler_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_handler_t)); + if (!item) + return; + + item->user_handler = user_handler; + item->handler = (void *)handler; + item->userdata = userdata; + item->period = period; + item->last_stamp = time_stamp(); + + hlistitem = list_init_item(conn->ctx); + if (!hlistitem) { + xmpp_free(conn->ctx, item); + return; + } + hlistitem->data = (void *)item; + list_push(conn->timed_handlers, hlistitem); } /** Delete a timed handler. @@ -267,27 +254,25 @@ static void _timed_handler_add(xmpp_conn_t * const conn, void xmpp_timed_handler_delete(xmpp_conn_t * const conn, xmpp_timed_handler handler) { - xmpp_handlist_t *item, *prev; - - if (!conn->timed_handlers) return; - - prev = NULL; - item = conn->timed_handlers; - while (item) { - if (item->handler == (void *)handler) - break; - prev = item; - item = item->next; - } + list_t *cur, *prev; + xmpp_handler_t *item; - if (item) { - if (prev) - prev->next = item->next; - else - conn->timed_handlers = item->next; - - xmpp_free(conn->ctx, item); - } + prev = NULL; + cur = list_get_first(conn->timed_handlers); + while (cur) { + item = (xmpp_handler_t *)cur->data; + if (item->handler == (void *)handler) { + if (!prev) + cur = list_shift(conn->timed_handlers); + else + cur = list_pop_next(conn->timed_handlers, prev); + xmpp_free(conn->ctx, item); + xmpp_free(conn->ctx, cur); + break; + } + prev = cur; + cur = list_get_next(conn->timed_handlers, cur); + } } static void _id_handler_add(xmpp_conn_t * const conn, @@ -379,61 +364,70 @@ static void _handler_add(xmpp_conn_t * const conn, const char * const type, void * const userdata, int user_handler) { - xmpp_handlist_t *item, *tail; - - /* check if handler already in list */ - for (item = conn->handlers; item; item = item->next) { - if (item->handler == (void *)handler) - break; - } - if (item) return; - - /* build new item */ - item = (xmpp_handlist_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t)); - if (!item) return; - - item->user_handler = user_handler; - item->handler = (void *)handler; - item->userdata = userdata; - item->enabled = 0; - item->next = NULL; - - if (ns) { - item->ns = xmpp_strdup(conn->ctx, ns); - if (!item->ns) { - xmpp_free(conn->ctx, item); - return; - } - } else - item->ns = NULL; - if (name) { - item->name = xmpp_strdup(conn->ctx, name); - if (!item->name) { - if (item->ns) xmpp_free(conn->ctx, item->ns); - xmpp_free(conn->ctx, item); - return; + list_t *hlistitem; + xmpp_handler_t *item; + xmpp_ctx_t *ctx = conn->ctx; + + /* check if handler is already in the list */ + hlistitem = list_get_first(conn->handlers); + while (hlistitem) { + item = (xmpp_handler_t *)hlistitem->data; + if (item->handler == (void *)handler) + break; + hlistitem = list_get_next(conn->handlers, hlistitem); } - } else - item->name = NULL; - if (type) { - item->type = xmpp_strdup(conn->ctx, type); - if (!item->type) { - if (item->ns) xmpp_free(conn->ctx, item->ns); - if (item->name) xmpp_free(conn->ctx, item->name); - xmpp_free(conn->ctx, item); - } - } else - item->type = NULL; + if (hlistitem) + return; + + item = (xmpp_handler_t *)xmpp_alloc(ctx, sizeof(xmpp_handler_t)); + if (!item) + return; + + item->user_handler = user_handler; + item->handler = (void *)handler; + item->userdata = userdata; + + if (ns) { + item->ns = xmpp_strdup(ctx, ns); + if (!item->ns) + goto out_free_item; + } else + item->ns = NULL; + + if (name) { + item->name = xmpp_strdup(ctx, name); + if (!item->name) + goto out_free_ns; + } else + item->name = NULL; + + if (type) { + item->type = xmpp_strdup(ctx, type); + if (!item->type) + goto out_free_name; + } else + item->type = NULL; + + hlistitem = list_init_item(ctx); + if (!hlistitem) + goto out_free_type; + + hlistitem->data = (void *)item; + list_push(conn->handlers, hlistitem); - /* append to list */ - if (!conn->handlers) - conn->handlers = item; - else { - tail = conn->handlers; - while (tail->next) - tail = tail->next; - tail->next = item; - } + return; + +out_free_type: + if (item->type) + xmpp_free(ctx, item->type); +out_free_name: + if (item->name) + xmpp_free(ctx, item->name); +out_free_ns: + if (item->ns) + xmpp_free(ctx, item->ns); +out_free_item: + xmpp_free(ctx, item); } /** Delete a stanza handler. @@ -446,31 +440,32 @@ static void _handler_add(xmpp_conn_t * const conn, void xmpp_handler_delete(xmpp_conn_t * const conn, xmpp_handler handler) { - xmpp_handlist_t *prev, *item; + list_t *cur, *prev; + xmpp_handler_t *item; - if (!conn->handlers) return; - - prev = NULL; - item = conn->handlers; - while (item) { - if (item->handler == (void *)handler) - break; - - prev = item; - item = item->next; - } - - if (item) { - if (prev) - prev->next = item->next; - else - conn->handlers = item->next; - - if (item->ns) xmpp_free(conn->ctx, item->ns); - if (item->name) xmpp_free(conn->ctx, item->name); - if (item->type) xmpp_free(conn->ctx, item->type); - xmpp_free(conn->ctx, item); - } + prev = NULL; + cur = list_get_first(conn->handlers); + while (cur) { + item = (xmpp_handler_t *)cur->data; + if (item->handler == (void *)handler) { + if (!prev) + cur = list_shift(conn->handlers); + else + cur = list_pop_next(conn->handlers, prev); + + if (item->ns) + xmpp_free(conn->ctx, item->ns); + if (item->name) + xmpp_free(conn->ctx, item->name); + if (item->type) + xmpp_free(conn->ctx, item->type); + xmpp_free(conn->ctx, item); + xmpp_free(conn->ctx, cur); + break; + } + prev = cur; + cur = list_get_next(conn->handlers, cur); + } } /** Add a timed handler. @@ -494,7 +489,7 @@ void xmpp_timed_handler_add(xmpp_conn_t * const conn, const unsigned long period, void * const userdata) { - _timed_handler_add(conn, handler, period, userdata, 1); + _timed_handler_add(conn, handler, period, userdata, 1); } /** Add a timed system handler. @@ -511,7 +506,7 @@ void handler_add_timed(xmpp_conn_t * const conn, const unsigned long period, void * const userdata) { - _timed_handler_add(conn, handler, period, userdata, 0); + _timed_handler_add(conn, handler, period, userdata, 0); } /** Add an id based stanza handler. @@ -535,7 +530,7 @@ void xmpp_id_handler_add(xmpp_conn_t * const conn, const char * const id, void * const userdata) { - _id_handler_add(conn, handler, id, userdata, 1); + _id_handler_add(conn, handler, id, userdata, 1); } /** Add an id based system stanza handler. @@ -552,7 +547,7 @@ void handler_add_id(xmpp_conn_t * const conn, const char * const id, void * const userdata) { - _id_handler_add(conn, handler, id, userdata, 0); + _id_handler_add(conn, handler, id, userdata, 0); } /** Add a stanza handler. @@ -584,7 +579,7 @@ void xmpp_handler_add(xmpp_conn_t * const conn, const char * const type, void * const userdata) { - _handler_add(conn, handler, ns, name, type, userdata, 1); + _handler_add(conn, handler, ns, name, type, userdata, 1); } /** Add a system stanza handler. @@ -605,5 +600,5 @@ void handler_add(xmpp_conn_t * const conn, const char * const type, void * const userdata) { - _handler_add(conn, handler, ns, name, type, userdata, 0); + _handler_add(conn, handler, ns, name, type, userdata, 0); } From 09b09894d0a20895d414e291dc4dc5b1d8b26097 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 24 Oct 2012 23:09:39 +0100 Subject: [PATCH 62/65] Added tags and cscope.out to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a1a39b74..36439b77 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,8 @@ tests/check_parser *.swp docs/html TAGS +tags +cscope.out examples/basic examples/active examples/roster From 4137a06742188f652e30478fe52e3af3c23c8433 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 24 Oct 2012 23:14:51 +0100 Subject: [PATCH 63/65] Added ping namespace to couplet.h --- couplet.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/couplet.h b/couplet.h index 1f32a30e..fc2b0f1c 100644 --- a/couplet.h +++ b/couplet.h @@ -74,6 +74,10 @@ extern "C" { * Namespace definition for 'jabber:iq:roster'. */ #define XMPP_NS_ROSTER "jabber:iq:roster" +/** @def XMPP_NS_PING + * Namespace definition for 'urn:xmpp:ping'. + */ +#define XMPP_NS_PING "urn:xmpp:ping" /* error defines */ /** @def XMPP_EOK From 59aedf9021888dc0cff1be16a14f811a1e334c9f Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sun, 28 Oct 2012 00:05:24 +0300 Subject: [PATCH 64/65] rewrite Makefile.am and configure.ac --- Makefile.am | 25 +------------------------ configure.ac | 48 +++++++++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 47 deletions(-) diff --git a/Makefile.am b/Makefile.am index 6b512958..969bc539 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,19 +1,12 @@ AUTOMAKE_OPTIONS = subdir-objects -AM_CFLAGS = -I$(top_srcdir) -g -Wall -PARSER_CFLAGS=@PARSER_CFLAGS@ - -PARSER_LIBS=@PARSER_LIBS@ -SSL_LIBS = -lssl -lcrypto -lz COUPLET_LIBS = libcouplet.la -LIBS += $(SSL_LIBS) $(PARSER_LIBS) pkgconfigdir = $(libdir)/pkgconfig ## Main build targets lib_LTLIBRARIES = libcouplet.la -libcouplet_la_CFLAGS=$(AM_CFLAGS) $(PARSER_CFLAGS) libcouplet_la_SOURCES = src/auth.c src/conn.c src/ctx.c \ src/event.c src/handler.c src/hash.c \ src/jid.c src/md5.c src/sasl.c src/sha1.c \ @@ -36,26 +29,10 @@ EXTRA_DIST = docs pkgconfig_DATA = libcouplet.pc -## Examples -noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot -examples_active_SOURCES = examples/active.c -examples_active_CFLAGS = $(AM_CFLAGS) -examples_active_LDADD = $(COUPLET_LIBS) -examples_roster_SOURCES = examples/roster.c -examples_roster_CFLAGS = $(AM_CFLAGS) -examples_roster_LDADD = $(COUPLET_LIBS) -examples_basic_SOURCES = examples/basic.c -examples_basic_CFLAGS = $(AM_CFLAGS) -examples_basic_LDADD = $(COUPLET_LIBS) -examples_bot_SOURCES = examples/bot.c -examples_bot_CFLAGS = $(AM_CFLAGS) -examples_bot_LDADD = $(COUPLET_LIBS) - - ## Tests TESTS = tests/check_parser check_PROGRAMS = tests/check_parser tests_check_parser_SOURCES = tests/check_parser.c tests/test.h -tests_check_parser_CFLAGS = @check_CFLAGS@ $(PARSER_CFLAGS) $(AM_CFLAGS) \ +tests_check_parser_CFLAGS = @check_CFLAGS@ $(AM_CFLAGS) \ -I$(top_srcdir)/src tests_check_parser_LDADD = @check_LIBS@ $(COUPLET_LIBS) diff --git a/configure.ac b/configure.ac index d7c81a39..8fbde770 100644 --- a/configure.ac +++ b/configure.ac @@ -1,48 +1,50 @@ -AC_INIT([libcouplet], [0.8-snapshot], [pasis.ua@gmail.com]) +AC_INIT([libcouplet], [0.8], [pasis.ua@gmail.com]) AM_INIT_AUTOMAKE +AC_CONFIG_FILES([Makefile libcouplet.pc]) AC_PROG_CC AM_PROG_CC_C_O LT_INIT -AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([could not find openssl headers, openssl required])]) -PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])]) - AC_ARG_WITH([libxml2], [AS_HELP_STRING([--with-libxml2], [use libxml2 for XML parsing])]) -AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([pthread support is required])]) +PKG_CHECK_MODULES([openssl], [openssl], [], + [AC_MSG_ERROR([openssl is required for libcouplet])]) +PKG_CHECK_MODULES([check], [check >= 0.9.4], [], + [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])]) +AC_CHECK_LIB(pthread, pthread_create, [], + [AC_MSG_ERROR([pthread support is required])]) +AC_CHECK_LIB(resolv, res_query, [], + [AC_MSG_ERROR([libresolv is not found])]) if test "x$with_libxml2" = xyes; then - PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7], - [with_libxml2=yes], - [AC_MSG_ERROR([could not find libxml2])]) -else - AC_CHECK_HEADER(expat.h, [], [AC_MSG_ERROR([could not find expat headers; expat required])]) + PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7], [], + [AC_MSG_ERROR([libxml2 is required for libcouplet])]) +else + PKG_CHECK_MODULES([expat], [expat], [], + [AC_MSG_ERROR([expat is required for libcouplet])]) fi if test "x$with_libxml2" = xyes; then - with_parser=libxml2 PARSER_NAME=libxml2 - PARSER_CFLAGS=\$\(libxml2_CFLAGS\) - PARSER_LIBS=\$\(libxml2_LIBS\) + LIBS="$LIBS $libxml2_LIBS" + AM_CFLAGS="$AM_CFLAGS $libxml2_CFLAGS" else - with_parser=expat PARSER_NAME=expat - PARSER_CFLAGS= - PARSER_LIBS=-lexpat + LIBS="$LIBS $expat_LIBS" + AM_CFLAGS="$AM_CFLAGS $expat_CFLAGS" fi -AC_MSG_NOTICE([libcouplet will use the $with_parser XML parser]) -AC_SEARCH_LIBS([socket], [socket]) +LIBS="$LIBS $openssl_LIBS" +AM_CFLAGS="$AM_CFLAGS $openssl_CFLAGS -I. -Wall" -AC_LINK_IFELSE([AC_LANG_CALL([#include ], [res_query])], [],[LIBS="$LIBS -lresolv"]) +AC_MSG_NOTICE([libcouplet will use the $PARSER_NAME XML parser]) +AC_SEARCH_LIBS([socket], [socket]) AC_CHECK_HEADERS([arpa/nameser_compat.h]) -AM_CONDITIONAL([PARSER_EXPAT], [test x$with_parser != xlibxml2]) +AM_CONDITIONAL([PARSER_EXPAT], [test x$PARSER_NAME != xlibxml2]) AC_SUBST(PARSER_NAME) -AC_SUBST(PARSER_CFLAGS) -AC_SUBST(PARSER_LIBS) -AC_CONFIG_FILES([Makefile libcouplet.pc]) +AC_SUBST(AM_CFLAGS) AC_OUTPUT From ed3917ce6acc66b29973ac4a15fc743c31610870 Mon Sep 17 00:00:00 2001 From: Jonas Wielicki Date: Fri, 11 Jan 2013 16:21:03 +0100 Subject: [PATCH 65/65] Fix two memory leaks, both related to cleanup (1) the connection did not release its sendqueue in xmpp_conn_release. (2) the connection did not release its TLS context in xmpp_conn_release. --- src/auth.c | 1 + src/conn.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/auth.c b/src/auth.c index 23719256..30d08321 100644 --- a/src/auth.c +++ b/src/auth.c @@ -554,6 +554,7 @@ static void _auth(xmpp_conn_t * const conn) disconnect_mem_error(conn); return; } + xmpp_free(conn->ctx, authid); xmpp_stanza_set_text(authdata, str); xmpp_free(conn->ctx, str); diff --git a/src/conn.c b/src/conn.c index 26df4186..cf297448 100644 --- a/src/conn.c +++ b/src/conn.c @@ -190,6 +190,8 @@ int xmpp_conn_release(xmpp_conn_t * const conn) xmpp_connlist_t *item, *prev; xmpp_handlist_t *hlitem, *thli; hash_iterator_t *iter; + xmpp_send_queue_t *sq; + xmpp_send_queue_t *tsq; const char *key; int released = 0; @@ -267,13 +269,28 @@ int xmpp_conn_release(xmpp_conn_t * const conn) } parser_free(conn->parser); - + if (conn->domain) xmpp_free(ctx, conn->domain); if (conn->jid) xmpp_free(ctx, conn->jid); - if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); + if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid); if (conn->pass) xmpp_free(ctx, conn->pass); if (conn->stream_id) xmpp_free(ctx, conn->stream_id); if (conn->lang) xmpp_free(ctx, conn->lang); + + sq = conn->send_queue_head; + while (sq != NULL) { + if (sq->data) { + xmpp_free(ctx, sq->data); + } + tsq = sq->next; + xmpp_free(ctx, sq); + sq = tsq; + } + + if (conn->tls) { + tls_free(conn->tls); + } + xmpp_free(ctx, conn); released = 1; }