comparison src/protocols/gg/libgg.c @ 2792:9123abd0db92

[gaim-migrate @ 2805] Arkadiusz Miskiewicz's updates to Gadu-Gadu committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Mon, 26 Nov 2001 21:22:56 +0000
parents 04a5f68f640c
children 4b3f17ca66bf
comparison
equal deleted inserted replaced
2791:8f6365332a05 2792:9123abd0db92
1 /* $Id: libgg.c 2608 2001-10-24 08:35:55Z warmenhoven $ */ 1 /* $Id: libgg.c 2805 2001-11-26 21:22:56Z warmenhoven $ */
2 2
3 /* 3 /*
4 * (C) Copyright 2001 Wojtek Kaniewski <wojtekka@irc.pl> 4 * (C) Copyright 2001 Wojtek Kaniewski <wojtekka@irc.pl>,
5 * Robert J. Woźny <speedy@atman.pl>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License Version 2 as 8 * it under the terms of the GNU General Public License Version 2 as
8 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
9 * 10 *
24 #include <sys/socket.h> 25 #include <sys/socket.h>
25 #include <netinet/in.h> 26 #include <netinet/in.h>
26 #include <arpa/inet.h> 27 #include <arpa/inet.h>
27 #include <sys/ioctl.h> 28 #include <sys/ioctl.h>
28 #include <sys/wait.h> 29 #include <sys/wait.h>
29 #include <sys/types.h> 30 #include <sys/time.h>
30 #include <fcntl.h>
31 #include <netdb.h> 31 #include <netdb.h>
32 #include <errno.h> 32 #include <errno.h>
33 #include <string.h> 33 #ifndef _AIX
34 # include <string.h>
35 #endif
34 #include <stdarg.h> 36 #include <stdarg.h>
35 #include <pwd.h> 37 #include <pwd.h>
38 #include <time.h>
39 #ifdef sun
40 #include <sys/filio.h>
41 #endif
36 #include <glib.h> 42 #include <glib.h>
43 #if G_BYTE_ORDER == G_BIG_ENDIAN
44 # define WORDS_BIGENDIAN 1
45 #endif
37 #include "libgg.h" 46 #include "libgg.h"
47 #include "config.h"
38 48
39 int gg_debug_level = 0; 49 int gg_debug_level = 0;
40 50
41 #ifdef GG_DEBUG 51 #ifndef lint
42 52
43 /* 53 static char rcsid[]
44 * gg_debug_real() 54 #ifdef __GNUC__
55 __attribute__ ((unused))
56 #endif
57 = "$Id: libgg.c 2805 2001-11-26 21:22:56Z warmenhoven $";
58
59 #endif
60
61 /*
62 * gg_debug()
45 * 63 *
46 * wyrzuca komunikat o danym poziomie, o ile użytkownik sobie tego życzy. 64 * wyrzuca komunikat o danym poziomie, o ile użytkownik sobie tego życzy.
47 * 65 *
48 * - level - poziom wiadomości, 66 * - level - poziom wiadomości,
49 * - format... - treść wiadomości (printf-alike.) 67 * - format... - treść wiadomości (printf-alike.)
50 * 68 *
51 * niczego nie zwraca. 69 * niczego nie zwraca.
52 */ 70 */
53 void gg_debug_real(int level, char *format, ...) 71 void gg_debug(int level, char *format, ...)
54 { 72 {
55 va_list ap; 73 va_list ap;
56 74
57 if ((gg_debug_level & level)) { 75 if ((gg_debug_level & level)) {
58 va_start(ap, format); 76 va_start(ap, format);
59 vprintf(format, ap); 77 vprintf(format, ap);
60 va_end(ap); 78 va_end(ap);
61 } 79 }
62 } 80 }
63 81
64 #endif /* GG_DEBUG */
65
66 /* 82 /*
67 * fix32() // funkcja wewnętrzna 83 * fix32() // funkcja wewnętrzna
68 * 84 *
69 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,long''ach. 85 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,long''ach.
70 */ 86 */
71 static inline unsigned long fix32(unsigned long x) 87 static inline unsigned long fix32(unsigned long x)
72 { 88 {
73 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 89 #ifndef WORDS_BIGENDIAN
74 return x; 90 return x;
75 #else 91 #else
76 return (unsigned long) 92 return (unsigned long)
77 (((x & (unsigned long) 0x000000ffU) << 24) | 93 (((x & (unsigned long)0x000000ffU) << 24) |
78 ((x & (unsigned long) 0x0000ff00U) << 8) | 94 ((x & (unsigned long)0x0000ff00U) << 8) |
79 ((x & (unsigned long) 0x00ff0000U) >> 8) | 95 ((x & (unsigned long)0x00ff0000U) >> 8) | ((x & (unsigned long)0xff000000U) >> 24));
80 ((x & (unsigned long) 0xff000000U) >> 24)); 96 #endif
81 #endif
82 } 97 }
83 98
84 /* 99 /*
85 * fix16() // funkcja wewnętrzna 100 * fix16() // funkcja wewnętrzna
86 * 101 *
87 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,short''ach. 102 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,short''ach.
88 */ 103 */
89 static inline unsigned short fix16(unsigned short x) 104 static inline unsigned short fix16(unsigned short x)
90 { 105 {
91 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 106 #ifndef WORDS_BIGENDIAN
92 return x; 107 return x;
93 #else 108 #else
94 return (unsigned short) 109 return (unsigned short)
95 (((x & (unsigned short) 0x00ffU) << 8) | 110 (((x & (unsigned short)0x00ffU) << 8) | ((x & (unsigned short)0xff00U) >> 8));
96 ((x & (unsigned short) 0xff00U) >> 8));
97 #endif 111 #endif
98 } 112 }
99 113
100 /* 114 /*
101 * gg_alloc_sprintf() // funkcja wewnętrzna 115 * gg_alloc_sprintf() // funkcja wewnętrzna
102 * 116 *
103 * robi dokładnie to samo, co sprintf(), tyle że alokuje sobie wcześniej 117 * robi dokładnie to samo, co sprintf(), tyle że alokuje sobie wcześniej
104 * miejsce na dane. jak znam życie, ze względu na różnice między funkcjami 118 * miejsce na dane. powinno działać na tych maszynach, które mają funkcję
105 * vsnprintf() na różnych platformach, nie będzie działało ;) 119 * vsnprintf() zgodną z C99, jak i na wcześniejszych.
106 * 120 *
107 * - format, ... - parametry takie same jak w innych funkcjach *printf() 121 * - format, ... - parametry takie same jak w innych funkcjach *printf()
108 * 122 *
109 * zwraca zaalokowany buforek, który wypadałoby później zwolnić, lub NULL 123 * zwraca zaalokowany buforek, który wypadałoby później zwolnić, lub NULL
110 * jeśli nie udało się wykonać zadania. 124 * jeśli nie udało się wykonać zadania.
111 */ 125 */
112 char *gg_alloc_sprintf(char *format, ...) 126 char *gg_alloc_sprintf(char *format, ...)
113 { 127 {
114 va_list ap; 128 va_list ap;
115 char *buf = NULL; 129 char *buf = NULL, *tmp;
116 int size; 130 int size = 0, res;
117 131
118 va_start(ap, format); 132 va_start(ap, format);
119 133
120 if ((size = vsnprintf(buf, 0, format, ap)) < 0) 134 if ((size = vsnprintf(buf, 0, format, ap)) < 1) {
135 size = 128;
136 do {
137 size *= 2;
138 if (!(tmp = realloc(buf, size))) {
139 free(buf);
140 return NULL;
141 }
142 buf = tmp;
143 res = vsnprintf(buf, size, format, ap);
144 } while (res == size - 1);
145 } else {
146 if (!(buf = malloc(size + 1)))
147 return NULL;
148 }
149
150 vsnprintf(buf, size + 1, format, ap);
151
152 va_end(ap);
153
154 return buf;
155 }
156
157 /*
158 * gg_get_line() // funkcja wewnętrzna
159 *
160 * podaje kolejną linię z bufora tekstowego. psuje co bezpowrotnie, dzieląc
161 * na kolejne stringi. zdarza się, nie ma potrzeby pisania funkcji dublującej
162 * bufor żeby tylko mieć nieruszone dane wejściowe, skoro i tak nie będą nam
163 * poźniej potrzebne. obcina `\r\n'.
164 *
165 * - ptr - wskaźnik do zmiennej, która przechowuje aktualną pozycję
166 * w przemiatanym buforze.
167 *
168 * wskaźnik do kolejnej linii tekstu lub NULL, jeśli to już koniec bufora.
169 */
170 char *gg_get_line(char **ptr)
171 {
172 char *foo, *res;
173
174 if (!ptr || !*ptr || !strcmp(*ptr, ""))
121 return NULL; 175 return NULL;
122 176
123 if (!(buf = malloc(size + 1))) 177 res = *ptr;
124 return NULL; 178
125 179 if (!(foo = strchr(*ptr, '\n')))
126 vsnprintf(buf, size + 1, format, ap); 180 *ptr += strlen(*ptr);
127 181 else {
128 va_end(ap); 182 *ptr = foo + 1;
129 183 *foo = 0;
130 return buf; 184 if (res[strlen(res) - 1] == '\r')
185 res[strlen(res) - 1] = 0;
186 }
187
188 return res;
131 } 189 }
132 190
133 /* 191 /*
134 * gg_resolve() // funkcja wewnętrzna 192 * gg_resolve() // funkcja wewnętrzna
135 * 193 *
148 { 206 {
149 int pipes[2], res; 207 int pipes[2], res;
150 struct in_addr a; 208 struct in_addr a;
151 209
152 gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve(..., \"%s\");\n", hostname); 210 gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve(..., \"%s\");\n", hostname);
153 211
154 if (!fd | !pid) { 212 if (!fd | !pid) {
155 errno = EFAULT; 213 errno = EFAULT;
156 return -1; 214 return -1;
157 } 215 }
158 216
163 return -1; 221 return -1;
164 222
165 if (!res) { 223 if (!res) {
166 if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) { 224 if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
167 struct hostent *he; 225 struct hostent *he;
168 226
169 if (!(he = gethostbyname(hostname))) 227 if (!(he = gethostbyname(hostname)))
170 a.s_addr = INADDR_NONE; 228 a.s_addr = INADDR_NONE;
171 else 229 else
172 memcpy((char*) &a, he->h_addr, sizeof(a)); 230 memcpy((char *)&a, he->h_addr, sizeof(a));
173 } 231 }
174 232
175 write(pipes[1], &a, sizeof(a)); 233 write(pipes[1], &a, sizeof(a));
176 234
177 exit(0); 235 exit(0);
203 int sock, one = 1; 261 int sock, one = 1;
204 struct sockaddr_in sin; 262 struct sockaddr_in sin;
205 struct in_addr *a = addr; 263 struct in_addr *a = addr;
206 264
207 gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async); 265 gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async);
208 266
209 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { 267 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
210 gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d (%s)\n", errno, strerror(errno)); 268 gg_debug(GG_DEBUG_MISC, "-- socket() failed. errno = %d (%s)\n", errno, strerror(errno));
211 return -1; 269 return -1;
212 } 270 }
213 271
214 if (async) { 272 if (async) {
215 #ifdef FIONBIO
216 if (ioctl(sock, FIONBIO, &one) == -1) { 273 if (ioctl(sock, FIONBIO, &one) == -1) {
217 #else 274 gg_debug(GG_DEBUG_MISC, "-- ioctl() failed. errno = %d (%s)\n", errno,
218 int flags = fcntl (sock, F_GETFL); 275 strerror(errno));
219 if (flags < 0 ||
220 fcntl (sock, F_SETFL, flags | O_NONBLOCK) < 0) {
221 #endif
222 gg_debug(GG_DEBUG_MISC, "-- ioctl() failed. errno = %d (%s)\n", errno, strerror(errno));
223 return -1; 276 return -1;
224 } 277 }
225 } 278 }
226 279
227 sin.sin_port = htons(port); 280 sin.sin_port = htons(port);
228 sin.sin_family = AF_INET; 281 sin.sin_family = AF_INET;
229 sin.sin_addr.s_addr = a->s_addr; 282 sin.sin_addr.s_addr = a->s_addr;
230 283
231 if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) { 284 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
232 gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); 285 if (errno && (!async || errno != EINPROGRESS)) {
233 if (errno && (!async || errno != EINPROGRESS)) 286 gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno,
287 strerror(errno));
234 return -1; 288 return -1;
235 } 289 }
236 290 gg_debug(GG_DEBUG_MISC, "-- connect() in progress\n");
291 }
292
237 return sock; 293 return sock;
238 } 294 }
239 295
240 /* 296 /*
241 * gg_read_line() // funkcja wewnętrzna 297 * gg_read_line() // funkcja wewnętrzna
251 static void gg_read_line(int sock, char *buf, int length) 307 static void gg_read_line(int sock, char *buf, int length)
252 { 308 {
253 int ret; 309 int ret;
254 310
255 gg_debug(GG_DEBUG_FUNCTION, "** gg_read_line(...);\n"); 311 gg_debug(GG_DEBUG_FUNCTION, "** gg_read_line(...);\n");
256 312
257 for (; length > 1; buf++, length--) { 313 for (; length > 1; buf++, length--) {
258 do { 314 do {
259 if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) { 315 if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) {
260 *buf = 0; 316 *buf = 0;
261 return; 317 return;
287 struct gg_header h; 343 struct gg_header h;
288 char *buf = NULL; 344 char *buf = NULL;
289 int ret = 0, offset, size = 0; 345 int ret = 0, offset, size = 0;
290 346
291 gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(...);\n"); 347 gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(...);\n");
292 348
293 if (!sess) { 349 if (!sess) {
294 errno = EFAULT; 350 errno = EFAULT;
295 return NULL; 351 return NULL;
296 } 352 }
297 353
299 while (ret != sizeof(h)) { 355 while (ret != sizeof(h)) {
300 ret = read(sess->fd, &h, sizeof(h)); 356 ret = read(sess->fd, &h, sizeof(h));
301 gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeof(h), ret); 357 gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeof(h), ret);
302 if (ret < sizeof(h)) { 358 if (ret < sizeof(h)) {
303 if (errno != EINTR) { 359 if (errno != EINTR) {
304 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); 360 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno,
361 strerror(errno));
305 return NULL; 362 return NULL;
306 } 363 }
307 } 364 }
308 } 365 }
309 366
341 ret = read(sess->fd, buf + sizeof(h) + offset, size); 398 ret = read(sess->fd, buf + sizeof(h) + offset, size);
342 gg_debug(GG_DEBUG_MISC, "-- body recv(..., %d) = %d\n", size, ret); 399 gg_debug(GG_DEBUG_MISC, "-- body recv(..., %d) = %d\n", size, ret);
343 if (ret > -1 && ret <= size) { 400 if (ret > -1 && ret <= size) {
344 offset += ret; 401 offset += ret;
345 size -= ret; 402 size -= ret;
346 } else if (ret == -1) { 403 } else if (ret == -1) {
347 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); 404 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno));
348 if (errno == EAGAIN) { 405 if (errno == EAGAIN) {
349 gg_debug(GG_DEBUG_MISC, "-- %d bytes received, %d left\n", offset, size); 406 gg_debug(GG_DEBUG_MISC, "-- %d bytes received, %d left\n", offset, size);
350 sess->recv_buf = buf; 407 sess->recv_buf = buf;
351 sess->recv_left = size; 408 sess->recv_left = size;
352 sess->recv_done = offset; 409 sess->recv_done = offset;
353 return NULL; 410 return NULL;
354 } 411 }
355 if (errno != EINTR) { 412 if (errno != EINTR) {
356 /* errno = EINVAL; */ 413 // errno = EINVAL;
357 free(buf); 414 free(buf);
358 return NULL; 415 return NULL;
359 } 416 }
360 } 417 }
361 } 418 }
362 419
363 sess->recv_left = 0; 420 sess->recv_left = 0;
364 421
365 #ifdef GG_DEBUG
366 if ((gg_debug_level & GG_DEBUG_DUMP)) { 422 if ((gg_debug_level & GG_DEBUG_DUMP)) {
367 int i; 423 int i;
368 424
369 gg_debug(GG_DEBUG_DUMP, ">> received packet (type=%.2x):", h.type); 425 gg_debug(GG_DEBUG_DUMP, ">> received packet (type=%.2x):", h.type);
370 for (i = 0; i < sizeof(h) + h.length; i++) 426 for (i = 0; i < sizeof(h) + h.length; i++)
371 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) buf[i]); 427 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char)buf[i]);
372 gg_debug(GG_DEBUG_DUMP, "\n"); 428 gg_debug(GG_DEBUG_DUMP, "\n");
373 } 429 }
374 #endif
375 430
376 return buf; 431 return buf;
377 } 432 }
378 433
379 /* 434 /*
390 * 445 *
391 * jeśli poszło dobrze, zwraca 0. w przypadku błędu -1. jeśli errno=ENOMEM, 446 * jeśli poszło dobrze, zwraca 0. w przypadku błędu -1. jeśli errno=ENOMEM,
392 * zabrakło pamięci. inaczej był błąd przy wysyłaniu pakietu. dla errno=0 447 * zabrakło pamięci. inaczej był błąd przy wysyłaniu pakietu. dla errno=0
393 * nie wysłano całego pakietu. 448 * nie wysłano całego pakietu.
394 */ 449 */
395 static int gg_send_packet(int sock, int type, void *packet, int length, void *payload, int payload_length) 450 static int gg_send_packet(int sock, int type, void *packet, int length, void *payload,
451 int payload_length)
396 { 452 {
397 struct gg_header *h; 453 struct gg_header *h;
398 int res, plen; 454 int res, plen;
399 char *tmp; 455 char *tmp;
400 456
401 gg_debug(GG_DEBUG_FUNCTION, "** gg_send_packet(0x%.2x, %d, %d);\n", type, length, payload_length); 457 gg_debug(GG_DEBUG_FUNCTION, "** gg_send_packet(0x%.2x, %d, %d);\n", type, length,
402 458 payload_length);
459
403 if (length < 0 || payload_length < 0) { 460 if (length < 0 || payload_length < 0) {
404 gg_debug(GG_DEBUG_MISC, "-- invalid packet/payload length\n"); 461 gg_debug(GG_DEBUG_MISC, "-- invalid packet/payload length\n");
405 errno = ERANGE; 462 errno = ERANGE;
406 return -1; 463 return -1;
407 } 464 }
409 if (!(tmp = malloc(sizeof(struct gg_header) + length + payload_length))) { 466 if (!(tmp = malloc(sizeof(struct gg_header) + length + payload_length))) {
410 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); 467 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
411 return -1; 468 return -1;
412 } 469 }
413 470
414 h = (struct gg_header*) tmp; 471 h = (struct gg_header *)tmp;
415 h->type = fix32(type); 472 h->type = fix32(type);
416 h->length = fix32(length + payload_length); 473 h->length = fix32(length + payload_length);
417 474
418 if (packet) 475 if (packet)
419 memcpy(tmp + sizeof(struct gg_header), packet, length); 476 memcpy(tmp + sizeof(struct gg_header), packet, length);
420 if (payload) 477 if (payload)
421 memcpy(tmp + sizeof(struct gg_header) + length, payload, payload_length); 478 memcpy(tmp + sizeof(struct gg_header) + length, payload, payload_length);
422 479
423 #ifdef GG_DEBUG
424 if ((gg_debug_level & GG_DEBUG_DUMP)) { 480 if ((gg_debug_level & GG_DEBUG_DUMP)) {
425 int i; 481 int i;
426 482
427 gg_debug(GG_DEBUG_DUMP, "%%%% sending packet (type=%.2x):", fix32(h->type)); 483 gg_debug(GG_DEBUG_DUMP, "%%%% sending packet (type=%.2x):", fix32(h->type));
428 for (i = 0; i < sizeof(struct gg_header) + fix32(h->length); i++) 484 for (i = 0; i < sizeof(struct gg_header) + fix32(h->length); i++)
429 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) tmp[i]); 485 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char)tmp[i]);
430 gg_debug(GG_DEBUG_DUMP, "\n"); 486 gg_debug(GG_DEBUG_DUMP, "\n");
431 } 487 }
432 #endif
433 488
434 plen = sizeof(struct gg_header) + length + payload_length; 489 plen = sizeof(struct gg_header) + length + payload_length;
435 490
436 if ((res = write(sock, tmp, plen)) < plen) { 491 if ((res = write(sock, tmp, plen)) < plen) {
437 gg_debug(GG_DEBUG_MISC, "-- write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno)); 492 gg_debug(GG_DEBUG_MISC, "-- write() failed. res = %d, errno = %d (%s)\n", res, errno,
493 strerror(errno));
438 free(tmp); 494 free(tmp);
439 return -1; 495 return -1;
440 } 496 }
441 497
442 free(tmp); 498 free(tmp);
443 return 0; 499 return 0;
444 } 500 }
445 501
446 502
447 /* 503 /*
477 sess->state = GG_STATE_RESOLVING; 533 sess->state = GG_STATE_RESOLVING;
478 sess->check = GG_CHECK_READ; 534 sess->check = GG_CHECK_READ;
479 sess->async = async; 535 sess->async = async;
480 sess->seq = 0; 536 sess->seq = 0;
481 sess->recv_left = 0; 537 sess->recv_left = 0;
538 sess->last_pong = 0;
539 sess->server_ip = 0;
540 sess->initial_status = 0;
482 541
483 if (async) { 542 if (async) {
484 if (gg_resolve(&sess->fd, &sess->pid, GG_APPMSG_HOST)) { 543 if (gg_resolve(&sess->fd, &sess->pid, GG_APPMSG_HOST)) {
485 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n"); 544 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n");
486 free(sess); 545 free(sess);
489 } else { 548 } else {
490 struct in_addr a; 549 struct in_addr a;
491 550
492 if ((a.s_addr = inet_addr(GG_APPMSG_HOST)) == INADDR_NONE) { 551 if ((a.s_addr = inet_addr(GG_APPMSG_HOST)) == INADDR_NONE) {
493 struct hostent *he; 552 struct hostent *he;
494 553
495 if (!(he = gethostbyname(GG_APPMSG_HOST))) { 554 if (!(he = gethostbyname(GG_APPMSG_HOST))) {
496 gg_debug(GG_DEBUG_MISC, "-- host %s not found\n", GG_APPMSG_HOST); 555 gg_debug(GG_DEBUG_MISC, "-- host %s not found\n", GG_APPMSG_HOST);
497 free(sess); 556 free(sess);
498 return NULL; 557 return NULL;
499 } else 558 } else
500 memcpy((char*) &a, he->h_addr, sizeof(a)); 559 memcpy((char *)&a, he->h_addr, sizeof(a));
501 } 560 }
502 561
503 if (!(sess->fd = gg_connect(&a, GG_APPMSG_PORT, 0)) == -1) { 562 if (!(sess->fd = gg_connect(&a, GG_APPMSG_PORT, 0)) == -1) {
504 gg_debug(GG_DEBUG_MISC, "-- connection failed\n"); 563 gg_debug(GG_DEBUG_MISC, "-- connection failed\n");
505 free(sess); 564 free(sess);
516 free(sess); 575 free(sess);
517 return NULL; 576 return NULL;
518 } 577 }
519 578
520 if (e->type == GG_EVENT_CONN_FAILED) { 579 if (e->type == GG_EVENT_CONN_FAILED) {
580 errno = EACCES;
521 gg_debug(GG_DEBUG_MISC, "-- could not login\n"); 581 gg_debug(GG_DEBUG_MISC, "-- could not login\n");
522 gg_free_event(e); 582 gg_free_event(e);
523 free(sess); 583 free(sess);
524 return NULL; 584 return NULL;
525 } 585 }
596 656
597 gg_debug(GG_DEBUG_FUNCTION, "** gg_logoff(...);\n"); 657 gg_debug(GG_DEBUG_FUNCTION, "** gg_logoff(...);\n");
598 658
599 if (sess->state == GG_STATE_CONNECTED) 659 if (sess->state == GG_STATE_CONNECTED)
600 gg_change_status(sess, GG_STATUS_NOT_AVAIL); 660 gg_change_status(sess, GG_STATUS_NOT_AVAIL);
601 661
602 if (sess->fd) { 662 if (sess->fd) {
603 shutdown(sess->fd, 2); 663 shutdown(sess->fd, 2);
604 close(sess->fd); 664 close(sess->fd);
605 } 665 }
606 } 666 }
624 684
625 if (!sess) { 685 if (!sess) {
626 errno = EFAULT; 686 errno = EFAULT;
627 return -1; 687 return -1;
628 } 688 }
629 689
630 if (sess->state != GG_STATE_CONNECTED) { 690 if (sess->state != GG_STATE_CONNECTED) {
631 errno = ENOTCONN; 691 errno = ENOTCONN;
632 return -1; 692 return -1;
633 } 693 }
634 694
638 if (!sess->seq) 698 if (!sess->seq)
639 sess->seq = 0x01740000 | (rand() & 0xffff); 699 sess->seq = 0x01740000 | (rand() & 0xffff);
640 s.seq = fix32(sess->seq); 700 s.seq = fix32(sess->seq);
641 s.msgclass = fix32(msgclass); 701 s.msgclass = fix32(msgclass);
642 sess->seq += (rand() % 0x300) + 0x300; 702 sess->seq += (rand() % 0x300) + 0x300;
643 703
644 if (gg_send_packet(sess->fd, GG_SEND_MSG, &s, sizeof(s), message, strlen(message) + 1) == -1) 704 if (gg_send_packet(sess->fd, GG_SEND_MSG, &s, sizeof(s), message, strlen(message) + 1) == -1)
645 return -1; 705 return -1;
646 706
647 return fix32(s.seq); 707 return fix32(s.seq);
648 } 708 }
702 * - userlist - wskaźnik do tablicy numerów, 762 * - userlist - wskaźnik do tablicy numerów,
703 * - count - ilość numerków. 763 * - count - ilość numerków.
704 * 764 *
705 * jeśli udało się, zwraca 0. jeśli błąd, dostajemy -1. 765 * jeśli udało się, zwraca 0. jeśli błąd, dostajemy -1.
706 */ 766 */
707 int gg_notify(struct gg_session *sess, uin_t *userlist, int count) 767 int gg_notify(struct gg_session *sess, uin_t * userlist, int count)
708 { 768 {
709 struct gg_notify *n; 769 struct gg_notify *n;
710 uin_t *u; 770 uin_t *u;
711 int i, res = 0; 771 int i, res = 0;
712 772
713 if (!sess) { 773 if (!sess) {
714 errno = EFAULT; 774 errno = EFAULT;
715 return -1; 775 return -1;
716 } 776 }
717 777
718 if (sess->state != GG_STATE_CONNECTED) { 778 if (sess->state != GG_STATE_CONNECTED) {
719 errno = ENOTCONN; 779 errno = ENOTCONN;
720 return -1; 780 return -1;
721 } 781 }
722 782
723 gg_debug(GG_DEBUG_FUNCTION, "** gg_notify(..., %d);\n", count); 783 gg_debug(GG_DEBUG_FUNCTION, "** gg_notify(..., %d);\n", count);
724 784
725 if (!userlist || !count) 785 if (!userlist || !count)
726 return 0; 786 return 0;
727 787
728 if (!(n = (struct gg_notify*) malloc(sizeof(*n) * count))) 788 if (!(n = (struct gg_notify *)malloc(sizeof(*n) * count)))
729 return -1; 789 return -1;
730 790
731 for (u = userlist, i = 0; i < count; u++, i++) { 791 for (u = userlist, i = 0; i < count; u++, i++) {
732 n[i].uin = fix32(*u); 792 n[i].uin = fix32(*u);
733 n[i].dunno1 = 3; 793 n[i].dunno1 = 3;
734 } 794 }
735 795
736 if (gg_send_packet(sess->fd, GG_NOTIFY, n, sizeof(*n) * count, NULL, 0) == -1) 796 if (gg_send_packet(sess->fd, GG_NOTIFY, n, sizeof(*n) * count, NULL, 0) == -1)
737 res = -1; 797 res = -1;
738 798
739 free(n); 799 free(n);
740 800
762 822
763 if (sess->state != GG_STATE_CONNECTED) { 823 if (sess->state != GG_STATE_CONNECTED) {
764 errno = ENOTCONN; 824 errno = ENOTCONN;
765 return -1; 825 return -1;
766 } 826 }
767 827
768 gg_debug(GG_DEBUG_FUNCTION, "** gg_add_notify(..., %u);\n", uin); 828 gg_debug(GG_DEBUG_FUNCTION, "** gg_add_notify(..., %u);\n", uin);
769 829
770 a.uin = fix32(uin); 830 a.uin = fix32(uin);
771 a.dunno1 = 3; 831 a.dunno1 = 3;
772 832
773 return gg_send_packet(sess->fd, GG_ADD_NOTIFY, &a, sizeof(a), NULL, 0); 833 return gg_send_packet(sess->fd, GG_ADD_NOTIFY, &a, sizeof(a), NULL, 0);
774 } 834 }
775 835
776 /* 836 /*
777 * gg_remove_notify() 837 * gg_remove_notify()
796 errno = ENOTCONN; 856 errno = ENOTCONN;
797 return -1; 857 return -1;
798 } 858 }
799 859
800 gg_debug(GG_DEBUG_FUNCTION, "** gg_remove_notify(..., %u);\n", uin); 860 gg_debug(GG_DEBUG_FUNCTION, "** gg_remove_notify(..., %u);\n", uin);
801 861
802 a.uin = fix32(uin); 862 a.uin = fix32(uin);
803 a.dunno1 = 3; 863 a.dunno1 = 3;
804 864
805 return gg_send_packet(sess->fd, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL, 0); 865 return gg_send_packet(sess->fd, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL, 0);
806 } 866 }
807 867
808 /* 868 /*
809 * gg_watch_fd_connected() // funkcja wewnętrzna 869 * gg_watch_fd_connected() // funkcja wewnętrzna
825 } 885 }
826 886
827 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd_connected(...);\n"); 887 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd_connected(...);\n");
828 888
829 if (!(h = gg_recv_packet(sess))) { 889 if (!(h = gg_recv_packet(sess))) {
830 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet failed. errno = %d (%d)\n", errno, strerror(errno)); 890 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet failed. errno = %d (%d)\n", errno,
831 return -1; 891 strerror(errno));
832 } 892 return -1;
833 893 }
834 p = (void*) h + sizeof(struct gg_header); 894
835 895 p = (void *)h + sizeof(struct gg_header);
896
836 if (h->type == GG_RECV_MSG) { 897 if (h->type == GG_RECV_MSG) {
837 struct gg_recv_msg *r = p; 898 struct gg_recv_msg *r = p;
838 899
839 gg_debug(GG_DEBUG_MISC, "-- received a message\n"); 900 gg_debug(GG_DEBUG_MISC, "-- received a message\n");
840 901
841 if (h->length >= sizeof(*r)) { 902 if (h->length >= sizeof(*r)) {
842 e->type = GG_EVENT_MSG; 903 e->type = GG_EVENT_MSG;
843 e->event.msg.msgclass = fix32(r->msgclass); 904 e->event.msg.msgclass = fix32(r->msgclass);
844 e->event.msg.sender = fix32(r->sender); 905 e->event.msg.sender = fix32(r->sender);
845 e->event.msg.message = strdup((char*) r + sizeof(*r)); 906 e->event.msg.message = strdup((char *)r + sizeof(*r));
907 e->event.msg.time = fix32(r->time);
846 } 908 }
847 } 909 }
848 910
849 if (h->type == GG_NOTIFY_REPLY) { 911 if (h->type == GG_NOTIFY_REPLY) {
850 struct gg_notify_reply *n = p; 912 struct gg_notify_reply *n = p;
851 int count, i; 913 int count, i;
852 914
853 gg_debug(GG_DEBUG_MISC, "-- received a notify reply\n"); 915 gg_debug(GG_DEBUG_MISC, "-- received a notify reply\n");
854 916
855 e->type = GG_EVENT_NOTIFY; 917 e->type = GG_EVENT_NOTIFY;
856 if (!(e->event.notify = (void*) malloc(h->length + 2 * sizeof(*n)))) { 918 if (!(e->event.notify = (void *)malloc(h->length + 2 * sizeof(*n)))) {
857 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); 919 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
858 free(h); 920 free(h);
859 return -1; 921 return -1;
860 } 922 }
861 count = h->length / sizeof(*n); 923 count = h->length / sizeof(*n);
891 e->event.ack.recipient = fix32(s->recipient); 953 e->event.ack.recipient = fix32(s->recipient);
892 e->event.ack.seq = fix32(s->seq); 954 e->event.ack.seq = fix32(s->seq);
893 } 955 }
894 } 956 }
895 957
958 if (h->type == GG_PONG) {
959 gg_debug(GG_DEBUG_MISC, "-- received a pong\n");
960
961 sess->last_pong = time(NULL);
962 }
963
896 free(h); 964 free(h);
897 965
898 return 0; 966 return 0;
899 } 967 }
900 968
942 return NULL; 1010 return NULL;
943 } 1011 }
944 1012
945 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(...);\n"); 1013 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(...);\n");
946 1014
947 if (!(e = (void*) malloc(sizeof(*e)))) { 1015 if (!(e = (void *)malloc(sizeof(*e)))) {
948 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); 1016 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
949 return NULL; 1017 return NULL;
950 } 1018 }
951 1019
952 e->type = GG_EVENT_NONE; 1020 e->type = GG_EVENT_NONE;
953 1021
954 switch (sess->state) { 1022 switch (sess->state) {
955 case GG_STATE_RESOLVING: 1023 case GG_STATE_RESOLVING:
956 { 1024 {
957 struct in_addr a; 1025 struct in_addr a;
958 1026
959 gg_debug(GG_DEBUG_MISC, "== GG_STATE_RESOLVING\n"); 1027 gg_debug(GG_DEBUG_MISC, "== GG_STATE_RESOLVING\n");
960 1028
961 if (read(sess->fd, &a, sizeof(a)) < sizeof(a) || a.s_addr == INADDR_NONE) { 1029 if (read(sess->fd, &a, sizeof(a)) < sizeof(a) || a.s_addr == INADDR_NONE) {
962 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n"); 1030 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n");
963 1031
1032 errno = ENOENT;
964 e->type = GG_EVENT_CONN_FAILED; 1033 e->type = GG_EVENT_CONN_FAILED;
965 e->event.failure = GG_FAILURE_RESOLVING; 1034 e->event.failure = GG_FAILURE_RESOLVING;
966 sess->state = GG_STATE_IDLE; 1035 sess->state = GG_STATE_IDLE;
967 1036
968 close(sess->fd); 1037 close(sess->fd);
969 1038
970 break; 1039 break;
971 } 1040 }
972 1041
1042 sess->server_ip = a.s_addr;
1043
973 close(sess->fd); 1044 close(sess->fd);
974 1045
975 waitpid(sess->pid, NULL, 0); 1046 waitpid(sess->pid, NULL, 0);
976 1047
977 gg_debug(GG_DEBUG_MISC, "-- resolved, now connecting\n"); 1048 gg_debug(GG_DEBUG_MISC, "-- resolved, now connecting\n");
978 1049
979 if ((sess->fd = gg_connect(&a, GG_APPMSG_PORT, sess->async)) == -1) { 1050 if ((sess->fd = gg_connect(&a, GG_APPMSG_PORT, sess->async)) == -1) {
980 gg_debug(GG_DEBUG_MISC, "-- connection failed\n"); 1051 struct in_addr *addr = (struct in_addr *)&sess->server_ip;
981 1052
982 e->type = GG_EVENT_CONN_FAILED; 1053 gg_debug(GG_DEBUG_MISC,
983 e->event.failure = GG_FAILURE_CONNECTING; 1054 "-- connection failed, trying direct connection\n");
984 sess->state = GG_STATE_IDLE; 1055
985 break; 1056 if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) {
986 } 1057 gg_debug(GG_DEBUG_MISC,
987 1058 "-- connection failed, trying https connection\n");
988 sess->state = GG_STATE_CONNECTING_HTTP; 1059 if ((sess->fd =
989 sess->check = GG_CHECK_WRITE; 1060 gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) {
1061 gg_debug(GG_DEBUG_MISC,
1062 "-- connect() failed. errno = %d (%s)\n", errno,
1063 strerror(errno));
1064
1065 e->type = GG_EVENT_CONN_FAILED;
1066 e->event.failure = GG_FAILURE_CONNECTING;
1067 sess->state = GG_STATE_IDLE;
1068 break;
1069 }
1070 }
1071 sess->state = GG_STATE_CONNECTING_GG;
1072 sess->check = GG_CHECK_WRITE;
1073 } else {
1074 sess->state = GG_STATE_CONNECTING_HTTP;
1075 sess->check = GG_CHECK_WRITE;
1076 }
990 1077
991 break; 1078 break;
992 } 1079 }
993 1080
994 case GG_STATE_CONNECTING_HTTP: 1081 case GG_STATE_CONNECTING_HTTP:
995 { 1082 {
996 char buf[1024]; 1083 char buf[1024];
997 int res, res_size = sizeof(res); 1084 int res, res_size = sizeof(res);
998 1085
999 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_HTTP\n"); 1086 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_HTTP\n");
1000 1087
1001 if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { 1088 if (sess->async
1002 gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d (%s)\n", res, strerror(res)); 1089 && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
1003 1090 struct in_addr *addr = (struct in_addr *)&sess->server_ip;
1004 errno = res; 1091 gg_debug(GG_DEBUG_MISC,
1005 e->type = GG_EVENT_CONN_FAILED; 1092 "-- http connection failed, errno = %d (%s), trying direct connection\n",
1006 e->event.failure = GG_FAILURE_CONNECTING; 1093 res, strerror(res));
1007 sess->state = GG_STATE_IDLE; 1094
1095 if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) {
1096 gg_debug(GG_DEBUG_MISC,
1097 "-- connection failed, trying https connection\n");
1098 if ((sess->fd =
1099 gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) {
1100 gg_debug(GG_DEBUG_MISC,
1101 "-- connect() failed. errno = %d (%s)\n", errno,
1102 strerror(errno));
1103
1104 e->type = GG_EVENT_CONN_FAILED;
1105 e->event.failure = GG_FAILURE_CONNECTING;
1106 sess->state = GG_STATE_IDLE;
1107 break;
1108 }
1109 }
1110
1111 sess->state = GG_STATE_CONNECTING_GG;
1112 sess->check = GG_CHECK_WRITE;
1008 break; 1113 break;
1009 } 1114 }
1010 1115
1011 gg_debug(GG_DEBUG_MISC, "-- http connection succeded, sending query\n"); 1116 gg_debug(GG_DEBUG_MISC, "-- http connection succeded, sending query\n");
1012 1117
1013
1014 snprintf(buf, sizeof(buf) - 1, 1118 snprintf(buf, sizeof(buf) - 1,
1015 "GET /appsvc/appmsg.asp?fmnumber=%u HTTP/1.0\r\n" 1119 "GET /appsvc/appmsg.asp?fmnumber=%lu HTTP/1.0\r\n"
1016 "Host: " GG_APPMSG_HOST "\r\n" 1120 "Host: " GG_APPMSG_HOST "\r\n"
1017 "User-Agent: Mozilla/4.7 [en] (Win98; I)\r\n" 1121 "User-Agent: " GG_HTTP_USERAGENT "\r\n"
1018 "Pragma: no-cache\r\n" 1122 "Pragma: no-cache\r\n" "\r\n", sess->uin);
1019 "\r\n", sess->uin);
1020 1123
1021 if (write(sess->fd, buf, strlen(buf)) < strlen(buf)) { 1124 if (write(sess->fd, buf, strlen(buf)) < strlen(buf)) {
1022 gg_debug(GG_DEBUG_MISC, "-- sending query failed\n"); 1125 gg_debug(GG_DEBUG_MISC, "-- sending query failed\n");
1023 1126
1127 errno = EIO;
1024 e->type = GG_EVENT_CONN_FAILED; 1128 e->type = GG_EVENT_CONN_FAILED;
1025 e->event.failure = GG_FAILURE_WRITING; 1129 e->event.failure = GG_FAILURE_WRITING;
1026 sess->state = GG_STATE_IDLE; 1130 sess->state = GG_STATE_IDLE;
1027 break; 1131 break;
1028 } 1132 }
1031 sess->check = GG_CHECK_READ; 1135 sess->check = GG_CHECK_READ;
1032 1136
1033 break; 1137 break;
1034 } 1138 }
1035 1139
1036 case GG_STATE_WRITING_HTTP: 1140 case GG_STATE_WRITING_HTTP:
1037 { 1141 {
1038 char buf[1024], *tmp, *host; 1142 char buf[1024], *tmp, *host;
1039 int port = GG_DEFAULT_PORT; 1143 int port = GG_DEFAULT_PORT;
1040 struct in_addr a; 1144 struct in_addr a;
1041 1145
1042 gg_debug(GG_DEBUG_MISC, "== GG_STATE_WRITING_HTTP\n"); 1146 gg_debug(GG_DEBUG_MISC, "== GG_STATE_WRITING_HTTP\n");
1043 1147
1044 gg_read_line(sess->fd, buf, sizeof(buf) - 1); 1148 gg_read_line(sess->fd, buf, sizeof(buf) - 1);
1045 gg_chomp(buf); 1149 gg_chomp(buf);
1046 1150
1047 gg_debug(GG_DEBUG_TRAFFIC, "-- got http response (%s)\n", buf); 1151 gg_debug(GG_DEBUG_TRAFFIC, "-- got http response (%s)\n", buf);
1048 1152
1049 if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) { 1153 if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) {
1050 gg_debug(GG_DEBUG_MISC, "-- but that's not what we've expected\n"); 1154 gg_debug(GG_DEBUG_MISC, "-- but that's not what we've expected\n");
1051 1155
1156 errno = EINVAL;
1052 e->type = GG_EVENT_CONN_FAILED; 1157 e->type = GG_EVENT_CONN_FAILED;
1053 e->event.failure = GG_FAILURE_INVALID; 1158 e->event.failure = GG_FAILURE_INVALID;
1054 sess->state = GG_STATE_IDLE; 1159 sess->state = GG_STATE_IDLE;
1055 break; 1160 break;
1056 } 1161 }
1057 1162
1058 while (strcmp(buf, "\r\n") && strcmp(buf, "")) 1163 while (strcmp(buf, "\r\n") && strcmp(buf, ""))
1059 gg_read_line(sess->fd, buf, sizeof(buf) - 1); 1164 gg_read_line(sess->fd, buf, sizeof(buf) - 1);
1060 1165
1061 gg_read_line(sess->fd, buf, sizeof(buf) - 1); 1166 gg_read_line(sess->fd, buf, sizeof(buf) - 1);
1062 gg_chomp(buf); 1167 gg_chomp(buf);
1063 1168
1064 close(sess->fd); 1169 close(sess->fd);
1065 1170
1066 gg_debug(GG_DEBUG_TRAFFIC, "-- received http data (%s)\n", buf); 1171 gg_debug(GG_DEBUG_TRAFFIC, "-- received http data (%s)\n", buf);
1067 1172
1068 tmp = buf; 1173 tmp = buf;
1069 while (*tmp && *tmp != ' ') 1174 while (*tmp && *tmp != ' ')
1070 tmp++; 1175 tmp++;
1083 tmp++; 1188 tmp++;
1084 *tmp = 0; 1189 *tmp = 0;
1085 1190
1086 if ((tmp = strchr(host, ':'))) { 1191 if ((tmp = strchr(host, ':'))) {
1087 *tmp = 0; 1192 *tmp = 0;
1088 port = atoi(tmp+1); 1193 port = atoi(tmp + 1);
1089 } 1194 }
1090 1195
1091 a.s_addr = inet_addr(host); 1196 a.s_addr = inet_addr(host);
1197 sess->server_ip = a.s_addr;
1092 1198
1093 if ((sess->fd = gg_connect(&a, port, sess->async)) == -1) { 1199 if ((sess->fd = gg_connect(&a, port, sess->async)) == -1) {
1094 gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); 1200 gg_debug(GG_DEBUG_MISC,
1095 1201 "-- connection failed, trying https connection\n");
1096 e->type = GG_EVENT_CONN_FAILED; 1202 if ((sess->fd = gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) {
1097 e->event.failure = GG_FAILURE_CONNECTING; 1203 gg_debug(GG_DEBUG_MISC,
1098 sess->state = GG_STATE_IDLE; 1204 "-- connection failed, errno = %d (%s)\n", errno,
1099 break; 1205 strerror(errno));
1206
1207 e->type = GG_EVENT_CONN_FAILED;
1208 e->event.failure = GG_FAILURE_CONNECTING;
1209 sess->state = GG_STATE_IDLE;
1210 break;
1211 }
1100 } 1212 }
1101 1213
1102 sess->state = GG_STATE_CONNECTING_GG; 1214 sess->state = GG_STATE_CONNECTING_GG;
1103 sess->check = GG_CHECK_WRITE; 1215 sess->check = GG_CHECK_WRITE;
1104 1216
1105 break; 1217 break;
1106 } 1218 }
1107 1219
1108 case GG_STATE_CONNECTING_GG: 1220 case GG_STATE_CONNECTING_GG:
1109 { 1221 {
1110 int res, res_size = sizeof(res); 1222 int res, res_size = sizeof(res);
1111 1223
1112 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_GG\n"); 1224 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_GG\n");
1113 1225
1114 if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { 1226 if (sess->async
1115 gg_debug(GG_DEBUG_MISC, "-- connection failed, errno = %d (%s)\n", errno, strerror(errno)); 1227 && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
1116 1228 struct in_addr *addr = (struct in_addr *)&sess->server_ip;
1117 errno = res; 1229
1118 e->type = GG_EVENT_CONN_FAILED; 1230 gg_debug(GG_DEBUG_MISC,
1119 e->event.failure = GG_FAILURE_CONNECTING; 1231 "-- connection failed, trying https connection\n");
1120 sess->state = GG_STATE_IDLE; 1232 if ((sess->fd = gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) {
1121 break; 1233 gg_debug(GG_DEBUG_MISC,
1234 "-- connection failed, errno = %d (%s)\n", errno,
1235 strerror(errno));
1236
1237 e->type = GG_EVENT_CONN_FAILED;
1238 e->event.failure = GG_FAILURE_CONNECTING;
1239 sess->state = GG_STATE_IDLE;
1240 break;
1241 }
1122 } 1242 }
1123 1243
1124 gg_debug(GG_DEBUG_MISC, "-- connected\n"); 1244 gg_debug(GG_DEBUG_MISC, "-- connected\n");
1125 1245
1126 sess->state = GG_STATE_WAITING_FOR_KEY; 1246 sess->state = GG_STATE_WAITING_FOR_KEY;
1127 sess->check = GG_CHECK_READ; 1247 sess->check = GG_CHECK_READ;
1128 1248
1129 break; 1249 break;
1130 } 1250 }
1131 1251
1132 case GG_STATE_WAITING_FOR_KEY: 1252 case GG_STATE_WAITING_FOR_KEY:
1133 { 1253 {
1134 struct gg_header *h; 1254 struct gg_header *h;
1135 struct gg_welcome *w; 1255 struct gg_welcome *w;
1136 struct gg_login l; 1256 struct gg_login l;
1137 unsigned int hash; 1257 unsigned int hash;
1138 char *password = sess->password; 1258 char *password = sess->password;
1139 1259
1140 gg_debug(GG_DEBUG_MISC, "== GG_STATE_WAITING_FOR_KEY\n"); 1260 gg_debug(GG_DEBUG_MISC, "== GG_STATE_WAITING_FOR_KEY\n");
1141 1261
1142 if (!(h = gg_recv_packet(sess))) { 1262 if (!(h = gg_recv_packet(sess))) {
1143 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d (%s)\n", errno, strerror(errno)); 1263 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d (%s)\n",
1264 errno, strerror(errno));
1144 1265
1145 e->type = GG_EVENT_CONN_FAILED; 1266 e->type = GG_EVENT_CONN_FAILED;
1146 e->event.failure = GG_FAILURE_READING; 1267 e->event.failure = GG_FAILURE_READING;
1147 sess->state = GG_STATE_IDLE; 1268 sess->state = GG_STATE_IDLE;
1148 close(sess->fd); 1269 close(sess->fd);
1149 break; 1270 break;
1150 } 1271 }
1151 1272
1152 if (h->type != GG_WELCOME) { 1273 if (h->type != GG_WELCOME) {
1153 gg_debug(GG_DEBUG_MISC, "-- invalid packet received\n"); 1274 gg_debug(GG_DEBUG_MISC, "-- invalid packet received\n");
1154 1275
1155 free(h); 1276 free(h);
1156 close(sess->fd); 1277 close(sess->fd);
1278 errno = EINVAL;
1157 e->type = GG_EVENT_CONN_FAILED; 1279 e->type = GG_EVENT_CONN_FAILED;
1158 e->event.failure = GG_FAILURE_INVALID; 1280 e->event.failure = GG_FAILURE_INVALID;
1159 sess->state = GG_STATE_IDLE; 1281 sess->state = GG_STATE_IDLE;
1160 break; 1282 break;
1161 } 1283 }
1162 1284
1163 w = (void*) h + sizeof(struct gg_header); 1285 w = (void *)h + sizeof(struct gg_header);
1164 w->key = fix32(w->key); 1286 w->key = fix32(w->key);
1165 1287
1166 for (hash = 1; *password; password++) 1288 for (hash = 1; *password; password++)
1167 hash *= (*password) + 1; 1289 hash *= (*password) + 1;
1168 hash *= w->key; 1290 hash *= w->key;
1169 1291
1170 gg_debug(GG_DEBUG_DUMP, "%%%% klucz serwera %.4x, hash hasła %.8x\n", w->key, hash); 1292 gg_debug(GG_DEBUG_DUMP, "%%%% klucz serwera %.4x, hash hasła %.8x\n", w->key,
1171 1293 hash);
1294
1172 free(h); 1295 free(h);
1173 1296
1174 free(sess->password); 1297 free(sess->password);
1175 sess->password = NULL; 1298 sess->password = NULL;
1176 1299
1177 l.uin = fix32(sess->uin); 1300 l.uin = fix32(sess->uin);
1178 l.hash = fix32(hash); 1301 l.hash = fix32(hash);
1179 l.status = fix32(GG_STATUS_AVAIL); 1302 l.status = fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL);
1180 l.dunno = fix32(0x0b); 1303 l.dunno = fix32(0x0b);
1181 l.local_ip = 0; 1304 l.local_ip = 0;
1182 l.local_port = 0; 1305 l.local_port = 0;
1183 1306
1184 gg_debug(GG_DEBUG_TRAFFIC, "-- sending GG_LOGIN packet\n"); 1307 gg_debug(GG_DEBUG_TRAFFIC, "-- sending GG_LOGIN packet\n");
1185 1308
1186 if (gg_send_packet(sess->fd, GG_LOGIN, &l, sizeof(l), NULL, 0) == -1) { 1309 if (gg_send_packet(sess->fd, GG_LOGIN, &l, sizeof(l), NULL, 0) == -1) {
1187 gg_debug(GG_DEBUG_TRAFFIC, "-- oops, failed. errno = %d (%s)\n", errno, strerror(errno)); 1310 gg_debug(GG_DEBUG_TRAFFIC, "-- oops, failed. errno = %d (%s)\n", errno,
1311 strerror(errno));
1188 1312
1189 close(sess->fd); 1313 close(sess->fd);
1190 e->type = GG_EVENT_CONN_FAILED; 1314 e->type = GG_EVENT_CONN_FAILED;
1191 e->event.failure = GG_FAILURE_WRITING; 1315 e->event.failure = GG_FAILURE_WRITING;
1192 sess->state = GG_STATE_IDLE; 1316 sess->state = GG_STATE_IDLE;
1193 break; 1317 break;
1194 } 1318 }
1195 1319
1196 sess->state = GG_STATE_SENDING_KEY; 1320 sess->state = GG_STATE_SENDING_KEY;
1197 1321
1198 break; 1322 break;
1199 } 1323 }
1200 1324
1201 case GG_STATE_SENDING_KEY: 1325 case GG_STATE_SENDING_KEY:
1202 { 1326 {
1203 struct gg_header *h; 1327 struct gg_header *h;
1204 1328
1205 gg_debug(GG_DEBUG_MISC, "== GG_STATE_SENDING_KEY\n"); 1329 gg_debug(GG_DEBUG_MISC, "== GG_STATE_SENDING_KEY\n");
1206 1330
1210 e->event.failure = GG_FAILURE_READING; 1334 e->event.failure = GG_FAILURE_READING;
1211 sess->state = GG_STATE_IDLE; 1335 sess->state = GG_STATE_IDLE;
1212 close(sess->fd); 1336 close(sess->fd);
1213 break; 1337 break;
1214 } 1338 }
1215 1339
1216 if (h->type == GG_LOGIN_OK) { 1340 if (h->type == GG_LOGIN_OK) {
1217 gg_debug(GG_DEBUG_MISC, "-- login succeded\n"); 1341 gg_debug(GG_DEBUG_MISC, "-- login succeded\n");
1218 e->type = GG_EVENT_CONN_SUCCESS; 1342 e->type = GG_EVENT_CONN_SUCCESS;
1219 sess->state = GG_STATE_CONNECTED; 1343 sess->state = GG_STATE_CONNECTED;
1344 free(h);
1220 break; 1345 break;
1221 } 1346 }
1222 1347
1223 if (h->type == GG_LOGIN_FAILED) { 1348 if (h->type == GG_LOGIN_FAILED) {
1224 gg_debug(GG_DEBUG_MISC, "-- login failed\n"); 1349 gg_debug(GG_DEBUG_MISC, "-- login failed\n");
1225 e->event.failure = GG_FAILURE_PASSWORD; 1350 e->event.failure = GG_FAILURE_PASSWORD;
1226 errno = EACCES; 1351 errno = EACCES;
1227 } else { 1352 } else {
1228 gg_debug(GG_DEBUG_MISC, "-- invalid packet\n"); 1353 gg_debug(GG_DEBUG_MISC, "-- invalid packet\n");
1229 e->event.failure = GG_FAILURE_INVALID; 1354 e->event.failure = GG_FAILURE_INVALID;
1355 errno = EINVAL;
1230 } 1356 }
1231 1357
1232 e->type = GG_EVENT_CONN_FAILED; 1358 e->type = GG_EVENT_CONN_FAILED;
1233 sess->state = GG_STATE_IDLE; 1359 sess->state = GG_STATE_IDLE;
1234 close(sess->fd); 1360 close(sess->fd);
1361 free(h);
1235 1362
1236 break; 1363 break;
1237 } 1364 }
1238 1365
1239 case GG_STATE_CONNECTED: 1366 case GG_STATE_CONNECTED:
1240 { 1367 {
1241 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTED\n"); 1368 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTED\n");
1242 1369
1243 if ((res = gg_watch_fd_connected(sess, e)) == -1) { 1370 if ((res = gg_watch_fd_connected(sess, e)) == -1) {
1244 1371
1245 gg_debug(GG_DEBUG_MISC, "-- watch_fd_connected failed. errno = %d (%s)\n", errno, strerror(errno)); 1372 gg_debug(GG_DEBUG_MISC,
1246 1373 "-- watch_fd_connected failed. errno = %d (%s)\n", errno,
1247 if (errno == EAGAIN) { 1374 strerror(errno));
1375
1376 if (errno == EAGAIN) {
1248 e->type = GG_EVENT_NONE; 1377 e->type = GG_EVENT_NONE;
1249 res = 0; 1378 res = 0;
1250 } else 1379 } else
1251 res = -1; 1380 res = -1;
1252 } 1381 }
1259 e = NULL; 1388 e = NULL;
1260 } 1389 }
1261 1390
1262 return e; 1391 return e;
1263 } 1392 }
1264
1265