òÅÐÏÚÉÔÏÒÉÊ ALT Linux backports/2.4
ðÏÓÌÅÄÎÅÅ ÏÂÎÏ×ÌÅÎÉÅ: 9 ÉÀÌÑ 2008 | ðÁËÅÔÏ×: 497 | ðÏÓÅÝÅÎÉÊ: 1494790
 ÐÏÉÓË   ÒÅÇÉÓÔÒÁÃÉÑ   Á×ÔÏÒÉÚÁÃÉÑ 
 
çÒÕÐÐÁ :: çÒÁÆÉÞÅÓËÉÅ ÏÂÏÌÏÞËÉ/KDE
ðÁËÅÔ: kdenetwork

 çÌÁ×ÎÁÑ   éÚÍÅÎÅÎÉÑ   óÐÅË   ðÁÔÞÉ   úÁÇÒÕÚÉÔØ   Bugs and FR 

ðÁÔÞ: post-3.3.2-kdenetwork-libgadu.patch


Index: kopete/protocols/gadu/libgadu/libgadu.h
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu.h	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/libgadu.h	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -19,7 +19,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #ifndef __GG_LIBGADU_H
@@ -32,15 +33,15 @@
 extern "C" {
 #endif
 
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+	
 #include <libgadu-config.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdarg.h>
 
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
 #ifdef __GG_LIBGADU_HAVE_OPENSSL
 #include <openssl/ssl.h>
 #endif
@@ -56,10 +57,10 @@
  * ogólna struktura opisuj±ca ró¿ne sesje. przydatna w klientach.
  */
 #define gg_common_head(x) \
-        int fd;                 /* podgl±dany deskryptor */ \
-        int check;              /* sprawdzamy zapis czy odczyt */ \
-        int state;              /* aktualny stan maszynki */ \
-        int error;              /* kod b³êdu dla GG_STATE_ERROR */ \
+	int fd;			/* podgl±dany deskryptor */ \
+	int check;		/* sprawdzamy zapis czy odczyt */ \
+	int state;		/* aktualny stan maszynki */ \
+	int error;		/* kod b³êdu dla GG_STATE_ERROR */ \
 	int type;		/* rodzaj sesji */ \
 	int id;			/* identyfikator */ \
 	int timeout;		/* sugerowany timeout w sekundach */ \
@@ -110,7 +111,7 @@
 
 	char *recv_buf;		/* bufor na otrzymywane pakiety */
 	int recv_done;		/* ile ju¿ wczytano do bufora */
-        int recv_left;		/* i ile jeszcze trzeba wczytaæ */
+	int recv_left;		/* i ile jeszcze trzeba wczytaæ */
 
 	int protocol_version;	/* wersja u¿ywanego protoko³u */
 	char *client_version;	/* wersja u¿ywanego klienta */
@@ -149,17 +150,17 @@
 struct gg_http {
 	gg_common_head(struct gg_http)
 
-        int async;              /* czy po³±czenie asynchroniczne */
+	int async;              /* czy po³±czenie asynchroniczne */
 	int pid;                /* pid procesu resolvera */
 	int port;               /* port, z którym siê ³±czymy */
 
-        char *query;            /* bufor zapytania http */
-        char *header;           /* bufor nag³ówka */
-        int header_size;        /* rozmiar wczytanego nag³ówka */
-        char *body;             /* bufor otrzymanych informacji */
-        unsigned int body_size; /* oczekiwana ilo¶æ informacji */
+	char *query;            /* bufor zapytania http */
+	char *header;           /* bufor nag³ówka */
+	int header_size;        /* rozmiar wczytanego nag³ówka */
+	char *body;             /* bufor otrzymanych informacji */
+	unsigned int body_size; /* oczekiwana ilo¶æ informacji */
 
-        void *data;             /* dane danej operacji http */
+	void *data;             /* dane danej operacji http */
 
 	char *user_data;	/* dane u¿ytkownika, nie s± zwalniane przez gg_http_free() */
 
@@ -264,27 +265,27 @@
  * opisuje stan asynchronicznej maszyny.
  */
 enum gg_state_t {
-        /* wspólne */
-        GG_STATE_IDLE = 0,		/* nie powinno wyst±piæ. */
-        GG_STATE_RESOLVING,             /* wywo³a³ gethostbyname() */
+		/* wspólne */
+	GG_STATE_IDLE = 0,		/* nie powinno wyst±piæ. */
+	GG_STATE_RESOLVING,             /* wywo³a³ gethostbyname() */
 	GG_STATE_CONNECTING,            /* wywo³a³ connect() */
 	GG_STATE_READING_DATA,		/* czeka na dane http */
 	GG_STATE_ERROR,			/* wyst±pi³ b³±d. kod w x->error */
 
-        /* gg_session */
+		/* gg_session */
 	GG_STATE_CONNECTING_HUB,	/* wywo³a³ connect() na huba */
 	GG_STATE_CONNECTING_GG,         /* wywo³a³ connect() na serwer */
 	GG_STATE_READING_KEY,           /* czeka na klucz */
 	GG_STATE_READING_REPLY,         /* czeka na odpowied¼ */
 	GG_STATE_CONNECTED,             /* po³±czy³ siê */
 
-        /* gg_http */
+		/* gg_http */
 	GG_STATE_SENDING_QUERY,		/* wysy³a zapytanie http */
 	GG_STATE_READING_HEADER,	/* czeka na nag³ówek http */
 	GG_STATE_PARSING,               /* przetwarza dane */
 	GG_STATE_DONE,                  /* skoñczy³ */
 
-	/* gg_dcc */
+		/* gg_dcc */
 	GG_STATE_LISTENING,		/* czeka na po³±czenia */
 	GG_STATE_READING_UIN_1,		/* czeka na uin peera */
 	GG_STATE_READING_UIN_2,		/* czeka na swój uin */
@@ -349,8 +350,9 @@
 	uint16_t external_port;		/* port widziany na zewnatrz */
 	int tls;			/* czy ³±czymy po TLS? */
 	int image_size;			/* maksymalny rozmiar obrazka w KiB */
+	int era_omnix;			/* czy udawaæ klienta era omnix? */
 
-	char dummy[7 * sizeof(int)];	/* miejsce na kolejnych 8 zmiennych,
+	char dummy[6 * sizeof(int)];	/* miejsce na kolejnych 6 zmiennych,
 					 * ¿eby z dodaniem parametru nie 
 					 * zmienia³ siê rozmiar struktury */
 };
@@ -499,8 +501,8 @@
  */
 struct gg_event {
 	int type;	/* rodzaj zdarzenia -- gg_event_t */
-        union {		/* @event */
-                struct gg_notify_reply *notify;	/* informacje o li¶cie kontaktów -- GG_EVENT_NOTIFY */
+	union {		/* @event */
+		struct gg_notify_reply *notify;	/* informacje o li¶cie kontaktów -- GG_EVENT_NOTIFY */
 
 		enum gg_failure_t failure;	/* b³±d po³±czenia -- GG_EVENT_FAILURE */
 
@@ -521,20 +523,20 @@
 			
 			int formats_length;	/* d³ugo¶æ informacji o formatowaniu tekstu */
 			void *formats;		/* informacje o formatowaniu tekstu */
-                } msg;
+		} msg;
 		
 		struct {			/* @notify_descr informacje o li¶cie kontaktów z opisami stanu -- GG_EVENT_NOTIFY_DESCR */
 			struct gg_notify_reply *notify;	/* informacje o li¶cie kontaktów */
 			char *descr;		/* opis stanu */
 		} notify_descr;
 		
-                struct {			/* @status zmiana stanu -- GG_EVENT_STATUS */
+		struct {			/* @status zmiana stanu -- GG_EVENT_STATUS */
 			uin_t uin;		/* numer */
 			uint32_t status;	/* nowy stan */
 			char *descr;		/* opis stanu */
 		} status;
 
-                struct {			/* @status60 zmiana stanu -- GG_EVENT_STATUS60 */
+		struct {			/* @status60 zmiana stanu -- GG_EVENT_STATUS60 */
 			uin_t uin;		/* numer */
 			int status;	/* nowy stan */
 			uint32_t remote_ip;	/* adres ip */
@@ -747,6 +749,7 @@
 /* przypomnienie has³a e-mailem */
 struct gg_http *gg_remind_passwd(uin_t uin, int async);
 struct gg_http *gg_remind_passwd2(uin_t uin, const char *tokenid, const char *tokenval, int async);
+struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async);
 #define gg_remind_passwd_watch_fd gg_pubdir_watch_fd
 #define gg_remind_passwd_free gg_pubdir_free
 #define gg_free_remind_passwd gg_pubdir_free
@@ -812,6 +815,7 @@
 struct gg_dcc *gg_dcc_voice_chat(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
 void gg_dcc_set_type(struct gg_dcc *d, int type);
 int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename);
+int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename);
 int gg_dcc_voice_send(struct gg_dcc *d, char *buf, int length);
 
 #define GG_DCC_VOICE_FRAME_LENGTH 195
@@ -939,10 +943,11 @@
 #define GG_HTTPS_PORT 443
 #define GG_HTTP_USERAGENT "Mozilla/4.7 [en] (Win98; I)"
 
-#define GG_DEFAULT_CLIENT_VERSION "6, 0, 0, 132"
-#define GG_DEFAULT_PROTOCOL_VERSION 0x20
+#define GG_DEFAULT_CLIENT_VERSION "6, 1, 0, 158"
+#define GG_DEFAULT_PROTOCOL_VERSION 0x24
 #define GG_DEFAULT_TIMEOUT 30
 #define GG_HAS_AUDIO_MASK 0x40000000
+#define GG_ERA_OMNIX_MASK 0x04000000
 #define GG_LIBGADU_VERSION "CVS"
 
 #define GG_DEFAULT_DCC_PORT 1550
@@ -1204,8 +1209,10 @@
 
 #define GG_SEND_MSG_ACK 0x0005
 
+#define GG_ACK_BLOCKED 0x0001
 #define GG_ACK_DELIVERED 0x0002
 #define GG_ACK_QUEUED 0x0003
+#define GG_ACK_MBOXFULL 0x0004
 #define GG_ACK_NOT_DELIVERED 0x0006
 	
 struct gg_send_msg_ack {
Index: kopete/protocols/gadu/libgadu/http.c
===================================================================
--- kopete/protocols/gadu/libgadu/http.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/http.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -14,7 +14,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <sys/types.h>
@@ -60,19 +61,19 @@
 	struct gg_http *h;
 
 	if (!hostname || !port || !method || !path || !header) {
-                gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n");
-		errno = EINVAL;
+		gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n");
+		errno = EFAULT;
 		return NULL;
 	}
 	
 	if (!(h = malloc(sizeof(*h))))
-                return NULL;        
+		return NULL;
 	memset(h, 0, sizeof(*h));
 
 	h->async = async;
 	h->port = port;
 	h->fd = -1;
-        h->type = GG_SESSION_HTTP;
+	h->type = GG_SESSION_HTTP;
 
 	if (gg_proxy_enabled) {
 		char *auth = gg_proxy_auth();
@@ -91,9 +92,9 @@
 	}
 
 	if (!h->query) {
-                gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n");
+		gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n");
 		free(h);
-                errno = ENOMEM;
+		errno = ENOMEM;
 		return NULL;
 	}
 	
@@ -105,9 +106,9 @@
 #else
 		if (gg_resolve_pthread(&h->fd, &h->resolver, hostname)) {
 #endif
-                        gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n");
+			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n");
 			gg_http_free(h);
-                        errno = ENOENT;
+			errno = ENOENT;
 			return NULL;
 		}
 
@@ -130,7 +131,7 @@
 		}
 
 		if (!(h->fd = gg_connect(&a, port, 0)) == -1) {
-                        gg_debug(GG_DEBUG_MISC, "// gg_http_connect() connection failed (errno=%d, %s)\n", errno, strerror(errno));
+			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() connection failed (errno=%d, %s)\n", errno, strerror(errno));
 			gg_http_free(h);
 			return NULL;
 		}
@@ -143,7 +144,7 @@
 		}
 
 		if (h->state != GG_STATE_PARSING) {
-                        gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n");
+			gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n");
 			gg_http_free(h);
 			return NULL;
 		}
@@ -180,7 +181,7 @@
 
 	if (!h) {
 		gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -242,7 +243,7 @@
 	}
 
 	if (h->state == GG_STATE_SENDING_QUERY) {
-		unsigned int res;
+		int res;
 
 		if ((res = write(h->fd, h->query, strlen(h->query))) < 1) {
 			gg_debug(GG_DEBUG_MISC, "=> http, write() failed (len=%d, res=%d, errno=%d)\n", strlen(h->query), res, errno);
@@ -271,7 +272,7 @@
 
 	if (h->state == GG_STATE_READING_HEADER) {
 		char buf[1024], *tmp;
-		unsigned int res;
+		int res;
 
 		if ((res = read(h->fd, buf, sizeof(buf))) == -1) {
 			gg_debug(GG_DEBUG_MISC, "=> http, reading header failed (errno=%d)\n", errno);
@@ -320,7 +321,7 @@
 
 			/* HTTP/1.1 200 OK */
 			if (strlen(h->header) < 16 || strncmp(h->header + 9, "200", 3)) {
-			        gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header);
+				gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header);
 
 				gg_debug(GG_DEBUG_MISC, "=> http, didn't get 200 OK -- no results\n");
 				free(h->header);
@@ -379,7 +380,7 @@
 
 	if (h->state == GG_STATE_READING_DATA) {
 		char buf[1024];
-		unsigned int res;
+		int res;
 
 		if ((res = read(h->fd, buf, sizeof(buf))) == -1) {
 			gg_debug(GG_DEBUG_MISC, "=> http, reading body failed (errno=%d)\n", errno);
@@ -464,7 +465,7 @@
 
 	if (h->fd != -1)
 		close(h->fd);
-        h->fd = -1;
+	h->fd = -1;
 }
 
 /*
Index: kopete/protocols/gadu/libgadu/events.c
===================================================================
--- kopete/protocols/gadu/libgadu/events.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/events.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -16,7 +16,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <sys/types.h>
@@ -132,7 +133,7 @@
 int gg_image_queue_remove(struct gg_session *s, struct gg_image_queue *q, int freeq)
 {
 	if (!s || !q) {
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -166,13 +167,15 @@
  *  - e - opis zdarzenia
  *  - 
  */
-static void gg_image_queue_parse(struct gg_event *e, char *p, int len, struct gg_session *sess, uin_t sender)
+static void gg_image_queue_parse(struct gg_event *e, char *p, unsigned int len, struct gg_session *sess, uin_t sender)
 {
 	struct gg_msg_image_reply *i = (void*) p;
 	struct gg_image_queue *q, *qq;
 
-	if (!p || !sess || !e)
+	if (!p || !sess || !e) {
+		errno = EFAULT;
 		return;
+	}
 
 	/* znajd¼ dany obrazek w kolejce danej sesji */
 	
@@ -298,19 +301,21 @@
 
 				count = gg_fix32(m->count);
 
-				if (p + count * sizeof(uin_t) > packet_end) {
+				if (p + count * sizeof(uin_t) > packet_end || p + count * sizeof(uin_t) < p || count > 0xffff) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (1.5)\n");
 					goto malformed;
 				}
 			
 				if (!(e->event.msg.recipients = (void*) malloc(count * sizeof(uin_t)))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() not enough memory for recipients data\n");
-					errno = ENOMEM;
 					goto fail;
 				}
 			
-				for (i = 0; i < count; i++, p += sizeof(uin_t))
-					e->event.msg.recipients[i] = gg_fix32(*((uint32_t*) p));
+				for (i = 0; i < count; i++, p += sizeof(uint32_t)) {
+					uint32_t u;
+					memcpy(&u, p, sizeof(uint32_t));
+					e->event.msg.recipients[i] = gg_fix32(u);
+				}
 				
 				e->event.msg.recipients_count = count;
 				
@@ -319,7 +324,7 @@
 
 			case 0x02:		/* richtext */
 			{
-				unsigned short len;
+				uint16_t len;
 				char *buf;
 			
 				if (p + 3 > packet_end) {
@@ -327,11 +332,11 @@
 					goto malformed;
 				}
 
-				len = gg_fix16(*((unsigned short*) (p + 1)));
+				memcpy(&len, p + 1, sizeof(uint16_t));
+				len = gg_fix16(len);
 
 				if (!(buf = malloc(len))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() not enough memory for richtext data\n");
-					errno = ENOMEM;
 					goto fail;
 				}
 
@@ -374,12 +379,29 @@
 			case 0x05:		/* image_reply */
 			case 0x06:
 			{
-				if (p + sizeof(struct gg_msg_image_reply) + 1 > packet_end) {
+				struct gg_msg_image_reply *rep = (void*) p;
+
+				if (p + sizeof(struct gg_msg_image_reply) == packet_end) {
+
+					/* pusta odpowied¼ - klient po drugiej stronie nie ma ¿±danego obrazka */
+
+					e->type = GG_EVENT_IMAGE_REPLY;
+					e->event.image_reply.sender = gg_fix32(r->sender);
+					e->event.image_reply.size = 0;
+					e->event.image_reply.crc32 = gg_fix32(rep->crc32);
+					e->event.image_reply.filename = NULL;
+					e->event.image_reply.image = NULL;
+					return 0;
+
+				} else if (p + sizeof(struct gg_msg_image_reply) + 1 > packet_end) {
+
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (4)\n");
 					goto malformed;
 				}
 
-				gg_image_queue_parse(e, p, (int)(packet_end - p), sess, gg_fix32(r->sender));
+				rep->size = gg_fix32(rep->size);
+				rep->crc32 = gg_fix32(rep->crc32);
+				gg_image_queue_parse(e, p, (unsigned int)(packet_end - p), sess, gg_fix32(r->sender));
 
 				return 0;
 			}
@@ -456,7 +478,7 @@
 		case GG_NOTIFY_REPLY:
 		{
 			struct gg_notify_reply *n = (void*) p;
-			int count, i;
+			unsigned int count, i;
 			char *tmp;
 
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
@@ -467,24 +489,23 @@
 				goto fail;
 			}
 
-			if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR || gg_fix32(n->status == GG_STATUS_NOT_AVAIL_DESCR) || gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR) {
+			if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR || gg_fix32(n->status) == GG_STATUS_NOT_AVAIL_DESCR || gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR) {
 				e->type = GG_EVENT_NOTIFY_DESCR;
 				
 				if (!(e->event.notify_descr.notify = (void*) malloc(sizeof(*n) * 2))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
-					errno = ENOMEM;
 					goto fail;
 				}
 				e->event.notify_descr.notify[1].uin = 0;
 				memcpy(e->event.notify_descr.notify, p, sizeof(*n));
 				e->event.notify_descr.notify[0].uin = gg_fix32(e->event.notify_descr.notify[0].uin);
 				e->event.notify_descr.notify[0].status = gg_fix32(e->event.notify_descr.notify[0].status);
+				e->event.notify_descr.notify[0].remote_ip = e->event.notify_descr.notify[0].remote_ip;
 				e->event.notify_descr.notify[0].remote_port = gg_fix16(e->event.notify_descr.notify[0].remote_port);
 
 				count = h->length - sizeof(*n);
 				if (!(tmp = malloc(count + 1))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
-					errno = ENOMEM;
 					goto fail;
 				}
 				memcpy(tmp, p + sizeof(*n), count);
@@ -496,7 +517,6 @@
 				
 				if (!(e->event.notify = (void*) malloc(h->length + 2 * sizeof(*n)))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
-					errno = ENOMEM;
 					goto fail;
 				}
 				
@@ -507,7 +527,8 @@
 				for (i = 0; i < count; i++) {
 					e->event.notify[i].uin = gg_fix32(e->event.notify[i].uin);
 					e->event.notify[i].status = gg_fix32(e->event.notify[i].status);
-					e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);		
+					e->event.notify[i].remote_ip = e->event.notify[i].remote_ip;
+					e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);
 				}
 			}
 
@@ -570,6 +591,11 @@
 				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 & 0x08000000)
+					e->event.notify60[i].version |= GG_ERA_OMNIX_MASK;
+
 				if (GG_S_D(n->status)) {
 					unsigned char descr_len = *((char*) n + sizeof(struct gg_notify_reply60));
 
@@ -629,6 +655,8 @@
 
 			if (uin & 0x40000000)
 				e->event.status60.version |= GG_HAS_AUDIO_MASK;
+			if (uin & 0x08000000)
+				e->event.status60.version |= GG_ERA_OMNIX_MASK;
 
 			if (h->length > sizeof(*s)) {
 				int len = h->length - sizeof(*s);
@@ -641,8 +669,11 @@
 
 				e->event.status60.descr = buf;
 
-				if (len > 4 && p[h->length - 5] == 0)
-					e->event.status60.time = *((int*) (p + h->length - 4));
+				if (len > 4 && p[h->length - 5] == 0) {
+					uint32_t t;
+					memcpy(&t, p + h->length - 4, sizeof(uint32_t));
+					e->event.status60.time = gg_fix32(t);
+				}
 			}
 
 			break;
@@ -708,7 +739,7 @@
 
 			if (h->length > 1) {
 				char *tmp;
-				int len = (sess->userlist_reply) ? strlen(sess->userlist_reply) : 0;
+				unsigned int len = (sess->userlist_reply) ? strlen(sess->userlist_reply) : 0;
 				
 				gg_debug(GG_DEBUG_MISC, "userlist_reply=%p, len=%d\n", sess->userlist_reply, len);
 				
@@ -766,6 +797,7 @@
 	struct gg_event *e;
 	int res = 0;
 	int port = 0;
+	int errno2 = 0;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(%p);\n", sess);
 	
@@ -792,6 +824,7 @@
 			if (read(sess->fd, &addr, sizeof(addr)) < (signed)sizeof(addr) || addr.s_addr == INADDR_NONE) {
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() resolving failed\n");
 				failed = 1;
+				errno2 = errno;
 			}
 			
 			close(sess->fd);
@@ -808,8 +841,10 @@
 			}
 #endif
 
-			if (failed)
+			if (failed) {
+				errno = errno2;
 				goto fail_resolving;
+			}
 
 			/* je¶li jeste¶my w resolverze i mamy ustawiony port
 			 * proxy, znaczy, ¿e resolvowali¶my proxy. zatem
@@ -924,7 +959,7 @@
 				sess->client_version = NULL;
 			}
 
-    			gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf);
+			gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf);
 	 
 			/* zapytanie jest krótkie, wiêc zawsze zmie¶ci siê
 			 * do bufora gniazda. je¶li write() zwróci mniej,
@@ -1056,7 +1091,7 @@
 
 			if ((tmp = strchr(host, ':'))) {
 				*tmp = 0;
-				port = atoi(tmp+1);
+				port = atoi(tmp + 1);
 			}
 
 			addr.s_addr = inet_addr(host);
@@ -1155,9 +1190,15 @@
 			/* je¶li mamy proxy, wy¶lijmy zapytanie. */
 			if (sess->proxy_addr && sess->proxy_port) {
 				char buf[100], *auth = gg_proxy_auth();
+				struct in_addr addr;
 
-				snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n", inet_ntoa(*((struct in_addr*) &sess->server_addr)), sess->port);
+				if (sess->server_addr)
+					addr.s_addr = sess->server_addr;
+				else
+					addr.s_addr = sess->hub_addr;
 
+				snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n", inet_ntoa(addr), sess->port);
+
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() proxy request:\n//   %s", buf);
 				
 				/* wysy³amy zapytanie. jest ono na tyle krótkie,
@@ -1326,7 +1367,9 @@
 				e->type = GG_EVENT_CONN_FAILED;
 				e->event.failure = GG_FAILURE_READING;
 				sess->state = GG_STATE_IDLE;
+				errno2 = errno;
 				close(sess->fd);
+				errno = errno2;
 				sess->fd = -1;
 				break;
 			}
@@ -1355,7 +1398,11 @@
 			free(sess->password);
 			sess->password = NULL;
 
-			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() gg_dcc_ip = %s\n", inet_ntoa(*((struct in_addr*) &gg_dcc_ip)));
+			{
+				struct in_addr dcc_ip;
+				dcc_ip.s_addr = gg_dcc_ip;
+				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() gg_dcc_ip = %s\n", inet_ntoa(dcc_ip));
+			}
 			
 			if (gg_dcc_ip == (unsigned long) inet_addr("255.255.255.255")) {
 				struct sockaddr_in sin;
@@ -1382,7 +1429,7 @@
 			
 			if (sess->external_addr && sess->external_port > 1023) {
 				l.external_ip = sess->external_addr;
-				l.external_port = sess->external_port;
+				l.external_port = gg_fix16(sess->external_port);
 			}
 
 			gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN60 packet\n");
@@ -1393,8 +1440,9 @@
 
 			if (ret == -1) {
 				gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending packet failed. (errno=%d, %s)\n", errno, strerror(errno));
-
+				errno2 = errno;
 				close(sess->fd);
+				errno = errno2;
 				sess->fd = -1;
 				e->type = GG_EVENT_CONN_FAILED;
 				e->event.failure = GG_FAILURE_WRITING;
@@ -1418,7 +1466,9 @@
 				e->type = GG_EVENT_CONN_FAILED;
 				e->event.failure = GG_FAILURE_READING;
 				sess->state = GG_STATE_IDLE;
+				errno2 = errno;
 				close(sess->fd);
+				errno = errno2;
 				sess->fd = -1;
 				break;
 			}
@@ -1449,7 +1499,9 @@
 
 			e->type = GG_EVENT_CONN_FAILED;
 			sess->state = GG_STATE_IDLE;
+			errno2 = errno;
 			close(sess->fd);
+			errno = errno2;
 			sess->fd = -1;
 			free(h);
 
@@ -1486,7 +1538,9 @@
 	
 fail_connecting:
 	if (sess->fd != -1) {
+		errno2 = errno;
 		close(sess->fd);
+		errno = errno2;
 		sess->fd = -1;
 	}
 	e->type = GG_EVENT_CONN_FAILED;
Index: kopete/protocols/gadu/libgadu/pubdir.c
===================================================================
--- kopete/protocols/gadu/libgadu/pubdir.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/pubdir.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -15,7 +15,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <ctype.h>
@@ -45,12 +46,12 @@
  */
 struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async)
 {
-        struct gg_http *h;
+	struct gg_http *h;
 	char *__pwd, *__email, *__tokenid, *__tokenval, *form, *query;
 
-	if (!email | !password | !tokenid | !tokenval) {
+	if (!email || !password || !tokenid || !tokenval) {
 		gg_debug(GG_DEBUG_MISC, "=> register, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
 
@@ -65,7 +66,6 @@
 		free(__email);
 		free(__tokenid);
 		free(__tokenval);
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -80,7 +80,6 @@
 
 	if (!form) {
 		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n");
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -98,10 +97,15 @@
 
 	free(form);
 
+	if (!query) {
+		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for query\n");
+		return NULL;
+	}
+
 	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
 		gg_debug(GG_DEBUG_MISC, "=> register, gg_http_connect() failed mysteriously\n");
 		free(query);
-                return NULL;
+		return NULL;
 	}
 
 	h->type = GG_SESSION_REGISTER;
@@ -138,7 +142,7 @@
 
 	if (!password || !tokenid || !tokenval) {
 		gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
     
@@ -153,7 +157,6 @@
 		free(__fmpwd);
 		free(__tokenid);
 		free(__tokenval);
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -166,7 +169,6 @@
 
 	if (!form) {
 		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n");
-		errno = ENOMEM;
 		return NULL;
 	}
 
@@ -184,6 +186,11 @@
 
 	free(form);
 
+	if (!query) {
+		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for query\n");
+		return NULL;
+	}
+
 	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
 		gg_debug(GG_DEBUG_MISC, "=> unregister, gg_http_connect() failed mysteriously\n");
 		free(query);
@@ -227,7 +234,7 @@
 
 	if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) {
 		gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
 	
@@ -244,7 +251,6 @@
 		free(__email);
 		free(__tokenid);
 		free(__tokenval);
-		errno = ENOMEM;
 		return NULL;
 	}
 	
@@ -256,7 +262,6 @@
 		free(__tokenid);
 		free(__tokenval);
 
-		errno = ENOMEM;
 		return NULL;
 	}
 	
@@ -268,21 +273,26 @@
 	
 	gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form);
 
-        query = gg_saprintf(
+	query = gg_saprintf(
 		"Host: " GG_REGISTER_HOST "\r\n"
-                "Content-Type: application/x-www-form-urlencoded\r\n"
-                "User-Agent: " GG_HTTP_USERAGENT "\r\n"
-                "Content-Length: %d\r\n"
-                "Pragma: no-cache\r\n"
-                "\r\n"
-                "%s",
-                (int) strlen(form), form);
+		"Content-Type: application/x-www-form-urlencoded\r\n"
+		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
+		"Content-Length: %d\r\n"
+		"Pragma: no-cache\r\n"
+		"\r\n"
+		"%s",
+		(int) strlen(form), form);
 
 	free(form);
 
+	if (!query) {
+		gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for query\n");
+		return NULL;
+	}
+
 	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
 		gg_debug(GG_DEBUG_MISC, "=> change, gg_http_connect() failed mysteriously\n");
-                free(query);
+		free(query);
 		return NULL;
 	}
 
@@ -300,11 +310,12 @@
 }
 
 /*
- * gg_remind_passwd()
+ * gg_remind_passwd3()
  *
  * wysy³a ¿±danie przypomnienia has³a e-mailem.
  *
  *  - uin - numer
+ *  - email - adres e-mail taki, jak ten zapisany na serwerze
  *  - async - po³±czenie asynchroniczne
  *  - tokenid - identyfikator tokenu
  *  - tokenval - warto¶æ tokenu
@@ -312,56 +323,63 @@
  * zaalokowana struct gg_http, któr± po¼niej nale¿y zwolniæ
  * funkcj± gg_remind_passwd_free(), albo NULL je¶li wyst±pi³ b³±d.
  */
-struct gg_http *gg_remind_passwd2(uin_t uin, const char *tokenid, const char *tokenval, int async)
+struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async)
 {
 	struct gg_http *h;
-	char *form, *query, *__tokenid, *__tokenval;
+	char *form, *query, *__tokenid, *__tokenval, *__email;
 
-	if (!tokenid || !tokenval) {
+	if (!tokenid || !tokenval || !email) {
 		gg_debug(GG_DEBUG_MISC, "=> remind, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
 	
 	__tokenid = gg_urlencode(tokenid);
 	__tokenval = gg_urlencode(tokenval);
+	__email = gg_urlencode(email);
 
-	if (!__tokenid || !__tokenval) {
+	if (!__tokenid || !__tokenval || !__email) {
 		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
 		free(__tokenid);
 		free(__tokenval);
-		errno = ENOMEM;
+		free(__email);
 		return NULL;
 	}
 
-	if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval))) {
+	if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s&email=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval, __email))) {
 		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
-		errno = ENOMEM;
 		free(__tokenid);
 		free(__tokenval);
+		free(__email);
 		return NULL;
 	}
 
 	free(__tokenid);
 	free(__tokenval);
+	free(__email);
 	
 	gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form);
 
-        query = gg_saprintf(
+	query = gg_saprintf(
 		"Host: " GG_REMIND_HOST "\r\n"
-                "Content-Type: application/x-www-form-urlencoded\r\n"
-                "User-Agent: " GG_HTTP_USERAGENT "\r\n"
-                "Content-Length: %d\r\n"
-                "Pragma: no-cache\r\n"
-                "\r\n"
-                "%s",
-                (int) strlen(form), form);
+		"Content-Type: application/x-www-form-urlencoded\r\n"
+		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
+		"Content-Length: %d\r\n"
+		"Pragma: no-cache\r\n"
+		"\r\n"
+		"%s",
+		(int) strlen(form), form);
 
 	free(form);
 
+	if (!query) {
+		gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for query\n");
+		return NULL;
+	}
+
 	if (!(h = gg_http_connect(GG_REMIND_HOST, GG_REMIND_PORT, async, "POST", "/appsvc/fmsendpwd3.asp", query))) {
 		gg_debug(GG_DEBUG_MISC, "=> remind, gg_http_connect() failed mysteriously\n");
-                free(query);
+		free(query);
 		return NULL;
 	}
 
@@ -396,33 +414,34 @@
 	char *tmp;
 
 	if (!h) {
+		errno = EFAULT;
+		return -1;
+	}
+
+	if (h->state == GG_STATE_ERROR) {
+		gg_debug(GG_DEBUG_MISC, "=> pubdir, watch_fd issued on failed session\n");
 		errno = EINVAL;
 		return -1;
 	}
-
-        if (h->state == GG_STATE_ERROR) {
-                gg_debug(GG_DEBUG_MISC, "=> pubdir, watch_fd issued on failed session\n");
-                errno = EINVAL;
-                return -1;
-        }
 	
 	if (h->state != GG_STATE_PARSING) {
 		if (gg_http_watch_fd(h) == -1) {
 			gg_debug(GG_DEBUG_MISC, "=> pubdir, http failure\n");
-                        errno = EINVAL;
+			errno = EINVAL;
 			return -1;
 		}
 	}
 
 	if (h->state != GG_STATE_PARSING)
-                return 0;
+		return 0;
 	
-        h->state = GG_STATE_DONE;
+	h->state = GG_STATE_DONE;
 	
 	if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) {
 		gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n");
 		return -1;
 	}
+
 	p->success = 0;
 	p->uin = 0;
 	
@@ -507,33 +526,34 @@
 int gg_token_watch_fd(struct gg_http *h)
 {
 	if (!h) {
+		errno = EFAULT;
+		return -1;
+	}
+
+	if (h->state == GG_STATE_ERROR) {
+		gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
 		errno = EINVAL;
 		return -1;
 	}
-
-        if (h->state == GG_STATE_ERROR) {
-                gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
-                errno = EINVAL;
-                return -1;
-        }
 	
 	if (h->state != GG_STATE_PARSING) {
 		if (gg_http_watch_fd(h) == -1) {
 			gg_debug(GG_DEBUG_MISC, "=> token, http failure\n");
-                        errno = EINVAL;
+			errno = EINVAL;
 			return -1;
 		}
 	}
 
 	if (h->state != GG_STATE_PARSING)
-                return 0;
+		return 0;
 	
 	/* je¶li h->data jest puste, to ¶ci±gali¶my tokenid i url do niego,
 	 * ale je¶li co¶ tam jest, to znaczy, ¿e mamy drugi etap polegaj±cy
 	 * na pobieraniu tokenu. */
 	if (!h->data) {
 		int width, height, length;
-		char *url = NULL, *tokenid = NULL, *path;
+		char *url = NULL, *tokenid = NULL, *path, *headers;
+		const char *host;
 		struct gg_http *h2;
 		struct gg_token *t;
 
@@ -549,29 +569,59 @@
 			gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
 			free(url);
 			free(tokenid);
+			errno = EINVAL;
 			return -1;
 		}
 		
 		/* dostali¶my tokenid i wszystkie niezbêdne informacje,
 		 * wiêc pobierzmy obrazek z tokenem */
 
-		if (!(path = gg_saprintf("%s?tokenid=%s", url, tokenid))) {
+		if (strncmp(url, "http://", 7)) {
+			path = gg_saprintf("%s?tokenid=%s", url, tokenid);
+			host = GG_REGISTER_HOST;
+		} else {
+			char *slash = strchr(url + 7, '/');
+
+			if (slash) {
+				path = gg_saprintf("%s?tokenid=%s", slash, tokenid);
+				*slash = 0;
+				host = url + 7;
+			} else {
+				gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n");
+				free(url);
+				free(tokenid);
+				errno = EINVAL;
+				return -1;
+			}
+		}
+
+		if (!path) {
 			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
 			free(url);
 			free(tokenid);
 			return -1;
 		}
 
-		free(url);
-	
-		if (!(h2 = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, h->async, "GET", path, "Host: " GG_REGISTER_HOST "\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n"))) {
+		if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) {
+			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
+			free(path);
+			free(url);
+			free(tokenid);
+			return -1;
+		}			
+
+		if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) {
 			gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
+			free(headers);
+			free(url);
 			free(path);
 			free(tokenid);
 			return -1;
 		}
 
+		free(headers);
 		free(path);
+		free(url);
 
 		memcpy(h, h2, sizeof(struct gg_http));
 		free(h2);
Index: kopete/protocols/gadu/libgadu/libgadu.c
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/libgadu.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -17,7 +17,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <sys/types.h>
@@ -106,9 +107,9 @@
 #else
 	return (uint32_t)
 		(((x & (uint32_t) 0x000000ffU) << 24) |
-                 ((x & (uint32_t) 0x0000ff00U) << 8) |
-                 ((x & (uint32_t) 0x00ff0000U) >> 8) |
-                 ((x & (uint32_t) 0xff000000U) >> 24));
+		((x & (uint32_t) 0x0000ff00U) << 8) |
+		((x & (uint32_t) 0x00ff0000U) >> 8) |
+		((x & (uint32_t) 0xff000000U) >> 24));
 #endif		
 }
 
@@ -130,7 +131,7 @@
 #else
 	return (uint16_t)
 		(((x & (uint16_t) 0x00ffU) << 8) |
-                 ((x & (uint16_t) 0xff00U) >> 8));
+		((x & (uint16_t) 0xff00U) >> 8));
 #endif
 }
 
@@ -186,6 +187,7 @@
 {
 	int pipes[2], res;
 	struct in_addr a;
+	int errno2;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve(%p, %p, \"%s\");\n", fd, pid, hostname);
 	
@@ -198,8 +200,10 @@
 		return -1;
 
 	if ((res = fork()) == -1) {
+		errno2 = errno;
 		close(pipes[0]);
 		close(pipes[1]);
+		errno = errno2;
 		return -1;
 	}
 
@@ -240,6 +244,8 @@
 	struct gg_resolve_pthread_data *d = arg;
 	struct in_addr a;
 
+	pthread_detach(pthread_self());
+
 	if ((a.s_addr = inet_addr(d->hostname)) == INADDR_NONE) {
 		struct in_addr *hn;
 		
@@ -294,7 +300,6 @@
 
 	if (!(tmp = malloc(sizeof(pthread_t)))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory for pthread id\n");
-		errno = ENOMEM;
 		return -1;
 	}
 	
@@ -306,7 +311,7 @@
 
 	if (!(d = malloc(sizeof(*d)))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
-		new_errno = ENOMEM;
+		new_errno = errno;
 		goto cleanup;
 	}
 	
@@ -314,7 +319,7 @@
 
 	if (!(d->hostname = strdup(hostname))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
-		new_errno = ENOMEM;
+		new_errno = errno;
 		goto cleanup;
 	}
 
@@ -403,7 +408,7 @@
  */
 int gg_write(struct gg_session *sess, const char *buf, int length)
 {
-	int res;
+	int res = 0;
 
 #ifdef __GG_LIBGADU_HAVE_OPENSSL
 	if (sess->ssl) {
@@ -450,13 +455,16 @@
  *
  *  - sess - opis sesji
  *
- * w przypadku b³êdu NULL, kod b³êdu w errno.
+ * w przypadku b³êdu NULL, kod b³êdu w errno. nale¿y zwróciæ uwagê, ¿e gdy
+ * po³±czenie jest nieblokuj±ce, a kod b³êdu wynosi EAGAIN, nie uda³o siê
+ * odczytaæ ca³ego pakietu i nie nale¿y tego traktowaæ jako b³±d.
  */
 void *gg_recv_packet(struct gg_session *sess)
 {
 	struct gg_header h;
 	char *buf = NULL;
-	int ret = 0, offset, size = 0;
+	int ret = 0;
+	unsigned int offset, size = 0;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess);
 	
@@ -480,7 +488,7 @@
 			gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv(%d,%p,%d) = %d\n", sess->fd, &h + sess->header_done, sizeof(h) - sess->header_done, ret);
 
 			if (!ret) {
-				errno = 0;
+				errno = ECONNRESET;
 				gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() failed: connection broken\n");
 				return NULL;
 			}
@@ -519,7 +527,7 @@
 		memcpy(&h, sess->recv_buf, sizeof(h));
 	
 	/* jakie¶ sensowne limity na rozmiar pakietu */
-	if (h.length < 0 || h.length > 65535) {
+	if (h.length > 65535) {
 		gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() invalid packet length (%d)\n", h.length);
 		errno = ERANGE;
 		return NULL;
@@ -545,11 +553,20 @@
 	while (size > 0) {
 		ret = gg_read(sess, buf + sizeof(h) + offset, size);
 		gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv(%d,%p,%d) = %d\n", sess->fd, buf + sizeof(h) + offset, size, ret);
+		if (!ret) {
+			gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv() failed: connection broken\n");
+			errno = ECONNRESET;
+			return NULL;
+		}
 		if (ret > -1 && ret <= size) {
 			offset += ret;
 			size -= ret;
 		} else if (ret == -1) {	
+			int errno2 = errno;
+
 			gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv() failed (errno=%d, %s)\n", errno, strerror(errno));
+			errno = errno2;
+
 			if (errno == EAGAIN) {
 				gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() %d bytes received, %d left\n", offset, size);
 				sess->recv_buf = buf;
@@ -600,25 +617,21 @@
 {
 	struct gg_header *h;
 	char *tmp;
-	int tmp_length;
+	unsigned int tmp_length;
 	void *payload;
-	int payload_length;
+	unsigned int payload_length;
 	va_list ap;
 	int res;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_send_packet(%p, 0x%.2x, ...)\n", sess, type);
 
-	tmp_length = 0;
+	tmp_length = sizeof(struct gg_header);
 
-	if (!(tmp = malloc(sizeof(struct gg_header)))) {
+	if (!(tmp = malloc(tmp_length))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for packet header\n");
 		return -1;
 	}
 
-	h = (struct gg_header*) tmp;
-	h->type = gg_fix32(type);
-	h->length = gg_fix32(0);
-
 	va_start(ap, type);
 
 	payload = va_arg(ap, void *);
@@ -626,21 +639,18 @@
 	while (payload) {
 		char *tmp2;
 
-		payload_length = va_arg(ap, int);
+		payload_length = va_arg(ap, unsigned int);
 
-		if (payload_length < 0)
-			gg_debug(GG_DEBUG_MISC, "// gg_send_packet() invalid payload length (%d)\n", payload_length);
-	
-		if (!(tmp2 = realloc(tmp, sizeof(struct gg_header) + tmp_length + payload_length))) {
-                        gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n");
+		if (!(tmp2 = realloc(tmp, tmp_length + payload_length))) {
+			gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n");
 			free(tmp);
 			va_end(ap);
-                        return -1;
-                }
+			return -1;
+		}
 
 		tmp = tmp2;
 		
-		memcpy(tmp + sizeof(struct gg_header) + tmp_length, payload, payload_length);
+		memcpy(tmp + tmp_length, payload, payload_length);
 		tmp_length += payload_length;
 
 		payload = va_arg(ap, void *);
@@ -649,19 +659,18 @@
 	va_end(ap);
 
 	h = (struct gg_header*) tmp;
-	h->length = gg_fix32(tmp_length);
+	h->type = gg_fix32(type);
+	h->length = gg_fix32(tmp_length - sizeof(struct gg_header));
 
 	if ((gg_debug_level & GG_DEBUG_DUMP)) {
-                unsigned int i;
-		
-                gg_debug(GG_DEBUG_DUMP, "// gg_send_packet(0x%.2x)", gg_fix32(h->type));
-                for (i = 0; i < sizeof(struct gg_header) + gg_fix32(h->length); i++)
-                        gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) tmp[i]);
-                gg_debug(GG_DEBUG_DUMP, "\n");
-        }
+		unsigned int i;
+
+		gg_debug(GG_DEBUG_DUMP, "// gg_send_packet(0x%.2x)", gg_fix32(h->type));
+		for (i = 0; i < tmp_length; ++i)
+			gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) tmp[i]);
+		gg_debug(GG_DEBUG_DUMP, "\n");
+	}
 	
-	tmp_length += sizeof(struct gg_header);
-	
 	if ((res = gg_write(sess, tmp, tmp_length)) < tmp_length) {
 		gg_debug(GG_DEBUG_MISC, "// gg_send_packet() write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno));
 		free(tmp);
@@ -681,7 +690,7 @@
 static int gg_session_callback(struct gg_session *s)
 {
 	if (!s) {
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -711,7 +720,7 @@
 
 	if (!p) {
 		gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p);\n", p);
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
 
@@ -726,7 +735,7 @@
 
 	if (!p->password || !p->uin) {
 		gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. uin and password needed\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		goto fail;
 	}
 
@@ -745,7 +754,7 @@
 	sess->check = GG_CHECK_READ;
 	sess->timeout = GG_DEFAULT_TIMEOUT;
 	sess->async = p->async;
-        sess->type = GG_SESSION_GG;
+	sess->type = GG_SESSION_GG;
 	sess->initial_status = p->status;
 	sess->callback = gg_session_callback;
 	sess->destroy = gg_free_session;
@@ -754,6 +763,8 @@
 	sess->external_port = p->external_port;
 	sess->external_addr = p->external_addr;
 	sess->protocol_version = (p->protocol_version) ? p->protocol_version : GG_DEFAULT_PROTOCOL_VERSION;
+	if (p->era_omnix)
+		sess->protocol_version |= GG_ERA_OMNIX_MASK;
 	if (p->has_audio)
 		sess->protocol_version |= GG_HAS_AUDIO_MASK;
 	sess->client_version = (p->client_version) ? strdup(p->client_version) : NULL;
@@ -1094,7 +1105,7 @@
 #endif
 	
 	if (sess->fd != -1) {
-		shutdown(sess->fd, 2);
+		shutdown(sess->fd, SHUT_RDWR);
 		close(sess->fd);
 		sess->fd = -1;
 	}
@@ -1131,6 +1142,11 @@
 		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);
@@ -1143,15 +1159,21 @@
 
 	if (!res) {
 		struct gg_image_queue *q = malloc(sizeof(*q));
-		char *buf = malloc(size);
+		char *buf;
 
 		if (!q) {
 			gg_debug(GG_DEBUG_MISC, "// gg_image_request() not enough memory for image queue\n");
-			free(buf);
-			errno = ENOMEM;
 			return -1;
 		}
 
+		buf = malloc(size);
+		if (size && !buf)
+		{
+			gg_debug(GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n");
+			free(q);
+			return -1;
+		}
+
 		memset(q, 0, sizeof(*q));
 
 		q->sender = recipient;
@@ -1193,7 +1215,7 @@
 	struct gg_send_msg s;
 	const char *tmp;
 	char buf[1910];
-	int res;
+	int res = -1;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, \"%s\", %p, %d);\n", sess, recipient, filename, image, size);
 
@@ -1202,6 +1224,16 @@
 		return -1;
 	}
 
+	if (sess->state != GG_STATE_CONNECTED) {
+		errno = ENOTCONN;
+		return -1;
+	}
+
+	if (size < 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
 	/* wytnij ¶cie¿ki, zostaw tylko nazwê pliku */
 	while ((tmp = strrchr(filename, '/')) || (tmp = strrchr(filename, '\\')))
 		filename = tmp + 1;
@@ -1211,11 +1243,6 @@
 		return -1;
 	}
 	
-	if (sess->state != GG_STATE_CONNECTED) {
-		errno = ENOTCONN;
-		return -1;
-	}
-
 	s.recipient = gg_fix32(recipient);
 	s.seq = gg_fix32(0);
 	s.msgclass = gg_fix32(GG_CLASS_MSG);
@@ -1338,12 +1365,17 @@
 		errno = EFAULT;
 		return -1;
 	}
-	
+
 	if (sess->state != GG_STATE_CONNECTED) {
 		errno = ENOTCONN;
 		return -1;
 	}
 
+	if (!message) {
+		errno = EFAULT;
+		return -1;
+	}
+	
 	s.recipient = gg_fix32(recipient);
 	if (!sess->seq)
 		sess->seq = 0x01740000 | (rand() & 0xffff);
@@ -1408,12 +1440,17 @@
 		errno = EFAULT;
 		return -1;
 	}
-	
+
 	if (sess->state != GG_STATE_CONNECTED) {
 		errno = ENOTCONN;
 		return -1;
 	}
 
+	if (!message || recipients_count <= 0 || recipients_count > 0xffff || !recipients) {
+		errno = EINVAL;
+		return -1;
+	}
+	
 	r.flag = 0x01;
 	r.count = gg_fix32(recipients_count - 1);
 	
@@ -1423,6 +1460,9 @@
 	s.msgclass = gg_fix32(msgclass);
 
 	recps = malloc(sizeof(uin_t) * recipients_count);
+	if (!recps)
+		return -1;
+
 	for (i = 0; i < recipients_count; i++) {
 	 
 		s.recipient = gg_fix32(recipients[i]);
@@ -1724,10 +1764,15 @@
 	int len;
 
 	if (!sess) {
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 	
+	if (sess->state != GG_STATE_CONNECTED) {
+		errno = ENOTCONN;
+		return -1;
+	}
+
 	if (!request) {
 		sess->userlist_blocks = 1;
 		return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), NULL);
Index: kopete/protocols/gadu/libgadu/common.c
===================================================================
--- kopete/protocols/gadu/libgadu/common.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/common.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -15,7 +15,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <sys/types.h>
@@ -90,7 +91,7 @@
  */
 char *gg_vsaprintf(const char *format, va_list ap)
 {
-        int size = 0;
+	int size = 0;
 	const char *start;
 	char *buf = NULL;
 	
@@ -192,23 +193,23 @@
  */
 char *gg_get_line(char **ptr)
 {
-        char *foo, *res;
+	char *foo, *res;
 
-        if (!ptr || !*ptr || !strcmp(*ptr, ""))
-                return NULL;
+	if (!ptr || !*ptr || !strcmp(*ptr, ""))
+		return NULL;
 
-        res = *ptr;
+	res = *ptr;
 
-        if (!(foo = strchr(*ptr, '\n')))
-                *ptr += strlen(*ptr);
-        else {
-                *ptr = foo + 1;
-                *foo = 0;
-                if (strlen(res) > 1 && res[strlen(res) - 1] == '\r')
-                        res[strlen(res) - 1] = 0;
-        }
+	if (!(foo = strchr(*ptr, '\n')))
+		*ptr += strlen(*ptr);
+	else {
+		*ptr = foo + 1;
+		*foo = 0;
+		if (strlen(res) > 1 && res[strlen(res) - 1] == '\r')
+			res[strlen(res) - 1] = 0;
+	}
 
-        return res;
+	return res;
 }
 
 /*
@@ -226,10 +227,10 @@
  */
 int gg_connect(void *addr, int port, int async)
 {
-	int sock, one = 1;
+	int sock, one = 1, errno2;
 	struct sockaddr_in sin;
 	struct in_addr *a = addr;
-        struct sockaddr_in myaddr;
+	struct sockaddr_in myaddr;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async);
 	
@@ -238,16 +239,16 @@
 		return -1;
 	}
 
-        memset(&myaddr, 0, sizeof(myaddr));
-        myaddr.sin_family = AF_INET;
+	memset(&myaddr, 0, sizeof(myaddr));
+	myaddr.sin_family = AF_INET;
 
-        myaddr.sin_addr.s_addr = gg_local_ip;
-        
-        if(bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) {
-                gg_debug(GG_DEBUG_MISC, "// gg_connect() bind() failed (errno=%d, %s)\n", errno, strerror(errno));
-                return -1;
-        }
+	myaddr.sin_addr.s_addr = gg_local_ip;
 
+	if (bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) {
+		gg_debug(GG_DEBUG_MISC, "// gg_connect() bind() failed (errno=%d, %s)\n", errno, strerror(errno));
+		return -1;
+	}
+
 #ifdef ASSIGN_SOCKETS_TO_THREADS
 	gg_win32_thread_socket(0, sock);
 #endif
@@ -259,7 +260,9 @@
 		if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
 #endif
 			gg_debug(GG_DEBUG_MISC, "// gg_connect() ioctl() failed (errno=%d, %s)\n", errno, strerror(errno));
+			errno2 = errno;
 			close(sock);
+			errno = errno2;
 			return -1;
 		}
 	}
@@ -271,7 +274,9 @@
 	if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) {
 		if (errno && (!async || errno != EINPROGRESS)) {
 			gg_debug(GG_DEBUG_MISC, "// gg_connect() connect() failed (errno=%d, %s)\n", errno, strerror(errno));
+			errno2 = errno;
 			close(sock);
+			errno = errno2;
 			return -1;
 		}
 		gg_debug(GG_DEBUG_MISC, "// gg_connect() connect() in progress\n");
@@ -289,12 +294,16 @@
  *  - buf - wska¼nik do bufora
  *  - length - d³ugo¶æ bufora
  *
- * je¶li trafi na b³±d odczytu, zwraca NULL. inaczej zwraca buf.
+ * je¶li trafi na b³±d odczytu lub podano nieprawid³owe parametry, zwraca NULL.
+ * inaczej zwraca buf.
  */
 char *gg_read_line(int sock, char *buf, int length)
 {
 	int ret;
 
+	if (!buf || length < 0)
+		return NULL;
+
 	for (; length > 1; buf++, length--) {
 		do {
 			if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) {
@@ -327,13 +336,17 @@
  */
 void gg_chomp(char *line)
 {
-	if (!line || strlen(line) < 1)
+	int len;
+	
+	if (!line)
 		return;
 
-	if (line[strlen(line) - 1] == '\n')
-		line[strlen(line) - 1] = 0;
-	if (line[strlen(line) - 1] == '\r')
-		line[strlen(line) - 1] = 0;
+	len = strlen(line);
+	
+	if (len > 0 && line[len - 1] == '\n')
+		line[--len] = 0;
+	if (len > 0 && line[len - 1] == '\r')
+		line[--len] = 0;
 }
 
 /*
@@ -351,10 +364,10 @@
 {
 	char *q, *buf, hex[] = "0123456789abcdef";
 	const char *p;
-	int size = 0;
+	unsigned int size = 0;
 
-	if (!str && !(str = strdup("")))
-		return NULL;
+	if (!str)
+		str = "";
 
 	for (p = str; *p; p++, size++) {
 		if (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == ' ') || (*p == '@') || (*p == '.') || (*p == '-'))
@@ -403,18 +416,18 @@
 	va_start(ap, format);
 
 	for (j = 0; j < strlen(format); j++) {
-		unsigned char *arg, buf[16];
+		char *arg, buf[16];
 
 		if (format[j] == 'u') {
 			snprintf(buf, sizeof(buf), "%d", va_arg(ap, uin_t));
 			arg = buf;
 		} else {
-			if (!(arg = va_arg(ap, unsigned char*)))
+			if (!(arg = va_arg(ap, char*)))
 				arg = "";
 		}	
 
 		i = 0;
-		while ((c = (int) arg[i++]) != 0) {
+		while ((c = (unsigned char) arg[i++]) != 0) {
 			a = (c ^ b) + (c << 8);
 			b = (a >> 24) | (a << 8);
 		}
@@ -496,7 +509,6 @@
 	struct hostent *hp;
 
 	if (!(addr = malloc(sizeof(struct in_addr)))) {
-		errno = ENOMEM;
 		goto cleanup;
 	}
 
@@ -556,37 +568,36 @@
 		if ((thread_id == -1 && wsk->socket == socket) || wsk->id == thread_id) {
 			if (close) {
 				/* socket zostaje usuniety */
-                        	closesocket(wsk->socket);
-         			*p_wsk = wsk->next;
-         			free(wsk);
-         			return 1;
-                        } else if (!socket) {
+				closesocket(wsk->socket);
+				*p_wsk = wsk->next;
+				free(wsk);
+				return 1;
+			} else if (!socket) {
 				/* socket zostaje zwrocony */
 				return wsk->socket;
-                        } else {
+			} else {
 				/* socket zostaje ustawiony */
 				wsk->socket = socket;
 				return socket;
 			}
-               }
-		
-               p_wsk = &(wsk->next);
-               wsk = wsk->next;
-        }
-	
-        if (close && socket != -1)
+		}
+		p_wsk = &(wsk->next);
+		wsk = wsk->next;
+	}
+
+	if (close && socket != -1)
 		closesocket(socket);
-        if (close || !socket)
+	if (close || !socket)
 		return 0;
 	
-        /* Dodaje nowy element */
-        wsk = malloc(sizeof(gg_win32_thread));
-        wsk->id = thread_id;
-        wsk->socket = socket;
-        wsk->next = 0;
-        *p_wsk = wsk;
-	
-        return socket;
+	/* Dodaje nowy element */
+	wsk = malloc(sizeof(gg_win32_thread));
+	wsk->id = thread_id;
+	wsk->socket = socket;
+	wsk->next = 0;
+	*p_wsk = wsk;
+
+	return socket;
 }
 
 #endif /* ASSIGN_SOCKETS_TO_THREADS */
@@ -606,7 +617,7 @@
 char *gg_base64_encode(const char *buf)
 {
 	char *out, *res;
-	int i = 0, j = 0, k = 0, len = strlen(buf);
+	unsigned int i = 0, j = 0, k = 0, len = strlen(buf);
 	
 	res = out = malloc((len / 3 + 1) * 4 + 2);
 
@@ -664,7 +675,7 @@
 {
 	char *res, *save, *foo, val;
 	const char *end;
-	int index = 0;
+	unsigned int index = 0;
 
 	if (!buf)
 		return NULL;
@@ -758,7 +769,7 @@
 static void gg_crc32_make_table()
 {
 	uint32_t h = 1;
-	int i, j;
+	unsigned int i, j;
 
 	memset(gg_crc32_table, 0, sizeof(gg_crc32_table));
 
@@ -788,6 +799,9 @@
 	if (!gg_crc32_initialized)
 		gg_crc32_make_table();
 
+	if (!buf || len < 0)
+		return crc;
+
 	crc ^= 0xffffffffL;
 
 	while (len--)
Index: kopete/protocols/gadu/libgadu/compat.h
===================================================================
--- kopete/protocols/gadu/libgadu/compat.h	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/compat.h	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -15,7 +15,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #ifndef __COMPAT_H
Index: kopete/protocols/gadu/libgadu/dcc.c
===================================================================
--- kopete/protocols/gadu/libgadu/dcc.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/dcc.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -15,7 +15,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <sys/types.h>
@@ -51,9 +52,9 @@
  *  - buf - bufor z danymi
  *  - size - rozmiar danych
  */
-static void gg_dcc_debug_data(const char *prefix, int fd, const void *buf, int size)
+static void gg_dcc_debug_data(const char *prefix, int fd, const void *buf, unsigned int size)
 {
-	int i;
+	unsigned int i;
 	
 	gg_debug(GG_DEBUG_MISC, "++ gg_dcc %s (fd=%d,len=%d)", prefix, fd, size);
 	
@@ -123,31 +124,48 @@
  */
 int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename)
 {
+	return gg_dcc_fill_file_info2(d, filename, filename);
+}
+
+/*
+ * gg_dcc_fill_file_info2()
+ *
+ * wype³nia pola struct gg_dcc niezbêdne do wys³ania pliku.
+ *
+ *  - d - struktura opisuj±ca po³±czenie DCC
+ *  - filename - nazwa pliku
+ *  - local_filename - nazwa na lokalnym systemie plików
+ *
+ * 0, -1.
+ */
+int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename)
+{
 	struct stat st;
 	const char *name, *ext, *p;
+	unsigned char *q;
 	int i, j;
-	
-	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_fill_file_info(%p, \"%s\");\n", d, filename);
-	
+
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_fill_file_info2(%p, \"%s\", \"%s\");\n", d, filename, local_filename);
+
 	if (!d || d->type != GG_SESSION_DCC_SEND) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info() invalid arguments\n");
+		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() invalid arguments\n");
 		errno = EINVAL;
 		return -1;
 	}
-		
-	if (stat(filename, &st) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info() stat() failed (%s)\n", strerror(errno));
+
+	if (stat(local_filename, &st) == -1) {
+		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() stat() failed (%s)\n", strerror(errno));
 		return -1;
 	}
 
 	if ((st.st_mode & S_IFDIR)) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info() that's a directory\n");
+		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() that's a directory\n");
 		errno = EINVAL;
 		return -1;
 	}
 
-	if ((d->file_fd = open(filename, O_RDONLY)) == -1) {
-		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info() open() failed (%s)\n", strerror(errno));
+	if ((d->file_fd = open(local_filename, O_RDONLY)) == -1) {
+		gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() open() failed (%s)\n", strerror(errno));
 		return -1;
 	}
 
@@ -159,7 +177,7 @@
 	gg_dcc_fill_filetime(st.st_atime, d->file_info.atime);
 	gg_dcc_fill_filetime(st.st_mtime, d->file_info.mtime);
 	gg_dcc_fill_filetime(st.st_ctime, d->file_info.ctime);
-	
+
 	d->file_info.size = gg_fix32(st.st_size);
 	d->file_info.mode = gg_fix32(0x20);	/* FILE_ATTRIBUTE_ARCHIVE */
 
@@ -173,14 +191,40 @@
 
 	for (i = 0, p = name; i < 8 && p < ext; i++, p++)
 		d->file_info.short_filename[i] = toupper(name[i]);
-	
+
+	if (i == 8 && p < ext) {
+		d->file_info.short_filename[6] = '~';
+		d->file_info.short_filename[7] = '1';
+	}
+
 	if (strlen(ext) > 0) {
 		for (j = 0; *ext && j < 4; j++, p++)
 			d->file_info.short_filename[i + j] = toupper(ext[j]);
-		
 	}
 
-	gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info() short name \"%s\", dos name \"%s\"\n", name, d->file_info.short_filename);
+	for (q = d->file_info.short_filename; *q; q++) {
+		if (*q == 185) {
+			*q = 165;
+		} else if (*q == 230) {
+			*q = 198;
+		} else if (*q == 234) {
+			*q = 202;
+		} else if (*q == 179) {
+			*q = 163;
+		} else if (*q == 241) {
+			*q = 209;
+		} else if (*q == 243) {
+			*q = 211;
+		} else if (*q == 156) {
+			*q = 140;
+		} else if (*q == 159) {
+			*q = 143;
+		} else if (*q == 191) {
+			*q = 175;
+		}
+	}
+	
+	gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() short name \"%s\", dos name \"%s\"\n", name, d->file_info.short_filename);
 	strncpy(d->file_info.filename, name, sizeof(d->file_info.filename) - 1);
 
 	return 0;
@@ -345,9 +389,9 @@
 {
 	struct gg_dcc *c;
 	struct sockaddr_in sin;
-	int sock, bound = 0;
+	int sock, bound = 0, errno2;
 	
-        gg_debug(GG_DEBUG_FUNCTION, "** gg_create_dcc_socket(%d, %d);\n", uin, port);
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_create_dcc_socket(%d, %d);\n", uin, port);
 	
 	if (!uin) {
 		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() invalid arguments\n");
@@ -374,6 +418,7 @@
 		else {
 			if (++port == 65535) {
 				gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() no free port found\n");
+				close(sock);
 				return NULL;
 			}
 		}
@@ -381,6 +426,9 @@
 
 	if (listen(sock, 10)) {
 		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() unable to listen (%s)\n", strerror(errno));
+		errno2 = errno;
+		close(sock);
+		errno = errno2;
 		return NULL;
 	}
 	
@@ -389,13 +437,13 @@
 	if (!(c = malloc(sizeof(*c)))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() not enough memory for struct\n");
 		close(sock);
-                return NULL;
+		return NULL;
 	}
 	memset(c, 0, sizeof(*c));
 
 	c->port = c->id = port;
 	c->fd = sock;
-        c->type = GG_SESSION_DCC_SOCKET;
+	c->type = GG_SESSION_DCC_SOCKET;
 	c->uin = uin;
 	c->timeout = -1;
 	c->state = GG_STATE_LISTENING;
@@ -403,7 +451,6 @@
 	c->callback = gg_dcc_callback;
 	c->destroy = gg_dcc_free;
 	
-	gg_dcc_ip = INADDR_ANY;	
 	return c;
 }
 
@@ -429,6 +476,7 @@
 	gg_debug(GG_DEBUG_FUNCTION, "++ gg_dcc_voice_send(%p, %p, %d);\n", d, buf, length);
 	if (!d || !buf || length < 0 || d->type != GG_SESSION_DCC_VOICE) {
 		gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() invalid argument\n");
+		errno = EINVAL;
 		return -1;
 	}
 
@@ -500,7 +548,7 @@
 	struct gg_event *e;
 	int foo;
 
-        gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_watch_fd(%p);\n", h);
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_watch_fd(%p);\n", h);
 	
 	if (!h || (h->type != GG_SESSION_DCC && h->type != GG_SESSION_DCC_SOCKET && h->type != GG_SESSION_DCC_SEND && h->type != GG_SESSION_DCC_GET && h->type != GG_SESSION_DCC_VOICE)) {
 		gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid argument\n");
@@ -508,12 +556,12 @@
 		return NULL;
 	}
 
-        if (!(e = (void*) calloc(1, sizeof(*e)))) {
+	if (!(e = (void*) calloc(1, sizeof(*e)))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() not enough memory\n");
-                return NULL;
-        }
+		return NULL;
+	}
 
-        e->type = GG_EVENT_NONE;
+	e->type = GG_EVENT_NONE;
 
 	if (h->type == GG_SESSION_DCC_SOCKET) {
 		struct sockaddr_in sin;
@@ -860,7 +908,6 @@
 					e->event.dcc_voice_data.length = h->chunk_size;
 					h->state = GG_STATE_READING_VOICE_HEADER;
 					h->voice_buf = NULL;
-				
 				}
 
 				h->check = GG_CHECK_READ;
@@ -1056,6 +1103,15 @@
 					utmp = sizeof(buf);
 				
 				gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() offset=%d, size=%d\n", h->offset, h->file_info.size);
+
+				/* koniec pliku? */
+				if (h->file_info.size == 0) {
+					gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof on empty file\n");
+					e->type = GG_EVENT_DCC_DONE;
+
+					return e;
+				}
+
 				lseek(h->file_fd, h->offset, SEEK_SET);
 
 				size = read(h->file_fd, buf, utmp);
@@ -1213,7 +1269,7 @@
  */
 void gg_dcc_free(struct gg_dcc *d)
 {
-        gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_free(%p);\n", d);
+	gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_free(%p);\n", d);
 	
 	if (!d)
 		return;
Index: kopete/protocols/gadu/libgadu/pubdir50.c
===================================================================
--- kopete/protocols/gadu/libgadu/pubdir50.c	(.../KDE_3_3_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)	(revision 367579)
+++ kopete/protocols/gadu/libgadu/pubdir50.c	(.../KDE/3.3/kdenetwork/kopete/protocols/gadu/libgadu)	(working copy)
@@ -14,7 +14,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
+ *  USA.
  */
 
 #include <errno.h>
@@ -265,7 +266,7 @@
 
 	if (!e || !packet) {
 		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
 
design & coding: Vladimir Lettiev aka crux © 2004-2005