From libgadu-commit at lists.ziew.org Mon Jun 1 17:22:51 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Mon, 1 Jun 2009 17:22:51 +0200 (CEST) Subject: [libgadu-commit] r734 - trunk/docs Message-ID: <20090601152252.0B00317B45@toxygen.net> Author: darkjames Date: 2009-06-01 17:22:51 +0200 (Mon, 01 Jun 2009) New Revision: 734 Modified: trunk/docs/protocol.html Log: Dodanie ostrze?enia o tym ?e po??czenia przez serwer w GG7.7 s? inne. Drobne poprawki. Modified: trunk/docs/protocol.html =================================================================== --- trunk/docs/protocol.html 2009-05-31 21:45:49 UTC (rev 733) +++ trunk/docs/protocol.html 2009-06-01 15:22:51 UTC (rev 734) @@ -10,6 +10,7 @@ .tabf { background-color: white; } .tabf2 { background-color: white; color: silver; } .check { background-color: white; color: silver; } +.warn { font-family: monospace; padding: 0.7em; background-color: red; border: 1px solid #80a0a0; } .c { font-family: monospace; padding: 0.7em; background-color: #e0e0e0; border: 1px solid #a0a0a0; } .http { font-family: monospace; padding: 0.7em; background-color: #c0f0c0; border: 1px solid #80a080; } .example { font-family: monospace; padding: 0.7em; background-color: #c0f0f0; border: 1px solid #80a0a0; } @@ -1669,32 +1670,7 @@

-Przed akceptacj? pliku przez stron? wywo?ywan?, u?ytkownik mo?e przerwa? -??danie wysy?aj?c pakiet: -

- -
-
#define GG_DCC7_ABORT 0x0025
-struct gg_dcc7_abort {
-	long long id;		/* identyfikator po??czenia */
-	int uin_from;		/* numer nadawcy */
-	int uin_to;		/* numer odbiorcy */
-};
-
- -

-Strona wywo?ywana powinna otrzyma? pakiet: -

- -
-
#define GG_DCC7_ABORTED 0x0025
-struct gg_dcc7_aborted {
-	long long id;		/* identyfikator po??czenia */
-};
-
- -

-Strona wywo?ywana, w przypadku gdy u?ytkownik zaakceptuje pobranie pliku, +Strona wywo?ywana po otrzymaniu pakietu GG_DCC7_NEW, mo?e zaakceptowa? pobieranie pliku, wysy?a pakiet:

@@ -1741,6 +1717,32 @@

+Przed akceptacj? pliku przez stron? wywo?ywan?, u?ytkownik mo?e przerwa? +??danie wysy?aj?c pakiet: +

+ +
+
#define GG_DCC7_ABORT 0x0025
+struct gg_dcc7_abort {
+	long long id;		/* identyfikator po??czenia */
+	int uin_from;		/* numer nadawcy */
+	int uin_to;		/* numer odbiorcy */
+};
+
+ +

+Strona wywo?ywana w takim przypadku powinna otrzyma? pakiet: +

+ +
+
#define GG_DCC7_ABORTED 0x0025
+struct gg_dcc7_aborted {
+	long long id;		/* identyfikator po??czenia */
+};
+
+ + +

Po zaakceptowaniu pliku, obie strony zaczynaj? nas?uchiwa? na losowo wybranym porcie i wysy?aj? pakiet GG_DCC7_INFO z informacjami potrzebnymi do po??czenia.

@@ -1790,7 +1792,7 @@
#define GG_DCC7_RELAY_REPLY 0x0b
-struct gg_dcc7_relay_rely {
+struct gg_dcc7_relay_reply {
 	int magic;	/* 0x0b */
 	int len;	/* d?ugo?? ca?ego pakietu */
 	int rcount;	/* prawdopodobnie ilo?? po?rednicz?cych serwer?w */
@@ -1890,6 +1892,13 @@
 numerek TBD
 

+
+
+GG7.7 wysy?a: GGidSHnumerek
+Protok?? jest inny, i raczej nie b?dzie dzia?a?.
+
+
+

Przyk?adowa zawarto?? pola info dla po??czenia 0x00000a0600000b27

From libgadu-commit at lists.ziew.org Thu Jun 4 23:37:29 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Thu, 4 Jun 2009 23:37:29 +0200 (CEST) Subject: [libgadu-commit] r735 - in trunk: include src Message-ID: <20090604213729.81C2917B4A@toxygen.net> Author: darkjames Date: 2009-06-04 23:37:28 +0200 (Thu, 04 Jun 2009) New Revision: 735 Added: trunk/include/protocol.h Modified: trunk/include/Makefile.am trunk/include/libgadu.h.in trunk/src/events.c trunk/src/libgadu.c Log: Obs?uga protoko?u Nowego Gadu Gadu. Modified: trunk/include/Makefile.am =================================================================== --- trunk/include/Makefile.am 2009-06-01 15:22:51 UTC (rev 734) +++ trunk/include/Makefile.am 2009-06-04 21:37:28 UTC (rev 735) @@ -1,2 +1,2 @@ nodist_include_HEADERS = libgadu.h -noinst_HEADERS = compat.h +noinst_HEADERS = compat.h protocol.h Modified: trunk/include/libgadu.h.in =================================================================== --- trunk/include/libgadu.h.in 2009-06-01 15:22:51 UTC (rev 734) +++ trunk/include/libgadu.h.in 2009-06-04 21:37:28 UTC (rev 735) @@ -267,6 +267,8 @@ gg_resolver_t resolver_type; /**< Spos?b rozwi?zywania nazw serwer?w */ int (*resolver_start)(int *fd, void **private_data, const char *hostname); /**< Funkcja rozpoczynaj?ca rozwi?zywanie nazwy */ void (*resolver_cleanup)(void **private_data, int force); /**< Funkcja zwalniaj?ca zasoby po rozwi?zaniu nazwy */ + + int protocol_features; /**< Opcje protoko?u */ }; /** @@ -556,9 +558,10 @@ int hash_type; /**< Rodzaj skr?tu has?a (domy?lnie SHA1) */ int encoding; /**< Rodzaj kodowania u?ywanego w sesji (domy?lnie CP1250) */ gg_resolver_t resolver; /**< Spos?b rozwi?zywania nazw (patrz \ref build-resolver) */ + int protocol_features; /**< Opcje protoko?u (flagi GG_FEATURE_*) */ #ifndef DOXYGEN - char dummy[3 * sizeof(int)]; /**< \internal Miejsce na kilka kolejnych + char dummy[2 * sizeof(int)]; /**< \internal Miejsce na kilka kolejnych parametr?w, ?eby wraz z dodawaniem kolejnych parametr?w nie zmienia? si? rozmiar struktury */ #endif @@ -1345,6 +1348,13 @@ #define GG_ERA_OMNIX_MASK 0x04000000 #undef GG_LIBGADU_VERSION +#define GG_FEATURE_STATUS80BETA 0x01 +#define GG_FEATURE_MSG80 0x02 +#define GG_FEATURE_STATUS80 (0x04|GG_FEATURE_STATUS80BETA) +#define GG_FEATURE_DND_FFC 0x30 + +#define GG_FEATURE_ALL (GG_FEATURE_STATUS80BETA|GG_FEATURE_MSG80|GG_FEATURE_STATUS80|GG_FEATURE_DND_FFC) + #define GG_DEFAULT_DCC_PORT 1550 struct gg_header { @@ -1400,7 +1410,7 @@ } GG_PACKED; #define GG_LOGIN70 0x0019 -#define GG_LOGIN80 0x0029 +#define GG_LOGIN80BETA 0x0029 struct gg_login70 { uint32_t uin; /* m?j numerek */ @@ -1438,7 +1448,7 @@ } GG_PACKED; #define GG_NEW_STATUS 0x0002 -#define GG_NEW_STATUS80 0x0028 +#define GG_NEW_STATUS80BETA 0x0028 #ifndef DOXYGEN @@ -1532,7 +1542,7 @@ #define GG_S_BL(x) (GG_S(x) == GG_STATUS_BLOCKED) /** - * Zmiana statusu (pakiet \c GG_NEW_STATUS) + * Zmiana statusu (pakiet \c GG_NEW_STATUS i \c GG_NEW_STATUS80BETA) */ struct gg_new_status { uint32_t status; /**< Nowy status */ @@ -1607,7 +1617,7 @@ } GG_PACKED; #define GG_NOTIFY_REPLY77 0x0018 -#define GG_NOTIFY_REPLY80 0x002b +#define GG_NOTIFY_REPLY80BETA 0x002b struct gg_notify_reply77 { uint32_t uin; /* numerek plus flagi w MSB */ @@ -1621,7 +1631,7 @@ } GG_PACKED; #define GG_STATUS77 0x0017 -#define GG_STATUS80 0x002a +#define GG_STATUS80BETA 0x002a struct gg_status77 { uint32_t uin; /* numerek plus flagi w MSB */ Added: trunk/include/protocol.h =================================================================== --- trunk/include/protocol.h (rev 0) +++ trunk/include/protocol.h 2009-06-04 21:37:28 UTC (rev 735) @@ -0,0 +1,64 @@ +#ifndef __GG_PROTOCOL_H +#define __GG_PROTOCOL_H + +#include "libgadu.h" + +#ifdef _WIN32 +#pragma pack(push, 1) +#endif + +#define GG_LOGIN80 0x0031 + +#define GG8_LANG "pl" +#define GG8_VERSION "Gadu-Gadu Client Build 8.0.0.8731" + +struct gg_login80 { + uint32_t uin; /* m?j numerek */ + uint8_t language[2]; /* j?zyk: GG8_LANG */ + uint8_t hash_type; /* rodzaj hashowania has?a */ + uint8_t hash[64]; /* hash has?a dope?niony zerami */ + uint32_t status; /* status na dzie? dobry */ + uint32_t flags; /* flagi (przeznaczenie nieznane) */ + uint32_t features; /* opcje protoko?u (GG8_FEATURES) */ + uint32_t local_ip; /* m?j adres ip */ + uint16_t local_port; /* port, na kt?rym s?ucham */ + uint32_t external_ip; /* zewn?trzny adres ip (???) */ + uint16_t external_port; /* zewn?trzny port (???) */ + uint8_t image_size; /* maksymalny rozmiar grafiki w KiB */ + uint8_t dunno2; /* 0x64 */ +} GG_PACKED; + +#define GG_LOGIN80_OK 0x0035 + +#define GG_NEW_STATUS80 0x0038 + +/** + * Zmiana stanu (pakiet \c GG_NEW_STATUS80) + */ +struct gg_new_status80 { + uint32_t status; /**< Nowy status */ + uint32_t flags; /**< flagi (nieznane przeznaczenie) */ + uint32_t description_size; /**< rozmiar opisu */ +} GG_PACKED; + +#define GG_STATUS80 0x0036 +#define GG_NOTIFY_REPLY80 0x0037 + +struct gg_notify_reply80 { + uint32_t uin; /* numerek plus flagi w najstarszym bajcie */ + uint32_t status; /* status danej osoby */ + uint32_t flags; /* flagi (przeznaczenie nieznane) */ + uint32_t remote_ip; /* adres IP bezpo?rednich po??cze? */ + uint16_t remote_port; /* port bezpo?rednich po??cze? */ + uint8_t image_size; /* maksymalny rozmiar obrazk?w w KB */ + uint8_t unknown2; /* 0x00 */ + uint32_t unknown3; /* 0x00000000 */ + uint32_t descr_len; /* rozmiar opisu */ +} GG_PACKED; + + +#ifdef _WIN32 +#pragma pack(pop) +#endif + +#endif /* __GG_PROTOCOL_H */ Modified: trunk/src/events.c =================================================================== --- trunk/src/events.c 2009-06-01 15:22:51 UTC (rev 734) +++ trunk/src/events.c 2009-06-04 21:37:28 UTC (rev 735) @@ -35,6 +35,7 @@ #include "compat.h" #include "libgadu.h" +#include "protocol.h" #include #include @@ -678,7 +679,7 @@ } case GG_NOTIFY_REPLY77: - case GG_NOTIFY_REPLY80: + case GG_NOTIFY_REPLY80BETA: { struct gg_notify_reply77 *n = (void*) p; unsigned int length = h->length, i = 0; @@ -729,7 +730,7 @@ memcpy(descr, (char*) n + sizeof(struct gg_notify_reply77) + 1, descr_len); descr[descr_len] = 0; - if (h->type == GG_NOTIFY_REPLY80 && sess->encoding != GG_ENCODING_UTF8) { + if (h->type == GG_NOTIFY_REPLY80BETA && sess->encoding != GG_ENCODING_UTF8) { char *cp_descr = gg_utf8_to_cp(descr); if (!cp_descr) { @@ -771,7 +772,7 @@ } case GG_STATUS77: - case GG_STATUS80: + case GG_STATUS80BETA: { struct gg_status77 *s = (void*) p; uint32_t uin; @@ -811,7 +812,7 @@ memcpy(buf, (char*) p + sizeof(*s), len); buf[len] = 0; - if (h->type == GG_STATUS80 && sess->encoding != GG_ENCODING_UTF8) { + if (h->type == GG_STATUS80BETA && sess->encoding != GG_ENCODING_UTF8) { char *cp_buf = gg_utf8_to_cp(buf); free(buf); buf = cp_buf; @@ -951,6 +952,127 @@ break; } + case GG_STATUS80: + { + struct gg_notify_reply80 *s = (void*) p; + uint32_t descr_len; + + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n"); + + if (h->length < sizeof(*s)) + break; + + e->type = GG_EVENT_STATUS60; + e->event.status60.uin = gg_fix32(s->uin); + e->event.status60.status = gg_fix32(s->status); + e->event.status60.remote_ip = s->remote_ip; + e->event.status60.remote_port = gg_fix16(s->remote_port); + e->event.status60.image_size = s->image_size; + e->event.status60.descr = NULL; + e->event.status60.version = 0x00; /* not-supported */ + e->event.status60.time = 0; /* not-supported */ + + descr_len = gg_fix32(s->descr_len); + + if (h->length-sizeof(*s) >= descr_len) { + char *buf = malloc(descr_len + 1); + + if (buf) { + memcpy(buf, (char*) p + sizeof(*s), descr_len); + buf[descr_len] = 0; + + if (sess->encoding != GG_ENCODING_UTF8) { + char *cp_buf = gg_utf8_to_cp(buf); + free(buf); + buf = cp_buf; + } + } + + e->event.status60.descr = buf; + } + break; + } + + case GG_NOTIFY_REPLY80: + { + struct gg_notify_reply80 *n = (void*) p; + unsigned int length = h->length, i = 0; + + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n"); + + e->type = GG_EVENT_NOTIFY60; + e->event.notify60 = malloc(sizeof(*e->event.notify60)); + + if (!e->event.notify60) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); + goto fail; + } + + e->event.notify60[0].uin = 0; + + while (length >= sizeof(struct gg_notify_reply80)) { + uint32_t descr_len; + char *tmp; + + e->event.notify60[i].uin = gg_fix32(n->uin); + e->event.notify60[i].status = gg_fix32(n->status); + e->event.notify60[i].remote_ip = n->remote_ip; + e->event.notify60[i].remote_port= gg_fix16(n->remote_port); + e->event.notify60[i].image_size = n->image_size; + e->event.notify60[i].descr = NULL; + e->event.notify60[i].version = 0x00; /* not-supported */ + e->event.notify60[i].time = 0; /* not-supported */ + + descr_len = gg_fix32(n->descr_len); + + length -= sizeof(struct gg_notify_reply80); + n = (void*) ((char*) n + sizeof(struct gg_notify_reply80)); + + if (descr_len) { + if (length >= descr_len) { + /* XXX, GG_S_D(n->status) */ + char *descr; + + if (!(descr = malloc(descr_len + 1))) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); + goto fail; + } + + memcpy(descr, n, descr_len); + descr[descr_len] = 0; + + if (sess->encoding != GG_ENCODING_UTF8) { + char *cp_descr = gg_utf8_to_cp(descr); + + if (!cp_descr) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); + free(descr); + goto fail; + } + + free(descr); + descr = cp_descr; + } + e->event.notify60[i].descr = descr; + + length -= descr_len; + n = (void*) ((char*) n + descr_len); + } else + length = 0; + } + + if (!(tmp = realloc(e->event.notify60, (i + 2) * sizeof(*e->event.notify60)))) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); + free(e->event.notify60); + goto fail; + } + + e->event.notify60 = (void*) tmp; + e->event.notify60[++i].uin = 0; + } + break; + } + case GG_SEND_MSG_ACK: { struct gg_send_msg_ack *s = (void*) p; @@ -1304,6 +1426,7 @@ } else #endif { + /* XXX, appmsg_ver8.asp */ appmsg = "appmsg4.asp"; fmt = "&fmt=2"; } @@ -1690,17 +1813,18 @@ { struct gg_header *h; struct gg_welcome *w; - struct gg_login70 l; unsigned char *password = (unsigned char*) sess->password; int ret; + int login_dunno2; + uint8_t login_hash[64]; + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_KEY\n"); - memset(&l, 0, sizeof(l)); if (sess->protocol_version >= 0x2d) - l.dunno2 = 0x64; + login_dunno2 = 0x64; else - l.dunno2 = 0xbe; + login_dunno2 = 0xbe; /* XXX bardzo, bardzo, bardzo g?upi pomys? na pozbycie * si? tekstu wrzucanego przez proxy. */ @@ -1760,8 +1884,6 @@ w = (struct gg_welcome*) ((char*) h + sizeof(struct gg_header)); w->key = gg_fix32(w->key); - l.hash_type = sess->hash_type; - switch (sess->hash_type) { case GG_LOGIN_HASH_GG32: { @@ -1769,7 +1891,7 @@ hash = gg_fix32(gg_login_hash(password, w->key)); gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_watch_fd() challenge %.4x --> GG32 hash %.8x\n", w->key, hash); - memcpy(l.hash, &hash, sizeof(hash)); + memcpy(login_hash, &hash, sizeof(hash)); break; } @@ -1779,9 +1901,9 @@ char tmp[41]; int i; - gg_login_hash_sha1((char*) password, w->key, l.hash); + gg_login_hash_sha1((char*) password, w->key, login_hash); for (i = 0; i < 40; i += 2) - snprintf(tmp + i, sizeof(tmp) - i, "%02x", l.hash[i / 2]); + snprintf(tmp + i, sizeof(tmp) - i, "%02x", login_hash[i / 2]); gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_watch_fd() challenge %.4x --> SHA1 hash: %s\n", w->key, tmp); @@ -1801,33 +1923,81 @@ if (!getsockname(sess->fd, (struct sockaddr*) &sin, &sin_len)) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() detected address to %s\n", inet_ntoa(sin.sin_addr)); - l.local_ip = sin.sin_addr.s_addr; + sess->client_addr = sin.sin_addr.s_addr; } else { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n"); - l.local_ip = 0; + sess->client_addr = 0; } } else - l.local_ip = gg_dcc_ip; + sess->client_addr = gg_dcc_ip; - sess->client_addr = l.local_ip; + if (sess->protocol_version >= 0x2e) { + struct gg_login80 l; - l.uin = gg_fix32(sess->uin); - l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); - l.version = gg_fix32(sess->protocol_version | sess->protocol_flags); - l.local_port = gg_fix16(gg_dcc_port); - l.image_size = sess->image_size; + uint32_t tmp_version_len = gg_fix32(strlen(GG8_VERSION)); + uint32_t tmp_descr_len = gg_fix32((sess->initial_descr) ? strlen(sess->initial_descr) : 0); + + memset(&l, 0, sizeof(l)); + l.uin = gg_fix32(sess->uin); + memcpy(l.language, GG8_LANG, sizeof(l.language)); + l.hash_type = sess->hash_type; + memcpy(l.hash, login_hash, sizeof(login_hash)); + l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); + l.flags = gg_fix32(0x01); + l.features = gg_fix32(sess->protocol_features); + /* + l.local_ip = (sess->external_addr) ? sess->external_addr : sess->client_addr; + l.local_port = gg_fix16((sess->external_port > 1023) ? sess->external_port : gg_dcc_port); + */ + l.image_size = sess->image_size; + l.dunno2 = login_dunno2; - if (sess->external_addr && sess->external_port > 1023) { - l.local_ip = sess->external_addr; - l.local_port = gg_fix16(sess->external_port); - } + gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN80 packet\n"); + ret = gg_send_packet(sess, GG_LOGIN80, + &l, sizeof(l), + &tmp_version_len, sizeof(uint32_t), GG8_VERSION, strlen(GG8_VERSION), + &tmp_descr_len, sizeof(uint32_t), sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, + NULL); - if (sess->protocol_version >= 0x2d) { - gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN80 packet\n"); - ret = gg_send_packet(sess, GG_LOGIN80, &l, sizeof(l), sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, (sess->initial_descr) ? "\0" : NULL, (sess->initial_descr) ? 1 : 0, NULL); + } else if (sess->protocol_version == 0x2d) { + struct gg_login70 l; + + memset(&l, 0, sizeof(l)); + l.uin = gg_fix32(sess->uin); + l.local_ip = (sess->external_addr) ? sess->external_addr : sess->client_addr; + l.local_port = gg_fix16((sess->external_port > 1023) ? sess->external_port : gg_dcc_port); + l.hash_type = sess->hash_type; + memcpy(l.hash, login_hash, sizeof(login_hash)); + l.image_size = sess->image_size; + l.dunno2 = login_dunno2; + l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); + l.version = gg_fix32(sess->protocol_version | sess->protocol_flags); + + gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN80BETA packet\n"); + ret = gg_send_packet(sess, GG_LOGIN80BETA, + &l, sizeof(l), + sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, + (sess->initial_descr) ? "\0" : NULL, (sess->initial_descr) ? 1 : 0, + NULL); } else { + struct gg_login70 l; + + memset(&l, 0, sizeof(l)); + l.local_ip = (sess->external_addr) ? sess->external_addr : sess->client_addr; + l.uin = gg_fix32(sess->uin); + l.local_port = gg_fix16((sess->external_port > 1023) ? sess->external_port : gg_dcc_port); + l.hash_type = sess->hash_type; + memcpy(l.hash, login_hash, sizeof(login_hash)); + l.image_size = sess->image_size; + l.dunno2 = login_dunno2; + l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); + l.version = gg_fix32(sess->protocol_version | sess->protocol_flags); + gg_debug_session(sess, GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN70 packet\n"); - ret = gg_send_packet(sess, GG_LOGIN70, &l, sizeof(l), sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, NULL); + ret = gg_send_packet(sess, GG_LOGIN70, + &l, sizeof(l), + sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, + NULL); } free(sess->initial_descr); @@ -1874,7 +2044,7 @@ break; } - if (h->type == GG_LOGIN_OK || h->type == GG_NEED_EMAIL) { + if (h->type == GG_LOGIN_OK || h->type == GG_NEED_EMAIL || h->type == GG_LOGIN80_OK) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() login succeded\n"); e->type = GG_EVENT_CONN_SUCCESS; sess->state = GG_STATE_CONNECTED; Modified: trunk/src/libgadu.c =================================================================== --- trunk/src/libgadu.c 2009-06-01 15:22:51 UTC (rev 734) +++ trunk/src/libgadu.c 2009-06-04 21:37:28 UTC (rev 735) @@ -38,6 +38,7 @@ #include "compat.h" #include "libgadu.h" +#include "protocol.h" #include "resolver.h" #include @@ -743,6 +744,7 @@ sess->server_addr = p->server_addr; sess->external_port = p->external_port; sess->external_addr = p->external_addr; + sess->protocol_features = p->protocol_features; sess->protocol_version = (p->protocol_version) ? p->protocol_version : GG_DEFAULT_PROTOCOL_VERSION; if (p->era_omnix) sess->protocol_flags |= GG_ERA_OMNIX_MASK; @@ -1043,7 +1045,6 @@ */ static int gg_change_status_common(struct gg_session *sess, int status, const char *descr, int time) { - struct gg_new_status p; char *new_descr = NULL; uint32_t new_time; int descr_len = 0; @@ -1062,13 +1063,12 @@ return -1; } - // dodaj flag? obs?ugi po??cze? g?osowych zgodn? z GG 7.x + /* XXX, obcina? stany kt?rych stary protok?? niezna (czyt. dnd->aw; ffc->av) */ - if ((sess->protocol_version >= 0x2a) && (sess->protocol_flags & GG_HAS_AUDIO_MASK) && !GG_S_I(status)) + /* dodaj flag? obs?ugi po??cze? g?osowych zgodn? z GG 7.x */ + if ((sess->protocol_version >= 0x2a) && (sess->protocol_version < 0x2d /* ? */ ) && (sess->protocol_flags & GG_HAS_AUDIO_MASK) && !GG_S_I(status)) status |= GG_STATUS_VOICE_MASK; - p.status = gg_fix32(status); - sess->status = status; if (sess->protocol_version >= 0x2d) { @@ -1079,9 +1079,13 @@ return -1; } - packet_type = GG_NEW_STATUS80; + if (sess->protocol_version >= 0x2e) + packet_type = GG_NEW_STATUS80; + else /* sess->protocol_version == 0x2d */ + packet_type = GG_NEW_STATUS80BETA; descr_len_max = GG_STATUS_DESCR_MAXSIZE; append_null = 1; + } else { packet_type = GG_NEW_STATUS; descr_len_max = GG_STATUS_DESCR_MAXSIZE_PRE_8_0; @@ -1102,18 +1106,37 @@ if (time) new_time = gg_fix32(time); - res = gg_send_packet(sess, - packet_type, - &p, - sizeof(p), - (new_descr) ? new_descr : descr, - descr_len, - (append_null) ? "\0" : NULL, - (append_null) ? 1 : 0, - (time) ? &new_time : NULL, - (time) ? sizeof(new_time) : 0, - NULL); + if (packet_type == GG_NEW_STATUS80) { + struct gg_new_status80 p; + p.status = gg_fix32(status); + p.flags = gg_fix32(0x01); + p.description_size = gg_fix32(descr_len); + res = gg_send_packet(sess, + packet_type, + &p, + sizeof(p), + (new_descr) ? new_descr : descr, + descr_len, + NULL); + + } else { + struct gg_new_status p; + + p.status = gg_fix32(status); + res = gg_send_packet(sess, + packet_type, + &p, + sizeof(p), + (new_descr) ? new_descr : descr, + descr_len, + (append_null) ? "\0" : NULL, + (append_null) ? 1 : 0, + (time) ? &new_time : NULL, + (time) ? sizeof(new_time) : 0, + NULL); + } + free(new_descr); return res; } From libgadu-commit at lists.ziew.org Thu Jun 4 23:56:29 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Thu, 4 Jun 2009 23:56:29 +0200 (CEST) Subject: [libgadu-commit] r736 - trunk/include Message-ID: <20090604215629.838AC17B4A@toxygen.net> Author: darkjames Date: 2009-06-04 23:56:29 +0200 (Thu, 04 Jun 2009) New Revision: 736 Modified: trunk/include/libgadu.h.in Log: - Dodanie makr GG_S_FF() oraz GG_S_DD() (gophi) - Zmiana nazw starego GG_S_A() na GG_S_AV() oraz starego GG_S_B() na GG_S_AW() - Nowe GG_S_A() oraz GG_S_B() sprawdza te? nowe stany (uzi18) Modified: trunk/include/libgadu.h.in =================================================================== --- trunk/include/libgadu.h.in 2009-06-04 21:37:28 UTC (rev 735) +++ trunk/include/libgadu.h.in 2009-06-04 21:56:29 UTC (rev 736) @@ -1518,18 +1518,33 @@ /* GG_S() stan bez uwzgl?dnienia dodatkowych flag */ #define GG_S(x) ((x) & GG_STATUS_MASK) -/* GG_S_A() dost?pny */ -#define GG_S_A(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR) +/* GG_S_FF() ch?tny do rozmowy */ +#define GG_S_FF(x) (GG_S(x) == GG_STATUS_FFC || GG_S(x) == GG_STATUS_FFC_DESCR) + +/* GG_S_AV() dost?pny */ +#define GG_S_AV(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR) + +/* GG_S_AW() zaraz wracam */ +#define GG_S_AW(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR) + +/* GG_S_DD() nie przeszkadza? */ +#define GG_S_DD(x) (GG_S(x) == GG_STATUS_DND || GG_S(x) == GG_STATUS_DND_DESCR) + /* GG_S_NA() niedost?pny */ #define GG_S_NA(x) (GG_S(x) == GG_STATUS_NOT_AVAIL || GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR) -/* GG_S_B() zaj?ty */ -#define GG_S_B(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR) - /* GG_S_I() niewidoczny */ #define GG_S_I(x) (GG_S(x) == GG_STATUS_INVISIBLE || GG_S(x) == GG_STATUS_INVISIBLE_DESCR) + +/* GG_S_A() dost?pny lub ch?tny do rozmowy */ +#define GG_S_A(x) (GG_S_FF(x) || GG_S_AV(x)) + +/* GG_S_B() zaj?ty lub nie przeszkadza? */ +#define GG_S_B(x) (GG_S_AW(x) || GG_S_DD(x)) + + /* GG_S_D() stan opisowy */ #define GG_S_D(x) (GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR || \ GG_S(x) == GG_STATUS_FFC_DESCR || \ From libgadu-commit at lists.ziew.org Wed Jun 10 00:09:02 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Wed, 10 Jun 2009 00:09:02 +0200 (CEST) Subject: [libgadu-commit] r737 - branches/new-api/src Message-ID: <20090609220902.9FBF417B48@toxygen.net> Author: wojtekka Date: 2009-06-10 00:09:02 +0200 (Wed, 10 Jun 2009) New Revision: 737 Modified: branches/new-api/src/common.c Log: Wygenerowana tablica CRC32. Modified: branches/new-api/src/common.c =================================================================== --- branches/new-api/src/common.c 2009-06-04 21:56:29 UTC (rev 736) +++ branches/new-api/src/common.c 2009-06-09 22:09:02 UTC (rev 737) @@ -781,34 +781,74 @@ /** * \internal Tablica pomocnicza do wyznaczania sumy kontrolnej. */ -static uint32_t gg_crc32_table[256]; - -/** - * \internal Flaga wype?nienia tablicy pomocniczej do wyznaczania sumy - * kontrolnej. - */ -static int gg_crc32_initialized = 0; - -/** - * \internal Tworzy tablic? pomocnicz? do wyznaczania sumy kontrolnej. - */ -static void gg_crc32_make_table(void) +static const uint32_t gg_crc32_table[256] = { - uint32_t h = 1; - unsigned int i, j; + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; - memset(gg_crc32_table, 0, sizeof(gg_crc32_table)); - - for (i = 128; i; i >>= 1) { - h = (h >> 1) ^ ((h & 1) ? 0xedb88320L : 0); - - for (j = 0; j < 256; j += 2 * i) - gg_crc32_table[i + j] = gg_crc32_table[j] ^ h; - } - - gg_crc32_initialized = 1; -} - /** * Wyznacza sum? kontroln? CRC32. * @@ -821,10 +861,7 @@ */ uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len) { - if (!gg_crc32_initialized) - gg_crc32_make_table(); - - if (!buf || len < 0) + if (buf == NULL || len < 0) return crc; crc ^= 0xffffffffL; From libgadu-commit at lists.ziew.org Wed Jun 10 00:17:51 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Wed, 10 Jun 2009 00:17:51 +0200 (CEST) Subject: [libgadu-commit] r738 - in branches/new-api: include src Message-ID: <20090609221751.F1A3917B48@toxygen.net> Author: wojtekka Date: 2009-06-10 00:17:51 +0200 (Wed, 10 Jun 2009) New Revision: 738 Modified: branches/new-api/include/libgadu.h.in branches/new-api/include/protocol.h branches/new-api/include/session.h branches/new-api/src/events.c branches/new-api/src/libgadu.c branches/new-api/src/session.c Log: Zmiana nazwy GG_DISCONNECT2 i odpowiedniego zdarzenia. Przeniesienie gg_image_*() do session.c. Optymalizacja wysy?ania obrazk?w. Modified: branches/new-api/include/libgadu.h.in =================================================================== --- branches/new-api/include/libgadu.h.in 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/include/libgadu.h.in 2009-06-09 22:17:51 UTC (rev 738) @@ -280,6 +280,7 @@ uint32_t bind_address; /**< Lokalny adres gniazda */ unsigned int max_contacts_chunk_length; /**< Maksymalna d?ugo?? fragmentu listy kontakt?w */ unsigned int ping_period; /**< Okres wysy?ania pakietu utrzymania po??czenia */ + unsigned int max_image_chunk_length; /**< Maksymalna d?ugo?? fragmentu obrazka */ }; /** @@ -651,6 +652,8 @@ uint32_t gg_session_send_message(struct gg_session *gs, gg_message_t *gm); int gg_session_export_contacts(struct gg_session *gs, const char *contacts); int gg_session_import_contacts(struct gg_session *gs); +int gg_session_image_request(struct gg_session *gs, uin_t recipient, size_t size, uint32_t crc32); +int gg_session_image_reply(struct gg_session *gs, uin_t recipient, const char *image, size_t size, uint32_t crc32); void gg_session_free(struct gg_session *gs); gg_message_t *gg_message_new(void); @@ -744,7 +747,8 @@ GG_EVENT_DCC7_DONE, /**< Zako?czono po??czenie bezpo?rednie (7.x) */ GG_EVENT_DCC7_PENDING, /**< Trwa pr?ba po??czenia bezpo?redniego (7.x), nowy deskryptor */ - GG_EVENT_XML_EVENT /**< Otrzymano komunikat systemowy (7.7) */ + GG_EVENT_XML_EVENT, /**< Otrzymano komunikat systemowy (7.7) */ + GG_EVENT_DISCONNECT_ACK, /**< \brief Serwer zrywa po??czenie. Zdarza si?, gdy r?wnolegle do serwera pod??czy si? druga sesja i trzeba zerwa? po??czenie z pierwsz?. */ }; #define GG_EVENT_SEARCH50_REPLY GG_EVENT_PUBDIR50_SEARCH_REPLY Modified: branches/new-api/include/protocol.h =================================================================== --- branches/new-api/include/protocol.h 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/include/protocol.h 2009-06-09 22:17:51 UTC (rev 738) @@ -102,6 +102,6 @@ #define GG_USERLIST_REPLY80 0x0030 -#define GG_DISCONNECTING2 0x000d +#define GG_DISCONNECT_ACK 0x000d #endif /* LIBGADU_PROTOCOL_H */ Modified: branches/new-api/include/session.h =================================================================== --- branches/new-api/include/session.h 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/include/session.h 2009-06-09 22:17:51 UTC (rev 738) @@ -49,6 +49,6 @@ #define GG_SESSION_IS_CONNECTING(gs) ((gs)->state != GG_STATE_IDLE && (gs)->state != GG_STATE_CONNECTED) #define GG_SESSION_IS_CONNECTED(gs) ((gs)->state == GG_STATE_CONNECTED) -int gg_session_contacts_request(struct gg_session *gs, uint8_t type, const char *request); +int gg_session_contacts_request(struct gg_session *gs, uint8_t type, const char *request, size_t length); #endif /* LIBGADU_SESSION_H */ Modified: branches/new-api/src/events.c =================================================================== --- branches/new-api/src/events.c 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/src/events.c 2009-06-09 22:17:51 UTC (rev 738) @@ -1063,10 +1063,10 @@ break; } - case GG_DISCONNECTING2: + case GG_DISCONNECT_ACK: { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd_connected() received logoff acknowledge\n"); - e->type = GG_EVENT_DISCONNECT; + e->type = GG_EVENT_DISCONNECT_ACK; break; } Modified: branches/new-api/src/libgadu.c =================================================================== --- branches/new-api/src/libgadu.c 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/src/libgadu.c 2009-06-09 22:17:51 UTC (rev 738) @@ -846,75 +846,14 @@ */ int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32) { - struct gg_send_msg s; - struct gg_msg_image_request r; - char dummy = 0; - int res; - gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_request(%p, %d, %u, 0x%.4x);\n", sess, recipient, size, crc32); - if (!sess) { - errno = EFAULT; - return -1; - } - - if (sess->state != GG_STATE_CONNECTED) { - errno = ENOTCONN; - return -1; - } - if (size < 0) { errno = EINVAL; return -1; } - s.recipient = gg_fix32(recipient); - s.seq = gg_fix32(0); - s.msgclass = gg_fix32(GG_CLASS_MSG); - - r.flag = 0x04; - r.size = gg_fix32(size); - r.crc32 = gg_fix32(crc32); - - res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), &dummy, 1, &r, sizeof(r), NULL); - - if (!res) { - struct gg_image_queue *q = malloc(sizeof(*q)); - char *buf; - - if (!q) { - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image queue\n"); - return -1; - } - - buf = malloc(size); - if (size && !buf) - { - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n"); - free(q); - return -1; - } - - memset(q, 0, sizeof(*q)); - - q->sender = recipient; - q->size = size; - q->crc32 = crc32; - q->image = buf; - - if (!sess->images) - sess->images = q; - else { - struct gg_image_queue *qq; - - for (qq = sess->images; qq->next; qq = qq->next) - ; - - qq->next = q; - } - } - - return res; + return gg_session_image_request(sess, recipient, size, crc32); } /** @@ -922,7 +861,7 @@ * * \param sess Struktura sesji * \param recipient Numer adresata - * \param filename Nazwa pliku + * \param filename Nazwa pliku (ignorowana) * \param image Bufor z obrazkiem * \param size Rozmiar obrazka * @@ -932,78 +871,18 @@ */ int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size) { - struct gg_msg_image_reply *r; - struct gg_send_msg s; - const char *tmp; - char buf[1922+64]; // XXX doda? sta?e - int res = -1; + uint32_t crc32; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, \"%s\", %p, %d);\n", sess, recipient, filename, image, size); - if (!sess || !filename || !image) { - errno = EFAULT; - return -1; - } - - if (sess->state != GG_STATE_CONNECTED) { - errno = ENOTCONN; - return -1; - } - if (size < 0) { errno = EINVAL; return -1; } + + crc32 = gg_crc32(0, (unsigned char*) image, size); - /* wytnij ?cie?ki, zostaw tylko nazw? pliku */ - while ((tmp = strrchr(filename, '/')) || (tmp = strrchr(filename, '\\'))) - filename = tmp + 1; - - if (strlen(filename) < 1 || strlen(filename) > 1024) { - errno = EINVAL; - return -1; - } - - s.recipient = gg_fix32(recipient); - s.seq = gg_fix32(0); - s.msgclass = gg_fix32(GG_CLASS_MSG); - - buf[0] = 0; - r = (void*) &buf[1]; - - r->flag = 0x05; - r->size = gg_fix32(size); - r->crc32 = gg_fix32(gg_crc32(0, (unsigned char*) image, size)); - - while (size > 0) { - int buflen, chunklen; - - /* \0 + struct gg_msg_image_reply */ - buflen = 1 + sizeof(struct gg_msg_image_reply); - - /* w pierwszym kawa?ku jest nazwa pliku */ - if (r->flag == 0x05) { - char tmp[17]; - sprintf(tmp, "%08x%08x", gg_crc32(0, (unsigned char*) image, size), size); - strcpy(buf + buflen, tmp); - buflen += 17; - } - - chunklen = (size >= 1922) ? 1922 : size; - - memcpy(buf + buflen, image, chunklen); - size -= chunklen; - image += chunklen; - - res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), buf, buflen + chunklen, NULL); - - if (res == -1) - break; - - r->flag = 0x06; - } - - return res; + return gg_session_image_reply(sess, recipient, image, size, crc32); } /** @@ -1237,9 +1116,14 @@ */ int gg_userlist_request(struct gg_session *gs, char type, const char *request) { - GG_SESSION_CHECK_CONNECTED(gs, -1); + size_t length; - return gg_session_contacts_request(gs, type, request); + if (request != NULL) + length = strlen(request); + else + length = 0; + + return gg_session_contacts_request(gs, type, request, length); } /** Modified: branches/new-api/src/session.c =================================================================== --- branches/new-api/src/session.c 2009-06-09 22:09:02 UTC (rev 737) +++ branches/new-api/src/session.c 2009-06-09 22:17:51 UTC (rev 738) @@ -257,6 +257,7 @@ // wersje. gs->max_contacts_chunk_length = 2047; // XXX sprawdzi? 8.0 + gs->max_image_chunk_length = 1922; return 0; } @@ -795,7 +796,7 @@ type = gh->type; free(gh); - if (type == GG_DISCONNECTING2) + if (type == GG_DISCONNECT_ACK) break; } @@ -873,6 +874,8 @@ r.flag = 0x01; r.count = gg_fix32(gm->recipient_count - 1); + // XXX potencjalny integer overflow + recipients = malloc(sizeof(uin_t) * gm->recipient_count); if (recipients == NULL) @@ -1018,6 +1021,8 @@ r.flag = 0x01; r.count = gg_fix32(gm->recipient_count - 1); + // XXX potencjalny integer overflow + recipients = malloc(sizeof(uin_t) * gm->recipient_count); if (recipients == NULL) @@ -1095,14 +1100,14 @@ * \param sess Struktura sesji * \param type Rodzaj zapytania * \param request Tre?? zapytania (mo?e by? r?wne NULL) + * \param length D?ugo?? zapytania * * \return 0 je?li si? powiod?o, -1 w przypadku b??du * * \ingroup importexport */ -int gg_session_contacts_request(struct gg_session *gs, uint8_t type, const char *request) +int gg_session_contacts_request(struct gg_session *gs, uint8_t type, const char *request, size_t length) { - size_t len; int packet_type; if (GG_SESSION_IS_PROTOCOL_8_0(gs)) @@ -1110,17 +1115,12 @@ else packet_type = GG_USERLIST_REQUEST; - if (request != NULL) - len = strlen(request); - else - len = 0; - // Liczymy liczb? blok?w, ?eby po otrzymaniu takiej samej liczby // potwierdze? poinformowa? aplikacj? o udanej operacji. // gs->userlist_blocks = 0; - while (request != NULL && len > gs->max_contacts_chunk_length) { + while (request != NULL && length > gs->max_contacts_chunk_length) { gs->userlist_blocks++; if (gg_send_packet(gs, GG_USERLIST_REQUEST, &type, sizeof(type), request, gs->max_contacts_chunk_length, NULL) == -1) @@ -1130,29 +1130,167 @@ type = GG_USERLIST_PUT_MORE; request += gs->max_contacts_chunk_length; - len -= gs->max_contacts_chunk_length; + length -= gs->max_contacts_chunk_length; } gs->userlist_blocks++; - return gg_send_packet(gs, GG_USERLIST_REQUEST, &type, sizeof(type), request, len, NULL); + return gg_send_packet(gs, GG_USERLIST_REQUEST, &type, sizeof(type), request, length, NULL); } int gg_session_export_contacts(struct gg_session *gs, const char *contacts) { GG_SESSION_CHECK_CONNECTED(gs, -1); - return gg_session_contacts_request(gs, GG_USERLIST_PUT, contacts); + return gg_session_contacts_request(gs, GG_USERLIST_PUT, contacts, strlen(contacts)); } int gg_session_import_contacts(struct gg_session *gs) { GG_SESSION_CHECK_CONNECTED(gs, -1); - return gg_session_contacts_request(gs, GG_USERLIST_GET, NULL); + return gg_session_contacts_request(gs, GG_USERLIST_GET, NULL, 0); } /** + * Wysy?a ??danie obrazka o podanych parametrach. + * + * Wiadomo?ci obrazkowe nie zawieraj? samych obrazk?w, a tylko ich rozmiary + * i sumy kontrolne. Odbiorca najpierw szuka obrazk?w w swojej pami?ci + * podr?cznej i dopiero gdy ich nie znajdzie, wysy?a ??danie do nadawcy. + * Wynik zostanie przekazany zdarzeniem \c GG_EVENT_IMAGE_REPLY. + * + * \param gs Struktura sesji + * \param recipient Numer adresata + * \param size Rozmiar obrazka w bajtach + * \param crc32 Suma kontrola obrazka + * + * \return 0 je?li si? powiod?o, -1 w przypadku b??du + * + * \ingroup messages + */ +int gg_session_image_request(struct gg_session *gs, uin_t recipient, size_t size, uint32_t crc32) +{ + struct gg_send_msg s; + struct gg_msg_image_request r; + int res; + + GG_SESSION_CHECK_CONNECTED(gs, -1); + + s.recipient = gg_fix32(recipient); + s.seq = gg_fix32(0); + s.msgclass = gg_fix32(GG_CLASS_MSG); + + r.flag = 0x04; + r.size = gg_fix32(size); + r.crc32 = gg_fix32(crc32); + + res = gg_send_packet(gs, GG_SEND_MSG, &s, sizeof(s), "\0", 1, &r, sizeof(r), NULL); + + if (res == 0) { + struct gg_image_queue *q; + char *buf; + + q = malloc(sizeof(*q)); + + if (q == NULL) { + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image queue\n"); + return -1; + } + + buf = malloc(size); + + if (size != 0 && buf == NULL) + { + gg_debug_session(gs, GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n"); + free(q); + return -1; + } + + memset(q, 0, sizeof(*q)); + + q->sender = recipient; + q->size = size; + q->crc32 = crc32; + q->image = buf; + + if (gs->images == NULL) { + gs->images = q; + } else { + struct gg_image_queue *qq; + + for (qq = gs->images; qq->next != NULL; qq = qq->next) + ; + + qq->next = q; + } + } + + return res; +} + +/** + * Wysy?a ??dany obrazek. + * + * \param gs Struktura sesji + * \param recipient Numer odbiorcy + * \param image Bufor z obrazkiem + * \param size Rozmiar obrazka + * + * \return 0 je?li si? powiod?o, -1 w przypadku b??du + * + * \ingroup messages + */ +int gg_session_image_reply(struct gg_session *gs, uin_t recipient, const char *image, size_t size, uint32_t crc32) +{ + struct gg_msg_image_reply r; + struct gg_send_msg s; + int res = 0; + int chunk = 0; + + GG_SESSION_CHECK_CONNECTED(gs, -1); + + if (image == NULL) { + errno = EFAULT; + return -1; + } + + s.recipient = gg_fix32(recipient); + s.seq = gg_fix32(0); + s.msgclass = gg_fix32(GG_CLASS_MSG); + + r.size = gg_fix32(size); + r.crc32 = gg_fix32(crc32); + + while (size > 0) { + int chunk_len; + + chunk_len = (size >= gs->max_image_chunk_length) ? gs->max_image_chunk_length : size; + + if (chunk == 0) { + char filename[17]; + + r.flag = 0x05; + snprintf(filename, sizeof(filename), "%08x%08x", r.crc32, size); + res = gg_send_packet(gs, GG_SEND_MSG, &s, sizeof(s), "\0", 1, &r, sizeof(r), filename, strlen(filename) + 1, image, chunk_len, NULL); + } else { + r.flag = 0x06; + res = gg_send_packet(gs, GG_SEND_MSG, &s, sizeof(s), "\0", 1, &r, sizeof(r), image, chunk_len, NULL); + } + + if (res == -1) + break; + + size -= chunk_len; + image += chunk_len; + + chunk++; + } + + return res; +} + +/** * Zwalnia zasoby u?ywane przez po??czenie z serwerem. Funkcj? nale?y wywo?a? * po zamkni?ciu po??czenia z serwerem, by nie doprowadzi? do wycieku zasob?w * systemowych. From libgadu-commit at lists.ziew.org Wed Jun 10 01:20:12 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Wed, 10 Jun 2009 01:20:12 +0200 (CEST) Subject: [libgadu-commit] r739 - in branches/new-api: include src Message-ID: <20090609232012.883D517B48@toxygen.net> Author: wojtekka Date: 2009-06-10 01:20:12 +0200 (Wed, 10 Jun 2009) New Revision: 739 Modified: branches/new-api/include/libgadu.h.in branches/new-api/src/libgadu.c branches/new-api/src/session.c Log: Dodanie listy kontakt?w do session.c. Modified: branches/new-api/include/libgadu.h.in =================================================================== --- branches/new-api/include/libgadu.h.in 2009-06-09 22:17:51 UTC (rev 738) +++ branches/new-api/include/libgadu.h.in 2009-06-09 23:20:12 UTC (rev 739) @@ -281,6 +281,7 @@ unsigned int max_contacts_chunk_length; /**< Maksymalna d?ugo?? fragmentu listy kontakt?w */ unsigned int ping_period; /**< Okres wysy?ania pakietu utrzymania po??czenia */ unsigned int max_image_chunk_length; /**< Maksymalna d?ugo?? fragmentu obrazka */ + unsigned int max_notify_chunk_size; /**< Maksymalny rozmiar bloku kontakt?w */ }; /** @@ -610,6 +611,15 @@ GG_SESSION_FLAG_INVALID = -1 /**< Nieprawid?owa flaga */ } gg_session_flag_t; +/** + * Informacja o kontakcie. + */ +typedef struct { + uin_t uin; /**< Numer */ + uint8_t type; /**< Typ u?ytkownika */ + uint8_t reserved[3]; /**< Zarezerwowane (musi by? r?wne 0) */ +} gg_contact_t; + struct gg_session *gg_session_new(void); int gg_session_set_uin(struct gg_session *gs, uin_t uin); uin_t gg_session_get_uin(struct gg_session *gs); @@ -650,6 +660,9 @@ int gg_session_connect(struct gg_session *gs); int gg_session_disconnect(struct gg_session *gs, int linger); uint32_t gg_session_send_message(struct gg_session *gs, gg_message_t *gm); +int gg_session_send_contacts(struct gg_session *gs, const gg_contact_t *contact, size_t count); +int gg_session_add_contact(struct gg_session *gs, const gg_contact_t *contact); +int gg_session_remove_contact(struct gg_session *gs, const gg_contact_t *contact); int gg_session_export_contacts(struct gg_session *gs, const char *contacts); int gg_session_import_contacts(struct gg_session *gs); int gg_session_image_request(struct gg_session *gs, uin_t recipient, size_t size, uint32_t crc32); Modified: branches/new-api/src/libgadu.c =================================================================== --- branches/new-api/src/libgadu.c 2009-06-09 22:17:51 UTC (rev 738) +++ branches/new-api/src/libgadu.c 2009-06-09 23:20:12 UTC (rev 739) @@ -907,10 +907,9 @@ */ int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count) { - struct gg_notify *n; - uin_t *u; - char *t; - int i, res = 0; + gg_contact_t *contacts = NULL; + int res; + int i; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_notify_ex(%p, %p, %p, %d);\n", sess, userlist, types, count); @@ -924,44 +923,23 @@ return -1; } - if (!userlist || !count) - return gg_send_packet(sess, GG_LIST_EMPTY, NULL); + if (userlist != NULL && count > 0) { + contacts = calloc(count, sizeof(gg_contact_t)); - while (count > 0) { - int part_count, packet_type; - - if (count > 400) { - part_count = 400; - packet_type = GG_NOTIFY_FIRST; - } else { - part_count = count; - packet_type = GG_NOTIFY_LAST; - } - - if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count))) + if (contacts == NULL) { + // XXX return -1; - - for (u = userlist, t = types, i = 0; i < part_count; u++, i++) { - n[i].uin = gg_fix32(*u); - if (t != NULL) - n[i].dunno1 = *(t++); - else - n[i].dunno1 = GG_USER_NORMAL; } - if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) { - free(n); - res = -1; - break; + for (i = 0; i < count; i++) { + contacts[i].uin = userlist[i]; + contacts[i].type = (types != NULL) ? types[i] : GG_USER_NORMAL; } + } - count -= part_count; - userlist += part_count; - if (types != NULL) - types += part_count; + res = gg_session_send_contacts(sess, contacts, count); - free(n); - } + free(contacts); return res; } @@ -1002,24 +980,14 @@ */ int gg_add_notify_ex(struct gg_session *sess, uin_t uin, char type) { - struct gg_add_remove a; + gg_contact_t contact; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_add_notify_ex(%p, %u, %d);\n", sess, uin, type); - if (!sess) { - errno = EFAULT; - return -1; - } + contact.uin = uin; + contact.type = type; - if (sess->state != GG_STATE_CONNECTED) { - errno = ENOTCONN; - return -1; - } - - a.uin = gg_fix32(uin); - a.dunno1 = type; - - return gg_send_packet(sess, GG_ADD_NOTIFY, &a, sizeof(a), NULL); + return gg_session_add_contact(sess, &contact); } /** @@ -1037,7 +1005,14 @@ */ int gg_add_notify(struct gg_session *sess, uin_t uin) { - return gg_add_notify_ex(sess, uin, GG_USER_NORMAL); + gg_contact_t contact; + + gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_add_notify(%p, %u);\n", sess, uin); + + contact.uin = uin; + contact.type = GG_USER_NORMAL; + + return gg_session_add_contact(sess, &contact); } /** @@ -1055,24 +1030,14 @@ */ int gg_remove_notify_ex(struct gg_session *sess, uin_t uin, char type) { - struct gg_add_remove a; + gg_contact_t contact; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_remove_notify_ex(%p, %u, %d);\n", sess, uin, type); - if (!sess) { - errno = EFAULT; - return -1; - } + contact.uin = uin; + contact.type = type; - if (sess->state != GG_STATE_CONNECTED) { - errno = ENOTCONN; - return -1; - } - - a.uin = gg_fix32(uin); - a.dunno1 = type; - - return gg_send_packet(sess, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL); + return gg_session_remove_contact(sess, &contact); } /** @@ -1090,7 +1055,14 @@ */ int gg_remove_notify(struct gg_session *sess, uin_t uin) { - return gg_remove_notify_ex(sess, uin, GG_USER_NORMAL); + gg_contact_t contact; + + gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_remove_notify(%p, %u);\n", sess, uin); + + contact.uin = uin; + contact.type = GG_USER_NORMAL; + + return gg_session_remove_contact(sess, &contact); } /** Modified: branches/new-api/src/session.c =================================================================== --- branches/new-api/src/session.c 2009-06-09 22:17:51 UTC (rev 738) +++ branches/new-api/src/session.c 2009-06-09 23:20:12 UTC (rev 739) @@ -258,6 +258,7 @@ gs->max_contacts_chunk_length = 2047; // XXX sprawdzi? 8.0 gs->max_image_chunk_length = 1922; + gs->max_notify_chunk_size = 400; return 0; } @@ -1291,6 +1292,135 @@ } /** + * Wysy?a do serwera list? kontakt?w. + * + * Funkcja informuje serwer o li?cie kontakt?w, kt?rych statusy b?d? + * obserwowane lub kontakt?w, kt?re bed? blokowane. + * + * List? kontakt?w nale?y \b zawsze wysy?a? po po??czeniu, nawet je?li + * jest pusta (\c contacts r?wne \c NULL lub \c count r?wne 0). + * + * \param gs Struktura sesji + * \param contacts Wska?nik do tablicy kontakt?w + * \param count Liczba kontakt?w + * + * \return 0 je?li si? powiod?o, -1 w przypadku b??du + * + * \ingroup contacts + */ +int gg_session_send_contacts(struct gg_session *gs, const gg_contact_t *contacts, size_t count) +{ + struct gg_notify *n; + const gg_contact_t *c; + int i, res = 0; + + GG_SESSION_CHECK_CONNECTED(gs, -1); + + if (contacts == NULL || count == 0) + return gg_send_packet(gs, GG_LIST_EMPTY, NULL); + + if (count > gs->max_notify_chunk_size) { + n = calloc(gs->max_notify_chunk_size, sizeof(struct gg_notify)); + } else { + n = calloc(count, sizeof(struct gg_notify)); + } + + if (n == NULL) { + // XXX + return -1; + } + + while (count > 0) { + int chunk_size, packet_type; + + if (count > gs->max_notify_chunk_size) { + chunk_size = gs->max_notify_chunk_size; + packet_type = GG_NOTIFY_FIRST; + } else { + chunk_size = count; + packet_type = GG_NOTIFY_LAST; + } + + for (i = 0, c = contacts; i < chunk_size; i++, c++) { + n[i].uin = gg_fix32(c->uin); + n[i].dunno1 = c->type; + } + + if (gg_send_packet(gs, packet_type, n, sizeof(struct gg_notify) * chunk_size, NULL) == -1) { + res = -1; + break; + } + + contacts += chunk_size; + count -= chunk_size; + } + + free(n); + + return res; +} + +/** + * Dodaje kontakt. + * + * Dodaje do listy kontakt?w dany numer w trakcie po??czenia. Aby zmieni? + * rodzaj kontaktu (np. z normalnego na zablokowany), nale?y najpierw usun?? + * poprzedni rodzaj, poniewa? serwer operuje na maskach bitowych. + * + * \param sess Struktura sesji + * \param contact Informacje o kontakcie + * + * \return 0 je?li si? powiod?o, -1 w przypadku b??du + * + * \ingroup contacts + */ +int gg_session_add_contact(struct gg_session *gs, const gg_contact_t *contact) +{ + struct gg_add_remove a; + + GG_SESSION_CHECK_CONNECTED(gs, -1); + + if (contact == NULL) { + errno = EFAULT; + return -1; + } + + a.uin = gg_fix32(contact->uin); + a.dunno1 = contact->type; + + return gg_send_packet(gs, GG_ADD_NOTIFY, &a, sizeof(a), NULL); +} + +/** + * Usuwa kontakt. + * + * Usuwa z listy kontakt?w dany numer w trakcie po??czenia. + * + * \param sess Struktura sesji + * \param contact Informacje o kontakcie + * + * \return 0 je?li si? powiod?o, -1 w przypadku b??du + * + * \ingroup contacts + */ +int gg_session_remove_contact(struct gg_session *gs, const gg_contact_t *contact) +{ + struct gg_add_remove a; + + GG_SESSION_CHECK_CONNECTED(gs, -1); + + if (contact == NULL) { + errno = EFAULT; + return -1; + } + + a.uin = gg_fix32(contact->uin); + a.dunno1 = contact->type; + + return gg_send_packet(gs, GG_ADD_NOTIFY, &a, sizeof(a), NULL); +} + +/** * Zwalnia zasoby u?ywane przez po??czenie z serwerem. Funkcj? nale?y wywo?a? * po zamkni?ciu po??czenia z serwerem, by nie doprowadzi? do wycieku zasob?w * systemowych. From libgadu-commit at lists.ziew.org Wed Jun 10 13:12:37 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Wed, 10 Jun 2009 13:12:37 +0200 (CEST) Subject: [libgadu-commit] r740 - trunk/src Message-ID: <20090610111237.EAADA17B3A@toxygen.net> Author: darkjames Date: 2009-06-10 13:12:37 +0200 (Wed, 10 Jun 2009) New Revision: 740 Modified: trunk/src/events.c Log: Zerowanie pami?ci dla hasha (valgrind) Modified: trunk/src/events.c =================================================================== --- trunk/src/events.c 2009-06-09 23:20:12 UTC (rev 739) +++ trunk/src/events.c 2009-06-10 11:12:37 UTC (rev 740) @@ -1821,6 +1821,7 @@ gg_debug_session(sess, GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_KEY\n"); + memset(login_hash, 0, sizeof(login_hash)); if (sess->protocol_version >= 0x2d) login_dunno2 = 0x64; else From libgadu-commit at lists.ziew.org Thu Jun 11 13:38:18 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Thu, 11 Jun 2009 13:38:18 +0200 (CEST) Subject: [libgadu-commit] r741 - in branches/new-api: include src Message-ID: <20090611113818.611A717B48@toxygen.net> Author: wojtekka Date: 2009-06-11 13:38:17 +0200 (Thu, 11 Jun 2009) New Revision: 741 Added: branches/new-api/src/debug.c Modified: branches/new-api/include/libgadu.h.in branches/new-api/src/Makefile.am branches/new-api/src/common.c branches/new-api/src/events.c branches/new-api/src/libgadu.c branches/new-api/src/session.c Log: Wydzielenie funkcji odpluskwiania do osobnego pliku. Dodanie obs?ugi zdarze? do session.c. Nie usuwamy gg_session->client_version po po??czeniu. Modified: branches/new-api/include/libgadu.h.in =================================================================== --- branches/new-api/include/libgadu.h.in 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/include/libgadu.h.in 2009-06-11 11:38:17 UTC (rev 741) @@ -282,6 +282,9 @@ unsigned int ping_period; /**< Okres wysy?ania pakietu utrzymania po??czenia */ unsigned int max_image_chunk_length; /**< Maksymalna d?ugo?? fragmentu obrazka */ unsigned int max_notify_chunk_size; /**< Maksymalny rozmiar bloku kontakt?w */ + + struct gg_event *event_queue_head; /**< Pocz?tek kolejki zdarze? */ + struct gg_event *event_queue_tail; /**< Koniec kolejki zdarze? */ }; /** @@ -667,6 +670,9 @@ int gg_session_import_contacts(struct gg_session *gs); int gg_session_image_request(struct gg_session *gs, uin_t recipient, size_t size, uint32_t crc32); int gg_session_image_reply(struct gg_session *gs, uin_t recipient, const char *image, size_t size, uint32_t crc32); +int gg_session_handle_io(struct gg_session *gs, int condition); +struct gg_event *gg_session_get_event(struct gg_session *gs); +const struct gg_event *gg_session_peek_event(struct gg_session *gs); void gg_session_free(struct gg_session *gs); gg_message_t *gg_message_new(void); @@ -1024,6 +1030,7 @@ struct gg_event { int type; /**< Rodzaj zdarzenia */ union gg_event_union event; /**< Informacja o zdarzeniu */ + struct gg_event *next; /**< Kolejne zdarzenie w kolejce */ }; struct gg_event *gg_watch_fd(struct gg_session *sess); Modified: branches/new-api/src/Makefile.am =================================================================== --- branches/new-api/src/Makefile.am 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/src/Makefile.am 2009-06-11 11:38:17 UTC (rev 741) @@ -1,4 +1,4 @@ lib_LTLIBRARIES = libgadu.la -libgadu_la_SOURCES = common.c dcc.c dcc7.c events.c http.c obsolete.c pubdir.c pubdir50.c libgadu.c sha1.c resolver.c session.c encoding.c message.c +libgadu_la_SOURCES = common.c dcc.c dcc7.c events.c http.c obsolete.c pubdir.c pubdir50.c libgadu.c sha1.c resolver.c session.c encoding.c message.c debug.c libgadu_la_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include libgadu_la_LDFLAGS = -version-number 3:10 Modified: branches/new-api/src/common.c =================================================================== --- branches/new-api/src/common.c 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/src/common.c 2009-06-11 11:38:17 UTC (rev 741) @@ -45,127 +45,6 @@ #include "libgadu.h" /** - * Plik, do kt?rego b?d? przekazywane informacje odpluskwiania. - * - * Funkcja \c gg_debug() i pochodne mog? by? przechwytywane przez aplikacj? - * korzystaj?c? z biblioteki, by wy?wietli? je na ??danie u?ytkownika lub - * zapisa? do p??niejszej analizy. Je?li nie okre?lono pliku, wybrane - * informacje b?d? wysy?ane do standardowego wyj?cia b??du (\c stderr). - * - * \ingroup debug - */ -FILE *gg_debug_file = NULL; - -#ifndef GG_DEBUG_DISABLE - -/** - * \internal Przekazuje informacje odpluskwiania do odpowiedniej funkcji. - * - * Je?li aplikacja ustawi?a odpowiedni? funkcj? obs?ugi w - * \c gg_debug_handler_session lub \c gg_debug_handler, jest ona wywo?ywana. - * W przeciwnym wypadku wynik jest wysy?any do standardowego wyj?cia b??du. - * - * \param sess Struktura sesji (mo?e by? \c NULL) - * \param level Poziom informacji - * \param format Format wiadomo?ci (zgodny z \c printf) - * \param ap Lista argument?w (zgodna z \c printf) - */ -void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap) -{ - if (gg_debug_handler_session) - (*gg_debug_handler_session)(sess, level, format, ap); - else if (gg_debug_handler) - (*gg_debug_handler)(level, format, ap); - else if (gg_debug_level & level) - vfprintf(gg_debug_file ? gg_debug_file : stderr, format, ap); -} - - -/** - * Przekazuje informacj? odpluskawiania. - * - * \param level Poziom wiadomo?ci - * \param format Format wiadomo?ci (zgodny z \c printf) - * - * \ingroup debug - */ -void gg_debug(int level, const char *format, ...) -{ - va_list ap; - int old_errno = errno; - va_start(ap, format); - gg_debug_common(NULL, level, format, ap); - va_end(ap); - errno = old_errno; -} - -/** - * Przekazuje informacj? odpluskwiania zwi?zan? z sesj?. - * - * \param sess Struktura sesji - * \param level Poziom wiadomo?ci - * \param format Format wiadomo?ci (zgodny z \c printf) - * - * \ingroup debug - */ -void gg_debug_session(struct gg_session *sess, int level, const char *format, ...) -{ - va_list ap; - int old_errno = errno; - va_start(ap, format); - gg_debug_common(sess, level, format, ap); - va_end(ap); - errno = old_errno; -} - -/** - * Przekazuje zrzut bufora do odpluskwiania. - * - * \param sess Struktura sesji - * \param level Poziom wiadomo?ci - * \param buf Bufor danych - * \param len D?ugo?? bufora danych - * - * \ingroup debug - */ -void gg_debug_dump(struct gg_session *sess, int level, const char *buf, int len) -{ - int i, j; - - for (i = 0; i < len; i += 16) { - gg_debug_session(sess, level, "%.4x: ", i); - - for (j = 0; j < 16; j++) { - if (i + j < len) - gg_debug_session(sess, level, " %02x", (unsigned char) buf[i + j]); - else - gg_debug_session(sess, level, " "); - } - - gg_debug_session(sess, level, " "); - - for (j = 0; j < 16; j++) { - unsigned char ch; - - if (i + j < len) { - ch = buf[i + j]; - - if (ch < 32 || ch > 126) - ch = '.'; - - gg_debug_session(sess, level, "%c", ch); - } else { - gg_debug_session(sess, level, " "); - } - } - - gg_debug_session(sess, level, "\n"); - } -} - -#endif - -/** * Odpowiednik funkcji \c vsprintf alokuj?cy miejsce na wynik. * * Funkcja korzysta z funkcji \c vsnprintf, sprawdzaj?c czy dost?pna funkcja Added: branches/new-api/src/debug.c =================================================================== --- branches/new-api/src/debug.c (rev 0) +++ branches/new-api/src/debug.c 2009-06-11 11:38:17 UTC (rev 741) @@ -0,0 +1,233 @@ +/* $Id$ */ + +/* + * (C) Copyright 2001-2006 Wojtek Kaniewski + * Robert J. Wo?ny + * Arkadiusz Mi?kiewicz + * Tomasz Chili?ski + * Adam Wysocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License Version + * 2.1 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/** + * \file debug.c + * + * \brief Funkcje odpluskwiania + */ +#include +#include +#include +#include +#include + +#include "libgadu.h" + +/** + * Poziom rejestracji informacji odpluskwiaj?cych. Zmienna jest mask? bitow? + * sk?adaj?c? si? ze sta?ych \c GG_DEBUG_... + * + * \ingroup debug + */ +int gg_debug_level = 0; + +/** + * Funkcja, do kt?rej s? przekazywane informacje odpluskwiaj?ce. Je?li zar?wno + * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, s? r?wne + * \c NULL, informacje s? wysy?ane do standardowego wyj?cia b??du (\c stderr). + * + * \param level Poziom rejestracji + * \param format Format wiadomo?ci (zgodny z \c printf) + * \param ap Lista argument?w (zgodna z \c printf) + * + * \note Funkcja jest przes?aniana przez \c gg_debug_handler_session. + * + * \ingroup debug + */ +void (*gg_debug_handler)(int level, const char *format, va_list ap) = NULL; + +/** + * Funkcja, do kt?rej s? przekazywane informacje odpluskwiaj?ce. Je?li zar?wno + * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, s? r?wne + * \c NULL, informacje s? wysy?ane do standardowego wyj?cia b??du. + * + * \param sess Sesja kt?rej dotyczy informacja lub \c NULL + * \param level Poziom rejestracji + * \param format Format wiadomo?ci (zgodny z \c printf) + * \param ap Lista argument?w (zgodna z \c printf) + * + * \note Funkcja przes?ania przez \c gg_debug_handler_session. + * + * \ingroup debug + */ +void (*gg_debug_handler_session)(struct gg_session *sess, int level, const char *format, va_list ap) = NULL; + +/** + * Plik, do kt?rego b?d? przekazywane informacje odpluskwiania. + * + * Funkcja \c gg_debug() i pochodne mog? by? przechwytywane przez aplikacj? + * korzystaj?c? z biblioteki, by wy?wietli? je na ??danie u?ytkownika lub + * zapisa? do p??niejszej analizy. Je?li nie okre?lono pliku, wybrane + * informacje b?d? wysy?ane do standardowego wyj?cia b??du (\c stderr). + * + * \ingroup debug + */ +FILE *gg_debug_file = NULL; + +#ifndef GG_DEBUG_DISABLE + +/** + * \internal Przekazuje informacje odpluskwiania do odpowiedniej funkcji. + * + * Je?li aplikacja ustawi?a odpowiedni? funkcj? obs?ugi w + * \c gg_debug_handler_session lub \c gg_debug_handler, jest ona wywo?ywana. + * W przeciwnym wypadku wynik jest wysy?any do standardowego wyj?cia b??du. + * + * \param sess Struktura sesji (mo?e by? \c NULL) + * \param level Poziom informacji + * \param format Format wiadomo?ci (zgodny z \c printf) + * \param ap Lista argument?w (zgodna z \c printf) + */ +void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap) +{ + if (gg_debug_handler_session) + (*gg_debug_handler_session)(sess, level, format, ap); + else if (gg_debug_handler) + (*gg_debug_handler)(level, format, ap); + else if (gg_debug_level & level) + vfprintf((gg_debug_file) ? gg_debug_file : stderr, format, ap); +} + + +/** + * Przekazuje informacj? odpluskawiania. + * + * \param level Poziom wiadomo?ci + * \param format Format wiadomo?ci (zgodny z \c printf) + * + * \ingroup debug + */ +void gg_debug(int level, const char *format, ...) +{ + va_list ap; + int old_errno = errno; + va_start(ap, format); + gg_debug_common(NULL, level, format, ap); + va_end(ap); + errno = old_errno; +} + +/** + * Przekazuje informacj? odpluskwiania zwi?zan? z sesj?. + * + * \param sess Struktura sesji + * \param level Poziom wiadomo?ci + * \param format Format wiadomo?ci (zgodny z \c printf) + * + * \ingroup debug + */ +void gg_debug_session(struct gg_session *gs, int level, const char *format, ...) +{ + va_list ap; + int old_errno = errno; + va_start(ap, format); + gg_debug_common(gs, level, format, ap); + va_end(ap); + errno = old_errno; +} + +/** + * Przekazuje zrzut bufora do odpluskwiania. + * + * \param sess Struktura sesji + * \param level Poziom wiadomo?ci + * \param buf Bufor danych + * \param len D?ugo?? bufora danych + * + * \ingroup debug + */ +void gg_debug_dump(struct gg_session *gs, int level, const char *buf, int len) +{ + char line[80]; + int i, j; + + for (i = 0; i < len; i += 16) { + int ofs; + + sprintf(line, "%.4x: ", i); + ofs = 6; +// gg_debug_session(sess, level, "%.4x: ", i); + + for (j = 0; j < 16; j++) { + if (i + j < len) + sprintf(line + ofs, " %02x", (unsigned char) buf[i + j]); +// gg_debug_session(sess, level, " %02x", (unsigned char) buf[i + j]); + else + sprintf(line + ofs, " "); +// gg_debug_session(sess, level, " "); + + ofs += 3; + } + + sprintf(line + ofs, " "); +// gg_debug_session(sess, level, " "); + ofs += 2; + + for (j = 0; j < 16; j++) { + unsigned char ch; + + if (i + j < len) { + ch = buf[i + j]; + + if (ch < 32 || ch > 126) + ch = '.'; + } else { + ch = ' '; + } + + line[ofs++] = ch; +// gg_debug_session(sess, level, "%c", ch); + } + + line[ofs++] = '\n'; + line[ofs++] = 0; + + gg_debug_session(gs, level, "%s", line); + } +} + +#else + +#undef gg_debug_common +void gg_debug_common(struct gg_session *sess, int level, const char *format, va_list ap) +{ +} + +#undef gg_debug +void gg_debug(int level, const char *format, ...) +{ +} + +#undef gg_debug_session +void gg_debug_session(struct gg_session *gs, int level, const char *format, ...) +{ +} + +#undef gg_debug_dump +void gg_debug_dump(struct gg_session *gs, int level, const char *buf, int len) +{ +} + +#endif Modified: branches/new-api/src/events.c =================================================================== --- branches/new-api/src/events.c 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/src/events.c 2009-06-11 11:38:17 UTC (rev 741) @@ -1404,10 +1404,6 @@ free(auth); free(client); - /* zwolnij pami?? po wersji klienta. */ - free(sess->client_version); - sess->client_version = NULL; - gg_debug_session(sess, GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf); /* zapytanie jest kr?tkie, wi?c zawsze zmie?ci si? Modified: branches/new-api/src/libgadu.c =================================================================== --- branches/new-api/src/libgadu.c 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/src/libgadu.c 2009-06-11 11:38:17 UTC (rev 741) @@ -56,45 +56,6 @@ #endif /** - * Poziom rejestracji informacji odpluskwiaj?cych. Zmienna jest mask? bitow? - * sk?adaj?c? si? ze sta?ych \c GG_DEBUG_... - * - * \ingroup debug - */ -int gg_debug_level = 0; - -/** - * Funkcja, do kt?rej s? przekazywane informacje odpluskwiaj?ce. Je?li zar?wno - * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, s? r?wne - * \c NULL, informacje s? wysy?ane do standardowego wyj?cia b??du (\c stderr). - * - * \param level Poziom rejestracji - * \param format Format wiadomo?ci (zgodny z \c printf) - * \param ap Lista argument?w (zgodna z \c printf) - * - * \note Funkcja jest przes?aniana przez \c gg_debug_handler_session. - * - * \ingroup debug - */ -void (*gg_debug_handler)(int level, const char *format, va_list ap) = NULL; - -/** - * Funkcja, do kt?rej s? przekazywane informacje odpluskwiaj?ce. Je?li zar?wno - * ten \c gg_debug_handler, jak i \c gg_debug_handler_session, s? r?wne - * \c NULL, informacje s? wysy?ane do standardowego wyj?cia b??du. - * - * \param sess Sesja kt?rej dotyczy informacja lub \c NULL - * \param level Poziom rejestracji - * \param format Format wiadomo?ci (zgodny z \c printf) - * \param ap Lista argument?w (zgodna z \c printf) - * - * \note Funkcja przes?ania przez \c gg_debug_handler_session. - * - * \ingroup debug - */ -void (*gg_debug_handler_session)(struct gg_session *sess, int level, const char *format, va_list ap) = NULL; - -/** * Port gniazda nas?uchuj?cego dla po??cze? bezpo?rednich. * * \ingroup ip @@ -538,70 +499,92 @@ int gg_send_packet(struct gg_session *sess, int type, ...) { struct gg_header *h; - char *tmp; - unsigned int tmp_length; - void *payload; - unsigned int payload_length; + char *packet; + unsigned int packet_ofs; + unsigned int packet_len; + void *chunk; + unsigned int chunk_len; va_list ap; int res; gg_debug_session(sess, GG_DEBUG_FUNCTION, "** gg_send_packet(%p, 0x%.2x, ...);\n", sess, type); - tmp_length = sizeof(struct gg_header); + /* Policz d?ugo?? pakietu */ - if (!(tmp = malloc(tmp_length))) { - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() not enough memory for packet header\n"); - return -1; - } + packet_len = sizeof(struct gg_header); va_start(ap, type); - payload = va_arg(ap, void *); + for (;;) { + chunk = va_arg(ap, void *); + if (chunk == NULL) + break; + chunk_len = va_arg(ap, unsigned int); - while (payload) { - char *tmp2; + packet_len += chunk_len; + } - payload_length = va_arg(ap, unsigned int); + va_end(ap); - if (!(tmp2 = realloc(tmp, tmp_length + payload_length))) { - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n"); - free(tmp); - va_end(ap); - return -1; - } + /* Zaalokuj pami?? */ - tmp = tmp2; + packet = malloc(packet_len); - memcpy(tmp + tmp_length, payload, payload_length); - tmp_length += payload_length; + if (packet == NULL) { + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() not enough memory for packet (%d bytes)\n", packet_len); + return -1; + } - payload = va_arg(ap, void *); + /* Wype?nij nag??wek */ + + h = (struct gg_header*) packet; + h->type = gg_fix32(type); + h->length = gg_fix32(packet_len - sizeof(struct gg_header)); + + /* Sklej wszystkie kawa?ki w jedn? ca?o?? */ + + packet_ofs = sizeof(struct gg_header); + + va_start(ap, type); + + for (;;) { + chunk = va_arg(ap, void *); + if (chunk == NULL) + break; + chunk_len = va_arg(ap, unsigned int); + + memcpy(packet + packet_ofs, chunk, chunk_len); + packet_ofs += chunk_len; } va_end(ap); - h = (struct gg_header*) tmp; - h->type = gg_fix32(type); - h->length = gg_fix32(tmp_length - sizeof(struct gg_header)); + /* Zaloguj */ if ((gg_debug_level & GG_DEBUG_DUMP)) { gg_debug_session(sess, GG_DEBUG_DUMP, "// gg_send_packet() packet dump:\n"); - gg_debug_dump(sess, GG_DEBUG_DUMP, tmp, tmp_length); + gg_debug_dump(sess, GG_DEBUG_DUMP, packet, packet_len); } - res = gg_write(sess, tmp, tmp_length); + /* Wy?lij */ - free(tmp); + res = gg_write(sess, packet, packet_len); + free(packet); + if (res == -1) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno)); return -1; } - if (sess->async) - gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() partial write(), %d sent, %d left, %d total left\n", res, tmp_length - res, sess->send_left); + if (sess->async) { + if (res != packet_len) + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() partial write: %d sent, %d left, %d total left\n", res, packet_len - res, sess->send_left); + else + gg_debug_session(sess, GG_DEBUG_MISC, "// gg_send_packet() written %d bytes\n", res); + } - if (sess->send_buf) + if (sess->send_buf != NULL) sess->check |= GG_CHECK_WRITE; return 0; Modified: branches/new-api/src/session.c =================================================================== --- branches/new-api/src/session.c 2009-06-10 11:12:37 UTC (rev 740) +++ branches/new-api/src/session.c 2009-06-11 11:38:17 UTC (rev 741) @@ -71,8 +71,8 @@ memset(gs, 0, sizeof(struct gg_session)); gs->type = GG_SESSION_GG; - gs->callback = gg_session_callback; - gs->destroy = gg_session_free; + gs->callback = gg_session_callback; // XXX do usuni?cia + gs->destroy = gg_session_free; // XXX do usuni?cia gs->pid = -1; gs->encoding = GG_ENCODING_UTF8; gs->hash_type = GG_LOGIN_HASH_SHA1; @@ -1420,6 +1420,53 @@ return gg_send_packet(gs, GG_ADD_NOTIFY, &a, sizeof(a), NULL); } +int gg_session_handle_io(struct gg_session *gs, int condition) +{ + struct gg_event *ge; + + GG_SESSION_CHECK(gs, -1); + + ge = gg_watch_fd(gs); + + if (ge == NULL) + return -1; + + if (gs->event_queue_head == NULL) { + gs->event_queue_head = ge; + gs->event_queue_tail = ge; + } else { + // XXX gs->event_queue_tail != NULL + gs->event_queue_tail->next = ge; + gs->event_queue_tail = ge; + } + + return 0; +} + +struct gg_event *gg_session_get_event(struct gg_session *gs) +{ + struct gg_event *res = NULL; + + GG_SESSION_CHECK(gs, NULL); + + if (gs->event_queue_head != NULL) { + res = gs->event_queue_head; + if (res == gs->event_queue_tail) + gs->event_queue_tail = NULL; + gs->event_queue_head = gs->event_queue_head->next; + res->next = NULL; + } + + return res; +} + +const struct gg_event *gg_session_peek_event(struct gg_session *gs) +{ + GG_SESSION_CHECK(gs, NULL); + + return gs->event_queue_head; +} + /** * Zwalnia zasoby u?ywane przez po??czenie z serwerem. Funkcj? nale?y wywo?a? * po zamkni?ciu po??czenia z serwerem, by nie doprowadzi? do wycieku zasob?w @@ -1432,6 +1479,7 @@ void gg_session_free(struct gg_session *gs) { struct gg_dcc7 *dcc; + struct gg_event *ge; if (gs == NULL) return; @@ -1464,6 +1512,12 @@ for (dcc = gs->dcc7_list; dcc != NULL; dcc = dcc->next) dcc->sess = NULL; + for (ge = gs->event_queue_head; ge != NULL; ) { + struct gg_event *next = ge->next; + gg_event_free(ge); + ge = next; + } + free(gs); } From libgadu-commit at lists.ziew.org Thu Jun 11 19:22:59 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Thu, 11 Jun 2009 19:22:59 +0200 (CEST) Subject: [libgadu-commit] r742 - branches/new-api/src Message-ID: <20090611172259.B669C17B3A@toxygen.net> Author: wojtekka Date: 2009-06-11 19:22:58 +0200 (Thu, 11 Jun 2009) New Revision: 742 Modified: branches/new-api/src/session.c Log: Poprawka wysy?ania wiadomo?ci na big-endianach. Modified: branches/new-api/src/session.c =================================================================== --- branches/new-api/src/session.c 2009-06-11 11:38:17 UTC (rev 741) +++ branches/new-api/src/session.c 2009-06-11 17:22:58 UTC (rev 742) @@ -998,8 +998,8 @@ s.seq = gg_fix32(gm->seq); s.msgclass = gg_fix32(gm->msgclass); - s.offset_plain = sizeof(s) + strlen(html) + 1; - s.offset_attr = s.offset_plain + strlen(text) + 1; + s.offset_plain = gg_fix32(sizeof(s) + strlen(html) + 1); + s.offset_attr = gg_fix32(s.offset_plain + strlen(text) + 1); if ((gm->attributes != NULL) && (gm->attributes_length > 0)) { attr = gm->attributes; From libgadu-commit at lists.ziew.org Thu Jun 11 19:24:34 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Thu, 11 Jun 2009 19:24:34 +0200 (CEST) Subject: [libgadu-commit] r743 - trunk/docs Message-ID: <20090611172434.0B56917B3A@toxygen.net> Author: wojtekka Date: 2009-06-11 19:24:33 +0200 (Thu, 11 Jun 2009) New Revision: 743 Modified: trunk/docs/protocol.html Log: Liter?wki. Modified: trunk/docs/protocol.html =================================================================== --- trunk/docs/protocol.html 2009-06-11 17:22:58 UTC (rev 742) +++ trunk/docs/protocol.html 2009-06-11 17:24:33 UTC (rev 743) @@ -835,14 +835,14 @@ int offset_plain; /* po?o?enie tre?ci czystym tekstem */ int offset_attributes; /* po?o?enie atrybut?w */ char html_message[]; /* tre?? w formacie HTML (zako?czona \0) */ - char plain_message; /* tre?? czystym tekstem (zako?czona \0) */ + char plain_message[]; /* tre?? czystym tekstem (zako?czona \0) */ char attributes[]; /* atrybuty wiadomo?ci */ };

-Czas nadania jest zapisany w postaci UTC, jako ilo?ci sekund od 1 stycznie +Czas nadania jest zapisany w postaci UTC, jako ilo?ci sekund od 1 stycznia 1970r.

From libgadu-commit at lists.ziew.org Sun Jun 14 17:43:33 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Sun, 14 Jun 2009 17:43:33 +0200 (CEST) Subject: [libgadu-commit] r744 - branches/new-api/src Message-ID: <20090614154333.241AC17B1F@toxygen.net> Author: wojtekka Date: 2009-06-14 17:43:32 +0200 (Sun, 14 Jun 2009) New Revision: 744 Modified: branches/new-api/src/events.c Log: Nie marudzimy, je?li dostaniemy pusty blok atrybut?w w GG_RECV_MSG80. Modified: branches/new-api/src/events.c =================================================================== --- branches/new-api/src/events.c 2009-06-11 17:24:33 UTC (rev 743) +++ branches/new-api/src/events.c 2009-06-14 15:43:32 UTC (rev 744) @@ -506,11 +506,15 @@ goto malformed; } - if (offset_attr <= sizeof(struct gg_recv_msg80) || offset_attr >= h->length) { + if (offset_attr < sizeof(struct gg_recv_msg80) || offset_attr > h->length) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg80() malformed packet, attr out of bounds (1)\n"); offset_attr = 0; /* nie parsuj attr. */ } + /* Normalna sytuacja, wi?c nie podpada pod powy?szy warunek. */ + if (offset_attr == h->length) + offset_attr = 0; + if (gg_find_null(packet, offset_plain, h->length) == NULL) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg80() malformed packet, message out of bounds (2)\n"); goto malformed; From libgadu-commit at lists.ziew.org Tue Jun 16 14:03:20 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Tue, 16 Jun 2009 14:03:20 +0200 (CEST) Subject: [libgadu-commit] r745 - trunk/src Message-ID: <20090616120320.2387617B3A@toxygen.net> Author: wojtekka Date: 2009-06-16 14:03:19 +0200 (Tue, 16 Jun 2009) New Revision: 745 Modified: trunk/src/resolver.c Log: Nieznalezione INADDR_NONE na Sunach (Szymon Zygmunt). Modified: trunk/src/resolver.c =================================================================== --- trunk/src/resolver.c 2009-06-14 15:43:32 UTC (rev 744) +++ trunk/src/resolver.c 2009-06-16 12:03:19 UTC (rev 745) @@ -40,6 +40,7 @@ #include "libgadu.h" #include "resolver.h" +#include "compat.h" #ifdef GG_CONFIG_HAVE_PTHREAD From libgadu-commit at lists.ziew.org Tue Jun 16 14:09:54 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Tue, 16 Jun 2009 14:09:54 +0200 (CEST) Subject: [libgadu-commit] r746 - trunk/src Message-ID: <20090616120954.2B0AD17B3A@toxygen.net> Author: wojtekka Date: 2009-06-16 14:09:53 +0200 (Tue, 16 Jun 2009) New Revision: 746 Modified: trunk/src/resolver.c Log: Tymczasowa poprawka gethostbyname_r() na Sunach (Szymon Zygmunt). Modified: trunk/src/resolver.c =================================================================== --- trunk/src/resolver.c 2009-06-16 12:03:19 UTC (rev 745) +++ trunk/src/resolver.c 2009-06-16 12:09:53 UTC (rev 746) @@ -78,7 +78,7 @@ */ int gg_gethostbyname(const char *hostname, struct in_addr *addr, int pthread) { -#ifdef GG_CONFIG_HAVE_GETHOSTBYNAME_R +#if defined(GG_CONFIG_HAVE_GETHOSTBYNAME_R) && !defined(sun) char *buf = NULL; char *new_buf = NULL; struct hostent he; @@ -164,7 +164,7 @@ memcpy(addr, he->h_addr, sizeof(struct in_addr)); return 0; -#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */ +#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R && !sun */ } /** From libgadu-commit at lists.ziew.org Tue Jun 16 22:32:57 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Tue, 16 Jun 2009 22:32:57 +0200 (CEST) Subject: [libgadu-commit] r747 - trunk/src Message-ID: <20090616203257.F1B6417B45@toxygen.net> Author: darkjames Date: 2009-06-16 22:32:57 +0200 (Tue, 16 Jun 2009) New Revision: 747 Modified: trunk/src/events.c Log: Nie marudzimy, je?li dostaniemy pusty blok atrybut?w w GG_RECV_MSG80. (wojtekka/r744 w new-api) Modified: trunk/src/events.c =================================================================== --- trunk/src/events.c 2009-06-16 12:09:53 UTC (rev 746) +++ trunk/src/events.c 2009-06-16 20:32:57 UTC (rev 747) @@ -476,12 +476,16 @@ goto ignore; } - if (offset_attr <= sizeof(struct gg_recv_msg80) || offset_attr >= h->length) { + if (offset_attr < sizeof(struct gg_recv_msg80) || offset_attr > h->length) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg80() malformed packet, attr out of bounds (1)\n"); offset_attr = 0; /* nie parsuj attr. */ /* goto ignore; */ } + /* Normalna sytuacja, wi?c nie podpada pod powy?szy warunek. */ + if (offset_attr == h->length) + offset_attr = 0; + if (gg_find_null(packet, offset_plain, h->length) == NULL) { gg_debug_session(sess, GG_DEBUG_MISC, "// gg_handle_recv_msg80() malformed packet, message out of bounds (2)\n"); goto ignore; From libgadu-commit at lists.ziew.org Tue Jun 16 23:40:16 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Tue, 16 Jun 2009 23:40:16 +0200 (CEST) Subject: [libgadu-commit] r748 - in trunk: . test Message-ID: <20090616214016.72C0B17B47@toxygen.net> Author: wojtekka Date: 2009-06-16 23:40:16 +0200 (Tue, 16 Jun 2009) New Revision: 748 Modified: trunk/configure.ac trunk/test/Makefile.am Log: Testujemy DCC7 tylko wtedy, gdy mamy odpowiedni? libc. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-06-16 20:32:57 UTC (rev 747) +++ trunk/configure.ac 2009-06-16 21:40:16 UTC (rev 748) @@ -199,7 +199,7 @@ AC_SUBST([OPTIONAL_TESTS]) AC_CHECK_LIB(c, __connect, [ - OPTIONAL_TESTS="connect resolver" + OPTIONAL_TESTS="dcc7 connect resolver" ], [ OPTIONAL_TESTS="" Modified: trunk/test/Makefile.am =================================================================== --- trunk/test/Makefile.am 2009-06-16 20:32:57 UTC (rev 747) +++ trunk/test/Makefile.am 2009-06-16 21:40:16 UTC (rev 748) @@ -1,3 +1,3 @@ -SUBDIRS = protocol dcc7 $(OPTIONAL_TESTS) -DIST_SUBDIRS = protocol dcc7 resolver connect +SUBDIRS = protocol $(OPTIONAL_TESTS) +DIST_SUBDIRS = protocol resolver connect EXTRA_DIST = config.sample From libgadu-commit at lists.ziew.org Wed Jun 17 00:51:03 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Wed, 17 Jun 2009 00:51:03 +0200 (CEST) Subject: [libgadu-commit] r749 - trunk/src Message-ID: <20090616225103.CAF0F17B45@toxygen.net> Author: wojtekka Date: 2009-06-17 00:51:03 +0200 (Wed, 17 Jun 2009) New Revision: 749 Modified: trunk/src/resolver.c Log: Porz?dna obs?uga gethostbyname_r() na Sunach. Modified: trunk/src/resolver.c =================================================================== --- trunk/src/resolver.c 2009-06-16 21:40:16 UTC (rev 748) +++ trunk/src/resolver.c 2009-06-16 22:51:03 UTC (rev 749) @@ -78,7 +78,7 @@ */ int gg_gethostbyname(const char *hostname, struct in_addr *addr, int pthread) { -#if defined(GG_CONFIG_HAVE_GETHOSTBYNAME_R) && !defined(sun) +#ifdef GG_CONFIG_HAVE_GETHOSTBYNAME_R char *buf = NULL; char *new_buf = NULL; struct hostent he; @@ -105,7 +105,11 @@ #endif if (buf != NULL) { +#ifndef sun while ((ret = gethostbyname_r(hostname, &he, buf, buf_len, &he_ptr, &h_errnop)) == ERANGE) { +#else + while (((he_ptr = gethostbyname_r(hostname, &he, buf, buf_len, &h_errnop)) == NULL) && (errno == ERANGE)) { +#endif buf_len *= 2; #ifdef GG_CONFIG_HAVE_PTHREAD @@ -164,7 +168,7 @@ memcpy(addr, he->h_addr, sizeof(struct in_addr)); return 0; -#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R && !sun */ +#endif /* GG_CONFIG_HAVE_GETHOSTBYNAME_R */ } /** From libgadu-commit at lists.ziew.org Sat Jun 27 17:33:50 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Sat, 27 Jun 2009 17:33:50 +0200 (CEST) Subject: [libgadu-commit] r750 - branches/new-api/src Message-ID: <20090627153350.1EF1817B4E@toxygen.net> Author: wojtekka Date: 2009-06-27 17:33:49 +0200 (Sat, 27 Jun 2009) New Revision: 750 Modified: branches/new-api/src/resolver.c Log: r745+r749 Modified: branches/new-api/src/resolver.c =================================================================== --- branches/new-api/src/resolver.c 2009-06-16 22:51:03 UTC (rev 749) +++ branches/new-api/src/resolver.c 2009-06-27 15:33:49 UTC (rev 750) @@ -40,6 +40,7 @@ #include "libgadu.h" #include "resolver.h" +#include "compat.h" #include "session.h" #ifdef GG_CONFIG_HAVE_PTHREAD @@ -105,7 +106,11 @@ #endif if (buf != NULL) { +#ifndef sun while ((ret = gethostbyname_r(hostname, &he, buf, buf_len, &he_ptr, &h_errnop)) == ERANGE) { +#else + while (((he_ptr = gethostbyname_r(hostname, &he, buf, buf_len, &h_errnop)) == NULL) && (errno == ERANGE)) { +#endif buf_len *= 2; #ifdef GG_CONFIG_HAVE_PTHREAD From libgadu-commit at lists.ziew.org Sat Jun 27 18:57:01 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Sat, 27 Jun 2009 18:57:01 +0200 (CEST) Subject: [libgadu-commit] r751 - branches/new-api/include Message-ID: <20090627165701.B8E4217B4E@toxygen.net> Author: wojtekka Date: 2009-06-27 18:57:01 +0200 (Sat, 27 Jun 2009) New Revision: 751 Modified: branches/new-api/include/libgadu.h.in Log: r722+r724+r735 Modified: branches/new-api/include/libgadu.h.in =================================================================== --- branches/new-api/include/libgadu.h.in 2009-06-27 15:33:49 UTC (rev 750) +++ branches/new-api/include/libgadu.h.in 2009-06-27 16:57:01 UTC (rev 751) @@ -271,6 +271,8 @@ int (*resolver_start)(int *fd, void **private_data, const char *hostname); /**< Funkcja rozpoczynaj?ca rozwi?zywanie nazwy */ void (*resolver_cleanup)(void **private_data, int force); /**< Funkcja zwalniaj?ca zasoby po rozwi?zaniu nazwy */ + int protocol_features; /**< Opcje protoko?u */ + char *status_descr; /**< Aktualny opis statusu */ time_t status_time; /**< Aktualny czas powrotu */ unsigned int max_descr_length; /**< Maksymalna d?ugo?? opisu */ @@ -576,6 +578,7 @@ int hash_type; /**< Rodzaj skr?tu has?a (domy?lnie SHA1) */ int encoding; /**< Rodzaj kodowania u?ywanego w sesji (domy?lnie CP1250) */ gg_resolver_t resolver; /**< Spos?b rozwi?zywania nazw (patrz \ref build-resolver) */ + int protocol_features; /**< Opcje protoko?u (flagi GG_FEATURE_*) */ #ifndef DOXYGEN char dummy[3 * sizeof(int)]; /**< \internal Miejsce na kilka kolejnych @@ -1465,6 +1468,13 @@ #define GG_ERA_OMNIX_MASK 0x04000000 #undef GG_LIBGADU_VERSION +#define GG_FEATURE_STATUS80BETA 0x01 +#define GG_FEATURE_MSG80 0x02 +#define GG_FEATURE_STATUS80 (0x04|GG_FEATURE_STATUS80BETA) +#define GG_FEATURE_DND_FFC 0x30 + +#define GG_FEATURE_ALL (GG_FEATURE_STATUS80BETA|GG_FEATURE_MSG80|GG_FEATURE_STATUS80|GG_FEATURE_DND_FFC) + #define GG_DEFAULT_DCC_PORT 1550 struct gg_header { @@ -1560,10 +1570,14 @@ #define GG_STATUS_NOT_AVAIL 0x0001 #define GG_STATUS_NOT_AVAIL_DESCR 0x0015 +#define GG_STATUS_FFC 0x0017 +#define GG_STATUS_FFC_DESCR 0x0018 #define GG_STATUS_AVAIL 0x0002 #define GG_STATUS_AVAIL_DESCR 0x0004 #define GG_STATUS_BUSY 0x0003 #define GG_STATUS_BUSY_DESCR 0x0005 +#define GG_STATUS_DND 0x0021 +#define GG_STATUS_DND_DESCR 0x0022 #define GG_STATUS_INVISIBLE 0x0014 #define GG_STATUS_INVISIBLE_DESCR 0x0016 #define GG_STATUS_BLOCKED 0x0006 @@ -1580,10 +1594,14 @@ enum { GG_STATUS_NOT_AVAIL, /**< Niedost?pny */ GG_STATUS_NOT_AVAIL_DESCR, /**< Niedost?pny z opisem */ + GG_STATUS_FFC, /**< PoGGadaj ze mn? */ + GG_STATUS_FFC_DESCR, /**< PoGGadaj ze mn? z opisem */ GG_STATUS_AVAIL, /**< Dost?pny */ GG_STATUS_AVAIL_DESCR, /**< Dost?pny z opisem */ GG_STATUS_BUSY, /**< Zaj?ty */ GG_STATUS_BUSY_DESCR, /**< Zaj?ty z opisem */ + GG_STATUS_DND, /**< Nie przeszkadza? */ + GG_STATUS_DND_DESCR, /**< Nie przeszakdza? z opisem */ GG_STATUS_INVISIBLE, /**< Niewidoczny (tylko w?asny status) */ GG_STATUS_INVISIBLE_DESCR, /**< Niewidoczny z opisem (tylko w?asny status) */ GG_STATUS_BLOCKED, /**< Zablokowany (tylko status innych) */ @@ -1608,26 +1626,50 @@ #define GG_STATUS_DESCR_MAXSIZE 0xff #define GG_STATUS_DESCR_MAXSIZE_PRE_8_0 70 +#define GG_STATUS_MASK 0xff + +#define GG_STATUS_MASK 0xff + /* GG_S_F() tryb tylko dla znajomych */ #define GG_S_F(x) (((x) & GG_STATUS_FRIENDS_MASK) != 0) -/* GG_S() stan bez uwzgl?dnienia trybu tylko dla znajomych */ -#define GG_S(x) ((x) & ~GG_STATUS_FRIENDS_MASK) +/* GG_S() stan bez uwzgl?dnienia dodatkowych flag */ +#define GG_S(x) ((x) & GG_STATUS_MASK) -/* GG_S_A() dost?pny */ -#define GG_S_A(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR) +/* GG_S_FF() ch?tny do rozmowy */ +#define GG_S_FF(x) (GG_S(x) == GG_STATUS_FFC || GG_S(x) == GG_STATUS_FFC_DESCR) + +/* GG_S_AV() dost?pny */ +#define GG_S_AV(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR) + +/* GG_S_AW() zaraz wracam */ +#define GG_S_AW(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR) + +/* GG_S_DD() nie przeszkadza? */ +#define GG_S_DD(x) (GG_S(x) == GG_STATUS_DND || GG_S(x) == GG_STATUS_DND_DESCR) + /* GG_S_NA() niedost?pny */ #define GG_S_NA(x) (GG_S(x) == GG_STATUS_NOT_AVAIL || GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR) -/* GG_S_B() zaj?ty */ -#define GG_S_B(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR) - /* GG_S_I() niewidoczny */ #define GG_S_I(x) (GG_S(x) == GG_STATUS_INVISIBLE || GG_S(x) == GG_STATUS_INVISIBLE_DESCR) + +/* GG_S_A() dost?pny lub ch?tny do rozmowy */ +#define GG_S_A(x) (GG_S_FF(x) || GG_S_AV(x)) + +/* GG_S_B() zaj?ty lub nie przeszkadza? */ +#define GG_S_B(x) (GG_S_AW(x) || GG_S_DD(x)) + + /* GG_S_D() stan opisowy */ -#define GG_S_D(x) (GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR || GG_S(x) == GG_STATUS_AVAIL_DESCR || GG_S(x) == GG_STATUS_BUSY_DESCR || GG_S(x) == GG_STATUS_INVISIBLE_DESCR) +#define GG_S_D(x) (GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR || \ + GG_S(x) == GG_STATUS_FFC_DESCR || \ + GG_S(x) == GG_STATUS_AVAIL_DESCR || \ + GG_S(x) == GG_STATUS_BUSY_DESCR || \ + GG_S(x) == GG_STATUS_DND_DESCR || \ + GG_S(x) == GG_STATUS_INVISIBLE_DESCR) /* GG_S_BL() blokowany lub blokuj?cy */ #define GG_S_BL(x) (GG_S(x) == GG_STATUS_BLOCKED) @@ -2029,7 +2071,7 @@ uint32_t type; /* rodzaj transmisji */ unsigned char filename[GG_DCC7_FILENAME_LEN]; /* nazwa pliku */ uint32_t size; /* rozmiar pliku */ - uint32_t dunno1; /* 0x00000000 */ + uint32_t size_hi; /* rozmiar pliku (starsze bajty) */ unsigned char hash[GG_DCC7_HASH_LEN]; /* hash SHA1 */ } GG_PACKED; From libgadu-commit at lists.ziew.org Sat Jun 27 19:45:49 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Sat, 27 Jun 2009 19:45:49 +0200 (CEST) Subject: [libgadu-commit] r752 - branches/new-api/src Message-ID: <20090627174549.A3C3917B4E@toxygen.net> Author: wojtekka Date: 2009-06-27 19:45:49 +0200 (Sat, 27 Jun 2009) New Revision: 752 Modified: branches/new-api/src/events.c branches/new-api/src/session.c Log: Korzystamy z nowych flag ficzer?w. Modified: branches/new-api/src/events.c =================================================================== --- branches/new-api/src/events.c 2009-06-27 16:57:01 UTC (rev 751) +++ branches/new-api/src/events.c 2009-06-27 17:45:49 UTC (rev 752) @@ -1904,7 +1904,7 @@ memcpy(l80.hash, hash_buf, sizeof(l80.hash)); l80.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); l80.dunno1 = 0; - l80.dunno2 = gg_fix32(0x00000007); + l80.dunno2 = gg_fix32(sess->protocol_features); l80.image_size = sess->image_size; l80.dunno3 = 0x64; Modified: branches/new-api/src/session.c =================================================================== --- branches/new-api/src/session.c 2009-06-27 16:57:01 UTC (rev 751) +++ branches/new-api/src/session.c 2009-06-27 17:45:49 UTC (rev 752) @@ -76,6 +76,7 @@ gs->pid = -1; gs->encoding = GG_ENCODING_UTF8; gs->hash_type = GG_LOGIN_HASH_SHA1; + gs->protocol_features = GG_FEATURE_MSG80 | GG_FEATURE_STATUS80; // XXX trzeba jako? to zmienia? gg_session_set_protocol_version(gs, GG_DEFAULT_PROTOCOL_VERSION); From libgadu-commit at lists.ziew.org Sun Jun 28 19:46:37 2009 From: libgadu-commit at lists.ziew.org (Libgadu commit list) Date: Sun, 28 Jun 2009 19:46:37 +0200 (CEST) Subject: [libgadu-commit] r753 - in branches/new-api: include src Message-ID: <20090628174637.DCBD017B58@toxygen.net> Author: darkjames Date: 2009-06-28 19:46:37 +0200 (Sun, 28 Jun 2009) New Revision: 753 Modified: branches/new-api/include/libgadu.h.in branches/new-api/src/events.c Log: - Usuni?cie podw?jnej definicji GG_STATUS_MASK - Poprawka przy obs?udze GG_NOTIFY_REPLY80 i GG_STATUS80 - ca?y uin jest uinem. Modified: branches/new-api/include/libgadu.h.in =================================================================== --- branches/new-api/include/libgadu.h.in 2009-06-27 17:45:49 UTC (rev 752) +++ branches/new-api/include/libgadu.h.in 2009-06-28 17:46:37 UTC (rev 753) @@ -1628,8 +1628,6 @@ #define GG_STATUS_MASK 0xff -#define GG_STATUS_MASK 0xff - /* GG_S_F() tryb tylko dla znajomych */ #define GG_S_F(x) (((x) & GG_STATUS_FRIENDS_MASK) != 0) Modified: branches/new-api/src/events.c =================================================================== --- branches/new-api/src/events.c 2009-06-27 17:45:49 UTC (rev 752) +++ branches/new-api/src/events.c 2009-06-28 17:46:37 UTC (rev 753) @@ -724,7 +724,7 @@ int descr_len; char *tmp; - e->event.notify60[i].uin = uin & 0x00ffffff; + e->event.notify60[i].uin = uin; e->event.notify60[i].status = gg_fix32(n->status); e->event.notify60[i].remote_ip = n->remote_ip; e->event.notify60[i].remote_port = gg_fix16(n->remote_port); @@ -733,14 +733,6 @@ e->event.notify60[i].descr = NULL; e->event.notify60[i].time = 0; -/* - if (uin & 0x40000000) - e->event.notify60[i].version |= GG_HAS_AUDIO_MASK; - if (uin & 0x20000000) - e->event.notify60[i].version |= GG_HAS_AUDIO7_MASK; - if (uin & 0x08000000) - e->event.notify60[i].version |= GG_ERA_OMNIX_MASK; -*/ descr_len = gg_fix32(n->descr_len); if (descr_len != 0) {