Index: kopete/protocols/gadu/libgadu/http.c
===================================================================
--- kopete/protocols/gadu/libgadu/http.c        (.../KDE_3_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/http.c        (.../KDE/3.2/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;
               }

@@ -117,21 +118,20 @@
               h->check = GG_CHECK_READ;
               h->timeout = GG_DEFAULT_TIMEOUT;
       } else {
-               struct hostent *he;
-               struct in_addr a;
+               struct in_addr *hn, a;

-               if (!(he = gg_gethostbyname(hostname))) {
-                        gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n");
+               if (!(hn = gg_gethostbyname(hostname))) {
+                       gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n");
                       gg_http_free(h);
                       errno = ENOENT;
                       return NULL;
               } else {
-                       memcpy((char*) &a, he->h_addr, sizeof(a));
-                       free(he);
+                       a.s_addr = hn->s_addr;
+                       free(hn);
               }

               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;
               }
@@ -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);
@@ -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);
@@ -465,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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/events.c      (.../KDE/3.2/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>
@@ -59,47 +60,60 @@
       if (!e)
               return;

-       if (e->type == GG_EVENT_MSG) {
-               free(e->event.msg.message);
-               free(e->event.msg.formats);
-               free(e->event.msg.recipients);
-       }
+       switch (e->type) {
+               case GG_EVENT_MSG:
+                       free(e->event.msg.message);
+                       free(e->event.msg.formats);
+                       free(e->event.msg.recipients);
+                       break;

-       if (e->type == GG_EVENT_NOTIFY)
-               free(e->event.notify);
+               case GG_EVENT_NOTIFY:
+                       free(e->event.notify);
+                       break;

-       if (e->type == GG_EVENT_NOTIFY60) {
-               int i;
+               case GG_EVENT_NOTIFY60:
+               {
+                       int i;

-               for (i = 0; e->event.notify60[i].uin; i++)
-                       free(e->event.notify60[i].descr);
+                       for (i = 0; e->event.notify60[i].uin; i++)
+                               free(e->event.notify60[i].descr);

-               free(e->event.notify60);
-       }
+                       free(e->event.notify60);

-       if (e->type == GG_EVENT_STATUS60)
-               free(e->event.status60.descr);
+                       break;
+               }
+
+               case GG_EVENT_STATUS60:
+                       free(e->event.status60.descr);
+                       break;

-       if (e->type == GG_EVENT_STATUS)
-               free(e->event.status.descr);
+               case GG_EVENT_STATUS:
+                       free(e->event.status.descr);
+                       break;

-       if (e->type == GG_EVENT_NOTIFY_DESCR) {
-               free(e->event.notify_descr.notify);
-               free(e->event.notify_descr.descr);
-       }
+               case GG_EVENT_NOTIFY_DESCR:
+                       free(e->event.notify_descr.notify);
+                       free(e->event.notify_descr.descr);
+                       break;

-       if (e->type == GG_EVENT_DCC_VOICE_DATA)
-               free(e->event.dcc_voice_data.data);
+               case GG_EVENT_DCC_VOICE_DATA:
+                       free(e->event.dcc_voice_data.data);
+                       break;

-       if (e->type == GG_EVENT_PUBDIR50_SEARCH_REPLY || e->type == GG_EVENT_PUBDIR50_READ || e->type == GG_EVENT_PUBDIR50_WRITE)
-               gg_pubdir50_free(e->event.pubdir50);
+               case GG_EVENT_PUBDIR50_SEARCH_REPLY:
+               case GG_EVENT_PUBDIR50_READ:
+               case GG_EVENT_PUBDIR50_WRITE:
+                       gg_pubdir50_free(e->event.pubdir50);
+                       break;

-       if (e->type == GG_EVENT_USERLIST)
-               free(e->event.userlist.reply);
+               case GG_EVENT_USERLIST:
+                       free(e->event.userlist.reply);
+                       break;

-       if (e->type == GG_EVENT_IMAGE_REPLY) {
-               free(e->event.image_reply.filename);
-               free(e->event.image_reply.image);
+               case GG_EVENT_IMAGE_REPLY:
+                       free(e->event.image_reply.filename);
+                       free(e->event.image_reply.image);
+                       break;
       }

       free(e);
@@ -119,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;
       }

@@ -153,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 */

@@ -285,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;

@@ -306,7 +324,7 @@

                       case 0x02:              /* richtext */
                       {
-                               unsigned short len;
+                               uint16_t len;
                               char *buf;

                               if (p + 3 > packet_end) {
@@ -314,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;
                               }

@@ -361,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,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");
@@ -454,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);
@@ -483,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;
                               }

@@ -494,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);
                               }
                       }

@@ -557,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));

@@ -616,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);
@@ -628,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;
@@ -695,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);

@@ -753,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);

@@ -779,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);
@@ -795,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
@@ -837,7 +885,7 @@

               case GG_STATE_CONNECTING_HUB:
               {
-                       char buf[1024], *client;
+                       char buf[1024], *client, *auth;
                       int res = 0, res_size = sizeof(res);
                       const char *host, *appmsg;

@@ -890,12 +938,18 @@
#endif
                               appmsg = "appmsg2.asp";

+                       auth = gg_proxy_auth();
+
                       snprintf(buf, sizeof(buf) - 1,
                               "GET %s/appsvc/%s?fmnumber=%u&version=%s&lastmsg=%d HTTP/1.0\r\n"
                               "Host: " GG_APPMSG_HOST "\r\n"
                               "User-Agent: " GG_HTTP_USERAGENT "\r\n"
                               "Pragma: no-cache\r\n"
-                               "\r\n", host, appmsg, sess->uin, client, sess->last_sysmsg);
+                               "%s"
+                               "\r\n", host, appmsg, sess->uin, client, sess->last_sysmsg, (auth) ? auth : "");
+
+                       if (auth)
+                               free(auth);

                       free(client);

@@ -905,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,
@@ -1037,7 +1091,7 @@

                       if ((tmp = strchr(host, ':'))) {
                               *tmp = 0;
-                               port = atoi(tmp+1);
+                               port = atoi(tmp + 1);
                       }

                       addr.s_addr = inet_addr(host);
@@ -1136,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,
@@ -1307,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;
                       }
@@ -1336,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;
@@ -1363,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");
@@ -1374,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;
@@ -1399,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;
                       }
@@ -1430,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);

@@ -1467,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/libgadu-config.h.in
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu-config.h.in   (.../KDE_3_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/libgadu-config.h.in   (.../KDE/3.2/kdenetwork/kopete/protocols/gadu/libgadu)  (working copy)
@@ -25,6 +25,6 @@
#undef __GG_LIBGADU_HAVE_OPENSSL

/* Include file containing uintXX_t declarations. */
-#include <stdint.h>
+#include <inttypes.h>

#endif /* __GG_LIBGADU_CONFIG_H */
Index: kopete/protocols/gadu/libgadu/pubdir.c
===================================================================
--- kopete/protocols/gadu/libgadu/pubdir.c      (.../KDE_3_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/pubdir.c      (.../KDE/3.2/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;

@@ -476,7 +495,7 @@
               "Pragma: no-cache\r\n"
               "\r\n";

-       if (!(h = gg_http_connect(GG_APPMSG_HOST, GG_APPMSG_PORT, async, "POST", "/appsvc/regtoken.asp", query))) {
+       if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) {
               gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
               return NULL;
       }
@@ -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_APPMSG_HOST, GG_APPMSG_PORT, h->async, "GET", path, "Host: " GG_APPMSG_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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/libgadu.c     (.../KDE/3.2/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);

@@ -197,18 +199,23 @@
       if (pipe(pipes) == -1)
               return -1;

-       if ((res = fork()) == -1)
+       if ((res = fork()) == -1) {
+               errno2 = errno;
+               close(pipes[0]);
+               close(pipes[1]);
+               errno = errno2;
               return -1;
+       }

       if (!res) {
               if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
-                       struct hostent *he;
+                       struct in_addr *hn;

-                       if (!(he = gg_gethostbyname(hostname)))
+                       if (!(hn = gg_gethostbyname(hostname)))
                               a.s_addr = INADDR_NONE;
                       else {
-                               memcpy((char*) &a, he->h_addr, sizeof(a));
-                               free(he);
+                               a.s_addr = hn->s_addr;
+                               free(hn);
                       }
               }

@@ -237,14 +244,16 @@
       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 hostent *he;
+               struct in_addr *hn;

-               if (!(he = gg_gethostbyname(d->hostname)))
+               if (!(hn = gg_gethostbyname(d->hostname)))
                       a.s_addr = INADDR_NONE;
               else {
-                       memcpy((char*) &a, he->h_addr, sizeof(a));
-                       free(he);
+                       a.s_addr = hn->s_addr;
+                       free(hn);
               }
       }

@@ -277,9 +286,9 @@
 */
int gg_resolve_pthread(int *fd, void **resolver, const char *hostname)
{
-       struct gg_resolve_pthread_data *d;
+       struct gg_resolve_pthread_data *d = NULL;
       pthread_t *tmp;
-       int pipes[2];
+       int pipes[2], new_errno;

       gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve_pthread(%p, %p, \"%s\");\n", fd, resolver, hostname);

@@ -300,20 +309,26 @@
               return -1;
       }

-       if (!(d = malloc(sizeof(*d))) || !(d->hostname = strdup(hostname))) {
+       if (!(d = malloc(sizeof(*d)))) {
               gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
-               free(tmp);
-               return -1;
+               new_errno = errno;
+               goto cleanup;
       }
+
+       d->hostname = NULL;

+       if (!(d->hostname = strdup(hostname))) {
+               gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
+               new_errno = errno;
+               goto cleanup;
+       }
+
       d->fd = pipes[1];

       if (pthread_create(tmp, NULL, gg_resolve_pthread_thread, d)) {
               gg_debug(GG_DEBUG_MISC, "// gg_resolve_phread() unable to create thread\n");
-               close(pipes[0]);
-               close(pipes[1]);
-               free(tmp);
-               return -1;
+               new_errno = errno;
+               goto cleanup;
       }

       gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() %p\n", tmp);
@@ -323,6 +338,21 @@
       *fd = pipes[0];

       return 0;
+
+cleanup:
+       if (d) {
+               free(d->hostname);
+               free(d);
+       }
+
+       close(pipes[0]);
+       close(pipes[1]);
+
+       free(tmp);
+
+       errno = new_errno;
+
+       return -1;
}

#endif
@@ -378,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) {
@@ -396,8 +426,24 @@
               }
       } else
#endif
-               res = write(sess->fd, buf, length);
+       {
+               int written = 0;
+
+               while (written < length) {
+                       res = write(sess->fd, buf + written, length - written);

+                       if (res == -1) {
+                               if (errno == EAGAIN)
+                                       continue;
+                               else
+                                       break;
+                       } else {
+                               written += res;
+                               res = written;
+                       }
+               }
+       }
+
       return res;
}

@@ -409,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);

@@ -439,6 +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 = ECONNRESET;
                               gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() failed: connection broken\n");
                               return NULL;
                       }
@@ -477,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;
@@ -503,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;
@@ -558,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 *);
@@ -584,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 *);
@@ -607,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);
@@ -639,7 +690,7 @@
static int gg_session_callback(struct gg_session *s)
{
       if (!s) {
-               errno = EINVAL;
+               errno = EFAULT;
               return -1;
       }

@@ -669,7 +720,7 @@

       if (!p) {
               gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p);\n", p);
-               errno = EINVAL;
+               errno = EFAULT;
               return NULL;
       }

@@ -684,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;
       }

@@ -703,15 +754,17 @@
       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;
-       sess->port = (p->server_port) ? p->server_port : GG_DEFAULT_PORT;
+       sess->port = (p->server_port) ? p->server_port : ((gg_proxy_enabled) ? GG_HTTPS_PORT : GG_DEFAULT_PORT);
       sess->server_addr = p->server_addr;
       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;
@@ -774,14 +827,14 @@

               if (!p->server_addr || !p->server_port) {
                       if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
-                               struct hostent *he;
+                               struct in_addr *hn;

-                               if (!(he = gg_gethostbyname(hostname))) {
+                               if (!(hn = gg_gethostbyname(hostname))) {
                                       gg_debug(GG_DEBUG_MISC, "// gg_login() host \"%s\" not found\n", hostname);
                                       goto fail;
                               } else {
-                                       memcpy((char*) &a, he->h_addr, sizeof(a));
-                                       free(he);
+                                       a.s_addr = hn->s_addr;
+                                       free(hn);
                               }
                       }
               } else {
@@ -791,6 +844,9 @@

               sess->hub_addr = a.s_addr;

+               if (gg_proxy_enabled)
+                       sess->proxy_addr = a.s_addr;
+
               if ((sess->fd = gg_connect(&a, port, 0)) == -1) {
                       gg_debug(GG_DEBUG_MISC, "// gg_login() connection failed (errno=%d, %s)\n", errno, strerror(errno));
                       goto fail;
@@ -1049,7 +1105,7 @@
#endif

       if (sess->fd != -1) {
-               shutdown(sess->fd, 2);
+               shutdown(sess->fd, SHUT_RDWR);
               close(sess->fd);
               sess->fd = -1;
       }
@@ -1086,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);
@@ -1098,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;
@@ -1148,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);

@@ -1157,8 +1224,18 @@
               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 = rindex(filename, '/')) || (tmp = rindex(filename, '\\')))
+       while ((tmp = strrchr(filename, '/')) || (tmp = strrchr(filename, '\\')))
               filename = tmp + 1;

       if (strlen(filename) < 1 || strlen(filename) > 1024) {
@@ -1166,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);
@@ -1293,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);
@@ -1363,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);

@@ -1378,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]);
@@ -1679,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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/common.c      (.../KDE/3.2/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);
               }
@@ -428,28 +441,90 @@
/*
 * gg_gethostbyname() // funkcja pomocnicza
 *
- * odpowiednik gethostbyname() u�ywaj�cy gethostbyname_r(), gdy potrzebna
- * jest wielobie�no��. chwilowo korzysta ze zwyk�ego gethostbyname().
+ * odpowiednik gethostbyname() troszcz�cy si� o wsp�bie�no��, gdy mamy do
+ * dyspozycji funkcj� gethostbyname_r().
 *
 *  - hostname - nazwa serwera
 *
- * zaalokowany bufor, kt�ry nale�y zwolni� lub NULL w przypadku b��du.
+ * zwraca wska�nik na struktur� in_addr, kt�r� nale�y zwolni�.
 */
-struct hostent *gg_gethostbyname(const char *hostname)
+struct in_addr *gg_gethostbyname(const char *hostname)
{
-       /* XXX u�y� gethostbyname_r() */
+       struct in_addr *addr = NULL;

-       struct hostent *hp, *hp2;
+#ifdef HAVE_GETHOSTBYNAME_R
+       char *tmpbuf = NULL, *buf = NULL;
+       struct hostent *hp = NULL, *hp2 = NULL;
+       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;

+       if (!(buf = malloc(buflen)))
+               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)))) {
+               goto cleanup;
+       }
+
       if (!(hp = gethostbyname(hostname)))
-               return NULL;
+               goto cleanup;

-       if (!(hp2 = calloc(1, sizeof(*hp))))
-               return NULL;
+       memcpy(addr, hp->h_addr, sizeof(struct in_addr));

-       memcpy(hp2, hp, sizeof(*hp));
+       return addr;
+
+cleanup:
+       if (addr)
+               free(addr);

-       return hp2;
+       return NULL;
+#endif
}

#ifdef ASSIGN_SOCKETS_TO_THREADS
@@ -493,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 */
@@ -543,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);

@@ -601,7 +675,7 @@
{
       char *res, *save, *foo, val;
       const char *end;
-       int index = 0;
+       unsigned int index = 0;

       if (!buf)
               return NULL;
@@ -694,8 +768,8 @@
 */
static void gg_crc32_make_table()
{
-       uint32_t h = 0;
-       int i, j;
+       uint32_t h = 1;
+       unsigned int i, j;

       memset(gg_crc32_table, 0, sizeof(gg_crc32_table));

@@ -725,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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/compat.h      (.../KDE/3.2/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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/dcc.c (.../KDE/3.2/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_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/pubdir50.c    (.../KDE/3.2/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;
       }

Index: kopete/protocols/gadu/libgadu/libgadu.h
===================================================================
--- kopete/protocols/gadu/libgadu/libgadu.h     (.../KDE_3_2_BRANCH/kdenetwork/kopete/protocols/gadu/libgadu)   (revision 316997)
+++ kopete/protocols/gadu/libgadu/libgadu.h     (.../KDE/3.2/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,6 +33,10 @@
extern "C" {
#endif

+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
#include <libgadu-config.h>
#include <sys/types.h>
#include <stdio.h>
@@ -52,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 */ \
@@ -106,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 */
@@ -145,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() */

@@ -260,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 */
@@ -345,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 */
};
@@ -495,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 */

@@ -517,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 */
@@ -743,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
@@ -808,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
@@ -903,7 +911,7 @@
char *gg_get_line(char **ptr);

int gg_connect(void *addr, int port, int async);
-struct hostent *gg_gethostbyname(const char *hostname);
+struct in_addr *gg_gethostbyname(const char *hostname);
char *gg_read_line(int sock, char *buf, int length);
void gg_chomp(char *line);
char *gg_urlencode(const char *str);
@@ -935,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 "1.4.20040512"
+#define GG_ERA_OMNIX_MASK 0x04000000
+#define GG_LIBGADU_VERSION "CVS"

#define GG_DEFAULT_DCC_PORT 1550

@@ -1200,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 {