òÅÐÏÚÉÔÏÒÉÊ Sisyphus
ðÏÓÌÅÄÎÅÅ ÏÂÎÏ×ÌÅÎÉÅ: 1 ÏËÔÑÂÒÑ 2023 | ðÁËÅÔÏ×: 18631 | ðÏÓÅÝÅÎÉÊ: 37892224
en ru br
òÅÐÏÚÉÔÏÒÉÉ ALT
5.1: 3.5.10-alt4
4.1: 3.5.10-alt2.M41.1
4.0: 3.5.9-alt0.M40.1
3.0: 3.4.1-alt4
+backports:3.5.6-alt2.0.M30
www.altlinux.org/Changes

çÒÕÐÐÁ :: çÒÁÆÉÞÅÓËÉÅ ÏÂÏÌÏÞËÉ/KDE
ðÁËÅÔ: kdenetwork

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

ðÁÔÞ: post-3.4.1-kdenetwork-libgadu.patch
óËÁÞÁÔØ


Index: kopete/protocols/gadu/libgadu/libgadu.h
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu.h	(revision 417278)
+++ kopete/protocols/gadu/libgadu/libgadu.h	(working copy)
@@ -33,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
@@ -57,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 */ \
@@ -111,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 */
@@ -150,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() */
 
@@ -265,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 */
@@ -350,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 */
 };
@@ -500,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 */
 
@@ -522,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 */
@@ -748,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
@@ -813,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
@@ -940,11 +943,12 @@
 #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_LIBGADU_VERSION "20041222"
+#define GG_ERA_OMNIX_MASK 0x04000000
+#define GG_LIBGADU_VERSION "CVS"
 
 #define GG_DEFAULT_DCC_PORT 1550
 
Index: kopete/protocols/gadu/libgadu/http.c
===================================================================
--- kopete/protocols/gadu/libgadu/http.c	(revision 417278)
+++ kopete/protocols/gadu/libgadu/http.c	(working copy)
@@ -12,10 +12,10 @@
  *  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 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.
+ *  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.
  */
 
 #include <sys/types.h>
@@ -61,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();
@@ -92,12 +92,12 @@
 	}
 
 	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;
 	}
-
+	
 	gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", h->query);
 
 	if (async) {
@@ -106,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;
 		}
 
@@ -131,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;
 		}
@@ -144,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;
 		}
@@ -152,7 +152,7 @@
 
 	h->callback = gg_http_watch_fd;
 	h->destroy = gg_http_free;
-
+	
 	return h;
 }
 
@@ -181,7 +181,7 @@
 
 	if (!h) {
 		gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -243,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);
@@ -272,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);
@@ -321,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);
@@ -332,7 +332,7 @@
 			h->body_size = 0;
 			line = h->header;
 			*tmp = 0;
-
+                        
 			gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header);
 
 			while (line) {
@@ -380,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);
@@ -435,7 +435,7 @@
 
 		return 0;
 	}
-
+	
 	if (h->fd != -1)
 		close(h->fd);
 
@@ -452,7 +452,7 @@
  * gg_http_stop()
  *
  * je¶li po³±czenie jest w trakcie, przerywa je. nie zwalnia h->data.
- *
+ * 
  *  - h - struktura opisuj±ca po³±czenie
  */
 void gg_http_stop(struct gg_http *h)
@@ -465,7 +465,7 @@
 
 	if (h->fd != -1)
 		close(h->fd);
-        h->fd = -1;
+	h->fd = -1;
 }
 
 /*
@@ -487,7 +487,7 @@
 		free(h->query);
 		h->query = NULL;
 	}
-
+	
 	if (h->header) {
 		free(h->header);
 		h->header = NULL;
Index: kopete/protocols/gadu/libgadu/events.c
===================================================================
--- kopete/protocols/gadu/libgadu/events.c	(revision 417278)
+++ kopete/protocols/gadu/libgadu/events.c	(working copy)
@@ -14,10 +14,10 @@
  *  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 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.
+ *  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.
  */
 
 #include <sys/types.h>
@@ -56,28 +56,28 @@
 void gg_event_free(struct gg_event *e)
 {
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_event_free(%p);\n", e);
-
+			
 	if (!e)
 		return;
-
+	
 	switch (e->type) {
 		case GG_EVENT_MSG:
 			free(e->event.msg.message);
 			free(e->event.msg.formats);
 			free(e->event.msg.recipients);
 			break;
-
+	
 		case GG_EVENT_NOTIFY:
 			free(e->event.notify);
 			break;
-
+	
 		case GG_EVENT_NOTIFY60:
 		{
 			int i;
 
 			for (i = 0; e->event.notify60[i].uin; i++)
 				free(e->event.notify60[i].descr);
-
+		
 			free(e->event.notify60);
 
 			break;
@@ -86,7 +86,7 @@
 		case GG_EVENT_STATUS60:
 			free(e->event.status60.descr);
 			break;
-
+	
 		case GG_EVENT_STATUS:
 			free(e->event.status.descr);
 			break;
@@ -109,7 +109,7 @@
 		case GG_EVENT_USERLIST:
 			free(e->event.userlist.reply);
 			break;
-
+	
 		case GG_EVENT_IMAGE_REPLY:
 			free(e->event.image_reply.filename);
 			free(e->event.image_reply.image);
@@ -133,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;
 	}
 
@@ -165,18 +165,20 @@
  * parsuje przychodz±cy pakiet z obrazkiem.
  *
  *  - 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 */
-
+	
 	for (qq = sess->images, q = NULL; qq; qq = qq->next) {
 		if (sender == qq->sender && i->size == qq->size && i->crc32 == qq->crc32) {
 			q = qq;
@@ -191,7 +193,7 @@
 
 	if (p[0] == 0x05) {
 		int i, ok = 0;
-
+		
 		q->done = 0;
 
 		len -= sizeof(struct gg_msg_image_reply);
@@ -225,7 +227,7 @@
 
 	if (q->done + len > q->size)
 		len = q->size - q->done;
-
+		
 	memcpy(q->image + q->done, p, len);
 	q->done += len;
 
@@ -268,7 +270,7 @@
 		e->type = GG_EVENT_NONE;
 		return 0;
 	}
-
+	
 	for (p = (char*) r + sizeof(*r); *p; p++) {
 		if (*p == 0x02 && p == packet_end - 1) {
 			gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() received ctcp packet\n");
@@ -279,7 +281,7 @@
 			goto malformed;
 		}
 	}
-
+	
 	p++;
 
 	/* przeanalizuj dodatkowe opcje */
@@ -289,9 +291,9 @@
 			{
 				struct gg_msg_recipients *m = (void*) p;
 				uint32_t i, count;
-
+			
 				p += sizeof(*m);
-
+			
 				if (p > packet_end) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (1)\n");
 					goto malformed;
@@ -299,40 +301,42 @@
 
 				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;
-
+				
 				break;
 			}
 
 			case 0x02:		/* richtext */
 			{
-				unsigned short len;
+				uint16_t len;
 				char *buf;
-
+			
 				if (p + 3 > packet_end) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (2)\n");
 					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;
 				}
 
@@ -343,7 +347,7 @@
 					free(buf);
 					goto malformed;
 				}
-
+				
 				memcpy(buf, p, len);
 
 				e->event.msg.formats = buf;
@@ -375,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;
 			}
@@ -443,21 +464,21 @@
 	}
 
 	p = (char*) h + sizeof(struct gg_header);
-
+	
 	switch (h->type) {
 		case GG_RECV_MSG:
 		{
 			if (h->length >= sizeof(struct gg_recv_msg))
 				if (gg_handle_recv_msg(h, e, sess))
 					goto fail;
-
+			
 			break;
 		}
 
 		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");
@@ -468,46 +489,45 @@
 				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);
 				tmp[count] = 0;
 				e->event.notify_descr.descr = tmp;
-
+				
 			} else {
 				e->type = GG_EVENT_NOTIFY;
-
+				
 				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;
 				}
-
+				
 				memcpy(e->event.notify, p, h->length);
 				count = h->length / sizeof(*n);
 				e->event.notify[count].uin = 0;
-
+				
 				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_ip = e->event.notify[i].remote_ip;
 					e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);
 				}
 			}
@@ -557,7 +577,7 @@
 			}
 
 			e->event.notify60[0].uin = 0;
-
+			
 			while (length >= sizeof(struct gg_notify_reply60)) {
 				uin_t uin = gg_fix32(n->uin);
 				char *tmp;
@@ -571,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));
 
@@ -585,7 +610,7 @@
 
 						/* XXX czas */
 					}
-
+					
 					length -= sizeof(struct gg_notify_reply60) + descr_len + 1;
 					n = (void*) ((char*) n + sizeof(struct gg_notify_reply60) + descr_len + 1);
 				} else {
@@ -605,7 +630,7 @@
 
 			break;
 		}
-
+		
 		case GG_STATUS60:
 		{
 			struct gg_status60 *s = (void*) p;
@@ -630,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);
@@ -642,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;
@@ -666,7 +696,7 @@
 			break;
 		}
 
-		case GG_PONG:
+		case GG_PONG: 
 		{
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a pong\n");
 
@@ -709,10 +739,10 @@
 
 			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);
-
+				
 				if (!(tmp = realloc(sess->userlist_reply, len + h->length))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for userlist reply\n");
 					free(sess->userlist_reply);
@@ -739,7 +769,7 @@
 		default:
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received unknown packet 0x%.2x\n", h->type);
 	}
-
+	
 	free(h);
 	return 0;
 
@@ -767,9 +797,10 @@
 	struct gg_event *e;
 	int res = 0;
 	int port = 0;
+	int errno2 = 0;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(%p);\n", sess);
-
+	
 	if (!sess) {
 		errno = EFAULT;
 		return NULL;
@@ -793,8 +824,9 @@
 			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);
 			sess->fd = -1;
 
@@ -809,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
@@ -829,7 +863,7 @@
 			}
 
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() resolved, connecting to %s:%d\n", inet_ntoa(addr), port);
-
+			
 			/* ³±czymy siê albo z hubem, albo z proxy, zale¿nie
 			 * od tego, co resolvowali¶my. */
 			if ((sess->fd = gg_connect(&addr, port, sess->async)) == -1) {
@@ -866,7 +900,7 @@
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", res, strerror(res));
 					goto fail_connecting;
 				}
-
+					
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to hub failed (errno=%d, %s), trying direct connection\n", res, strerror(res));
 				close(sess->fd);
 
@@ -884,7 +918,7 @@
 				sess->timeout = GG_DEFAULT_TIMEOUT;
 				break;
 			}
-
+			
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connected to hub, sending query\n");
 
 			if (!(client = gg_urlencode((sess->client_version) ? sess->client_version : GG_DEFAULT_CLIENT_VERSION))) {
@@ -911,12 +945,12 @@
 				"Host: " GG_APPMSG_HOST "\r\n"
 				"User-Agent: " GG_HTTP_USERAGENT "\r\n"
 				"Pragma: no-cache\r\n"
-				"%s"
+				"%s" 
 				"\r\n", host, appmsg, sess->uin, client, sess->last_sysmsg, (auth) ? auth : "");
 
 			if (auth)
 				free(auth);
-
+			
 			free(client);
 
 			/* zwolnij pamiêæ po wersji klienta. */
@@ -925,8 +959,8 @@
 				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,
 			 * sta³o siê co¶ z³ego. */
@@ -960,7 +994,7 @@
 			gg_read_line(sess->fd, buf, sizeof(buf) - 1);
 			gg_chomp(buf);
 			gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() received http header (%s)\n", buf);
-
+	
 			/* sprawdzamy, czy wszystko w porz±dku. */
 			if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) {
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() that's not what we've expected, trying direct connection\n");
@@ -981,7 +1015,7 @@
 					sess->timeout = GG_DEFAULT_TIMEOUT;
 					break;
 				}
-
+				
 				sess->port = GG_DEFAULT_PORT;
 
 				/* ³±czymy siê na port 8074 huba. */
@@ -989,20 +1023,20 @@
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), trying https\n", errno, strerror(errno));
 
 					sess->port = GG_HTTPS_PORT;
-
+					
 					/* ³±czymy siê na port 443. */
 					if ((sess->fd = gg_connect(&sess->hub_addr, sess->port, sess->async)) == -1) {
 						gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno));
 						goto fail_connecting;
 					}
 				}
-
+				
 				sess->state = GG_STATE_CONNECTING_GG;
 				sess->check = GG_CHECK_WRITE;
 				sess->timeout = GG_DEFAULT_TIMEOUT;
 				break;
 			}
-
+	
 			/* ignorujemy resztê nag³ówka. */
 			while (strcmp(buf, "\r\n") && strcmp(buf, ""))
 				gg_read_line(sess->fd, buf, sizeof(buf) - 1);
@@ -1010,13 +1044,13 @@
 			/* czytamy pierwsz± liniê danych. */
 			gg_read_line(sess->fd, buf, sizeof(buf) - 1);
 			gg_chomp(buf);
-
+			
 			/* je¶li pierwsza liczba w linii nie jest równa zeru,
 			 * oznacza to, ¿e mamy wiadomo¶æ systemow±. */
 			if (atoi(buf)) {
 				char tmp[1024], *foo, *sysmsg_buf = NULL;
 				int len = 0;
-
+				
 				while (gg_read_line(sess->fd, tmp, sizeof(tmp) - 1)) {
 					if (!(foo = realloc(sysmsg_buf, len + strlen(tmp) + 2))) {
 						gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() out of memory for system message, ignoring\n");
@@ -1029,23 +1063,23 @@
 						strcpy(sysmsg_buf, tmp);
 					else
 						strcat(sysmsg_buf, tmp);
-
+					
 					len += strlen(tmp);
 				}
-
+				
 				e->type = GG_EVENT_MSG;
 				e->event.msg.msgclass = atoi(buf);
 				e->event.msg.sender = 0;
 				e->event.msg.message = sysmsg_buf;
 			}
-
+	
 			close(sess->fd);
-
+	
 			gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() received http data (%s)\n", buf);
 
 			/* analizujemy otrzymane dane. */
 			tmp = buf;
-
+			
 			while (*tmp && *tmp != ' ')
 				tmp++;
 			while (*tmp && *tmp == ' ')
@@ -1057,7 +1091,7 @@
 
 			if ((tmp = strchr(host, ':'))) {
 				*tmp = 0;
-				port = atoi(tmp+1);
+				port = atoi(tmp + 1);
 			}
 
 			addr.s_addr = inet_addr(host);
@@ -1070,7 +1104,7 @@
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", errno, strerror(errno));
 					goto fail_connecting;
 				}
-
+				
 				sess->state = GG_STATE_CONNECTING_GG;
 				sess->check = GG_CHECK_WRITE;
 				sess->timeout = GG_DEFAULT_TIMEOUT;
@@ -1097,7 +1131,7 @@
 			sess->state = GG_STATE_CONNECTING_GG;
 			sess->check = GG_CHECK_WRITE;
 			sess->timeout = GG_DEFAULT_TIMEOUT;
-
+		
 			break;
 		}
 
@@ -1149,18 +1183,24 @@
 			}
 
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connected\n");
-
+			
 			if (gg_proxy_http_only)
 				sess->proxy_port = 0;
 
 			/* 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,
 				 * ¿e musi siê zmie¶ciæ w buforze gniazda. je¶li
 				 * write() zawiedzie, sta³o siê co¶ z³ego. */
@@ -1225,7 +1265,7 @@
 					sess->fd = -1;
 					break;
 				}
-
+				
 				if (err == SSL_ERROR_WANT_READ) {
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() wants to read\n");
 
@@ -1248,7 +1288,7 @@
 					ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
 
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() bailed out: %s\n", buf);
-
+ 
 					e->type = GG_EVENT_CONN_FAILED;
 					e->event.failure = GG_FAILURE_TLS;
 					sess->state = GG_STATE_IDLE;
@@ -1284,13 +1324,13 @@
 
 		case GG_STATE_READING_KEY:
 		{
-			struct gg_header *h;
+			struct gg_header *h;			
 			struct gg_welcome *w;
 			struct gg_login60 l;
 			unsigned int hash;
 			unsigned char *password = sess->password;
 			int ret;
-
+			
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_KEY\n");
 
 			memset(&l, 0, sizeof(l));
@@ -1305,7 +1345,7 @@
 				gg_read_line(sess->fd, buf, sizeof(buf) - 1);
 				gg_chomp(buf);
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() proxy response:\n//   %s\n", buf);
-
+				
 				while (strcmp(buf, "")) {
 					gg_read_line(sess->fd, buf, sizeof(buf) - 1);
 					gg_chomp(buf);
@@ -1316,7 +1356,7 @@
 				/* XXX niech czeka jeszcze raz w tej samej
 				 * fazie. g³upio, ale dzia³a. */
 				sess->proxy_port = 0;
-
+				
 				break;
 			}
 
@@ -1327,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;
 			}
@@ -1343,21 +1385,25 @@
 				sess->state = GG_STATE_IDLE;
 				break;
 			}
-
+	
 			w = (struct gg_welcome*) ((char*) h + sizeof(struct gg_header));
 			w->key = gg_fix32(w->key);
 
 			hash = gg_login_hash(password, w->key);
-
+	
 			gg_debug(GG_DEBUG_DUMP, "// gg_watch_fd() challenge %.4x --> hash %.8x\n", w->key, hash);
-
+	
 			free(h);
 
 			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;
 				int sin_len = sizeof(sin);
@@ -1371,19 +1417,19 @@
 					gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n");
 					l.local_ip = 0;
 				}
-			} else
+			} else 
 				l.local_ip = gg_dcc_ip;
-
+		
 			l.uin = gg_fix32(sess->uin);
 			l.hash = gg_fix32(hash);
 			l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL);
 			l.version = gg_fix32(sess->protocol_version);
 			l.local_port = gg_fix16(gg_dcc_port);
 			l.image_size = sess->image_size;
-
+			
 			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");
@@ -1394,15 +1440,16 @@
 
 			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;
 				sess->state = GG_STATE_IDLE;
 				break;
 			}
-
+	
 			sess->state = GG_STATE_READING_REPLY;
 
 			break;
@@ -1419,11 +1466,13 @@
 				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;
 			}
-
+	
 			if (h->type == GG_LOGIN_OK) {
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() login succeded\n");
 				e->type = GG_EVENT_CONN_SUCCESS;
@@ -1450,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);
 
@@ -1462,7 +1513,7 @@
 			gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTED\n");
 
 			sess->last_event = time(NULL);
-
+			
 			if ((res = gg_watch_fd_connected(sess, e)) == -1) {
 
 				gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() watch_fd_connected failed (errno=%d, %s)\n", errno, strerror(errno));
@@ -1484,10 +1535,12 @@
 	}
 
 	return e;
-
+	
 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	(revision 417278)
+++ kopete/protocols/gadu/libgadu/pubdir.c	(working copy)
@@ -13,10 +13,10 @@
  *  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 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.
+ *  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.
  */
 
 #include <ctype.h>
@@ -46,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;
 	}
 
@@ -66,7 +66,6 @@
 		free(__email);
 		free(__tokenid);
 		free(__tokenval);
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -81,7 +80,6 @@
 
 	if (!form) {
 		gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n");
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -99,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;
@@ -111,10 +114,10 @@
 
 	h->callback = gg_pubdir_watch_fd;
 	h->destroy = gg_pubdir_free;
-
+	
 	if (!async)
 		gg_pubdir_watch_fd(h);
-
+	
 	return h;
 }
 
@@ -139,10 +142,10 @@
 
 	if (!password || !tokenid || !tokenval) {
 		gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
-
+    
 	__pwd = gg_saprintf("%ld", random());
 	__fmpwd = gg_urlencode(password);
 	__tokenid = gg_urlencode(tokenid);
@@ -154,7 +157,6 @@
 		free(__fmpwd);
 		free(__tokenid);
 		free(__tokenval);
-                errno = ENOMEM;
 		return NULL;
 	}
 
@@ -167,7 +169,6 @@
 
 	if (!form) {
 		gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n");
-		errno = ENOMEM;
 		return NULL;
 	}
 
@@ -185,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);
@@ -197,10 +203,10 @@
 
 	h->callback = gg_pubdir_watch_fd;
 	h->destroy = gg_pubdir_free;
-
+	
 	if (!async)
 		gg_pubdir_watch_fd(h);
-
+	
 	return h;
 }
 
@@ -228,10 +234,10 @@
 
 	if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) {
 		gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
-
+	
 	__fmpwd = gg_urlencode(passwd);
 	__pwd = gg_urlencode(newpasswd);
 	__email = gg_urlencode(email);
@@ -245,10 +251,9 @@
 		free(__email);
 		free(__tokenid);
 		free(__tokenval);
-		errno = ENOMEM;
 		return NULL;
 	}
-
+	
 	if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, newpasswd)))) {
 		gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n");
 		free(__fmpwd);
@@ -257,33 +262,37 @@
 		free(__tokenid);
 		free(__tokenval);
 
-		errno = ENOMEM;
 		return NULL;
 	}
-
+	
 	free(__fmpwd);
 	free(__pwd);
 	free(__email);
 	free(__tokenid);
 	free(__tokenval);
-
+	
 	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;
 	}
 
@@ -301,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
@@ -313,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;
 	}
 
@@ -397,36 +414,37 @@
 	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;
-
-        h->state = GG_STATE_DONE;
-
+		return 0;
+	
+	h->state = GG_STATE_DONE;
+	
 	if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) {
 		gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n");
 		return -1;
 	}
+
 	p->success = 0;
 	p->uin = 0;
-
+	
 	gg_debug(GG_DEBUG_MISC, "=> pubdir, let's parse \"%s\"\n", h->body);
 
 	if ((tmp = strstr(h->body, "success")) || (tmp = strstr(h->body, "results"))) {
@@ -451,7 +469,7 @@
 {
 	if (!h)
 		return;
-
+	
 	free(h->data);
 	gg_http_free(h);
 }
@@ -486,10 +504,10 @@
 
 	h->callback = gg_token_watch_fd;
 	h->destroy = gg_token_free;
-
+	
 	if (!async)
 		gg_token_watch_fd(h);
-
+	
 	return h;
 }
 
@@ -508,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;
 
@@ -545,34 +564,64 @@
 			free(url);
 			return -1;
 		}
-
+		
 		if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) {
 			gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
 			free(url);
 			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 (!(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(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 (!(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);
@@ -581,7 +630,7 @@
 
 		h->callback = gg_token_watch_fd;
 		h->destroy = gg_token_free;
-
+	
 		if (!h->async)
 			gg_token_watch_fd(h);
 
@@ -599,7 +648,7 @@
 		/* obrazek mamy w h->body */
 		h->state = GG_STATE_DONE;
 	}
-
+	
 	return 0;
 }
 
@@ -619,7 +668,7 @@
 
 	if ((t = h->data))
 		free(t->tokenid);
-
+	
 	free(h->data);
 	gg_http_free(h);
 }
Index: kopete/protocols/gadu/libgadu/libgadu.c
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu.c	(revision 417278)
+++ kopete/protocols/gadu/libgadu/libgadu.c	(working copy)
@@ -107,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		
 }
 
@@ -131,7 +131,7 @@
 #else
 	return (uint16_t)
 		(((x & (uint16_t) 0x00ffU) << 8) |
-                 ((x & (uint16_t) 0xff00U) >> 8));
+		((x & (uint16_t) 0xff00U) >> 8));
 #endif
 }
 
@@ -187,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);
 	
@@ -199,8 +200,10 @@
 		return -1;
 
 	if ((res = fork()) == -1) {
+		errno2 = errno;
 		close(pipes[0]);
 		close(pipes[1]);
+		errno = errno2;
 		return -1;
 	}
 
@@ -297,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;
 	}
 	
@@ -309,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;
 	}
 	
@@ -317,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;
 	}
 
@@ -406,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) {
@@ -453,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);
 	
@@ -483,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;
 			}
@@ -522,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;
@@ -548,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;
@@ -603,9 +617,9 @@
 {
 	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;
 
@@ -625,11 +639,8 @@
 	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, tmp_length + payload_length))) {
 			gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n");
 			free(tmp);
@@ -679,7 +690,7 @@
 static int gg_session_callback(struct gg_session *s)
 {
 	if (!s) {
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -709,7 +720,7 @@
 
 	if (!p) {
 		gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p);\n", p);
-		errno = EINVAL;
+		errno = EFAULT;
 		return NULL;
 	}
 
@@ -724,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;
 	}
 
@@ -743,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;
@@ -752,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;
@@ -1092,7 +1105,7 @@
 #endif
 	
 	if (sess->fd != -1) {
-		shutdown(sess->fd, 2);
+		shutdown(sess->fd, SHUT_RDWR);
 		close(sess->fd);
 		sess->fd = -1;
 	}
@@ -1129,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);
@@ -1141,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;
@@ -1191,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);
 
@@ -1200,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;
@@ -1209,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);
@@ -1336,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);
@@ -1406,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);
 	
@@ -1421,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]);
@@ -1722,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	(revision 417278)
+++ kopete/protocols/gadu/libgadu/common.c	(working copy)
@@ -13,10 +13,10 @@
  *  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 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.
+ *  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.
  */
 
 #include <sys/types.h>
@@ -39,7 +39,7 @@
 
 #include "libgadu.h"
 
-FILE *gg_debug_file;
+FILE *gg_debug_file = NULL;
 
 #ifndef GG_DEBUG_DISABLE
 
@@ -55,7 +55,7 @@
 {
 	va_list ap;
 	int old_errno = errno;
-
+	
 	if (gg_debug_handler) {
 		va_start(ap, format);
 		(*gg_debug_handler)(level, format, ap);
@@ -63,7 +63,7 @@
 
 		goto cleanup;
 	}
-
+	
 	if ((gg_debug_level & level)) {
 		va_start(ap, format);
 		vfprintf((gg_debug_file) ? gg_debug_file : stderr, format, ap);
@@ -91,10 +91,10 @@
  */
 char *gg_vsaprintf(const char *format, va_list ap)
 {
-        int size = 0;
+	int size = 0;
 	const char *start;
 	char *buf = NULL;
-
+	
 #ifdef __GG_LIBGADU_HAVE_VA_COPY
 	va_list aq;
 
@@ -107,13 +107,13 @@
 #  endif
 #endif
 
-	start = format;
+	start = format; 
 
 #ifndef __GG_LIBGADU_HAVE_C99_VSNPRINTF
 	{
 		int res;
 		char *tmp;
-
+		
 		size = 128;
 		do {
 			size *= 2;
@@ -128,7 +128,7 @@
 #else
 	{
 		char tmp[2];
-
+		
 		/* libce Solarisa przy buforze NULL zawsze zwracaj± -1, wiêc
 		 * musimy podaæ co¶ istniej±cego jako cel printf()owania. */
 		size = vsnprintf(tmp, sizeof(tmp), format, ap);
@@ -138,7 +138,7 @@
 #endif
 
 	format = start;
-
+	
 #ifdef __GG_LIBGADU_HAVE_VA_COPY
 	vsnprintf(buf, size + 1, format, aq);
 	va_end(aq);
@@ -150,7 +150,7 @@
 	vsnprintf(buf, size + 1, format, ap);
 #  endif
 #endif
-
+	
 	return buf;
 }
 
@@ -180,36 +180,36 @@
 
 /*
  * gg_get_line() // funkcja pomocnicza
- *
+ * 
  * podaje kolejn± liniê z bufora tekstowego. niszczy go bezpowrotnie, dziel±c
  * na kolejne stringi. zdarza siê, nie ma potrzeby pisania funkcji dubluj±cej
  * bufor ¿eby tylko mieæ nieruszone dane wej¶ciowe, skoro i tak nie bêd± nam
  * po¼niej potrzebne. obcina `\r\n'.
- *
+ * 
  *  - ptr - wska¼nik do zmiennej, która przechowuje aktualn± pozycjê
  *    w przemiatanym buforze
- *
+ * 
  * wska¼nik do kolejnej linii tekstu lub NULL, je¶li to ju¿ koniec bufora.
  */
 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;
 }
 
 /*
@@ -227,27 +227,27 @@
  */
 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);
-
+	
 	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
 		gg_debug(GG_DEBUG_MISC, "// gg_connect() socket() failed (errno=%d, %s)\n", errno, strerror(errno));
 		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;
+	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;
-        }
+	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);
@@ -260,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;
 		}
 	}
@@ -268,16 +270,18 @@
 	sin.sin_port = htons(port);
 	sin.sin_family = AF_INET;
 	sin.sin_addr.s_addr = a->s_addr;
-
+	
 	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");
 	}
-
+	
 	return sock;
 }
 
@@ -290,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) {
@@ -328,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;
 }
 
 /*
@@ -352,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 == '-'))
@@ -404,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);
 		}
@@ -446,12 +458,12 @@
 	int h_errnop, ret;
 	size_t buflen = 1024;
 	int new_errno;
-
+	
 	new_errno = ENOMEM;
-
+	
 	if (!(addr = malloc(sizeof(struct in_addr))))
 		goto cleanup;
-
+	
 	if (!(hp = calloc(1, sizeof(*hp))))
 		goto cleanup;
 
@@ -459,45 +471,44 @@
 		goto cleanup;
 
 	tmpbuf = buf;
-
+	
 	while ((ret = gethostbyname_r(hostname, hp, buf, buflen, &hp2, &h_errnop)) == ERANGE) {
 		buflen *= 2;
-
+		
 		if (!(tmpbuf = realloc(buf, buflen)))
 			break;
-
+		
 		buf = tmpbuf;
 	}
-
+	
 	if (ret)
 		new_errno = h_errnop;
 
 	if (ret || !hp2 || !tmpbuf)
 		goto cleanup;
-
+	
 	memcpy(addr, hp->h_addr, sizeof(struct in_addr));
-
+	
 	free(buf);
 	free(hp);
-
+	
 	return addr;
-
+	
 cleanup:
 	errno = new_errno;
-
+	
 	if (addr)
 		free(addr);
 	if (hp)
 		free(hp);
 	if (buf)
 		free(buf);
-
+	
 	return NULL;
 #else
 	struct hostent *hp;
 
 	if (!(addr = malloc(sizeof(struct in_addr)))) {
-		errno = ENOMEM;
 		goto cleanup;
 	}
 
@@ -507,7 +518,7 @@
 	memcpy(addr, hp->h_addr, sizeof(struct in_addr));
 
 	return addr;
-
+	
 cleanup:
 	if (addr)
 		free(addr);
@@ -535,7 +546,7 @@
  * je¶li na win32 przy po³±czeniach synchronicznych zapamiêtamy w jakim
  * w±tku uruchomili¶my funkcjê, która siê z czymkolwiek ³±czy, to z osobnego
  * w±tku mo¿emy anulowaæ po³±czenie poprzez gg_win32_thread_socket(watek, -1);
- *
+ * 
  * - thread_id - id w±tku. je¶li jest równe 0, brany jest aktualny w±tek,
  *               je¶li równe -1, usuwa wpis o podanym sockecie.
  * - socket - deskryptor gniazda. je¶li równe 0, zwraca deskryptor gniazda
@@ -552,42 +563,41 @@
 
 	if (!thread_id)
 		thread_id = GetCurrentThreadId();
-
+	
 	while (wsk) {
 		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;
+	}
 
-               p_wsk = &(wsk->next);
-               wsk = wsk->next;
-        }
-
-        if (close && socket != -1)
+	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;
 
-        /* Dodaje nowy element */
-        wsk = malloc(sizeof(gg_win32_thread));
-        wsk->id = thread_id;
-        wsk->socket = socket;
-        wsk->next = 0;
-        *p_wsk = wsk;
-
-        return socket;
+	return socket;
 }
 
 #endif /* ASSIGN_SOCKETS_TO_THREADS */
@@ -607,14 +617,14 @@
 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);
 
 	if (!res)
 		return NULL;
-
-	while (j < len) {
+	
+	while (j <= len) {
 		switch (i % 4) {
 			case 0:
 				k = (buf[j] & 252) >> 2;
@@ -646,9 +656,9 @@
 	if (i % 4)
 		for (j = 0; j < 4 - (i % 4); j++, out++)
 			*out = '=';
-
+	
 	*out = 0;
-
+	
 	return res;
 }
 
@@ -665,11 +675,11 @@
 {
 	char *res, *save, *foo, val;
 	const char *end;
-	int index = 0;
+	unsigned int index = 0;
 
 	if (!buf)
 		return NULL;
-
+	
 	save = res = calloc(1, (strlen(buf) / 4 + 1) * 3 + 2);
 
 	if (!save)
@@ -706,7 +716,7 @@
 		index %= 4;
 	}
 	*res = 0;
-
+	
 	return save;
 }
 
@@ -714,7 +724,7 @@
  * gg_proxy_auth() // funkcja wewnêtrzna
  *
  * tworzy nag³ówek autoryzacji dla proxy.
- *
+ * 
  * zaalokowany tekst lub NULL, je¶li proxy nie jest w³±czone lub nie wymaga
  * autoryzacji.
  */
@@ -722,7 +732,7 @@
 {
 	char *tmp, *enc, *out;
 	unsigned int tmp_size;
-
+	
 	if (!gg_proxy_enabled || !gg_proxy_username || !gg_proxy_password)
 		return NULL;
 
@@ -735,14 +745,14 @@
 		free(tmp);
 		return NULL;
 	}
-
+	
 	free(tmp);
 
 	if (!(out = malloc(strlen(enc) + 40))) {
 		free(enc);
 		return NULL;
 	}
-
+	
 	snprintf(out, strlen(enc) + 40,  "Proxy-Authorization: Basic %s\r\n", enc);
 
 	free(enc);
@@ -759,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));
 
@@ -789,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	(revision 417278)
+++ kopete/protocols/gadu/libgadu/compat.h	(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	(revision 417278)
+++ kopete/protocols/gadu/libgadu/dcc.c	(working copy)
@@ -52,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);
 	
@@ -92,7 +92,7 @@
  *  - unix - czas w postaci unixowej
  *  - filetime - czas w postaci windowsowej
  */
-static void gg_dcc_fill_filetime(uint32_t ut, uint32_t *ft)
+void gg_dcc_fill_filetime(uint32_t ut, uint32_t *ft)
 {
 #ifdef __GG_LIBGADU_HAVE_LONG_LONG
 	unsigned long long tmp;
@@ -124,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;
 	}
 
@@ -160,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 */
 
@@ -174,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;
@@ -346,7 +389,7 @@
 {
 	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);
 	
@@ -383,7 +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;
 	}
 	
@@ -431,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;
 	}
 
@@ -502,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");
@@ -862,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;
@@ -1058,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);
@@ -1215,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	(revision 417278)
+++ kopete/protocols/gadu/libgadu/pubdir50.c	(working copy)
@@ -12,10 +12,10 @@
  *  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 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.
+ *  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.
  */
 
 #include <errno.h>
@@ -84,7 +84,7 @@
 
 		return 0;
 	}
-
+		
 	if (!(dupfield = strdup(field))) {
 		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
 		free(dupvalue);
@@ -139,7 +139,7 @@
 int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq)
 {
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_seq_set(%p, %d);\n", req, seq);
-
+	
 	if (!req) {
 		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_seq_set() invalid arguments\n");
 		errno = EFAULT;
@@ -164,7 +164,7 @@
 
 	if (!s)
 		return;
-
+	
 	for (i = 0; i < s->entries_count; i++) {
 		free(s->entries[i].field);
 		free(s->entries[i].value);
@@ -192,7 +192,7 @@
 	struct gg_pubdir50_request *r;
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req);
-
+	
 	if (!sess || !req) {
 		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n");
 		errno = EFAULT;
@@ -209,7 +209,7 @@
 		/* wyszukiwanie bierze tylko pierwszy wpis */
 		if (req->entries[i].num)
 			continue;
-
+		
 		size += strlen(req->entries[i].field) + 1;
 		size += strlen(req->entries[i].value) + 1;
 	}
@@ -261,12 +261,12 @@
 	struct gg_pubdir50_reply *r = (struct gg_pubdir50_reply*) packet;
 	gg_pubdir50_t res;
 	int num = 0;
-
+	
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply(%p, %p, %d);\n", e, packet, length);
 
 	if (!e || !packet) {
 		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n");
-		errno = EINVAL;
+		errno = EFAULT;
 		return -1;
 	}
 
@@ -318,7 +318,7 @@
 		}
 
 		value = NULL;
-
+		
 		for (p = field; p < end; p++) {
 			/* je¶li mamy koniec tekstu... */
 			if (!*p) {
@@ -333,7 +333,7 @@
 					break;
 			}
 		}
-
+		
 		/* sprawd¼my, czy pole nie wychodzi poza pakiet, ¿eby nie
 		 * mieæ segfaultów, je¶li serwer przestanie zakañczaæ pakietów
 		 * przez \0 */
@@ -354,10 +354,10 @@
 			if (gg_pubdir50_add_n(res, num, field, value) == -1)
 				goto failure;
 		}
-	}
+	}	
 
 	res->count = num + 1;
-
+	
 	return 0;
 
 failure:
 
ÄÉÚÁÊÎ É ÒÁÚÒÁÂÏÔËÁ: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
ÔÅËÕÝÉÊ ÍÁÊÎÔÅÊÎÅÒ: Michael Shigorin