Mercurial > pidgin.yaz
changeset 32072:3a90a59ddea2
Update libgadu to 0.11.0 plus local changes; thanks to Tomasz Wasilczyk.
Fixes 14248
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sun, 05 Jun 2011 01:28:53 +0000 (2011-06-05) |
parents | 3e53f6871805 |
children | b185aa2c7318 |
files | configure.ac libpurple/protocols/gg/Makefile.am libpurple/protocols/gg/Makefile.mingw libpurple/protocols/gg/lib/common.c libpurple/protocols/gg/lib/dcc.c libpurple/protocols/gg/lib/dcc7.c libpurple/protocols/gg/lib/debug.c libpurple/protocols/gg/lib/encoding.c libpurple/protocols/gg/lib/events.c libpurple/protocols/gg/lib/handlers.c libpurple/protocols/gg/lib/http.c libpurple/protocols/gg/lib/libgadu-config.h libpurple/protocols/gg/lib/libgadu-debug.h libpurple/protocols/gg/lib/libgadu.c libpurple/protocols/gg/lib/libgadu.h libpurple/protocols/gg/lib/obsolete.c libpurple/protocols/gg/lib/protocol.h libpurple/protocols/gg/lib/pubdir.c libpurple/protocols/gg/lib/pubdir50.c libpurple/protocols/gg/lib/resolver.c libpurple/protocols/gg/lib/sha1.c |
diffstat | 21 files changed, 797 insertions(+), 570 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac Tue May 24 01:48:26 2011 +0000 +++ b/configure.ac Sun Jun 05 01:28:53 2011 +0000 @@ -1024,7 +1024,7 @@ gadu_manual_check="no" fi if test "x$gadu_manual_check" = "xno"; then - PKG_CHECK_MODULES(GADU, [libgadu >= 1.10.1], [ + PKG_CHECK_MODULES(GADU, [libgadu >= 1.11.0], [ gadu_includes="yes" gadu_libs="yes" ], [ @@ -1058,7 +1058,7 @@ ]])], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libgadu.h>]], [[ #if GG_DEFAULT_PROTOCOL_VERSION < 0x2e -#error "Your libgadu version is too old. libpurple requires 1.10.1 or higher." +#error "Your libgadu version is too old. libpurple requires 1.11.0 or higher." #endif ]])], [ AC_MSG_RESULT(yes) @@ -1069,7 +1069,7 @@ echo echo echo "Your supplied copy of libgadu is too old." - echo "Install version 1.10.1 or newer." + echo "Install version 1.11.0 or newer." echo "Then rerun this ./configure" echo echo "Falling back to using our own copy of libgadu"
--- a/libpurple/protocols/gg/Makefile.am Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/Makefile.am Sun Jun 05 01:28:53 2011 +0000 @@ -6,6 +6,7 @@ lib/dcc.c \ lib/dcc7.c \ lib/debug.c \ + lib/deflate.c \ lib/encoding.c \ lib/encoding.h \ lib/events.c \ @@ -36,6 +37,7 @@ lib/dcc.c \ lib/dcc7.c \ lib/debug.c \ + lib/deflate.c \ lib/encoding.c \ lib/encoding.h \ lib/events.c \ @@ -59,7 +61,6 @@ INTGG_CFLAGS = -I$(top_srcdir)/libpurple/protocols/gg/lib -DGG_IGNORE_DEPRECATED -DUSE_INTERNAL_LIBGADU if USE_GNUTLS -INTGG_CFLAGS += -DUSE_GNUTLS GADU_LIBS += $(GNUTLS_LIBS) endif
--- a/libpurple/protocols/gg/Makefile.mingw Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/Makefile.mingw Sun Jun 05 01:28:53 2011 +0000 @@ -44,6 +44,7 @@ lib/dcc.c \ lib/dcc7.c \ lib/debug.c \ + lib/deflate.c \ lib/encoding.c \ lib/events.c \ lib/handlers.c \
--- a/libpurple/protocols/gg/lib/common.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/common.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: common.c 1037 2010-12-17 22:18:08Z wojtekka $ */ +/* $Id: common.c 1101 2011-05-05 21:17:28Z wojtekka $ */ /* * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl> @@ -24,10 +24,6 @@ * * \brief Funkcje wykorzystywane przez r坦甜ne modu�y biblioteki */ - -#include "libgadu.h" -#include "libgadu-internal.h" - #ifndef _WIN32 # include <sys/types.h> # include <sys/ioctl.h> @@ -41,17 +37,16 @@ #include <errno.h> #include <fcntl.h> - #ifndef _WIN32 # include <netdb.h> #endif - #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include "libgadu.h" /** * \internal Odpowiednik funkcji \c vsprintf alokuj�cy miejsce na wynik. @@ -329,7 +324,7 @@ * Zamienia znaki niedrukowalne, spoza ASCII i maj�ce specjalne znaczenie * dla protoko�u HTTP na encje postaci \c %XX, gdzie \c XX jest szesnastkow� * warto�ci� znaku. - * + * * \param str Ci�g znak坦w do zakodowania * * \return Zaalokowany bufor lub \c NULL w przypadku b��du.
--- a/libpurple/protocols/gg/lib/dcc.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/dcc.c Sun Jun 05 01:28:53 2011 +0000 @@ -25,11 +25,9 @@ * * \brief Obs�uga po��cze� bezpo�rednich do wersji Gadu-Gadu 6.x */ -#include "libgadu.h" #include <sys/types.h> #include <sys/stat.h> - #ifndef _WIN32 # include <sys/ioctl.h> # include <sys/socket.h> @@ -50,6 +48,7 @@ #include <unistd.h> #include "compat.h" +#include "libgadu.h" #ifndef GG_DEBUG_DISABLE @@ -421,7 +420,7 @@ return NULL; } - if (port == 0 || port == -1) + if (port == 0 || port == (uint16_t)-1) /* XXX: port is unsigned */ port = GG_DEFAULT_DCC_PORT; while (!bound) {
--- a/libpurple/protocols/gg/lib/dcc7.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/dcc7.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,11 +1,11 @@ -/* $Id: dcc7.c 1037 2010-12-17 22:18:08Z wojtekka $ */ +/* $Id: dcc7.c 1087 2011-04-14 20:53:25Z wojtekka $ */ /* * (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl> * Tomasz Chili�ski <chilek@chilan.com> * Adam Wysocki <gophi@ekg.chmurka.net> * Bart�omiej Zimo� <uzi18@o2.pl> - * + * * Thanks to Jakub Zawadzki <darkjames@darkjames.ath.cx> * * This program is free software; you can redistribute it and/or modify @@ -29,13 +29,8 @@ * \brief Obs�uga po��cze� bezpo�rednich od wersji Gadu-Gadu 7.x */ -#include "libgadu.h" -#include "libgadu-internal.h" -#include "libgadu-debug.h" - #include <sys/types.h> #include <sys/stat.h> - #ifndef _WIN32 # include <sys/ioctl.h> # include <sys/socket.h> @@ -45,7 +40,6 @@ # include <sys/filio.h> # endif #endif - #include <time.h> #include <ctype.h> @@ -58,8 +52,11 @@ #include <unistd.h> #include "compat.h" +#include "libgadu.h" #include "protocol.h" #include "resolver.h" +#include "libgadu-internal.h" +#include "libgadu-debug.h" #define gg_debug_dcc(dcc, level, fmt...) \ gg_debug_session(((dcc) != NULL) ? (dcc)->sess : NULL, level, fmt) @@ -223,13 +220,16 @@ * \internal Tworzy gniazdo nas�uchuj�ce dla po��czenia bezpo�redniego * * \param dcc Struktura po��czenia - * \param port Preferowany port (je�li r坦wny 0 lub -1, pr坦buje si� domy�lnego) + * \param addr Preferowany adres (je�li r坦wny 0, nas�uchujemy na wszystkich interfejsach) + * \param port Preferowany port (je�li r坦wny 0, nas�uchujemy na losowym) * * \return 0 je�li si� powiod�o, -1 w przypadku b��du */ -static int gg_dcc7_listen(struct gg_dcc7 *dcc, uint16_t port) +static int gg_dcc7_listen(struct gg_dcc7 *dcc, uint32_t addr, uint16_t port) { struct sockaddr_in sin; + socklen_t sin_len = sizeof(sin); + int errsv; int fd; gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_listen(%p, %d)\n", dcc, port); @@ -245,45 +245,40 @@ return -1; } - // XXX losowa� porty? - - if (!port) - port = GG_DEFAULT_DCC_PORT; - - while (1) { - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(port); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = addr; + sin.sin_port = htons(port); - gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() trying port %d\n", port); - - if (!bind(fd, (struct sockaddr*) &sin, sizeof(sin))) - break; + if (bind(fd, (struct sockaddr*) &sin, sizeof(sin)) == -1) { + gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to bind to %s:%d\n", inet_ntoa(sin.sin_addr), port); + goto fail; + } - if (port++ == 65535) { - gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() no free port found\n"); - close(fd); - errno = ENOENT; - return -1; - } + if (port == 0 && getsockname(fd, (struct sockaddr*) &sin, &sin_len) == -1) { + gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to bind to port %d\n", port); + goto fail; } if (listen(fd, 1)) { - int errsv = errno; gg_debug_dcc(dcc, GG_DEBUG_MISC, "// gg_dcc7_listen() unable to listen (%s)\n", strerror(errno)); - close(fd); - errno = errsv; - return -1; + goto fail; } dcc->fd = fd; - dcc->local_port = port; - + dcc->local_addr = sin.sin_addr.s_addr; + dcc->local_port = ntohs(sin.sin_port); + dcc->state = GG_STATE_LISTENING; dcc->check = GG_CHECK_READ; dcc->timeout = GG_DCC7_TIMEOUT_FILE_ACK; return 0; + +fail: + errsv = errno; + close(fd); + errno = errsv; + return -1; } /** @@ -297,38 +292,34 @@ { struct gg_dcc7_info pkt; uint16_t external_port; - uint16_t local_port; + uint32_t external_addr; + struct in_addr addr; gg_debug_dcc(dcc, GG_DEBUG_FUNCTION, "** gg_dcc7_listen_and_send_info(%p)\n", dcc); - if (!dcc->sess->client_port) - local_port = dcc->sess->external_port; - else - local_port = dcc->sess->client_port; - - if (gg_dcc7_listen(dcc, local_port) == -1) + if (gg_dcc7_listen(dcc, dcc->sess->client_addr, dcc->sess->client_port) == -1) return -1; - if (!dcc->sess->external_port || dcc->local_port != local_port) + if (dcc->sess->external_port != 0) + external_port = dcc->sess->external_port; + else external_port = dcc->local_port; - else - external_port = dcc->sess->external_port; - if (!dcc->sess->external_addr || dcc->local_port != local_port) - dcc->local_addr = dcc->sess->client_addr; - else - dcc->local_addr = dcc->sess->external_addr; + if (dcc->sess->external_addr != 0) + external_addr = dcc->sess->external_addr; + else + external_addr = dcc->local_addr; - gg_debug_dcc(dcc, GG_DEBUG_MISC, "// dcc7_listen_and_send_info() sending IP address %s and port %d\n", inet_ntoa(*((struct in_addr*) &dcc->local_addr)), external_port); + addr.s_addr = external_addr; + + gg_debug_dcc(dcc, GG_DEBUG_MISC, "// dcc7_listen_and_send_info() sending IP address %s and port %d\n", inet_ntoa(addr), external_port); memset(&pkt, 0, sizeof(pkt)); pkt.uin = gg_fix32(dcc->peer_uin); pkt.type = GG_DCC7_TYPE_P2P; pkt.id = dcc->cid; - snprintf((char*) pkt.info, sizeof(pkt.info), "%s %d", inet_ntoa(*((struct in_addr*) &dcc->local_addr)), external_port); - // TODO: implement hash count - // we MUST fill hash to recive from server request for server connection - snprintf((char*) pkt.hash, sizeof(pkt.hash), "0"); + snprintf((char*) pkt.info, sizeof(pkt.info), "%s %d", inet_ntoa(addr), external_port); + snprintf((char*) pkt.hash, sizeof(pkt.hash), "%u", external_addr + external_port * rand()); return gg_send_packet(dcc->sess, GG_DCC7_INFO, &pkt, sizeof(pkt), NULL); } @@ -388,7 +379,7 @@ errno = EINVAL; return -1; } - + memset(&pkt, 0, sizeof(pkt)); pkt.type = gg_fix32(type); @@ -649,7 +640,7 @@ if (tmp->state != GG_STATE_REQUESTING_ID || tmp->dcc_type != gg_fix32(p->type)) continue; - + tmp->cid = p->id; switch (tmp->dcc_type) { @@ -708,9 +699,9 @@ e->event.dcc7_error = GG_ERROR_DCC7_HANDSHAKE; return 0; } - + // XXX czy dla odwrotnego po��czenia powinni�my wywo�a� ju甜 zdarzenie GG_DCC7_ACCEPT? - + dcc->offset = gg_fix32(p->offset); dcc->state = GG_STATE_WAITING_FOR_INFO; @@ -764,8 +755,10 @@ } if (dcc->state == GG_STATE_WAITING_FOR_INFO) { - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() wainting for info so send one\n"); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() waiting for info so send one\n"); gg_dcc7_listen_and_send_info(dcc); + e->type = GG_EVENT_DCC7_PENDING; + e->event.dcc7_pending.dcc7 = dcc; return 0; } @@ -809,7 +802,7 @@ gg_send_packet(dcc->sess, GG_DCC7_INFO, payload, len, NULL); - break; + return 0; default: gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_info() unhandled transfer type (%d)\n", p->type); @@ -877,7 +870,7 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_reject() unknown dcc session\n"); return 0; } - + if (dcc->state != GG_STATE_WAITING_FOR_ACCEPT) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_reject() invalid state\n"); e->type = GG_EVENT_DCC7_ERROR; @@ -917,7 +910,7 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_new() not enough memory\n"); return -1; } - + memset(dcc, 0, sizeof(struct gg_dcc7)); dcc->type = GG_SESSION_DCC7_GET; dcc->dcc_type = GG_DCC7_TYPE_FILE; @@ -949,7 +942,7 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_dcc7_handle_packet() not enough memory\n"); return -1; } - + memset(dcc, 0, sizeof(struct gg_dcc7)); dcc->type = GG_SESSION_DCC7_VOICE; @@ -984,7 +977,7 @@ /** * \internal Ustawia odpowiednie stany wewn�trzne w zale甜no�ci od rodzaju * po��czenia. - * + * * \param dcc Struktura po��czenia * * \return 0 je�li si� powiod�o, -1 w przypadku b��du. @@ -1382,6 +1375,9 @@ dcc->check = GG_CHECK_WRITE; dcc->timeout = GG_DEFAULT_TIMEOUT; + e->type = GG_EVENT_DCC7_PENDING; + e->event.dcc7_pending.dcc7 = dcc; + return e; }
--- a/libpurple/protocols/gg/lib/debug.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/debug.c Sun Jun 05 01:28:53 2011 +0000 @@ -32,7 +32,7 @@ #include <string.h> #include "libgadu.h" -#include "debug.h" +#include "libgadu-debug.h" /** * Poziom rejestracji informacji odpluskwiaj�cych. Zmienna jest mask� bitow� @@ -265,8 +265,74 @@ GG_DEBUG_STATE(GG_STATE_CONNECTING_RELAY) GG_DEBUG_STATE(GG_STATE_READING_RELAY) GG_DEBUG_STATE(GG_STATE_DISCONNECTING) +#undef GG_DEBUG_STATE - // Celowo nie ma default, 甜eby kompilator wy�apa� brakuj�ce stany + /* Celowo nie ma default, 甜eby kompilator wy�apa� brakuj�ce stany */ + + } + + return NULL; +} + +/** + * \internal Zwraca ci�g z nazw� podanego zdarzenia. + * + * \param event Zdarzenie. + * + * \return Ci�g z nazw� zdarzenia + * + * \ingroup debug + */ +const char *gg_debug_event(enum gg_event_t event) +{ + switch (event) { +#define GG_DEBUG_EVENT(x) case x: return #x; + GG_DEBUG_EVENT(GG_EVENT_NONE) + GG_DEBUG_EVENT(GG_EVENT_MSG) + GG_DEBUG_EVENT(GG_EVENT_NOTIFY) + GG_DEBUG_EVENT(GG_EVENT_NOTIFY_DESCR) + GG_DEBUG_EVENT(GG_EVENT_STATUS) + GG_DEBUG_EVENT(GG_EVENT_ACK) + GG_DEBUG_EVENT(GG_EVENT_PONG) + GG_DEBUG_EVENT(GG_EVENT_CONN_FAILED) + GG_DEBUG_EVENT(GG_EVENT_CONN_SUCCESS) + GG_DEBUG_EVENT(GG_EVENT_DISCONNECT) + GG_DEBUG_EVENT(GG_EVENT_DCC_NEW) + GG_DEBUG_EVENT(GG_EVENT_DCC_ERROR) + GG_DEBUG_EVENT(GG_EVENT_DCC_DONE) + GG_DEBUG_EVENT(GG_EVENT_DCC_CLIENT_ACCEPT) + GG_DEBUG_EVENT(GG_EVENT_DCC_CALLBACK) + GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_FILE_INFO) + GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_FILE_ACK) + GG_DEBUG_EVENT(GG_EVENT_DCC_NEED_VOICE_ACK) + GG_DEBUG_EVENT(GG_EVENT_DCC_VOICE_DATA) + GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_SEARCH_REPLY) + GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_READ) + GG_DEBUG_EVENT(GG_EVENT_PUBDIR50_WRITE) + GG_DEBUG_EVENT(GG_EVENT_STATUS60) + GG_DEBUG_EVENT(GG_EVENT_NOTIFY60) + GG_DEBUG_EVENT(GG_EVENT_USERLIST) + GG_DEBUG_EVENT(GG_EVENT_IMAGE_REQUEST) + GG_DEBUG_EVENT(GG_EVENT_IMAGE_REPLY) + GG_DEBUG_EVENT(GG_EVENT_DCC_ACK) + GG_DEBUG_EVENT(GG_EVENT_DCC7_NEW) + GG_DEBUG_EVENT(GG_EVENT_DCC7_ACCEPT) + GG_DEBUG_EVENT(GG_EVENT_DCC7_REJECT) + GG_DEBUG_EVENT(GG_EVENT_DCC7_CONNECTED) + GG_DEBUG_EVENT(GG_EVENT_DCC7_ERROR) + GG_DEBUG_EVENT(GG_EVENT_DCC7_DONE) + GG_DEBUG_EVENT(GG_EVENT_DCC7_PENDING) + GG_DEBUG_EVENT(GG_EVENT_XML_EVENT) + GG_DEBUG_EVENT(GG_EVENT_DISCONNECT_ACK) + GG_DEBUG_EVENT(GG_EVENT_TYPING_NOTIFICATION) + GG_DEBUG_EVENT(GG_EVENT_USER_DATA) + GG_DEBUG_EVENT(GG_EVENT_MULTILOGON_MSG) + GG_DEBUG_EVENT(GG_EVENT_MULTILOGON_INFO) + GG_DEBUG_EVENT(GG_EVENT_USERLIST100_VERSION) + GG_DEBUG_EVENT(GG_EVENT_USERLIST100_REPLY) +#undef GG_DEBUG_EVENT + + /* Celowo nie ma default, 甜eby kompilator wy�apa� brakuj�ce zdarzenia */ } @@ -291,7 +357,7 @@ } #undef gg_debug_dump -void gg_debug_dump(struct gg_session *gs, int level, const char *buf, int len) +void gg_debug_dump(struct gg_session *gs, int level, const char *buf, size_t len) { }
--- a/libpurple/protocols/gg/lib/encoding.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/encoding.c Sun Jun 05 01:28:53 2011 +0000 @@ -22,6 +22,7 @@ #include <errno.h> #include "libgadu.h" +#include "encoding.h" /** * \file encoding.c
--- a/libpurple/protocols/gg/lib/events.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/events.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: events.c 1062 2011-03-13 18:10:24Z wojtekka $ */ +/* $Id: events.c 1105 2011-05-25 21:34:50Z wojtekka $ */ /* * (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl> @@ -27,22 +27,22 @@ * \brief Obs�uga zdarze� */ -#include "libgadu.h" -#include "libgadu-internal.h" -#include "libgadu-debug.h" - #include <sys/types.h> - #ifndef _WIN32 # include <sys/ioctl.h> # include <sys/socket.h> # include <netinet/in.h> # include <arpa/inet.h> #endif +#include <ctype.h> #include "compat.h" +#include "libgadu.h" +#include "libgadu-config.h" #include "protocol.h" +#include "libgadu-internal.h" #include "encoding.h" +#include "libgadu-debug.h" #include "session.h" #include <errno.h> @@ -156,7 +156,7 @@ break; } - + case GG_EVENT_MULTILOGON_INFO: { int i; @@ -168,6 +168,10 @@ break; } + + case GG_EVENT_USERLIST100_REPLY: + free(e->event.userlist100_reply.reply); + break; } free(e); @@ -258,9 +262,9 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() write() failed (errno=%d, %s)\n", errno, strerror(errno)); if (sess->state == GG_STATE_READING_REPLY) - goto fail_connecting; - else - goto done; + e->event.failure = GG_FAILURE_CONNECTING; + + goto fail; } if (res == sess->send_left) { @@ -299,7 +303,7 @@ if (failed) { errno = errno2; - goto fail_resolving; + goto fail_proxy_hub; } /* je�li jeste�my w resolverze i mamy ustawiony port @@ -326,7 +330,7 @@ /* je�li w trybie asynchronicznym gg_connect() * zwr坦ci b��d, nie ma sensu pr坦bowa� dalej. */ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), critical\n", errno, strerror(errno)); - goto fail_connecting; + goto fail_proxy_hub; } /* je�li podano serwer i ��czmy si� przez proxy, @@ -357,19 +361,20 @@ /* je�li asynchroniczne, sprawdzamy, czy nie wyst�pi� * przypadkiem jaki� b��d. */ if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { - if (sess->proxy_addr && sess->proxy_port) - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", res, strerror(res)); - else - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection to hub failed (errno=%d, %s)\n", res, strerror(res)); - - goto fail_connecting; + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection to %s failed (errno=%d, %s)\n", (sess->proxy_addr && sess->proxy_port) ? "proxy" : "hub", res, strerror(res)); + goto fail_proxy_hub; } gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connected to hub, sending query\n"); - if (!(client = gg_urlencode((sess->client_version) ? sess->client_version : GG_DEFAULT_CLIENT_VERSION))) { + if (sess->client_version != NULL && isdigit(sess->client_version[0])) + client = gg_urlencode(sess->client_version); + else + client = gg_urlencode(GG_DEFAULT_CLIENT_VERSION); + + if (client == NULL) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() out of memory for client version\n"); - goto fail_connecting; + goto fail; } if (!gg_proxy_http_only && sess->proxy_addr && sess->proxy_port) @@ -407,13 +412,7 @@ * sta�o si� co� z�ego. */ if (write(sess->fd, buf, strlen(buf)) < (signed)strlen(buf)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() sending query failed\n"); - - e->type = GG_EVENT_CONN_FAILED; - e->event.failure = GG_FAILURE_WRITING; - sess->state = GG_STATE_IDLE; - close(sess->fd); - sess->fd = -1; - break; + goto fail_proxy_hub; } sess->state = GG_STATE_READING_DATA; @@ -439,7 +438,7 @@ /* sprawdzamy, czy wszystko w porz�dku. */ if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() invalid http reply, connection failed\n"); - goto fail_connecting; + goto fail_proxy_hub; } /* ignorujemy reszt� nag�坦wka. */ @@ -447,7 +446,10 @@ gg_read_line(sess->fd, buf, sizeof(buf) - 1); /* czytamy pierwsz� lini� danych. */ - gg_read_line(sess->fd, buf, sizeof(buf) - 1); + if (gg_read_line(sess->fd, buf, sizeof(buf) - 1) == NULL) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() read error\n"); + goto fail_proxy_hub; + } gg_chomp(buf); /* je�li pierwsza liczba w linii nie jest r坦wna zeru, @@ -479,6 +481,7 @@ } close(sess->fd); + sess->fd = -1; gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// gg_watch_fd() received http data (%s)\n", buf); @@ -503,10 +506,16 @@ port = atoi(tmp + 1); } + if (strcmp(host, "") == 0) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() invalid response\n"); + e->event.failure = GG_FAILURE_HUB; + goto fail; + } + if (!strcmp(host, "notoperating")) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() service unavailable\n", errno, strerror(errno)); - sess->fd = -1; - goto fail_unavailable; + e->event.failure = GG_FAILURE_UNAVAILABLE; + goto fail; } addr.s_addr = inet_addr(host); @@ -517,7 +526,8 @@ if ((sess->fd = gg_connect(&sess->proxy_addr, sess->proxy_port, sess->async)) == -1) { /* nie wysz�o? trudno. */ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", errno, strerror(errno)); - goto fail_connecting; + e->event.failure = GG_FAILURE_PROXY; + goto fail; } sess->state = GG_STATE_CONNECTING_GG; @@ -533,7 +543,7 @@ if (sess->server_addr == INADDR_NONE) { if (sess->resolver_start(&sess->fd, &sess->resolver, host) == -1) { gg_debug(GG_DEBUG_MISC, "// gg_login() resolving failed (errno=%d, %s)\n", errno, strerror(errno)); - goto fail_resolving; + goto fail; } sess->state = GG_STATE_RESOLVING_GG; @@ -553,7 +563,8 @@ /* ostatnia deska ratunku zawiod�a? * w takim razie zwijamy manatki. */ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno)); - goto fail_connecting; + e->event.failure = GG_FAILURE_CONNECTING; + goto fail; } } @@ -585,7 +596,8 @@ if (failed) { errno = errno2; - goto fail_resolving; + e->event.failure = GG_FAILURE_RESOLVING; + goto fail; } sess->server_addr = addr.s_addr; @@ -601,7 +613,8 @@ /* ostatnia deska ratunku zawiod�a? * w takim razie zwijamy manatki. */ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno)); - goto fail_connecting; + e->event.failure = GG_FAILURE_CONNECTING; + goto fail; } } @@ -628,7 +641,8 @@ * nie mamy czego pr坦bowa� wi�cej. */ if (sess->proxy_addr && sess->proxy_port) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", res, strerror(res)); - goto fail_connecting; + e->event.failure = GG_FAILURE_PROXY; + goto fail; } close(sess->fd); @@ -648,21 +662,25 @@ if (sess->ssl) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", res, strerror(res)); - goto fail_connecting; + e->event.failure = GG_FAILURE_CONNECTING; + goto fail; } #endif gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), trying https\n", res, strerror(res)); - if (sess->port == GG_HTTPS_PORT) - goto fail_connecting; + if (sess->port == GG_HTTPS_PORT) { + e->event.failure = GG_FAILURE_CONNECTING; + goto fail; + } sess->port = GG_HTTPS_PORT; /* pr坦bujemy na port 443. */ if ((sess->fd = gg_connect(&sess->server_addr, sess->port, sess->async)) == -1) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno)); - goto fail_connecting; + e->event.failure = GG_FAILURE_CONNECTING; + goto fail; } sess->state = GG_STATE_CONNECTING_GG; @@ -698,7 +716,8 @@ if (write(sess->fd, buf, strlen(buf)) < (signed)strlen(buf)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n"); free(auth); - goto fail_connecting; + e->event.failure = GG_FAILURE_PROXY; + goto fail; } if (auth) { @@ -706,7 +725,8 @@ if (write(sess->fd, auth, strlen(auth)) < (signed)strlen(auth)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n"); free(auth); - goto fail_connecting; + e->event.failure = GG_FAILURE_PROXY; + goto fail; } free(auth); @@ -714,7 +734,8 @@ if (write(sess->fd, "\r\n", 2) < 2) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n"); - goto fail_connecting; + e->event.failure = GG_FAILURE_PROXY; + goto fail; } } @@ -904,7 +925,14 @@ { struct gg_header *gh; - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTED\n"); + if (sess->state == GG_STATE_READING_KEY) + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_KEY\n"); + else if (sess->state == GG_STATE_READING_REPLY) + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_REPLY\n"); + else if (sess->state == GG_STATE_CONNECTED) + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTED\n"); + else if (sess->state == GG_STATE_DISCONNECTING) + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_DISCONNECTING\n"); /* XXX bardzo, bardzo, bardzo g�upi pomys� na pozbycie * si� tekstu wrzucanego przez proxy. */ @@ -936,64 +964,56 @@ if (gh == NULL) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() gg_recv_packet failed (errno=%d, %s)\n", errno, strerror(errno)); - if (errno == EAGAIN) { - e->type = GG_EVENT_NONE; - res = 0; - } else { - res = -1; + + if (errno != EAGAIN) + goto fail; + } else { + if (gg_session_handle_packet(sess, gh->type, (const char *) gh + sizeof(struct gg_header), gh->length, e) == -1) { + free(gh); + goto fail; } - goto done; + free(gh); } - if (gg_session_handle_packet(sess, gh->type, (const char *) gh + sizeof(struct gg_header), gh->length, e) == -1) { - free(gh); - res = -1; - goto done; - } - - free(gh); - sess->check = GG_CHECK_READ; break; } } -done: - if (res == -1) { - free(e); - e = NULL; - } else { - if (sess->send_buf && (sess->state == GG_STATE_READING_REPLY || sess->state == GG_STATE_CONNECTED)) - sess->check |= GG_CHECK_WRITE; - } + if (sess->send_buf && (sess->state == GG_STATE_READING_REPLY || sess->state == GG_STATE_CONNECTED)) + sess->check |= GG_CHECK_WRITE; return e; -fail_connecting: +fail_proxy_hub: + if (sess->proxy_port) + e->event.failure = GG_FAILURE_PROXY; + else + e->event.failure = GG_FAILURE_HUB; + +fail: + sess->resolver_cleanup(&sess->resolver, 1); + + sess->state = GG_STATE_IDLE; + if (sess->fd != -1) { + int errno2; + errno2 = errno; close(sess->fd); errno = errno2; sess->fd = -1; } - e->type = GG_EVENT_CONN_FAILED; - e->event.failure = GG_FAILURE_CONNECTING; - sess->state = GG_STATE_IDLE; - goto done; -fail_resolving: - e->type = GG_EVENT_CONN_FAILED; - e->event.failure = GG_FAILURE_RESOLVING; - sess->state = GG_STATE_IDLE; - goto done; - -fail_unavailable: - e->type = GG_EVENT_CONN_FAILED; - e->event.failure = GG_FAILURE_UNAVAILABLE; - sess->state = GG_STATE_IDLE; - goto done; + if (e->event.failure != 0) { + e->type = GG_EVENT_CONN_FAILED; + return e; + } else { + free(e); + return NULL; + } } /*
--- a/libpurple/protocols/gg/lib/handlers.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/handlers.c Sun Jun 05 01:28:53 2011 +0000 @@ -27,11 +27,13 @@ */ #include <sys/types.h> - #ifndef _WIN32 # include <sys/socket.h> # include <netinet/in.h> # include <arpa/inet.h> +#endif +#include <ctype.h> +#ifndef _WIN32 # ifdef sun # include <sys/filio.h> # endif @@ -39,12 +41,14 @@ #include "compat.h" #include "libgadu.h" +#include "libgadu-config.h" #include "resolver.h" #include "session.h" #include "protocol.h" #include "encoding.h" #include "message.h" #include "libgadu-internal.h" +#include "deflate.h" #include <errno.h> #ifndef _WIN32 @@ -87,6 +91,8 @@ int ret; uint8_t hash_buf[64]; uint32_t local_ip; + struct sockaddr_in sin; + unsigned int sin_len = sizeof(sin); if (len < sizeof(struct gg_welcome)) { ge->type = GG_EVENT_CONN_FAILED; @@ -145,28 +151,21 @@ } #endif - if (gg_dcc_ip == (unsigned long) inet_addr("255.255.255.255")) { - struct sockaddr_in sin; - unsigned int sin_len = sizeof(sin); - - gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() detecting address\n"); - - if (!getsockname(gs->fd, (struct sockaddr*) &sin, &sin_len)) { - gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() detected address to %s\n", inet_ntoa(sin.sin_addr)); - local_ip = sin.sin_addr.s_addr; - } else { - gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n"); - local_ip = 0; - } - } else - local_ip = gg_dcc_ip; - - gs->client_addr = local_ip; + if (!getsockname(gs->fd, (struct sockaddr*) &sin, &sin_len)) { + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() detected address to %s\n", inet_ntoa(sin.sin_addr)); + local_ip = sin.sin_addr.s_addr; + } else { + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n"); + local_ip = 0; + } if (GG_SESSION_IS_PROTOCOL_8_0(gs)) { struct gg_login80 l80; - const char *version, *descr; - uint32_t version_len, descr_len; + const char *client_name, *version, *descr; + uint32_t client_name_len, version_len, descr_len; + + if (gs->external_addr == 0) + gs->external_addr = local_ip; memset(&l80, 0, sizeof(l80)); gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd() sending GG_LOGIN80 packet\n"); @@ -180,8 +179,16 @@ l80.image_size = gs->image_size; l80.dunno2 = 0x64; + if (gs->client_version != NULL && !isdigit(gs->client_version[0])) { + client_name = ""; + client_name_len = 0; + } else { + client_name = GG8_VERSION; + client_name_len = strlen(GG8_VERSION); + } + version = (gs->client_version != NULL) ? gs->client_version : GG_DEFAULT_CLIENT_VERSION; - version_len = gg_fix32(strlen(GG8_VERSION) + strlen(version)); + version_len = gg_fix32(client_name_len + strlen(version)); descr = (gs->initial_descr != NULL) ? gs->initial_descr : ""; descr_len = (gs->initial_descr != NULL) ? gg_fix32(strlen(gs->initial_descr)) : 0; @@ -190,7 +197,7 @@ GG_LOGIN80, &l80, sizeof(l80), &version_len, sizeof(version_len), - GG8_VERSION, strlen(GG8_VERSION), + client_name, client_name_len, version, strlen(version), &descr_len, sizeof(descr_len), descr, strlen(descr), @@ -198,6 +205,11 @@ } else { struct gg_login70 l70; + if (gg_dcc_ip != (unsigned long) inet_addr("255.255.255.255")) + local_ip = gg_dcc_ip; + + gs->client_addr = local_ip; + memset(&l70, 0, sizeof(l70)); l70.uin = gg_fix32(gs->uin); l70.hash_type = gs->hash_type; @@ -460,7 +472,7 @@ /** * \internal Obs�uguje pakiet GG_DCC7_NEW. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_dcc7_new(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -472,7 +484,7 @@ /** * \internal Obs�uguje pakiet GG_DCC7_REJECT. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_dcc7_reject(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -484,7 +496,7 @@ /** * \internal Obs�uguje pakiet GG_DCC7_INFO. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_dcc7_info(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -574,7 +586,7 @@ /** * \internal Analizuje informacje rozszerzone wiadomo�ci. - * + * * \param sess Struktura sesji. * \param e Struktura zdarzenia. * \param sender Numer nadawcy. @@ -756,10 +768,11 @@ * \internal Wysy�a potwierdzenie odebrania wiadomo�ci. * * \param gs Struktura sesji + * \param seq Numer sekwencyjny odebranej wiadomo�ci * * \return 0 je�li si� powiod�o, -1 je�li wyst�pi� b��d */ -static int gg_session_send_msg_ack(struct gg_session *gs) +static int gg_session_send_msg_ack(struct gg_session *gs, uint32_t seq) { struct gg_recv_msg_ack pkt; @@ -768,15 +781,18 @@ if ((gs->protocol_features & GG_FEATURE_MSG_ACK) == 0) return 0; + /* Kiedy� zdawa�o nam si�, 甜e mamy wysy�a� liczb� odebranych + * wiadomo�ci, ale okaza�o si�, 甜e numer sekwencyjny. */ gs->recv_msg_count++; - pkt.count = gg_fix32(gs->recv_msg_count); + + pkt.seq = gg_fix32(seq); return gg_send_packet(gs, GG_RECV_MSG_ACK, &pkt, sizeof(pkt), NULL); } /** * \internal Obs�uguje pakiet GG_RECV_MSG. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_recv_msg(struct gg_session *sess, uint32_t type, const char *packet, size_t length, struct gg_event *e) @@ -799,19 +815,19 @@ length = 1; } else { const char *options; - + options = memchr(payload, 0, (size_t) (payload_end - payload)); if (options == NULL) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg() malformed packet, message out of bounds (0)\n"); goto malformed; } - + length = (size_t) (options - payload); switch (gg_handle_recv_msg_options(sess, e, gg_fix32(r->sender), options + 1, payload_end)) { case -1: // handled - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; case -2: // failed @@ -833,7 +849,7 @@ goto fail; e->event.msg.message = (unsigned char*) tmp; - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; fail: @@ -848,13 +864,13 @@ free(e->event.msg.xhtml_message); free(e->event.msg.recipients); free(e->event.msg.formats); - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; } /** * \internal Obs�uguje pakiet GG_RECV_MSG80. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_recv_msg_80(struct gg_session *sess, uint32_t type, const char *packet, size_t length, struct gg_event *e) @@ -906,7 +922,7 @@ if (offset_attr != 0) { switch (gg_handle_recv_msg_options(sess, e, gg_fix32(r->sender), packet + offset_attr, packet + length)) { case -1: // handled - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; case -2: // failed @@ -940,7 +956,7 @@ else e->event.msg.xhtml_message = NULL; - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; fail: @@ -956,13 +972,13 @@ free(e->event.msg.xhtml_message); free(e->event.msg.recipients); free(e->event.msg.formats); - gg_session_send_msg_ack(sess); + gg_session_send_msg_ack(sess, gg_fix32(r->seq)); return 0; } /** * \internal Obs�uguje pakiet GG_STATUS. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_status(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -990,7 +1006,7 @@ /** * \internal Obs�uguje pakiety GG_STATUS60, GG_STATUS77 i GG_STATUS80BETA. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_status_60_77_80beta(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1057,7 +1073,7 @@ /** * \internal Obs�uguje pakiet GG_NOTIFY_REPLY. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_notify_reply(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1121,7 +1137,7 @@ /** * \internal Obs�uguje pakiet GG_STATUS80. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_status_80(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1159,7 +1175,7 @@ /** * \internal Obs�uguje pakiet GG_NOTIFY_REPLY80. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_notify_reply_80(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1235,7 +1251,7 @@ /** * \internal Obs�uguje pakiety GG_NOTIFY_REPLY77 i GG_NOTIFY_REPLY80BETA. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_notify_reply_77_80beta(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1287,7 +1303,7 @@ } /* XXX czas */ - + length -= sizeof(struct gg_notify_reply77) + descr_len + 1; n = (void*) ((char*) n + sizeof(struct gg_notify_reply77) + descr_len + 1); } else { @@ -1314,7 +1330,7 @@ /** * \internal Obs�uguje pakiet GG_NOTIFY_REPLY60. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_notify_reply_60(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1368,7 +1384,7 @@ ge->event.notify60[i].descr = descr; /* XXX czas */ - + length -= sizeof(struct gg_notify_reply60) + descr_len + 1; n = (void*) ((char*) n + sizeof(struct gg_notify_reply60) + descr_len + 1); } else { @@ -1395,7 +1411,7 @@ /** * \internal Obs�uguje pakiet GG_USER_DATA. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_user_data(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1441,7 +1457,7 @@ ge->event.user_data.type = d.type; ge->event.user_data.user_count = d.user_count; ge->event.user_data.users = users; - + gg_debug_session(gs, GG_DEBUG_DUMP, "type=%d, count=%d\n", d.type, d.user_count); for (i = 0; i < d.user_count; i++) { @@ -1577,7 +1593,7 @@ /** * \internal Obs�uguje pakiet GG_TYPING_NOTIFICATION. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_typing_notification(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1598,7 +1614,7 @@ /** * \internal Obs�uguje pakiet GG_MULTILOGON_INFO. - * + * * Patrz gg_packet_handler_t */ static int gg_session_handle_multilogon_info(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) @@ -1626,7 +1642,7 @@ gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_multilogon_info() out of memory (%d*%d)\n", count, sizeof(struct gg_multilogon_session)); return -1; } - + ge->type = GG_EVENT_MULTILOGON_INFO; ge->event.multilogon_info.count = count; ge->event.multilogon_info.sessions = sessions; @@ -1687,6 +1703,53 @@ } /** + * \internal Obs�uguje pakiet GG_USERLIST100_VERSION. + * + * Patrz gg_packet_handler_t + */ +static int gg_session_handle_userlist_100_version(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) +{ + struct gg_userlist100_version *version = (struct gg_userlist100_version*) ptr; + + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist 100 version\n"); + + ge->type = GG_EVENT_USERLIST100_VERSION; + ge->event.userlist100_version.version = gg_fix32(version->version); + + return 0; +} + +/** + * \internal Obs�uguje pakiet GG_USERLIST100_REPLY. + * + * Patrz gg_packet_handler_t + */ +static int gg_session_handle_userlist_100_reply(struct gg_session *gs, uint32_t type, const char *ptr, size_t len, struct gg_event *ge) +{ + struct gg_userlist100_reply *reply = (struct gg_userlist100_reply*) ptr; + char *data = NULL; + + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist 100 reply\n"); + + if (len > sizeof(*reply)) { + data = gg_inflate((const unsigned char*) ptr + sizeof(*reply), len - sizeof(*reply)); + + if (data == NULL) { + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_handle_userlist_100_reply() gg_inflate() failed\n"); + return -1; + } + } + + ge->type = GG_EVENT_USERLIST100_REPLY; + ge->event.userlist100_reply.type = reply->type; + ge->event.userlist100_reply.version = gg_fix32(reply->version); + ge->event.userlist100_reply.format_type = reply->format_type; + ge->event.userlist100_reply.reply = data; + + return 0; +} + +/** * \internal Tablica obs�ugiwanych pakiet坦w */ static const gg_packet_handler_t handlers[] = @@ -1726,6 +1789,8 @@ { GG_MULTILOGON_INFO, GG_STATE_CONNECTED, sizeof(struct gg_multilogon_info), gg_session_handle_multilogon_info }, { GG_XML_ACTION, GG_STATE_CONNECTED, 0, gg_session_handle_xml_event }, { GG_RECV_OWN_MSG, GG_STATE_CONNECTED, sizeof(struct gg_recv_msg80), gg_session_handle_recv_msg_80 }, + { GG_USERLIST100_VERSION, GG_STATE_CONNECTED, sizeof(struct gg_userlist100_version), gg_session_handle_userlist_100_version }, + { GG_USERLIST100_REPLY, GG_STATE_CONNECTED, sizeof(struct gg_userlist100_reply), gg_session_handle_userlist_100_reply }, }; /**
--- a/libpurple/protocols/gg/lib/http.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/http.c Sun Jun 05 01:28:53 2011 +0000 @@ -24,25 +24,22 @@ * \brief Obs�uga po��cze� HTTP */ -#include "libgadu.h" - #include <sys/types.h> - #ifndef _WIN32 # include <sys/socket.h> # include <netinet/in.h> # include <arpa/inet.h> #endif +#include "compat.h" +#include "libgadu.h" #include "resolver.h" #include <ctype.h> #include <errno.h> - #ifndef _WIN32 # include <netdb.h> #endif - #include <signal.h> #include <stdarg.h> #include <stdio.h>
--- a/libpurple/protocols/gg/lib/libgadu-config.h Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/libgadu-config.h Sun Jun 05 01:28:53 2011 +0000 @@ -27,6 +27,13 @@ /* We don't like pthreads. */ #undef __GG_LIBGADU_HAVE_PTHREAD +/* Defined if libgadu was compiled and linked with GnuTLS encryption support. */ +#ifdef HAVE_GNUTLS +# define GG_CONFIG_HAVE_GNUTLS +#else +# undef GG_CONFIG_HAVE_GNUTLS +#endif + /* Defined if libgadu was compiled and linked with TLS support. */ /* Always undefined in Purple. */ #undef __GG_LIBGADU_HAVE_OPENSSL
--- a/libpurple/protocols/gg/lib/libgadu-debug.h Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/libgadu-debug.h Sun Jun 05 01:28:53 2011 +0000 @@ -22,6 +22,8 @@ #include "libgadu.h" const char *gg_debug_state(enum gg_state_t state); +const char *gg_debug_event(enum gg_event_t event); void gg_debug_dump(struct gg_session *sess, int level, const char *buf, size_t len); +void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap); #endif /* LIBGADU_DEBUG_H */
--- a/libpurple/protocols/gg/lib/libgadu.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/libgadu.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: libgadu.c 1062 2011-03-13 18:10:24Z wojtekka $ */ +/* $Id: libgadu.c 1102 2011-05-05 21:17:57Z wojtekka $ */ /* * (C) Copyright 2001-2010 Wojtek Kaniewski <wojtekka@irc.pl> @@ -28,13 +28,7 @@ * \brief G�坦wny modu� biblioteki */ -#include "libgadu.h" -#include "libgadu-config.h" -#include "libgadu-internal.h" -#include "libgadu-debug.h" - #include <sys/types.h> - #ifdef _WIN32 # include <io.h> # include <fcntl.h> @@ -50,16 +44,21 @@ #endif #include "compat.h" +#include "libgadu.h" +#include "libgadu-config.h" #include "protocol.h" #include "resolver.h" +#include "libgadu-internal.h" #include "encoding.h" +#include "libgadu-debug.h" #include "session.h" +#include "message.h" +#include "deflate.h" #ifndef _WIN32 # include <errno.h> /* on Win32 this is included above */ # include <netdb.h> #endif - #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -75,11 +74,11 @@ # include <openssl/rand.h> #endif -#define GG_LIBGADU_VERSION "1.10.1" +#define GG_LIBGADU_VERSION "1.11.0" /** * Port gniazda nas�uchuj�cego dla po��cze� bezpo�rednich. - * + * * \ingroup ip */ int gg_dcc_port = 0; @@ -147,7 +146,7 @@ #ifdef __GNUC__ __attribute__ ((unused)) #endif -= "$Id: libgadu.c 1062 2011-03-13 18:10:24Z wojtekka $"; += "$Id: libgadu.c 1102 2011-05-05 21:17:57Z wojtekka $"; #endif #endif /* DOXYGEN */ @@ -290,11 +289,11 @@ */ int gg_read(struct gg_session *sess, char *buf, int length) { + int res; + #ifdef GG_CONFIG_HAVE_GNUTLS if (sess->ssl != NULL) { for (;;) { - int res; - res = gnutls_record_recv(GG_SESSION_GNUTLS(sess), buf, length); if (res < 0) { @@ -317,7 +316,7 @@ #ifdef GG_CONFIG_HAVE_OPENSSL if (sess->ssl != NULL) { for (;;) { - int res, err; + int err; res = SSL_read(sess->ssl, buf, length); @@ -340,7 +339,14 @@ } #endif - return read(sess->fd, buf, length); + for (;;) { + res = read(sess->fd, buf, length); + + if (res == -1 && errno == EINTR) + continue; + + return res; + } } /** @@ -361,11 +367,11 @@ */ static int gg_write_common(struct gg_session *sess, const char *buf, int length) { + int res; + #ifdef GG_CONFIG_HAVE_GNUTLS if (sess->ssl != NULL) { for (;;) { - int res; - res = gnutls_record_send(GG_SESSION_GNUTLS(sess), buf, length); if (res < 0) { @@ -388,7 +394,7 @@ #ifdef GG_CONFIG_HAVE_OPENSSL if (sess->ssl != NULL) { for (;;) { - int res, err; + int err; res = SSL_write(sess->ssl, buf, length); @@ -411,7 +417,14 @@ } #endif - return write(sess->fd, buf, length); + for (;;) { + res = write(sess->fd, buf, length); + + if (res == -1 && errno == EINTR) + continue; + + return res; + } } @@ -489,7 +502,7 @@ void *gg_recv_packet(struct gg_session *sess) { struct gg_header h; - char *buf = NULL; + char *packet; int ret = 0; unsigned int offset, size = 0; @@ -542,7 +555,6 @@ } sess->header_done += ret; - } h.type = gg_fix32(h.type); @@ -561,26 +573,25 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() resuming last gg_recv_packet()\n"); size = sess->recv_left; offset = sess->recv_done; - buf = sess->recv_buf; } else { - if (!(buf = malloc(sizeof(h) + h.length + 1))) { + if (!(sess->recv_buf = malloc(sizeof(h) + h.length + 1))) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() not enough memory for packet data\n"); return NULL; } - memcpy(buf, &h, sizeof(h)); + memcpy(sess->recv_buf, &h, sizeof(h)); offset = 0; size = h.length; } while (size > 0) { - ret = gg_read(sess, buf + sizeof(h) + offset, size); - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() body recv(%d,%p,%d) = %d\n", sess->fd, buf + sizeof(h) + offset, size, ret); + ret = gg_read(sess, sess->recv_buf + sizeof(h) + offset, size); + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() body recv(%d,%p,%d) = %d\n", sess->fd, sess->recv_buf + sizeof(h) + offset, size, ret); if (!ret) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() body recv() failed: connection broken\n"); errno = ECONNRESET; - return NULL; + goto fail; } if (ret > -1 && ret <= size) { offset += ret; @@ -590,23 +601,30 @@ if (errno == EAGAIN) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_recv_packet() %d bytes received, %d left\n", offset, size); - sess->recv_buf = buf; sess->recv_left = size; sess->recv_done = offset; return NULL; } - free(buf); - return NULL; + goto fail; } } + packet = sess->recv_buf; + sess->recv_buf = NULL; sess->recv_left = 0; gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_recv_packet(type=0x%.2x, length=%d)\n", h.type, h.length); - gg_debug_dump(sess, GG_DEBUG_DUMP, buf, sizeof(h) + h.length); + gg_debug_dump(sess, GG_DEBUG_DUMP, packet, sizeof(h) + h.length); + + return packet; - return buf; +fail: + free(sess->recv_buf); + sess->recv_buf = NULL; + sess->recv_left = 0; + + return NULL; } /** @@ -735,7 +753,10 @@ * serwera -- z tego powodu program musi poprawnie obs�u甜y� sygna� SIGCHLD. * * \note Po nawi�zaniu po��czenia z serwerem nale甜y wys�a� list� kontakt坦w - * za pomoc� funkcji \c gg_notify() lub \c gg_notify_ex(). + * za pomoc� funkcji \c gg_notify() lub \c gg_notify_ex(). + * + * \note Funkcja zwr坦ci b��d ENOSYS je�li po��czenie SSL by�o wymagane, ale + * obs�uga SSL nie jest wkompilowana. * * \param p Struktura opisuj�ca parametry po��czenia. Wymagane pola: uin, * password, async. @@ -796,6 +817,7 @@ sess->server_addr = p->server_addr; sess->external_port = p->external_port; sess->external_addr = p->external_addr; + sess->client_addr = p->client_addr; sess->client_port = p->client_port; if (p->protocol_features == 0) { @@ -848,14 +870,14 @@ gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for status\n"); goto fail; } - + // XXX pami�ta�, 甜eby nie ci�� w �rodku znaku utf-8 - + if (strlen(sess->initial_descr) > max_length) sess->initial_descr[max_length] = 0; } - if (p->tls == 1) { + if (p->tls != GG_SSL_DISABLED) { #ifdef GG_CONFIG_HAVE_GNUTLS gg_session_gnutls_t *tmp; @@ -912,6 +934,11 @@ } #else gg_debug(GG_DEBUG_MISC, "// gg_login() client requested TLS but no support compiled in\n"); + + if (p->tls == GG_SSL_REQUIRED) { + errno = ENOSYS; + goto fail; + } #endif } @@ -1141,6 +1168,7 @@ free(sess->password); free(sess->initial_descr); free(sess->client_version); + free(sess->recv_buf); free(sess->header_buf); #ifdef GG_CONFIG_HAVE_OPENSSL @@ -1277,8 +1305,10 @@ free(new_descr); - if (GG_S_NA(status)) + if (GG_S_NA(status)) { sess->state = GG_STATE_DISCONNECTING; + sess->timeout = GG_TIMEOUT_DISCONNECT; + } return res; } @@ -1436,208 +1466,6 @@ } /** - * \internal Dodaje tekst na koniec bufora. - * - * \param dst Wska添nik na bufor roboczy - * \param pos Wska添nik na aktualne po�o甜enie w buforze roboczym - * \param src Dodawany tekst - * \param len D�ugo�� dodawanego tekstu - */ -static void gg_append(char *dst, int *pos, const void *src, int len) -{ - if (dst != NULL) - memcpy(&dst[*pos], src, len); - - *pos += len; -} - -/** - * \internal Zamienia tekst z formatowaniem Gadu-Gadu na HTML. - * - * \param dst Bufor wynikowy (mo甜e by� \c NULL) - * \param src Tekst 添r坦d�owy w UTF-8 - * \param format Atrybuty tekstu 添r坦d�owego - * \param format_len D�ugo�� bloku atrybut坦w tekstu 添r坦d�owego - * - * \note Wynikowy tekst nie jest idealnym kodem HTML, poniewa甜 ma jak - * dok�adniej odzwierciedla� to, co wygenerowa�by oryginalny klient. - * - * \note Dokleja \c \\0 na ko�cu bufora wynikowego. - * - * \return D�ugo�� tekstu wynikowego bez \c \\0 (nawet je�li \c dst to \c NULL). - */ -static int gg_convert_to_html(char *dst, const char *src, const unsigned char *format, int format_len) -{ - const char span_fmt[] = "<span style=\"color:#%02x%02x%02x; font-family:'MS Shell Dlg 2'; font-size:9pt; \">"; - const int span_len = 75; - const char img_fmt[] = "<img name=\"%02x%02x%02x%02x%02x%02x%02x%02x\">"; - const int img_len = 29; - int char_pos = 0; - int format_idx = 0; - unsigned char old_attr = 0; - const unsigned char *color = (const unsigned char*) "\x00\x00\x00"; - int len, i; - - len = 0; - - /* Nie mamy atrybut坦w dla pierwsze znaku, a tekst nie jest pusty, wi�c - * tak czy inaczej trzeba otworzy� <span>. */ - - if (src[0] != 0 && (format_idx + 3 > format_len || (format[format_idx] | (format[format_idx + 1] << 8)) != 0)) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - - len += span_len; - } - - /* P�tla przechodzi te甜 przez ko�cz�ce \0, 甜eby m坦c doklei� obrazek - * na ko�cu tekstu. */ - - for (i = 0; ; i++) { - /* Analizuj atrybuty tak d�ugo jak dotycz� aktualnego znaku. */ - for (;;) { - unsigned char attr; - int attr_pos; - - if (format_idx + 3 > format_len) - break; - - attr_pos = format[format_idx] | (format[format_idx + 1] << 8); - - if (attr_pos != char_pos) - break; - - attr = format[format_idx + 2]; - - /* Nie doklejaj atrybut坦w na ko�cu, co najwy甜ej obrazki. */ - - if (src[i] == 0) - attr &= ~(GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR); - - format_idx += 3; - - if ((attr & (GG_FONT_BOLD | GG_FONT_ITALIC | GG_FONT_UNDERLINE | GG_FONT_COLOR)) != 0 || (attr == 0 && old_attr != 0)) { - if (char_pos != 0) { - if ((old_attr & GG_FONT_UNDERLINE) != 0) - gg_append(dst, &len, "</u>", 4); - - if ((old_attr & GG_FONT_ITALIC) != 0) - gg_append(dst, &len, "</i>", 4); - - if ((old_attr & GG_FONT_BOLD) != 0) - gg_append(dst, &len, "</b>", 4); - - if (src[i] != 0) - gg_append(dst, &len, "</span>", 7); - } - - if (((attr & GG_FONT_COLOR) != 0) && (format_idx + 3 <= format_len)) { - color = &format[format_idx]; - format_idx += 3; - } else { - color = (const unsigned char*) "\x00\x00\x00"; - } - - if (src[i] != 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, color[0], color[1], color[2]); - len += span_len; - } - } else if (char_pos == 0 && src[0] != 0) { - if (dst != NULL) - sprintf(&dst[len], span_fmt, 0, 0, 0); - len += span_len; - } - - if ((attr & GG_FONT_BOLD) != 0) - gg_append(dst, &len, "<b>", 3); - - if ((attr & GG_FONT_ITALIC) != 0) - gg_append(dst, &len, "<i>", 3); - - if ((attr & GG_FONT_UNDERLINE) != 0) - gg_append(dst, &len, "<u>", 3); - - if (((attr & GG_FONT_IMAGE) != 0) && (format_idx + 10 <= format_len)) { - if (dst != NULL) { - sprintf(&dst[len], img_fmt, - format[format_idx + 9], - format[format_idx + 8], - format[format_idx + 7], - format[format_idx + 6], - format[format_idx + 5], - format[format_idx + 4], - format[format_idx + 3], - format[format_idx + 2]); - } - - len += img_len; - format_idx += 10; - } - - old_attr = attr; - } - - /* Doklej znak zachowuj�c htmlowe escapowanie. */ - - switch (src[i]) { - case '&': - gg_append(dst, &len, "&", 5); - break; - case '<': - gg_append(dst, &len, "<", 4); - break; - case '>': - gg_append(dst, &len, ">", 4); - break; - case '\'': - gg_append(dst, &len, "'", 6); - break; - case '\"': - gg_append(dst, &len, """, 6); - break; - case '\n': - gg_append(dst, &len, "<br>", 4); - break; - case '\r': - case 0: - break; - default: - if (dst != NULL) - dst[len] = src[i]; - len++; - } - - /* Sprawd添, czy bajt nie jest kontynuacj� znaku unikodowego. */ - - if ((src[i] & 0xc0) != 0xc0) - char_pos++; - - if (src[i] == 0) - break; - } - - /* Zamknij tagi. */ - - if ((old_attr & GG_FONT_UNDERLINE) != 0) - gg_append(dst, &len, "</u>", 4); - - if ((old_attr & GG_FONT_ITALIC) != 0) - gg_append(dst, &len, "</i>", 4); - - if ((old_attr & GG_FONT_BOLD) != 0) - gg_append(dst, &len, "</b>", 4); - - if (src[0] != 0) - gg_append(dst, &len, "</span>", 7); - - if (dst != NULL) - dst[len] = 0; - - return len; -} - -/** * Wysy�a wiadomo�� formatowan� w ramach konferencji. * * Zwraca losowy numer sekwencyjny, kt坦ry mo甜na zignorowa� albo wykorzysta� @@ -1652,7 +1480,7 @@ * \param formatlen D�ugo�� informacji o formatowaniu * * \return Numer sekwencyjny wiadomo�ci lub -1 w przypadku b��du. - * + * * \ingroup messages */ int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen) @@ -1708,7 +1536,7 @@ s.seq = gg_fix32(seq_no); } else { int len; - + // Drobne odchylenie od protoko�u. Je�li wysy�amy kilka // wiadomo�ci w ci�gu jednej sekundy, zwi�kszamy poprzedni� // warto��, 甜eby ka甜da wiadomo�� mia�a unikalny numer. @@ -1725,7 +1553,7 @@ formatlen = 9; } - len = gg_convert_to_html(NULL, utf_msg, format + 3, formatlen - 3); + len = gg_message_text_to_html(NULL, utf_msg, (char*) format + 3, formatlen - 3); html_msg = malloc(len + 1); @@ -1734,7 +1562,7 @@ goto cleanup; } - gg_convert_to_html(html_msg, utf_msg, format + 3, formatlen - 3); + gg_message_text_to_html(html_msg, utf_msg, (char*) format + 3, formatlen - 3); s80.seq = gg_fix32(seq_no); s80.msgclass = gg_fix32(msgclass); @@ -2335,6 +2163,70 @@ } /** + * Wysy�a do serwera zapytanie dotycz�ce listy kontakt坦w (10.0). + * + * Funkcja s�u甜y do importu lub eksportu listy kontakt坦w do serwera. + * W odr坦甜nieniu od funkcji \c gg_notify(), ta lista kontakt坦w jest przez + * serwer jedynie przechowywana i nie ma wp�ywu na po��czenie. Format + * listy kontakt坦w jest jednak weryfikowany przez serwer, kt坦ry stara si� + * synchronizowa� list� kontakt坦w zapisan� w formatach GG 7.0 oraz GG 10.0. + * Serwer przyjmuje listy kontakt坦w przys�ane w formacie niezgodnym z podanym + * jako \c format_type, ale nie zachowuje ich, a przes�anie takiej listy jest + * r坦wnoznaczne z usuni�ciem listy kontakt坦w. + * + * Program nie musi si� przejmowa� kompresj� listy kontakt坦w zgodn� + * z protoko�em -- wysy�a i odbiera kompletn� list� zapisan� czystym tekstem. + * + * \param sess Struktura sesji + * \param type Rodzaj zapytania + * \param version Numer ostatniej znanej programowi wersji listy kontakt坦w lub 0 + * \param format_type Typ formatu listy kontakt坦w + * \param request Tre�� zapytania (mo甜e by� r坦wne NULL) + * + * \return 0 je�li si� powiod�o, -1 w przypadku b��du + * + * \ingroup importexport + */ +int gg_userlist100_request(struct gg_session *sess, char type, unsigned int version, char format_type, const char *request) +{ + struct gg_userlist100_request pkt; + unsigned char *zrequest; + size_t zrequest_len; + int ret; + + if (!sess) { + errno = EFAULT; + return -1; + } + + if (sess->state != GG_STATE_CONNECTED) { + errno = ENOTCONN; + return -1; + } + + pkt.type = type; + pkt.version = gg_fix32(version); + pkt.format_type = format_type; + pkt.unknown1 = 0x01; + + if (request == NULL) + return gg_send_packet(sess, GG_USERLIST100_REQUEST, &pkt, sizeof(pkt), NULL); + + zrequest = gg_deflate(request, &zrequest_len); + + if (zrequest == NULL) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_userlist100_request() gg_deflate() failed"); + return -1; + } + + ret = gg_send_packet(sess, GG_USERLIST100_REQUEST, &pkt, sizeof(pkt), zrequest, zrequest_len, NULL); + + free(zrequest); + + return ret; +} + +/** * Informuje rozm坦wc� o pisaniu wiadomo�ci. * * \param sess Struktura sesji @@ -2377,6 +2269,47 @@ /* @} */ +/** + * Sprawdza czy biblioteka obs�uguje dan� funkcj�. + * + * \param feature Identyfikator funkcji. + * + * \return Warto�� niezerowa je�li funkcja jest obs�giwana. + * + * \ingroup version + */ +int gg_libgadu_check_feature(gg_libgadu_feature_t feature) +{ + switch (feature) + { + case GG_LIBGADU_FEATURE_SSL: +#if defined(GG_CONFIG_HAVE_OPENSSL) || defined(GG_CONFIG_HAVE_GNUTLS) + return 1; +#else + return 0; +#endif + + case GG_LIBGADU_FEATURE_PTHREAD: +#ifdef GG_CONFIG_HAVE_PTHREAD + return 1; +#else + return 0; +#endif + + case GG_LIBGADU_FEATURE_USERLIST100: +#ifdef GG_CONFIG_HAVE_ZLIB + return 1; +#else + return 0; +#endif + + /* Celowo nie ma default, 甜eby kompilator wy�apa� brakuj�ce funkcje */ + + } + + return 0; +} + /* * Local variables: * c-indentation-style: k&r
--- a/libpurple/protocols/gg/lib/libgadu.h Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/libgadu.h Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: libgadu.h.in 1037 2010-12-17 22:18:08Z wojtekka $ */ +/* $Id: libgadu.h.in 1105 2011-05-25 21:34:50Z wojtekka $ */ /* * (C) Copyright 2001-2009 Wojtek Kaniewski <wojtekka@irc.pl> @@ -57,7 +57,7 @@ #undef GG_CONFIG_HAVE_PTHREAD /* Defined if pthread resolver is the default one. */ -#undef GG_CONFIG_PTHREAD_DEFAULT +#undef GG_CONFIG_PTHREAD_DEFAULT /* Defined if this machine has C99-compiliant vsnprintf(). */ #undef GG_CONFIG_HAVE_C99_VSNPRINTF @@ -72,15 +72,14 @@ #undef GG_CONFIG_HAVE_LONG_LONG /* Defined if libgadu was compiled and linked with GnuTLS support. */ -#ifdef USE_GNUTLS -# define GG_CONFIG_HAVE_GNUTLS -#else -# undef GG_CONFIG_HAVE_GNUTLS -#endif +#undef GG_CONFIG_HAVE_GNUTLS /* Defined if libgadu was compiled and linked with OpenSSL support. */ #undef GG_CONFIG_HAVE_OPENSSL +/* Defined if libgadu was compiled and linked with zlib support. */ +#undef GG_CONFIG_HAVE_ZLIB + /* Defined if uintX_t types are defined in <stdint.h>. */ #undef GG_CONFIG_HAVE_STDINT_H @@ -235,11 +234,11 @@ uint32_t hub_addr; /**< Adres huba po rozwi�zaniu nazwy */ uint32_t server_addr; /**< Adres serwera otrzymany od huba */ - uint32_t client_addr; /**< Adres gniazda dla po��cze� bezpo�rednich do wersji Gadu-Gadu 6.x */ - uint16_t client_port; /**< Port gniazda dla po��cze� bezpo�rednich do wersji Gadu-Gadu 6.x */ + uint32_t client_addr; /**< Adres gniazda dla po��cze� bezpo�rednich */ + uint16_t client_port; /**< Port gniazda dla po��cze� bezpo�rednich */ - uint32_t external_addr; /**< Publiczny adres dla po��cze� bezpo�rednich do wersji Gadu-Gadu 6.x */ - uint16_t external_port; /**< Publiczny port dla po��cze� bezpo�rednich do wersji Gadu-Gadu 6.x */ + uint32_t external_addr; /**< Publiczny adres dla po��cze� bezpo�rednich */ + uint16_t external_port; /**< Publiczny port dla po��cze� bezpo�rednich */ uin_t uin; /**< W�asny numer Gadu-Gadu */ char *password; /**< Has�o (zwalniane po u甜yciu) */ @@ -284,7 +283,7 @@ int send_left; /**< Liczba bajt坦w do wys�ania */ struct gg_dcc7 *dcc7_list; /**< Lista po��cze� bezpo�rednich skojarzonych z sesj� */ - + int soft_timeout; /**< Flaga m坦wi�ca, 甜e po przekroczeniu \c timeout nale甜y wywo�a� \c gg_watch_fd() */ int protocol_flags; /**< Flagi protoko�u */ @@ -573,6 +572,17 @@ }; /** + * Flaga po��czenia szyfrowanego. + * + * \ingroup login + */ +typedef enum { + GG_SSL_DISABLED = 0, /**< Po��czenie SSL wy��czone */ + GG_SSL_ENABLED, /**< Po��czenie SSL w��czone gdy dost�pne */ + GG_SSL_REQUIRED /**< Po��czenie SSL wymagane */ +} gg_ssl_t; + +/** * Parametry po��czenia z serwerem Gadu-Gadu. Parametry zosta�y przeniesione * do struktury, by unikn�� zmian API po rozszerzeniu protoko�u i dodaniu * kolejnych opcji po��czenia. Cz��� parametr坦w, kt坦re nie s� ju甜 aktualne @@ -588,19 +598,15 @@ char *status_descr; /**< Pocz�tkowy opis u甜ytkownika (domy�lnie brak) */ uint32_t server_addr; /**< Adres serwera Gadu-Gadu (domy�lnie pobierany automatycznie) */ uint16_t server_port; /**< Port serwera Gadu-Gadu (domy�lnie pobierany automatycznie) */ -#ifndef DOXYGEN - uint32_t client_addr; /**< Adres po��cze� bezpo�rednich (nieaktualne) */ - uint16_t client_port; /**< Port po��cze� bezpo�rednich (nieaktualne) */ -#endif + uint32_t client_addr; /**< Adres po��cze� bezpo�rednich (domy�lnie dobierany automatycznie) */ + uint16_t client_port; /**< Port po��cze� bezpo�rednich (domy�lnie dobierany automatycznie) */ int protocol_version; /**< Wersja protoko�u wysy�ana do serwera (domy�lnie najnowsza obs�ugiwana) */ char *client_version; /**< Wersja klienta wysy�ana do serwera (domy�lnie najnowsza znana) */ int has_audio; /**< Flaga obs�ugi po��cze� g�osowych */ int last_sysmsg; /**< Numer ostatnio odebranej wiadomo�ci systemowej */ - uint32_t external_addr; /**< Adres publiczny dla po��cze� bezpo�rednich (6.x) */ - uint16_t external_port; /**< Port publiczny dla po��cze� bezpo�rednich (6.x) */ -#ifndef DOXYGEN - int tls; /**< Flaga po��czenia szyfrowanego (nieaktualna) */ -#endif + uint32_t external_addr; /**< Adres publiczny dla po��cze� bezpo�rednich (domy�lnie dobierany automatycznie) */ + uint16_t external_port; /**< Port publiczny dla po��cze� bezpo�rednich (domy�lnie dobierany automatycznie) */ + int tls; /**< Flaga po��czenia szyfrowanego (patrz \ref gg_ssl_t) */ int image_size; /**< Maksymalny rozmiar obs�ugiwanych obrazk坦w w kilobajtach */ #ifndef DOXYGEN int era_omnix; /**< Flaga udawania klienta Era Omnix (nieaktualna) */ @@ -633,6 +639,7 @@ int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, int message_len); int gg_ping(struct gg_session *sess); int gg_userlist_request(struct gg_session *sess, char type, const char *request); +int gg_userlist100_request(struct gg_session *sess, char type, unsigned int version, char format_type, const char *request); int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32); int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size); int gg_typing_notification(struct gg_session *sess, uin_t recipient, int length); @@ -705,6 +712,9 @@ GG_EVENT_USER_DATA, /**< Informacja o kontaktach */ GG_EVENT_MULTILOGON_MSG, /**< Wiadomo�� wys�ana z innej sesji multilogowania */ GG_EVENT_MULTILOGON_INFO, /**< Informacja o innych sesjach multilogowania */ + + GG_EVENT_USERLIST100_VERSION, /**< Otrzymano numer wersji listy kontakt坦w na serwerze (10.0) */ + GG_EVENT_USERLIST100_REPLY, /**< Wynik importu lub eksportu listy kontakt坦w (10.0) */ }; #define GG_EVENT_SEARCH50_REPLY GG_EVENT_PUBDIR50_SEARCH_REPLY @@ -723,7 +733,9 @@ GG_FAILURE_TLS, /**< B��d negocjacji szyfrowanego po��czenia */ GG_FAILURE_NEED_EMAIL, /**< Serwer roz��czy� nas z pro�b� o zmian� adresu e-mail */ GG_FAILURE_INTRUDER, /**< Zbyt wiele pr坦b po��czenia z nieprawid�owym has�em */ - GG_FAILURE_UNAVAILABLE /**< Serwery s� wy��czone */ + GG_FAILURE_UNAVAILABLE, /**< Serwery s� wy��czone */ + GG_FAILURE_PROXY, /**< B��d serwera po�rednicz�cego */ + GG_FAILURE_HUB, /**< B��d po��czenia z hubem */ }; /** @@ -995,7 +1007,24 @@ }; /** - * Unia wszystkich zdarze� zwracanych przez funkcje \c gg_watch_fd(), + * Opis zdarzenia \c GG_EVENT_USERLIST100_VERSION. + */ +struct gg_event_userlist100_version { + uint32_t version; /**< Numer wersji listy kontakt坦w na serwerze */ +}; + +/** + * Opis zdarzenia \c GG_EVENT_USERLIST100_REPLY. + */ +struct gg_event_userlist100_reply { + char type; /**< Rodzaj odpowiedzi */ + uint32_t version; /**< Aktualna wersja listy kontakt坦w na serwerze */ + char format_type; /**< Typ formatu listy kontakt坦w (甜�dany w \c gg_userlist100_request.format_type) */ + char *reply; /**< Tre�� listy kontakt坦w w przesy�anej wersji i formacie */ +}; + +/** + * Unia wszystkich zdarze� zwracanych przez funkcje \c gg_watch_fd(), * \c gg_dcc_watch_fd() i \c gg_dcc7_watch_fd(). * * \ingroup events @@ -1028,6 +1057,8 @@ struct gg_event_user_data user_data; /**< Informacje o kontaktach */ struct gg_event_msg multilogon_msg; /**< Inna sesja wys�a�a wiadomo�� (\c GG_EVENT_MULTILOGON_MSG) */ struct gg_event_multilogon_info multilogon_info; /**< Informacja o innych sesjach multilogowania (\c GG_EVENT_MULTILOGON_INFO) */ + struct gg_event_userlist100_version userlist100_version; /**< Informacja o numerze wersji listy kontakt坦w na serwerze (\c GG_EVENT_USERLIST100_VERSION) */ + struct gg_event_userlist100_reply userlist100_reply; /**< Odpowied添 listy kontakt坦w (10.0) (\c GG_EVENT_USERLIST100_REPLY) */ }; /** @@ -1092,7 +1123,7 @@ #else -/** +/** * \ingroup pubdir50 * * Rodzaj pola zapytania. @@ -1158,7 +1189,7 @@ /** * Token autoryzacji niekt坦rych operacji HTTP. - * + * * \ingroup token */ struct gg_token { @@ -1257,6 +1288,19 @@ const char *gg_libgadu_version(void); +/** + * Lista funkcji biblioteki, kt坦re zale甜� od zewn�trznych bibliotek. + * + * \ingroup version + */ +typedef enum { + GG_LIBGADU_FEATURE_SSL, /**< Biblioteka obs�uguje po��czenia szyfrowane */ + GG_LIBGADU_FEATURE_PTHREAD, /**< Biblioteka obs�uguje rozwi�zywanie nazw za pomoc� w�tk坦w */ + GG_LIBGADU_FEATURE_USERLIST100, /**< Biblioteka obs�uguje list� kontakt坦w zgodn� z Gadu-Gadu 10 */ +} gg_libgadu_feature_t; + +int gg_libgadu_check_feature(gg_libgadu_feature_t feature); + extern int gg_proxy_enabled; extern char *gg_proxy_host; extern int gg_proxy_port; @@ -1281,7 +1325,7 @@ /** * \ingroup pubdir50 - * + * * Rodzaj zapytania lub odpowiedzi katalogu publicznego. */ enum { @@ -1362,10 +1406,6 @@ struct gg_http *gg_change_passwd2(uin_t uin, const char *passwd, const char *newpasswd, const char *email, const char *newemail, int async) GG_DEPRECATED; struct gg_http *gg_change_passwd3(uin_t uin, const char *passwd, const char *newpasswd, const char *qa, int async) GG_DEPRECATED; -int gg_resolve(int *fd, int *pid, const char *hostname) GG_DEPRECATED; -int gg_resolve_pthread(int *fd, void **resolver, const char *hostname) GG_DEPRECATED; -void gg_resolve_pthread_cleanup(void *arg, int kill) GG_DEPRECATED; - struct gg_change_info_request { char *first_name; char *last_name; @@ -1427,8 +1467,8 @@ int gg_send_packet(struct gg_session *sess, int type, ...) GG_DEPRECATED; unsigned int gg_login_hash(const unsigned char *password, unsigned int seed) GG_DEPRECATED; void gg_login_hash_sha1(const char *password, uint32_t seed, uint8_t *result) GG_DEPRECATED; -uint32_t gg_fix32(uint32_t x) GG_DEPRECATED;; -uint16_t gg_fix16(uint16_t x) GG_DEPRECATED;; +uint32_t gg_fix32(uint32_t x); +uint16_t gg_fix16(uint16_t x); #define fix16 gg_fix16 #define fix32 gg_fix32 char *gg_proxy_auth(void) GG_DEPRECATED; @@ -1506,7 +1546,7 @@ #else -/** +/** * \ingroup login * * Flagi opcji protoko�u. @@ -2087,6 +2127,67 @@ uint8_t type; } GG_PACKED; +#ifndef DOXYGEN + +#define GG_USERLIST100_PUT 0x00 +#define GG_USERLIST100_GET 0x02 + +#else + +/** + * \ingroup importexport + * + * Rodzaj zapytania (10.0). + */ +enum { + GG_USERLIST100_PUT, /**< Eksport listy kontakt坦w. */ + GG_USERLIST100_GET, /**< Import listy kontakt坦w. */ +}; + +#endif /* DOXYGEN */ + +#ifndef DOXYGEN + +#define GG_USERLIST100_FORMAT_TYPE_NONE 0x00 +#define GG_USERLIST100_FORMAT_TYPE_GG70 0x01 +#define GG_USERLIST100_FORMAT_TYPE_GG100 0x02 + +#else + +/** + * \ingroup importexport + * + * Typ formatu listy kontakt坦w (10.0). + */ +enum { + GG_USERLIST100_FORMAT_TYPE_NONE, /**< Brak tre�ci listy kontakt坦w. */ + GG_USERLIST100_FORMAT_TYPE_GG70, /**< Format listy kontakt坦w zgodny z Gadu-Gadu 7.0. */ + GG_USERLIST100_FORMAT_TYPE_GG100, /**< Format listy kontakt坦w zgodny z Gadu-Gadu 10.0. */ +}; + +#endif /* DOXYGEN */ + +#ifndef DOXYGEN + +#define GG_USERLIST100_REPLY_LIST 0x00 +#define GG_USERLIST100_REPLY_ACK 0x10 +#define GG_USERLIST100_REPLY_REJECT 0x12 + +#else + +/** + * \ingroup importexport + * + * Typ odpowiedzi listy kontakt坦w (10.0). + */ +enum { + GG_USERLIST100_REPLY_LIST, /**< W odpowiedzi znajduje si� aktualna lista kontakt坦w na serwerze. */ + GG_USERLIST100_REPLY_ACK, /**< Potwierdzenie odebrania nowej wersji listy kontakt坦w. W polu \c gg_userlist100_reply.version znajduje si� numer nowej wersji listy kontakt坦w. */ + GG_USERLIST100_REPLY_REJECT, /**< Odmowa przyj�cia nowej wersji listy kontakt坦w. W polu \c gg_userlist100_reply.version znajduje si� numer wersji listy kontakt坦w aktualnie przechowywanej przez serwer. */ +}; + +#endif /* DOXYGEN */ + struct gg_dcc_tiny_packet { uint8_t type; /* rodzaj pakietu */ } GG_PACKED;
--- a/libpurple/protocols/gg/lib/obsolete.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/obsolete.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: obsolete.c 1036 2010-12-15 00:02:28Z wojtekka $ */ +/* $Id: obsolete.c 1082 2011-04-08 17:50:14Z wojtekka $ */ /* * (C) Copyright 2001-2003 Wojtek Kaniewski <wojtekka@irc.pl> @@ -34,6 +34,7 @@ #include <errno.h> #include "libgadu.h" +#include "libgadu-internal.h" struct gg_http *gg_userlist_get(uin_t uin, const char *passwd, int async) {
--- a/libpurple/protocols/gg/lib/protocol.h Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/protocol.h Sun Jun 05 01:28:53 2011 +0000 @@ -136,7 +136,7 @@ #define GG_RECV_MSG_ACK 0x0046 struct gg_recv_msg_ack { - uint32_t count; + uint32_t seq; } GG_PACKED; #define GG_USER_DATA 0x0044 @@ -192,6 +192,20 @@ #define GG_MSG_OPTION_IMAGE_REPLY 0x05 #define GG_MSG_OPTION_IMAGE_REPLY_MORE 0x06 +#define GG_DCC7_ABORT 0x0025 + +struct gg_dcc7_abort { + gg_dcc7_id_t id; /* identyfikator po��czenia */ + uint32_t uin_from; /* numer nadawcy */ + uint32_t uin_to; /* numer odbiorcy */ +} GG_PACKED; + +#define GG_DCC7_ABORTED 0x0025 + +struct gg_dcc7_aborted { + gg_dcc7_id_t id; /* identyfikator po��czenia */ +} GG_PACKED; + #define GG_DCC7_VOICE_RETRIES 0x11 /* 17 powtorzen */ #define GG_DCC7_RESERVED1 0xdeadc0de @@ -277,6 +291,34 @@ gg_dcc7_id_t id; /* identyfikator po��czenia */ } GG_PACKED; +#define GG_TIMEOUT_DISCONNECT 5 /**< Maksymalny czas oczekiwania na roz��czenie */ + +#define GG_USERLIST100_VERSION 0x5c + +struct gg_userlist100_version { + uint32_t version; /* numer wersji listy kontakt坦w */ +} GG_PACKED; + +#define GG_USERLIST100_REQUEST 0x0040 + +struct gg_userlist100_request { + uint8_t type; /* rodzaj 甜�dania */ + uint32_t version; /* numer ostatniej znanej wersji listy kontakt坦w b�d添 0 */ + uint8_t format_type; /* rodzaj 甜�danego typu formatu listy kontakt坦w */ + uint8_t unknown1; /* 0x01 */ + /* char request[]; */ +} GG_PACKED; + +#define GG_USERLIST100_REPLY 0x41 + +struct gg_userlist100_reply { + uint8_t type; /* rodzaj odpowiedzi */ + uint32_t version; /* numer wersji listy kontakt坦w aktualnie przechowywanej przez serwer */ + uint8_t format_type; /* rodzaj przesy�anego typu formatu listy kontakt坦w */ + uint8_t unknown1; /* 0x01 */ + /* char reply[]; */ +} GG_PACKED; + #ifdef _WIN32 #pragma pack(pop) #endif
--- a/libpurple/protocols/gg/lib/pubdir.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/pubdir.c Sun Jun 05 01:28:53 2011 +0000 @@ -26,9 +26,6 @@ * \brief Obs�uga katalogu publicznego */ -#include "libgadu.h" -#include "libgadu-config.h" - #include <ctype.h> #include <errno.h> #include <stdarg.h> @@ -37,6 +34,9 @@ #include <string.h> #include <unistd.h> +#include "libgadu.h" +#include "libgadu-config.h" + /** * Rejestruje nowego u甜ytkownika. * @@ -122,10 +122,10 @@ h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; - + if (!async) gg_pubdir_watch_fd(h); - + return h; } @@ -193,7 +193,7 @@ errno = EFAULT; return NULL; } - + __pwd = gg_saprintf("%ld", random()); __fmpwd = gg_urlencode(password); __tokenid = gg_urlencode(tokenid); @@ -251,10 +251,10 @@ h->callback = gg_pubdir_watch_fd; h->destroy = gg_pubdir_free; - + if (!async) gg_pubdir_watch_fd(h); - + return h; } @@ -324,7 +324,7 @@ errno = EFAULT; return NULL; } - + __fmpwd = gg_urlencode(passwd); __pwd = gg_urlencode(newpasswd); __email = gg_urlencode(email); @@ -340,7 +340,7 @@ free(__tokenval); return NULL; } - + if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, newpasswd)))) { gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n"); free(__fmpwd); @@ -351,13 +351,13 @@ return NULL; } - + free(__fmpwd); free(__pwd); free(__email); free(__tokenid); free(__tokenval); - + gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form); query = gg_saprintf( @@ -460,7 +460,7 @@ errno = EFAULT; return NULL; } - + __tokenid = gg_urlencode(tokenid); __tokenval = gg_urlencode(tokenval); __email = gg_urlencode(email); @@ -484,7 +484,7 @@ free(__tokenid); free(__tokenval); free(__email); - + gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form); query = gg_saprintf( @@ -588,7 +588,7 @@ errno = EINVAL; return -1; } - + if (h->state != GG_STATE_PARSING) { if (gg_http_watch_fd(h) == -1) { gg_debug(GG_DEBUG_MISC, "=> pubdir, http failure\n"); @@ -599,9 +599,9 @@ if (h->state != GG_STATE_PARSING) return 0; - + h->state = GG_STATE_DONE; - + if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) { gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n"); return -1; @@ -609,7 +609,7 @@ p->success = 0; p->uin = 0; - + gg_debug(GG_DEBUG_MISC, "=> pubdir, let's parse \"%s\"\n", h->body); if ((tmp = strstr(h->body, "Tokens okregisterreply_packet.reg.dwUserId="))) { @@ -636,7 +636,7 @@ { if (!h) return; - + free(h->data); gg_http_free(h); } @@ -674,10 +674,10 @@ h->callback = gg_token_watch_fd; h->destroy = gg_token_free; - + if (!async) gg_token_watch_fd(h); - + return h; } @@ -706,7 +706,7 @@ errno = EINVAL; return -1; } - + if (h->state != GG_STATE_PARSING) { if (gg_http_watch_fd(h) == -1) { gg_debug(GG_DEBUG_MISC, "=> token, http failure\n"); @@ -717,7 +717,7 @@ if (h->state != GG_STATE_PARSING) return 0; - + /* je�li h->data jest puste, to �ci�gali�my tokenid i url do niego, * ale je�li co� tam jest, to znaczy, 甜e mamy drugi etap polegaj�cy * na pobieraniu tokenu. */ @@ -735,7 +735,7 @@ free(url); return -1; } - + if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) { gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n"); free(url); @@ -743,7 +743,7 @@ errno = EINVAL; return -1; } - + /* dostali�my tokenid i wszystkie niezb�dne informacje, * wi�c pobierzmy obrazek z tokenem */ @@ -779,7 +779,7 @@ free(url); free(tokenid); return -1; - } + } if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) { gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n"); @@ -803,7 +803,7 @@ h->callback = gg_token_watch_fd; h->destroy = gg_token_free; - + if (!h->async) gg_token_watch_fd(h); @@ -821,7 +821,7 @@ /* obrazek mamy w h->body */ h->state = GG_STATE_DONE; } - + return 0; } @@ -841,7 +841,7 @@ if ((t = h->data)) free(t->tokenid); - + free(h->data); gg_http_free(h); }
--- a/libpurple/protocols/gg/lib/pubdir50.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/pubdir50.c Sun Jun 05 01:28:53 2011 +0000 @@ -31,6 +31,7 @@ #include <time.h> #include "libgadu.h" +#include "libgadu-config.h" #include "libgadu-internal.h" #include "encoding.h" @@ -94,7 +95,7 @@ return 0; } - + if (!(dupfield = strdup(field))) { gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n"); free(dupvalue); @@ -149,7 +150,7 @@ int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq) { gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_seq_set(%p, %d);\n", req, seq); - + if (!req) { gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_seq_set() invalid arguments\n"); errno = EFAULT; @@ -174,7 +175,7 @@ if (!s) return; - + for (i = 0; i < s->entries_count; i++) { free(s->entries[i].field); free(s->entries[i].value); @@ -202,7 +203,7 @@ struct gg_pubdir50_request *r; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req); - + if (!sess || !req) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n"); errno = EFAULT; @@ -219,7 +220,7 @@ /* wyszukiwanie bierze tylko pierwszy wpis */ if (req->entries[i].num) continue; - + if (sess->encoding == GG_ENCODING_CP1250) { size += strlen(req->entries[i].field) + 1; size += strlen(req->entries[i].value) + 1; @@ -327,7 +328,7 @@ struct gg_pubdir50_reply *r = (struct gg_pubdir50_reply*) packet; gg_pubdir50_t res; int num = 0; - + gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply_sess(%p, %p, %p, %d);\n", sess, e, packet, length); if (!sess || !e || !packet) { @@ -384,7 +385,7 @@ } value = NULL; - + for (p = field; p < end; p++) { /* je�li mamy koniec tekstu... */ if (!*p) { @@ -399,7 +400,7 @@ break; } } - + /* sprawd添my, czy pole nie wychodzi poza pakiet, 甜eby nie * mie� segfault坦w, je�li serwer przestanie zaka�cza� pakiet坦w * przez \0 */ @@ -436,10 +437,10 @@ free(tmp); } } - } + } res->count = num + 1; - + return 0; failure:
--- a/libpurple/protocols/gg/lib/resolver.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/resolver.c Sun Jun 05 01:28:53 2011 +0000 @@ -29,17 +29,19 @@ #ifndef _WIN32 # include <sys/wait.h> # include <netdb.h> +#endif +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#ifndef _WIN32 # include <signal.h> # include <netinet/in.h> # include <arpa/inet.h> #endif -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - #include "libgadu.h" +#include "libgadu-config.h" #include "resolver.h" #include "compat.h" #include "session.h" @@ -212,7 +214,6 @@ struct hostent *he; int i; - if (result == NULL || count == NULL) { errno = EINVAL; return -1; @@ -256,7 +257,7 @@ * * \return 0 je�li si� powiod�o, -1 w przypadku b��du */ -int gg_resolver_run(int fd, const char *hostname) +static int gg_resolver_run(int fd, const char *hostname) { struct in_addr addr_ip[2], *addr_list; int addr_count; @@ -595,7 +596,7 @@ * * Po��czenia asynchroniczne nie mog� blokowa� procesu w trakcie rozwi�zywania * nazwy serwera. W tym celu tworzony jest potok, nowy proces i dopiero w nim - * przeprowadzane jest rozwi�zywanie nazwy. Deskryptor strony do odczytu + * przeprowadzane jest rozwi�zywanie nazwy. Deskryptor strony do odczytu * zapisuje si� w strukturze sieci i czeka na dane w postaci struktury * \c in_addr. Je�li nie znaleziono nazwy, zwracana jest \c INADDR_NONE. * @@ -865,13 +866,13 @@ return 0; } -#ifdef _WIN32 +#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT) +# ifdef _WIN32 type = GG_RESOLVER_WIN32; -#else +# else type = GG_RESOLVER_FORK; -#endif - -#if defined(GG_CONFIG_HAVE_PTHREAD) || defined(GG_CONFIG_PTHREAD_DEFAULT) +# endif +#else type = GG_RESOLVER_PTHREAD; #endif } @@ -936,7 +937,7 @@ * - \c "int force" — flaga m坦wi�ca o tym, 甜e zasoby s� zwalniane przed zako�czeniem rozwi�zywania nazwy, np. z powodu zamkni�cia sesji. * * W�asny kod rozwi�zywania nazwy powinien stworzy� potok, par� gniazd lub - * inny deskryptor pozwalaj�cy na co najmniej jednostronn� komunikacj� i + * inny deskryptor pozwalaj�cy na co najmniej jednostronn� komunikacj� i * przekaza� go w parametrze \c fd. Po zako�czeniu rozwi�zywania nazwy, * powinien wys�a� otrzymany adres IP w postaci sieciowej (big-endian) do * deskryptora. Je�li rozwi�zywanie nazwy si� nie powiedzie, nale甜y wys�a� @@ -986,13 +987,13 @@ return 0; } -#ifdef _WIN32 +#if !defined(GG_CONFIG_HAVE_PTHREAD) || !defined(GG_CONFIG_PTHREAD_DEFAULT) +# ifdef _WIN32 type = GG_RESOLVER_WIN32; -#else +# else type = GG_RESOLVER_FORK; -#endif - -#if defined(GG_CONFIG_HAVE_PTHREAD) || defined(GG_CONFIG_PTHREAD_DEFAULT) +# endif +#else type = GG_RESOLVER_PTHREAD; #endif } @@ -1082,20 +1083,18 @@ gg_global_resolver_cleanup = NULL; return 0; -#ifndef _WIN32 - case GG_RESOLVER_FORK: - gg_global_resolver_type = type; - gg_global_resolver_start = gg_resolver_fork_start; - gg_global_resolver_cleanup = gg_resolver_fork_cleanup; - return 0; -#endif - #ifdef _WIN32 case GG_RESOLVER_WIN32: gg_global_resolver_type = type; gg_global_resolver_start = gg_resolve_win32thread; gg_global_resolver_cleanup = gg_resolve_win32thread_cleanup; return 0; +#else + case GG_RESOLVER_FORK: + gg_global_resolver_type = type; + gg_global_resolver_start = gg_resolver_fork_start; + gg_global_resolver_cleanup = gg_resolver_fork_cleanup; + return 0; #endif #ifdef GG_CONFIG_HAVE_PTHREAD
--- a/libpurple/protocols/gg/lib/sha1.c Tue May 24 01:48:26 2011 +0000 +++ b/libpurple/protocols/gg/lib/sha1.c Sun Jun 05 01:28:53 2011 +0000 @@ -1,4 +1,4 @@ -/* $Id: sha1.c 632 2008-07-30 18:40:06Z darkjames $ */ +/* $Id: sha1.c 1067 2011-03-15 18:57:16Z wojtekka $ */ /* * (C) Copyright 2007 Wojtek Kaniewski <wojtekka@irc.pl> @@ -23,7 +23,7 @@ /** * \file sha1.c * - * \brief Funkcje wyznaczania skr��tu SHA1 + * \brief Funkcje wyznaczania skr坦tu SHA1 */ #include <string.h> @@ -228,12 +228,12 @@ void gg_login_hash_sha1(const char *password, uint32_t seed, uint8_t *result) { SHA_CTX ctx; - + SHA1_Init(&ctx); SHA1_Update(&ctx, (const unsigned char*) password, strlen(password)); seed = gg_fix32(seed); SHA1_Update(&ctx, (uint8_t*) &seed, 4); - + SHA1_Final(result, &ctx); }