Mercurial > pidgin.yaz
annotate src/protocols/gg/libgg.c @ 11157:f068eaabe332
[gaim-migrate @ 13242]
Patch submitted to gaim-devel...
"Marcin Owsiany sent you a draft advisory regarding multiple libgadu
vulnerabilities. "Fortunately" gaim contains an extremely old version of
libgadu and is affected only by memory alignment bug, which cannot be
exploited on x86. No other critical vulnerabilities are known in gaim's
version of libgadu.
You'll find the patch in attachment.
Regards,
Wojtek Kaniewski
ekg/libgadu maintainer"
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Mon, 25 Jul 2005 21:20:14 +0000 |
parents | 64895571248f |
children | ff4884029708 |
rev | line source |
---|---|
2393 | 1 /* |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
2 * (C) Copyright 2001 Wojtek Kaniewski <wojtekka@irc.pl>, |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
3 * Robert J. Woźny <speedy@ziew.org> |
2393 | 4 * |
5 * This program is free software; you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License Version 2 as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This program is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with this program; if not, write to the Free Software | |
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
17 */ | |
18 | |
4016 | 19 #include <sys/types.h> |
3630 | 20 #ifndef _WIN32 |
2393 | 21 #include <sys/socket.h> |
22 #include <netinet/in.h> | |
23 #include <arpa/inet.h> | |
24 #include <sys/ioctl.h> | |
25 #include <sys/wait.h> | |
3630 | 26 #include <netdb.h> |
27 #include <pwd.h> | |
28 #else | |
29 #include <fcntl.h> | |
30 #endif | |
31 | |
32 #include <stdio.h> | |
33 #include <stdlib.h> | |
34 #include <unistd.h> | |
35 #include <stdio.h> | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
36 #include <sys/time.h> |
2393 | 37 #include <errno.h> |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
38 #ifndef _AIX |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
39 # include <string.h> |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
40 #endif |
2393 | 41 #include <stdarg.h> |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
42 #include <time.h> |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
43 #ifdef sun |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
44 #include <sys/filio.h> |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
45 #endif |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
46 #include <glib.h> |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
47 #if G_BYTE_ORDER == G_BIG_ENDIAN |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
48 # define WORDS_BIGENDIAN 1 |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
49 #endif |
9265 | 50 #include "internal.h" |
2393 | 51 #include "libgg.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
52 |
3630 | 53 #include "proxy.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5681
diff
changeset
|
54 #include "debug.h" |
2393 | 55 |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
56 #ifdef _WIN32 |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
57 #include "win32dep.h" |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
58 #endif |
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
59 |
3630 | 60 int gg_debug_level = (GG_DEBUG_NET | GG_DEBUG_TRAFFIC | GG_DEBUG_DUMP | GG_DEBUG_FUNCTION | GG_DEBUG_MISC); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
61 int gg_http_use_proxy = 0; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
62 int gg_http_proxy_port = 0; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
63 char *gg_http_proxy_host = NULL; |
2393 | 64 |
65 /* | |
66 * fix32() // funkcja wewnętrzna | |
67 * | |
68 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,long''ach. | |
69 */ | |
70 static inline unsigned long fix32(unsigned long x) | |
71 { | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
72 #ifndef WORDS_BIGENDIAN |
2393 | 73 return x; |
74 #else | |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
75 return (unsigned long) |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
76 (((x & (unsigned long) 0x000000ffU) << 24) | |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
77 ((x & (unsigned long) 0x0000ff00U) << 8) | |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
78 ((x & (unsigned long) 0x00ff0000U) >> 8) | |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
79 ((x & (unsigned long) 0xff000000U) >> 24)); |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
80 #endif |
2393 | 81 } |
82 | |
83 /* | |
84 * fix16() // funkcja wewnętrzna | |
85 * | |
86 * dla maszyn big-endianowych zamienia kolejność bajtów w ,,short''ach. | |
87 */ | |
4298 | 88 |
2393 | 89 static inline unsigned short fix16(unsigned short x) |
90 { | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
91 #ifndef WORDS_BIGENDIAN |
2393 | 92 return x; |
93 #else | |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
94 return (unsigned short) |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
95 (((x & (unsigned short) 0x00ffU) << 8) | |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
96 ((x & (unsigned short) 0xff00U) >> 8)); |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
97 #endif |
2393 | 98 } |
99 | |
3630 | 100 #ifndef _WIN32 |
2393 | 101 /* |
102 * gg_resolve() // funkcja wewnętrzna | |
103 * | |
104 * tworzy pipe'y, forkuje się i w drugim procesie zaczyna resolvować | |
105 * podanego hosta. zapisuje w sesji deskryptor pipe'u. jeśli coś tam | |
106 * będzie gotowego, znaczy, że można wczytać ,,struct in_addr''. jeśli | |
107 * nie znajdzie, zwraca INADDR_NONE. | |
108 * | |
109 * - fd - wskaźnik gdzie wrzucić deskryptor, | |
110 * - pid - gdzie wrzucić pid dzieciaka, | |
111 * - hostname - nazwa hosta do zresolvowania. | |
112 * | |
113 * zwraca 0 jeśli udało się odpalić proces lub -1 w przypadku błędu. | |
114 */ | |
115 int gg_resolve(int *fd, int *pid, char *hostname) | |
116 { | |
117 int pipes[2], res; | |
118 struct in_addr a; | |
119 | |
120 gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve(..., \"%s\");\n", hostname); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
121 |
2393 | 122 if (!fd | !pid) { |
123 errno = EFAULT; | |
124 return -1; | |
125 } | |
126 | |
127 if (pipe(pipes) == -1) | |
128 return -1; | |
129 | |
130 if ((res = fork()) == -1) | |
131 return -1; | |
132 | |
133 if (!res) { | |
134 if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) { | |
135 struct hostent *he; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
136 |
2393 | 137 if (!(he = gethostbyname(hostname))) |
138 a.s_addr = INADDR_NONE; | |
139 else | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
140 memcpy((char*) &a, he->h_addr, sizeof(a)); |
2393 | 141 } |
142 | |
143 write(pipes[1], &a, sizeof(a)); | |
144 | |
145 exit(0); | |
146 } | |
147 | |
148 close(pipes[1]); | |
149 | |
150 *fd = pipes[0]; | |
151 *pid = res; | |
152 | |
153 return 0; | |
154 } | |
3630 | 155 #endif /*!_WIN32*/ |
2393 | 156 |
157 /* | |
158 * gg_recv_packet() // funkcja wewnętrzna | |
159 * | |
160 * odbiera jeden pakiet gg i zwraca wskaźnik do niego. pamięć po nim | |
161 * wypadałoby uwolnić. | |
162 * | |
163 * - sock - połączony socket. | |
164 * | |
165 * jeśli wystąpił błąd, zwraca NULL. reszta w errno. | |
166 */ | |
167 static void *gg_recv_packet(struct gg_session *sess) | |
168 { | |
169 struct gg_header h; | |
170 char *buf = NULL; | |
171 int ret = 0, offset, size = 0; | |
3630 | 172 int sizeh = sizeof(struct gg_header); |
2393 | 173 |
174 gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(...);\n"); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
175 |
2393 | 176 if (!sess) { |
177 errno = EFAULT; | |
178 return NULL; | |
179 } | |
180 | |
181 if (sess->recv_left < 1) { | |
3630 | 182 while (ret != sizeh) { |
183 ret = read(sess->fd, &h, sizeh); | |
184 gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeh, ret); | |
185 if (ret < sizeh) { | |
2393 | 186 if (errno != EINTR) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
187 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); |
2393 | 188 return NULL; |
189 } | |
190 } | |
191 } | |
192 | |
193 h.type = fix32(h.type); | |
194 h.length = fix32(h.length); | |
195 } else { | |
3630 | 196 memcpy(&h, sess->recv_buf, sizeh); |
2393 | 197 } |
198 | |
199 /* jakieś sensowne limity na rozmiar pakietu */ | |
200 if (h.length < 0 || h.length > 65535) { | |
201 gg_debug(GG_DEBUG_MISC, "-- invalid packet length (%d)\n", h.length); | |
202 errno = ERANGE; | |
203 return NULL; | |
204 } | |
205 | |
206 if (sess->recv_left > 0) { | |
207 gg_debug(GG_DEBUG_MISC, "-- resuming last gg_recv_packet()\n"); | |
208 size = sess->recv_left; | |
209 offset = sess->recv_done; | |
210 buf = sess->recv_buf; | |
211 } else { | |
3630 | 212 if (!(buf = malloc(sizeh + h.length + 1))) { |
2393 | 213 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); |
214 return NULL; | |
215 } | |
216 | |
3630 | 217 memcpy(buf, &h, sizeh); |
2393 | 218 |
219 offset = 0; | |
220 size = h.length; | |
221 } | |
222 | |
223 while (size > 0) { | |
3630 | 224 ret = read(sess->fd, buf + sizeh + offset, size); |
2393 | 225 gg_debug(GG_DEBUG_MISC, "-- body recv(..., %d) = %d\n", size, ret); |
226 if (ret > -1 && ret <= size) { | |
227 offset += ret; | |
228 size -= ret; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
229 } else if (ret == -1) { |
2393 | 230 gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno)); |
231 if (errno == EAGAIN) { | |
232 gg_debug(GG_DEBUG_MISC, "-- %d bytes received, %d left\n", offset, size); | |
233 sess->recv_buf = buf; | |
234 sess->recv_left = size; | |
235 sess->recv_done = offset; | |
236 return NULL; | |
237 } | |
238 if (errno != EINTR) { | |
6063 | 239 /* errno = EINVAL; */ |
2393 | 240 free(buf); |
241 return NULL; | |
242 } | |
243 } | |
244 } | |
245 | |
246 sess->recv_left = 0; | |
247 | |
248 if ((gg_debug_level & GG_DEBUG_DUMP)) { | |
249 int i; | |
250 | |
251 gg_debug(GG_DEBUG_DUMP, ">> received packet (type=%.2x):", h.type); | |
3630 | 252 for (i = 0; i < sizeh + h.length; i++) |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
253 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) buf[i]); |
2393 | 254 gg_debug(GG_DEBUG_DUMP, "\n"); |
255 } | |
256 | |
257 return buf; | |
258 } | |
259 | |
260 /* | |
261 * gg_send_packet() // funkcja wewnętrzna | |
262 * | |
8775 | 263 * konstruuje pakiet i wysyła go do serwera. |
2393 | 264 * |
8775 | 265 * - sock - deskryptor gniazda |
266 * - type - typ pakietu | |
267 * - payload_1 - pierwsza część pakietu | |
268 * - payload_length_1 - długość pierwszej części | |
269 * - payload_2 - druga część pakietu | |
270 * - payload_length_2 - długość drugiej części | |
271 * - ... - kolejne części pakietu i ich długości | |
272 * - NULL - końcowym parametr (konieczny!) | |
2393 | 273 * |
8775 | 274 * jeśli się powiodło, zwraca 0, w przypadku błędu -1. jeśli errno == ENOMEM, |
275 * zabrakło pamięci. inaczej był błąd przy wysyłaniu pakietu. dla errno == 0 | |
2393 | 276 * nie wysłano całego pakietu. |
277 */ | |
8775 | 278 int gg_send_packet(struct gg_session *sess, int type, ...) |
2393 | 279 { |
280 struct gg_header *h; | |
281 char *tmp; | |
8775 | 282 int tmp_length; |
283 void *payload; | |
284 int payload_length; | |
285 va_list ap; | |
286 int res; | |
2393 | 287 |
8775 | 288 gg_debug(GG_DEBUG_FUNCTION, "** gg_send_packet(%p, 0x%.2x, ...)\n", sess, type); |
2393 | 289 |
8775 | 290 tmp_length = 0; |
291 | |
292 if (!(tmp = malloc(sizeof(struct gg_header)))) { | |
293 gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for packet header\n"); | |
2393 | 294 return -1; |
295 } | |
296 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
297 h = (struct gg_header*) tmp; |
2393 | 298 h->type = fix32(type); |
8775 | 299 h->length = fix32(0); |
300 | |
301 va_start(ap, type); | |
302 | |
303 payload = va_arg(ap, void *); | |
304 | |
305 while (payload) { | |
306 char *tmp2; | |
307 | |
308 payload_length = va_arg(ap, int); | |
2393 | 309 |
8775 | 310 if (payload_length < 0) |
311 gg_debug(GG_DEBUG_MISC, "// gg_send_packet() invalid payload length (%d)\n", payload_length); | |
312 | |
313 if (!(tmp2 = realloc(tmp, sizeof(struct gg_header) + tmp_length + payload_length))) { | |
314 gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n"); | |
315 free(tmp); | |
316 va_end(ap); | |
317 return -1; | |
318 } | |
319 | |
320 tmp = tmp2; | |
321 | |
322 memcpy(tmp + sizeof(struct gg_header) + tmp_length, payload, payload_length); | |
323 tmp_length += payload_length; | |
324 | |
325 payload = va_arg(ap, void *); | |
326 } | |
327 | |
328 va_end(ap); | |
329 | |
330 h = (struct gg_header*) tmp; | |
331 h->length = fix32(tmp_length); | |
2393 | 332 |
333 if ((gg_debug_level & GG_DEBUG_DUMP)) { | |
8775 | 334 unsigned int i; |
335 | |
336 gg_debug(GG_DEBUG_DUMP, "// gg_send_packet(0x%.2x)", fix32(h->type)); | |
337 for (i = 0; i < sizeof(struct gg_header) + fix32(h->length); i++) | |
338 gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) tmp[i]); | |
339 gg_debug(GG_DEBUG_DUMP, "\n"); | |
340 } | |
341 | |
342 tmp_length += sizeof(struct gg_header); | |
343 | |
344 if ((res = gg_write(sess, tmp, tmp_length)) < tmp_length) { | |
345 gg_debug(GG_DEBUG_MISC, "// gg_send_packet() write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno)); | |
2393 | 346 free(tmp); |
347 return -1; | |
348 } | |
8775 | 349 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
350 free(tmp); |
2393 | 351 return 0; |
352 } | |
353 | |
8775 | 354 /* |
355 * gg_write() // funkcja pomocnicza | |
356 * | |
357 * zapisuje do gniazda określoną ilość bajtów. bierze pod uwagę, czy mamy | |
358 * połączenie zwykłe czy TLS. | |
359 * | |
360 * - sess - sesja, | |
361 * - buf - bufor, | |
362 * - length - ilość bajtów, | |
363 * | |
364 * takie same wartości jak write(). | |
365 */ | |
366 int gg_write(struct gg_session *sess, const char *buf, int length) | |
367 { | |
368 int res; | |
369 | |
370 #ifdef __GG_LIBGADU_HAVE_OPENSSL | |
371 if (sess->ssl) { | |
372 int err; | |
373 | |
374 res = SSL_write(sess->ssl, buf, length); | |
375 | |
376 if (res < 0) { | |
377 err = SSL_get_error(sess->ssl, res); | |
378 | |
379 if (err == SSL_ERROR_WANT_WRITE) | |
380 errno = EAGAIN; | |
381 | |
382 return -1; | |
383 } | |
384 } else | |
385 #endif | |
386 res = write(sess->fd, buf, length); | |
387 | |
388 return res; | |
389 } | |
390 | |
391 | |
3630 | 392 #ifndef _WIN32 |
2393 | 393 /* |
394 * gg_login() | |
395 * | |
396 * rozpoczyna procedurę łączenia się z serwerem. resztę obsłguje się przez | |
397 * gg_watch_event. | |
398 * | |
399 * - uin - numerek usera, | |
400 * - password - jego hasełko, | |
401 * - async - ma być asynchronicznie? | |
402 * | |
403 * UWAGA! program musi obsłużyć SIGCHLD, jeśli łączy się asynchronicznie, | |
404 * żeby zrobić pogrzeb zmarłemu procesowi resolvera. | |
405 * | |
406 * w przypadku błędu zwraca NULL, jeśli idzie dobrze (async) albo poszło | |
407 * dobrze (sync), zwróci wskaźnik do zaalokowanej struktury `gg_session'. | |
408 */ | |
409 struct gg_session *gg_login(uin_t uin, char *password, int async) | |
410 { | |
411 struct gg_session *sess; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
412 char *hostname; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
413 int port; |
2393 | 414 |
415 gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%u, \"...\", %d);\n", uin, async); | |
416 | |
417 if (!(sess = malloc(sizeof(*sess)))) | |
418 return NULL; | |
419 | |
420 sess->uin = uin; | |
421 if (!(sess->password = strdup(password))) { | |
422 free(sess); | |
423 return NULL; | |
424 } | |
425 sess->state = GG_STATE_RESOLVING; | |
426 sess->check = GG_CHECK_READ; | |
427 sess->async = async; | |
428 sess->seq = 0; | |
429 sess->recv_left = 0; | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
430 sess->last_pong = 0; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
431 sess->server_ip = 0; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
432 sess->initial_status = 0; |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
433 sess->type = GG_SESSION_GG; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
434 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
435 if (gg_http_use_proxy) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
436 hostname = gg_http_proxy_host; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
437 port = gg_http_proxy_port; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
438 } else { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
439 hostname = GG_APPMSG_HOST; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
440 port = GG_APPMSG_PORT; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
441 }; |
2393 | 442 |
443 if (async) { | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
444 if (gg_resolve(&sess->fd, &sess->pid, hostname)) { |
2393 | 445 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n"); |
446 free(sess); | |
447 return NULL; | |
448 } | |
449 } else { | |
450 struct in_addr a; | |
451 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
452 if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) { |
2393 | 453 struct hostent *he; |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
454 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
455 if (!(he = gethostbyname(hostname))) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
456 gg_debug(GG_DEBUG_MISC, "-- host %s not found\n", hostname); |
2393 | 457 free(sess); |
458 return NULL; | |
459 } else | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
460 memcpy((char*) &a, he->h_addr, sizeof(a)); |
2393 | 461 } |
462 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
463 if (!(sess->fd = gg_connect(&a, port, 0)) == -1) { |
2393 | 464 gg_debug(GG_DEBUG_MISC, "-- connection failed\n"); |
465 free(sess); | |
466 return NULL; | |
467 } | |
468 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
469 sess->state = GG_STATE_CONNECTING; |
2393 | 470 |
471 while (sess->state != GG_STATE_CONNECTED) { | |
472 struct gg_event *e; | |
473 | |
474 if (!(e = gg_watch_fd(sess))) { | |
475 gg_debug(GG_DEBUG_MISC, "-- some nasty error in gg_watch_fd()\n"); | |
476 free(sess); | |
477 return NULL; | |
478 } | |
479 | |
480 if (e->type == GG_EVENT_CONN_FAILED) { | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
481 errno = EACCES; |
2393 | 482 gg_debug(GG_DEBUG_MISC, "-- could not login\n"); |
483 gg_free_event(e); | |
484 free(sess); | |
485 return NULL; | |
486 } | |
487 | |
488 gg_free_event(e); | |
489 } | |
490 } | |
491 | |
492 return sess; | |
493 } | |
3630 | 494 #endif /*!_WIN32*/ |
2393 | 495 |
496 /* | |
8775 | 497 * gg_login_hash() // funkcja wewnętrzna |
498 * | |
499 * liczy hash z hasła i danego seeda. | |
500 * | |
501 * - password - hasło do hashowania | |
502 * - seed - wartość podana przez serwer | |
503 * | |
504 * hash. | |
505 */ | |
506 unsigned int gg_login_hash(const unsigned char *password, unsigned int seed) | |
507 { | |
508 unsigned int x, y, z; | |
509 | |
510 y = seed; | |
511 | |
512 for (x = 0; *password; password++) { | |
513 x = (x & 0xffffff00) | *password; | |
514 y ^= x; | |
515 y += x; | |
516 x <<= 8; | |
517 y ^= x; | |
518 x <<= 8; | |
519 y -= x; | |
520 x <<= 8; | |
521 y ^= x; | |
522 | |
523 z = y & 0x1F; | |
524 y = (y << z) | (y >> (32 - z)); | |
525 } | |
526 | |
527 return y; | |
528 } | |
529 | |
530 /* | |
2393 | 531 * gg_free_session() |
532 * | |
533 * zwalnia pamięć zajmowaną przez opis sesji. | |
534 * | |
535 * - sess - opis sesji. | |
536 * | |
537 * nie zwraca niczego, bo i po co? | |
538 */ | |
539 void gg_free_session(struct gg_session *sess) | |
540 { | |
541 if (!sess) | |
542 return; | |
543 | |
544 free(sess->password); | |
545 free(sess); | |
546 } | |
547 | |
548 /* | |
549 * gg_change_status() | |
550 * | |
551 * zmienia status użytkownika. przydatne do /away i /busy oraz /quit. | |
552 * | |
553 * - sess - opis sesji, | |
554 * - status - nowy status użytkownika. | |
555 * | |
556 * jeśli wysłał pakiet zwraca 0, jeśli nie udało się, zwraca -1. | |
557 */ | |
558 int gg_change_status(struct gg_session *sess, int status) | |
559 { | |
560 struct gg_new_status p; | |
561 | |
562 if (!sess) { | |
563 errno = EFAULT; | |
564 return -1; | |
565 } | |
566 | |
567 if (sess->state != GG_STATE_CONNECTED) { | |
568 errno = ENOTCONN; | |
569 return -1; | |
570 } | |
571 | |
572 gg_debug(GG_DEBUG_FUNCTION, "** gg_change_status(..., %d);\n", status); | |
573 | |
574 p.status = fix32(status); | |
575 | |
8775 | 576 return gg_send_packet(sess, GG_NEW_STATUS, &p, sizeof(p), NULL, 0); |
2393 | 577 } |
578 | |
579 /* | |
9415 | 580 * gg_change_status_descr() |
581 * | |
582 * zmienia status uøytkownika na opisowy. | |
583 * | |
584 * - sess - opis sesji | |
585 * - status - nowy status uøytkownika | |
586 * - descr - opis statusu | |
587 * | |
588 * 0, -1. | |
589 */ | |
590 int gg_change_status_descr(struct gg_session *sess, int status, const char *descr) | |
591 { | |
592 struct gg_new_status p; | |
593 | |
594 gg_debug(GG_DEBUG_FUNCTION, "** gg_change_status_descr(%p, %d, \"%s\");\n", sess, status, descr); | |
595 | |
596 if (!sess || !descr) { | |
597 errno = EFAULT; | |
598 return -1; | |
599 } | |
600 | |
601 if (sess->state != GG_STATE_CONNECTED) { | |
602 errno = ENOTCONN; | |
603 return -1; | |
604 } | |
605 | |
606 p.status = fix32(status); | |
607 | |
608 return gg_send_packet(sess, GG_NEW_STATUS, &p, sizeof(p), descr, (strlen(descr) > GG_STATUS_DESCR_MAXSIZE) ? GG_STATUS_DESCR_MAXSIZE : strlen(descr), NULL); | |
609 } | |
610 | |
611 /* | |
2393 | 612 * gg_logoff() |
613 * | |
614 * wylogowuje użytkownika i zamyka połączenie. | |
615 * | |
616 * - sock - deskryptor socketu. | |
617 * | |
618 * nie zwraca błędów. skoro się żegnamy, to olewamy wszystko. | |
619 */ | |
620 void gg_logoff(struct gg_session *sess) | |
621 { | |
622 if (!sess) | |
623 return; | |
624 | |
625 gg_debug(GG_DEBUG_FUNCTION, "** gg_logoff(...);\n"); | |
626 | |
627 if (sess->state == GG_STATE_CONNECTED) | |
628 gg_change_status(sess, GG_STATUS_NOT_AVAIL); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
629 |
2393 | 630 if (sess->fd) { |
631 shutdown(sess->fd, 2); | |
632 close(sess->fd); | |
633 } | |
634 } | |
635 | |
636 /* | |
637 * gg_send_message() | |
638 * | |
639 * wysyła wiadomość do innego użytkownika. zwraca losowy numer | |
8775 | 640 * sekwencyjny, który można zignorować albo wykorzystać do potwierdzenia. |
641 * | |
642 * - sess - opis sesji | |
643 * - msgclass - rodzaj wiadomości | |
644 * - recipient - numer adresata | |
645 * - message - treść wiadomości | |
2393 | 646 * |
8775 | 647 * numer sekwencyjny wiadomości lub -1 w przypadku błędu. |
648 */ | |
10344 | 649 int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const char *message) |
8775 | 650 { |
651 gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, %u, %p)\n", sess, msgclass, recipient, message); | |
652 | |
653 return gg_send_message_richtext(sess, msgclass, recipient, message, NULL, 0); | |
654 } | |
655 | |
656 /* | |
657 * gg_send_message_richtext() | |
2393 | 658 * |
8775 | 659 * wysyła kolorową wiadomość do innego użytkownika. zwraca losowy numer |
660 * sekwencyjny, który można zignorować albo wykorzystać do potwierdzenia. | |
661 * | |
662 * - sess - opis sesji | |
663 * - msgclass - rodzaj wiadomości | |
664 * - recipient - numer adresata | |
665 * - message - treść wiadomości | |
666 * - format - informacje o formatowaniu | |
667 * - formatlen - długość informacji o formatowaniu | |
668 * | |
669 * numer sekwencyjny wiadomości lub -1 w przypadku błędu. | |
2393 | 670 */ |
10344 | 671 int gg_send_message_richtext(struct gg_session *sess, int msgclass, uin_t recipient, const char *message, const unsigned char *format, int formatlen) |
2393 | 672 { |
673 struct gg_send_msg s; | |
674 | |
8775 | 675 gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message_richtext(%p, %d, %u, %p, %p, %d);\n", sess, msgclass, recipient, message, format, formatlen); |
676 | |
2393 | 677 if (!sess) { |
678 errno = EFAULT; | |
679 return -1; | |
680 } | |
9863 | 681 |
2393 | 682 if (sess->state != GG_STATE_CONNECTED) { |
683 errno = ENOTCONN; | |
684 return -1; | |
685 } | |
686 | |
687 s.recipient = fix32(recipient); | |
688 if (!sess->seq) | |
689 sess->seq = 0x01740000 | (rand() & 0xffff); | |
690 s.seq = fix32(sess->seq); | |
691 s.msgclass = fix32(msgclass); | |
692 sess->seq += (rand() % 0x300) + 0x300; | |
9863 | 693 |
8775 | 694 if (gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), message, strlen(message) + 1, format, formatlen, NULL) == -1) |
2393 | 695 return -1; |
696 | |
697 return fix32(s.seq); | |
698 } | |
699 | |
700 /* | |
701 * gg_ping() | |
702 * | |
703 * wysyła do serwera pakiet typu yeah-i'm-still-alive. | |
704 * | |
705 * - sess - zgadnij. | |
706 * | |
707 * jeśli nie powiodło się wysłanie pakietu, zwraca -1. otherwise 0. | |
708 */ | |
709 int gg_ping(struct gg_session *sess) | |
710 { | |
711 if (!sess) { | |
712 errno = EFAULT; | |
713 return -1; | |
714 } | |
715 | |
716 if (sess->state != GG_STATE_CONNECTED) { | |
717 errno = ENOTCONN; | |
718 return -1; | |
719 } | |
720 | |
721 gg_debug(GG_DEBUG_FUNCTION, "** gg_ping(...);\n"); | |
9863 | 722 |
8775 | 723 return gg_send_packet(sess, GG_PING, NULL); |
2393 | 724 } |
725 | |
726 /* | |
727 * gg_free_event() | |
728 * | |
729 * zwalnia pamięć zajmowaną przez informację o zdarzeniu | |
730 * | |
731 * - event - wskaźnik do informacji o zdarzeniu | |
732 * | |
733 * nie ma czego zwracać. | |
734 */ | |
735 void gg_free_event(struct gg_event *e) | |
736 { | |
737 if (!e) | |
738 return; | |
739 if (e->type == GG_EVENT_MSG) | |
740 free(e->event.msg.message); | |
741 if (e->type == GG_EVENT_NOTIFY) | |
742 free(e->event.notify); | |
743 free(e); | |
744 } | |
745 | |
746 /* | |
747 * gg_notify() | |
748 * | |
749 * wysyła serwerowi listę ludków, za którymi tęsknimy. | |
750 * | |
751 * - sess - identyfikator sesji, | |
752 * - userlist - wskaźnik do tablicy numerów, | |
753 * - count - ilość numerków. | |
754 * | |
755 * jeśli udało się, zwraca 0. jeśli błąd, dostajemy -1. | |
756 */ | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
757 int gg_notify(struct gg_session *sess, uin_t *userlist, int count) |
2393 | 758 { |
759 struct gg_notify *n; | |
760 uin_t *u; | |
761 int i, res = 0; | |
762 | |
763 if (!sess) { | |
764 errno = EFAULT; | |
765 return -1; | |
766 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
767 |
2393 | 768 if (sess->state != GG_STATE_CONNECTED) { |
769 errno = ENOTCONN; | |
770 return -1; | |
771 } | |
772 | |
773 gg_debug(GG_DEBUG_FUNCTION, "** gg_notify(..., %d);\n", count); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
774 |
2393 | 775 if (!userlist || !count) |
776 return 0; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
777 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
778 if (!(n = (struct gg_notify*) malloc(sizeof(*n) * count))) |
2393 | 779 return -1; |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
780 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
781 for (u = userlist, i = 0; i < count; u++, i++) { |
2393 | 782 n[i].uin = fix32(*u); |
783 n[i].dunno1 = 3; | |
784 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
785 |
8775 | 786 if (gg_send_packet(sess, GG_NOTIFY, n, sizeof(*n) * count, NULL, 0) == -1) |
2393 | 787 res = -1; |
788 | |
789 free(n); | |
790 | |
791 return res; | |
792 } | |
793 | |
794 /* | |
795 * gg_add_notify() | |
796 * | |
797 * dodaje w locie do listy ukochanych dany numerek. | |
798 * | |
799 * - sess - identyfikator sesji, | |
800 * - uin - numerek ukochanej. | |
801 * | |
802 * jeśli udało się wysłać, daje 0. inaczej -1. | |
803 */ | |
804 int gg_add_notify(struct gg_session *sess, uin_t uin) | |
805 { | |
806 struct gg_add_remove a; | |
807 | |
808 if (!sess) { | |
809 errno = EFAULT; | |
810 return -1; | |
811 } | |
812 | |
813 if (sess->state != GG_STATE_CONNECTED) { | |
814 errno = ENOTCONN; | |
815 return -1; | |
816 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
817 |
2393 | 818 gg_debug(GG_DEBUG_FUNCTION, "** gg_add_notify(..., %u);\n", uin); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
819 |
2393 | 820 a.uin = fix32(uin); |
821 a.dunno1 = 3; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
822 |
8775 | 823 return gg_send_packet(sess, GG_ADD_NOTIFY, &a, sizeof(a), NULL); |
2393 | 824 } |
825 | |
826 /* | |
827 * gg_remove_notify() | |
828 * | |
829 * w locie usuwa z listy zainteresowanych. | |
830 * | |
831 * - sess - id sesji, | |
832 * - uin - numerek. | |
833 * | |
834 * zwraca -1 jeśli był błąd, 0 jeśli się udało wysłać pakiet. | |
835 */ | |
836 int gg_remove_notify(struct gg_session *sess, uin_t uin) | |
837 { | |
838 struct gg_add_remove a; | |
839 | |
840 if (!sess) { | |
841 errno = EFAULT; | |
842 return -1; | |
843 } | |
844 | |
845 if (sess->state != GG_STATE_CONNECTED) { | |
846 errno = ENOTCONN; | |
847 return -1; | |
848 } | |
849 | |
850 gg_debug(GG_DEBUG_FUNCTION, "** gg_remove_notify(..., %u);\n", uin); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
851 |
2393 | 852 a.uin = fix32(uin); |
853 a.dunno1 = 3; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
854 |
8775 | 855 return gg_send_packet(sess, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL, 0); |
856 } | |
857 | |
858 /* | |
859 * gg_userlist_request() | |
860 * | |
861 * wysyła żądanie/zapytanie listy kontaktów na serwerze. | |
862 * | |
863 * - sess - opis sesji | |
864 * - type - rodzaj zapytania/żądania | |
865 * - request - treść zapytania/żądania (może być NULL) | |
866 * | |
867 * 0, -1 | |
868 */ | |
869 int gg_userlist_request(struct gg_session *sess, char type, const char *request) | |
870 { | |
871 int len; | |
872 | |
873 if (!sess) { | |
874 errno = EINVAL; | |
875 return -1; | |
876 } | |
877 | |
878 if (!request) { | |
879 sess->userlist_blocks = 1; | |
880 return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), NULL); | |
881 } | |
882 | |
883 len = strlen(request); | |
884 | |
885 sess->userlist_blocks = 0; | |
886 | |
887 while (len > 2047) { | |
888 sess->userlist_blocks++; | |
889 | |
890 if (gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, 2047, NULL) == -1) | |
891 return -1; | |
892 | |
893 if (type == GG_USERLIST_PUT) | |
894 type = GG_USERLIST_PUT_MORE; | |
895 | |
896 request += 2047; | |
897 len -= 2047; | |
898 } | |
899 | |
900 sess->userlist_blocks++; | |
901 | |
902 return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, len, NULL); | |
2393 | 903 } |
904 | |
905 /* | |
906 * gg_watch_fd_connected() // funkcja wewnętrzna | |
907 * | |
908 * patrzy na socketa, odbiera pakiet i wypełnia strukturę zdarzenia. | |
909 * | |
910 * - sock - lalala, trudno zgadnąć. | |
911 * | |
912 * jeśli błąd -1, jeśli dobrze 0. | |
913 */ | |
914 static int gg_watch_fd_connected(struct gg_session *sess, struct gg_event *e) | |
915 { | |
916 struct gg_header *h; | |
8775 | 917 char *p; |
2393 | 918 |
919 if (!sess) { | |
920 errno = EFAULT; | |
921 return -1; | |
922 } | |
923 | |
924 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd_connected(...);\n"); | |
925 | |
926 if (!(h = gg_recv_packet(sess))) { | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
927 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet failed. errno = %d (%d)\n", errno, strerror(errno)); |
2393 | 928 return -1; |
929 } | |
930 | |
6247 | 931 p = (void *)h + sizeof(struct gg_header); |
9863 | 932 |
933 | |
8775 | 934 switch (h->type) { |
935 case GG_RECV_MSG: | |
936 { | |
937 struct gg_recv_msg *r = (void *)p; | |
2393 | 938 |
939 gg_debug(GG_DEBUG_MISC, "-- received a message\n"); | |
940 | |
941 if (h->length >= sizeof(*r)) { | |
942 e->type = GG_EVENT_MSG; | |
943 e->event.msg.msgclass = fix32(r->msgclass); | |
944 e->event.msg.sender = fix32(r->sender); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
945 e->event.msg.message = strdup((char*) r + sizeof(*r)); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
946 e->event.msg.time = fix32(r->time); |
2393 | 947 } |
8775 | 948 break; |
949 } | |
950 case GG_NOTIFY_REPLY: | |
951 { | |
952 struct gg_notify_reply *n = (void *)p; | |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
953 int count, i; |
2393 | 954 |
955 gg_debug(GG_DEBUG_MISC, "-- received a notify reply\n"); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
956 |
2393 | 957 e->type = GG_EVENT_NOTIFY; |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
958 if (!(e->event.notify = (void*) malloc(h->length + 2 * sizeof(*n)))) { |
2393 | 959 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); |
960 free(h); | |
961 return -1; | |
962 } | |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
963 count = h->length / sizeof(*n); |
2393 | 964 memcpy(e->event.notify, p, h->length); |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
965 e->event.notify[count].uin = 0; |
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
966 for (i = 0; i < count; i++) { |
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
967 e->event.notify[i].uin = fix32(e->event.notify[i].uin); |
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
968 e->event.notify[i].status = fix32(e->event.notify[i].status); |
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
969 } |
8775 | 970 break; |
971 } | |
972 | |
973 case GG_NOTIFY_REPLY60: | |
974 { | |
975 struct gg_notify_reply60 *n = (void*) p; | |
976 unsigned int length = h->length, i = 0; | |
977 | |
978 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n"); | |
979 | |
980 e->type = GG_EVENT_NOTIFY60; | |
981 e->event.notify60 = malloc(sizeof(*e->event.notify60)); | |
982 | |
983 if (!e->event.notify60) { | |
984 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); | |
985 goto fail; | |
986 } | |
987 | |
988 e->event.notify60[0].uin = 0; | |
989 | |
990 while (length >= sizeof(struct gg_notify_reply60)) { | |
991 uin_t uin = fix32(n->uin); | |
992 char *tmp; | |
993 | |
994 e->event.notify60[i].uin = uin & 0x00ffffff; | |
995 e->event.notify60[i].status = n->status; | |
996 e->event.notify60[i].remote_ip = n->remote_ip; | |
997 e->event.notify60[i].remote_port = fix16(n->remote_port); | |
998 e->event.notify60[i].version = n->version; | |
999 e->event.notify60[i].image_size = n->image_size; | |
1000 e->event.notify60[i].descr = NULL; | |
1001 e->event.notify60[i].time = 0; | |
1002 | |
1003 if (GG_S_D(n->status)) { | |
1004 unsigned char descr_len = *((char*) n + sizeof(struct gg_notify_reply60)); | |
2393 | 1005 |
8775 | 1006 if (descr_len < length) { |
1007 if (!(e->event.notify60[i].descr = malloc(descr_len + 1))) { | |
1008 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); | |
1009 goto fail; | |
1010 } | |
1011 | |
1012 memcpy(e->event.notify60[i].descr, (char*) n + sizeof(struct gg_notify_reply60) + 1, descr_len); | |
1013 e->event.notify60[i].descr[descr_len] = 0; | |
1014 | |
1015 /* XXX czas */ | |
1016 } | |
1017 | |
1018 length -= sizeof(struct gg_notify_reply60) + descr_len + 1; | |
1019 n = (void*) ((char*) n + sizeof(struct gg_notify_reply60) + descr_len + 1); | |
1020 } else { | |
1021 length -= sizeof(struct gg_notify_reply60); | |
1022 n = (void*) ((char*) n + sizeof(struct gg_notify_reply60)); | |
1023 } | |
1024 | |
1025 if (!(tmp = realloc(e->event.notify60, (i + 2) * sizeof(*e->event.notify60)))) { | |
1026 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n"); | |
1027 free(e->event.notify60); | |
1028 goto fail; | |
1029 } | |
1030 | |
1031 e->event.notify60 = (void*) tmp; | |
1032 e->event.notify60[++i].uin = 0; | |
1033 } | |
1034 | |
1035 break; | |
1036 } | |
1037 | |
1038 case GG_STATUS: | |
1039 { | |
1040 struct gg_status *s = (void *)p; | |
2393 | 1041 |
1042 gg_debug(GG_DEBUG_MISC, "-- received a status change\n"); | |
1043 | |
1044 if (h->length >= sizeof(*s)) { | |
1045 e->type = GG_EVENT_STATUS; | |
10648 | 1046 memcpy(&e->event.status, p, sizeof(*s)); |
2399
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
1047 e->event.status.uin = fix32(e->event.status.uin); |
b2926d21f067
[gaim-migrate @ 2412]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
1048 e->event.status.status = fix32(e->event.status.status); |
2393 | 1049 } |
8775 | 1050 break; |
1051 } | |
1052 | |
1053 case GG_STATUS60: | |
1054 { | |
1055 struct gg_status60 *s = (void*) p; | |
1056 uint32_t uin; | |
1057 | |
1058 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n"); | |
1059 | |
1060 if (h->length < sizeof(*s)) | |
1061 break; | |
1062 | |
1063 uin = fix32(s->uin); | |
1064 | |
1065 e->type = GG_EVENT_STATUS60; | |
1066 e->event.status60.uin = uin & 0x00ffffff; | |
1067 e->event.status60.status = s->status; | |
1068 e->event.status60.remote_ip = s->remote_ip; | |
1069 e->event.status60.remote_port = fix16(s->remote_port); | |
1070 e->event.status60.version = s->version; | |
1071 e->event.status60.image_size = s->image_size; | |
1072 e->event.status60.descr = NULL; | |
1073 e->event.status60.time = 0; | |
2393 | 1074 |
8775 | 1075 if (uin & 0x40000000) |
1076 e->event.status60.version |= GG_HAS_AUDIO_MASK; | |
1077 | |
1078 if (h->length > sizeof(*s)) { | |
1079 int len = h->length - sizeof(*s); | |
1080 char *buf = malloc(len + 1); | |
1081 | |
1082 if (buf) { | |
1083 memcpy(buf, (char*) p + sizeof(*s), len); | |
1084 buf[len] = 0; | |
1085 } | |
1086 | |
1087 e->event.status60.descr = buf; | |
1088 | |
11157
f068eaabe332
[gaim-migrate @ 13242]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
1089 if (len > 4 && p[h->length - 5] == 0) { |
f068eaabe332
[gaim-migrate @ 13242]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
1090 uint32_t t; |
f068eaabe332
[gaim-migrate @ 13242]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
1091 memcpy(&t, p + h->length - 4, sizeof(uint32_t)); |
f068eaabe332
[gaim-migrate @ 13242]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
1092 e->event.status60.time = t; |
f068eaabe332
[gaim-migrate @ 13242]
Richard Laager <rlaager@wiktel.com>
parents:
11105
diff
changeset
|
1093 } |
8775 | 1094 } |
1095 | |
1096 break; | |
1097 } | |
1098 | |
1099 case GG_SEND_MSG_ACK: | |
1100 { | |
1101 struct gg_send_msg_ack *s = (void *)p; | |
2393 | 1102 |
1103 gg_debug(GG_DEBUG_MISC, "-- received a message ack\n"); | |
1104 | |
1105 if (h->length >= sizeof(*s)) { | |
1106 e->type = GG_EVENT_ACK; | |
1107 e->event.ack.status = fix32(s->status); | |
1108 e->event.ack.recipient = fix32(s->recipient); | |
1109 e->event.ack.seq = fix32(s->seq); | |
1110 } | |
8775 | 1111 break; |
1112 } | |
2393 | 1113 |
8775 | 1114 case GG_PONG: |
1115 { | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1116 gg_debug(GG_DEBUG_MISC, "-- received a pong\n"); |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1117 sess->last_pong = time(NULL); |
8775 | 1118 break; |
1119 } | |
1120 | |
1121 case GG_USERLIST_REPLY: | |
1122 { | |
1123 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist reply\n"); | |
1124 | |
1125 if (h->length < 1) | |
1126 break; | |
1127 | |
1128 /* jeśli odpowiedź na eksport, wywołaj zdarzenie tylko | |
1129 * gdy otrzymano wszystkie odpowiedzi */ | |
1130 if (p[0] == GG_USERLIST_PUT_REPLY || p[0] == GG_USERLIST_PUT_MORE_REPLY) { | |
1131 if (--sess->userlist_blocks) | |
1132 break; | |
1133 | |
1134 p[0] = GG_USERLIST_PUT_REPLY; | |
1135 } | |
1136 | |
1137 if (h->length > 1) { | |
1138 char *tmp; | |
1139 int len = (sess->userlist_reply) ? strlen(sess->userlist_reply) : 0; | |
1140 | |
1141 gg_debug(GG_DEBUG_MISC, "userlist_reply=%p, len=%d\n", sess->userlist_reply, len); | |
1142 | |
1143 if (!(tmp = realloc(sess->userlist_reply, len + h->length))) { | |
1144 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for userlist reply\n"); | |
1145 free(sess->userlist_reply); | |
1146 sess->userlist_reply = NULL; | |
1147 goto fail; | |
1148 } | |
1149 | |
1150 sess->userlist_reply = tmp; | |
1151 sess->userlist_reply[len + h->length - 1] = 0; | |
1152 memcpy(sess->userlist_reply + len, p + 1, h->length - 1); | |
1153 } | |
1154 | |
1155 if (p[0] == GG_USERLIST_GET_MORE_REPLY) | |
1156 break; | |
1157 | |
1158 e->type = GG_EVENT_USERLIST; | |
1159 e->event.userlist.type = p[0]; | |
1160 e->event.userlist.reply = sess->userlist_reply; | |
1161 sess->userlist_reply = NULL; | |
1162 | |
1163 break; | |
1164 } | |
1165 | |
1166 default: | |
1167 gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received unknown packet 0x%.2x\n", h->type); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1168 } |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1169 |
2393 | 1170 free(h); |
1171 | |
1172 return 0; | |
8775 | 1173 |
1174 fail: | |
1175 free(h); | |
1176 return -1; | |
2393 | 1177 } |
1178 | |
1179 /* | |
1180 * gg_watch_fd() | |
1181 * | |
1182 * funkcja wywoływana, gdy coś się stanie na obserwowanym deskryptorze. | |
1183 * zwraca klientowi informację o tym, co się dzieje. | |
1184 * | |
1185 * - sess - identyfikator sesji. | |
1186 * | |
1187 * zwraca wskaźnik do struktury gg_event, którą trzeba zwolnić później | |
1188 * za pomocą gg_free_event(). jesli rodzaj zdarzenia jest równy | |
1189 * GG_EVENT_NONE, należy je olać kompletnie. jeśli zwróciło NULL, | |
1190 * stało się coś niedobrego -- albo brakło pamięci albo zerwało | |
1191 * połączenie albo coś takiego. | |
1192 */ | |
1193 struct gg_event *gg_watch_fd(struct gg_session *sess) | |
1194 { | |
1195 struct gg_event *e; | |
1196 int res = 0; | |
3630 | 1197 #ifndef _WIN32 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1198 int port; |
3630 | 1199 #endif |
2393 | 1200 |
1201 if (!sess) { | |
1202 errno = EFAULT; | |
1203 return NULL; | |
1204 } | |
1205 | |
1206 gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(...);\n"); | |
1207 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1208 if (!(e = (void*) malloc(sizeof(*e)))) { |
2393 | 1209 gg_debug(GG_DEBUG_MISC, "-- not enough memory\n"); |
1210 return NULL; | |
1211 } | |
1212 | |
1213 e->type = GG_EVENT_NONE; | |
1214 | |
1215 switch (sess->state) { | |
3630 | 1216 #ifndef _WIN32 |
1217 /* Apparantly we will never be in this state as long as we are | |
5681
46d7ad0dfa26
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
4298
diff
changeset
|
1218 using gaim_proxy_connect instead of gg_login - Herman */ |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1219 case GG_STATE_RESOLVING: |
2393 | 1220 { |
1221 struct in_addr a; | |
1222 | |
1223 gg_debug(GG_DEBUG_MISC, "== GG_STATE_RESOLVING\n"); | |
1224 | |
1225 if (read(sess->fd, &a, sizeof(a)) < sizeof(a) || a.s_addr == INADDR_NONE) { | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1226 gg_debug(GG_DEBUG_MISC, "-- resolving failed\n"); |
2393 | 1227 |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1228 errno = ENOENT; |
2393 | 1229 e->type = GG_EVENT_CONN_FAILED; |
1230 e->event.failure = GG_FAILURE_RESOLVING; | |
1231 sess->state = GG_STATE_IDLE; | |
1232 | |
1233 close(sess->fd); | |
1234 | |
1235 break; | |
1236 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1237 |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1238 sess->server_ip = a.s_addr; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1239 |
2393 | 1240 close(sess->fd); |
1241 | |
1242 waitpid(sess->pid, NULL, 0); | |
1243 | |
1244 gg_debug(GG_DEBUG_MISC, "-- resolved, now connecting\n"); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1245 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1246 if (gg_http_use_proxy) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1247 port = gg_http_proxy_port; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1248 } else { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1249 port = GG_APPMSG_PORT; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1250 }; |
2393 | 1251 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1252 if ((sess->fd = gg_connect(&a, port, sess->async)) == -1) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1253 struct in_addr *addr = (struct in_addr*) &sess->server_ip; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1254 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1255 gg_debug(GG_DEBUG_MISC, "-- connection failed, trying direct connection\n"); |
2393 | 1256 |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1257 if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1258 gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1259 if ((sess->fd = gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1260 gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1261 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1262 e->type = GG_EVENT_CONN_FAILED; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1263 e->event.failure = GG_FAILURE_CONNECTING; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1264 sess->state = GG_STATE_IDLE; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1265 break; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1266 } |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1267 } |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1268 sess->state = GG_STATE_CONNECTING_GG; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1269 sess->check = GG_CHECK_WRITE; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1270 } else { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1271 sess->state = GG_STATE_CONNECTING; |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1272 sess->check = GG_CHECK_WRITE; |
2393 | 1273 } |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1274 |
2393 | 1275 break; |
1276 } | |
3630 | 1277 #endif /* !_WIN32 */ |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1278 case GG_STATE_CONNECTING: |
2393 | 1279 { |
1280 char buf[1024]; | |
6063 | 1281 unsigned int res, res_size = sizeof(res); |
2393 | 1282 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1283 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING\n"); |
2393 | 1284 |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
1285 if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { |
3630 | 1286 #if 0 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1287 struct in_addr *addr = (struct in_addr*) &sess->server_ip; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1288 gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d (%s), trying direct connection\n", res, strerror(res)); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1289 if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1290 gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1291 if ((sess->fd = gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) { |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1292 gg_debug(GG_DEBUG_MISC, "-- connect() failed. errno = %d (%s)\n", errno, strerror(errno)); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1293 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1294 e->type = GG_EVENT_CONN_FAILED; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1295 e->event.failure = GG_FAILURE_CONNECTING; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1296 sess->state = GG_STATE_IDLE; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1297 break; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1298 } |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1299 } |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1300 |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1301 sess->state = GG_STATE_CONNECTING_GG; |
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1302 sess->check = GG_CHECK_WRITE; |
3630 | 1303 #else |
1304 gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d\n", res); | |
1305 e->type = GG_EVENT_CONN_FAILED; | |
1306 e->event.failure = GG_FAILURE_CONNECTING; | |
1307 sess->state = GG_STATE_IDLE; | |
1308 #endif | |
2393 | 1309 break; |
1310 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1311 |
2393 | 1312 gg_debug(GG_DEBUG_MISC, "-- http connection succeded, sending query\n"); |
1313 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1314 if (gg_http_use_proxy) { |
3630 | 1315 g_snprintf(buf, sizeof(buf) - 1, |
9663 | 1316 "GET http://" GG_APPMSG_HOST "/appsvc/appmsg2.asp?fmnumber=%lu&version=%s&lastmsg=0 HTTP/1.0\r\n" |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1317 "Host: " GG_APPMSG_HOST "\r\n" |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1318 "User-Agent: " GG_HTTP_USERAGENT "\r\n" |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1319 "Pragma: no-cache\r\n" |
9663 | 1320 "\r\n", sess->uin, gg_urlencode(GG_DEFAULT_CLIENT_VERSION)); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1321 } else { |
3630 | 1322 g_snprintf(buf, sizeof(buf) - 1, |
9663 | 1323 "GET /appsvc/appmsg2.asp?fmnumber=%lu&version=%s&lastmsg=0 HTTP/1.0\r\n" |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1324 "Host: " GG_APPMSG_HOST "\r\n" |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1325 "User-Agent: " GG_HTTP_USERAGENT "\r\n" |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1326 "Pragma: no-cache\r\n" |
9663 | 1327 "\r\n", sess->uin, gg_urlencode(GG_DEFAULT_CLIENT_VERSION)); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1328 }; |
2393 | 1329 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1330 gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf); |
2393 | 1331 if (write(sess->fd, buf, strlen(buf)) < strlen(buf)) { |
1332 gg_debug(GG_DEBUG_MISC, "-- sending query failed\n"); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1333 errno = EIO; |
2393 | 1334 e->type = GG_EVENT_CONN_FAILED; |
1335 e->event.failure = GG_FAILURE_WRITING; | |
1336 sess->state = GG_STATE_IDLE; | |
1337 break; | |
1338 } | |
1339 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1340 sess->state = GG_STATE_READING_DATA; |
2393 | 1341 sess->check = GG_CHECK_READ; |
1342 | |
1343 break; | |
1344 } | |
1345 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1346 case GG_STATE_READING_DATA: |
2393 | 1347 { |
1348 char buf[1024], *tmp, *host; | |
1349 int port = GG_DEFAULT_PORT; | |
1350 struct in_addr a; | |
1351 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1352 gg_debug(GG_DEBUG_MISC, "== GG_STATE_READING_DATA\n"); |
2393 | 1353 |
1354 gg_read_line(sess->fd, buf, sizeof(buf) - 1); | |
1355 gg_chomp(buf); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1356 |
2393 | 1357 gg_debug(GG_DEBUG_TRAFFIC, "-- got http response (%s)\n", buf); |
1358 if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) { | |
1359 gg_debug(GG_DEBUG_MISC, "-- but that's not what we've expected\n"); | |
1360 | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1361 errno = EINVAL; |
2393 | 1362 e->type = GG_EVENT_CONN_FAILED; |
1363 e->event.failure = GG_FAILURE_INVALID; | |
1364 sess->state = GG_STATE_IDLE; | |
1365 break; | |
1366 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1367 |
2393 | 1368 while (strcmp(buf, "\r\n") && strcmp(buf, "")) |
1369 gg_read_line(sess->fd, buf, sizeof(buf) - 1); | |
1370 | |
1371 gg_read_line(sess->fd, buf, sizeof(buf) - 1); | |
1372 gg_chomp(buf); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1373 |
2393 | 1374 close(sess->fd); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1375 |
2393 | 1376 gg_debug(GG_DEBUG_TRAFFIC, "-- received http data (%s)\n", buf); |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1377 |
8775 | 1378 /* analizujemy otrzymane dane. */ |
2393 | 1379 tmp = buf; |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1380 |
2393 | 1381 while (*tmp && *tmp != ' ') |
9663 | 1382 tmp++; |
1383 while (*tmp && *tmp == ' ') | |
1384 tmp++; | |
1385 host = tmp; | |
1386 while (*tmp && *tmp != ' ') | |
1387 tmp++; | |
1388 *tmp = 0; | |
2393 | 1389 |
1390 if ((tmp = strchr(host, ':'))) { | |
1391 *tmp = 0; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1392 port = atoi(tmp+1); |
2393 | 1393 } |
1394 | |
1395 a.s_addr = inet_addr(host); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1396 sess->server_ip = a.s_addr; |
8775 | 1397 |
3630 | 1398 #if 0 |
5681
46d7ad0dfa26
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
4298
diff
changeset
|
1399 /* We need to watch this non-blocking socket so lets use gaim_proxy_connect |
3630 | 1400 in gg.c - Herman */ |
1401 if((sess->fd = gg_connect(&a, port, sess->assync)) == -1) { | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1402 gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1403 if ((sess->fd = gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1404 gg_debug(GG_DEBUG_MISC, "-- connection failed, errno = %d (%s)\n", errno, strerror(errno)); |
2393 | 1405 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1406 e->type = GG_EVENT_CONN_FAILED; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1407 e->event.failure = GG_FAILURE_CONNECTING; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1408 sess->state = GG_STATE_IDLE; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1409 break; |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1410 } |
2393 | 1411 } |
3630 | 1412 #else |
1413 sess->port = port; | |
1414 #endif | |
2393 | 1415 sess->state = GG_STATE_CONNECTING_GG; |
1416 sess->check = GG_CHECK_WRITE; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1417 |
2393 | 1418 break; |
1419 } | |
1420 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1421 case GG_STATE_CONNECTING_GG: |
2393 | 1422 { |
6063 | 1423 unsigned int res, res_size = sizeof(res); |
2393 | 1424 |
1425 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_GG\n"); | |
1426 | |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3630
diff
changeset
|
1427 if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1428 struct in_addr *addr = (struct in_addr*) &sess->server_ip; |
2393 | 1429 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1430 gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1431 if ((sess->fd = gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1432 gg_debug(GG_DEBUG_MISC, "-- connection failed, errno = %d (%s)\n", errno, strerror(errno)); |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1433 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1434 e->type = GG_EVENT_CONN_FAILED; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1435 e->event.failure = GG_FAILURE_CONNECTING; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1436 sess->state = GG_STATE_IDLE; |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1437 break; |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1438 } |
2393 | 1439 } |
1440 | |
1441 gg_debug(GG_DEBUG_MISC, "-- connected\n"); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1442 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1443 sess->state = GG_STATE_READING_KEY; |
2393 | 1444 sess->check = GG_CHECK_READ; |
1445 | |
1446 break; | |
1447 } | |
1448 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1449 case GG_STATE_READING_KEY: |
2393 | 1450 { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1451 struct gg_header *h; |
2393 | 1452 struct gg_welcome *w; |
8775 | 1453 struct gg_login60 l; |
2393 | 1454 unsigned int hash; |
10388 | 1455 unsigned char *password = sess->password; |
2393 | 1456 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1457 gg_debug(GG_DEBUG_MISC, "== GG_STATE_READING_KEY\n"); |
2393 | 1458 |
1459 if (!(h = gg_recv_packet(sess))) { | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1460 gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d (%s)\n", errno, strerror(errno)); |
2393 | 1461 e->type = GG_EVENT_CONN_FAILED; |
1462 e->event.failure = GG_FAILURE_READING; | |
1463 sess->state = GG_STATE_IDLE; | |
1464 close(sess->fd); | |
1465 break; | |
1466 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1467 |
2393 | 1468 if (h->type != GG_WELCOME) { |
1469 gg_debug(GG_DEBUG_MISC, "-- invalid packet received\n"); | |
1470 | |
1471 free(h); | |
1472 close(sess->fd); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1473 errno = EINVAL; |
2393 | 1474 e->type = GG_EVENT_CONN_FAILED; |
1475 e->event.failure = GG_FAILURE_INVALID; | |
1476 sess->state = GG_STATE_IDLE; | |
1477 break; | |
1478 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1479 |
6247 | 1480 w = (struct gg_welcome *)((void *)h + sizeof(struct gg_header)); |
2393 | 1481 w->key = fix32(w->key); |
8775 | 1482 |
1483 hash = gg_login_hash(password, w->key); | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1484 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1485 gg_debug(GG_DEBUG_DUMP, "%%%% klucz serwera %.4x, hash hasła %.8x\n", w->key, hash); |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1486 |
2393 | 1487 free(h); |
1488 | |
1489 free(sess->password); | |
1490 sess->password = NULL; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1491 |
2393 | 1492 l.uin = fix32(sess->uin); |
1493 l.hash = fix32(hash); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1494 l.status = fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL); |
8775 | 1495 l.version = fix32(0x20); |
2393 | 1496 l.local_ip = 0; |
1497 l.local_port = 0; | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1498 |
2393 | 1499 gg_debug(GG_DEBUG_TRAFFIC, "-- sending GG_LOGIN packet\n"); |
1500 | |
8775 | 1501 if (gg_send_packet(sess, GG_LOGIN60, &l, sizeof(l), NULL, 0) == -1) { |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1502 gg_debug(GG_DEBUG_TRAFFIC, "-- oops, failed. errno = %d (%s)\n", errno, strerror(errno)); |
2393 | 1503 |
1504 close(sess->fd); | |
1505 e->type = GG_EVENT_CONN_FAILED; | |
1506 e->event.failure = GG_FAILURE_WRITING; | |
1507 sess->state = GG_STATE_IDLE; | |
1508 break; | |
1509 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1510 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1511 sess->state = GG_STATE_READING_REPLY; |
2393 | 1512 |
1513 break; | |
1514 } | |
1515 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1516 case GG_STATE_READING_REPLY: |
2393 | 1517 { |
1518 struct gg_header *h; | |
1519 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1520 gg_debug(GG_DEBUG_MISC, "== GG_STATE_READING_REPLY\n"); |
2393 | 1521 |
1522 if (!(h = gg_recv_packet(sess))) { | |
1523 gg_debug(GG_DEBUG_MISC, "-- recv_packet failed\n"); | |
1524 e->type = GG_EVENT_CONN_FAILED; | |
1525 e->event.failure = GG_FAILURE_READING; | |
1526 sess->state = GG_STATE_IDLE; | |
1527 close(sess->fd); | |
1528 break; | |
1529 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1530 |
2393 | 1531 if (h->type == GG_LOGIN_OK) { |
1532 gg_debug(GG_DEBUG_MISC, "-- login succeded\n"); | |
1533 e->type = GG_EVENT_CONN_SUCCESS; | |
1534 sess->state = GG_STATE_CONNECTED; | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1535 free(h); |
2393 | 1536 break; |
1537 } | |
1538 | |
1539 if (h->type == GG_LOGIN_FAILED) { | |
1540 gg_debug(GG_DEBUG_MISC, "-- login failed\n"); | |
1541 e->event.failure = GG_FAILURE_PASSWORD; | |
1542 errno = EACCES; | |
1543 } else { | |
1544 gg_debug(GG_DEBUG_MISC, "-- invalid packet\n"); | |
1545 e->event.failure = GG_FAILURE_INVALID; | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1546 errno = EINVAL; |
2393 | 1547 } |
1548 | |
1549 e->type = GG_EVENT_CONN_FAILED; | |
1550 sess->state = GG_STATE_IDLE; | |
1551 close(sess->fd); | |
2792
9123abd0db92
[gaim-migrate @ 2805]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2595
diff
changeset
|
1552 free(h); |
2393 | 1553 |
1554 break; | |
1555 } | |
1556 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1557 case GG_STATE_CONNECTED: |
2393 | 1558 { |
1559 gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTED\n"); | |
1560 | |
1561 if ((res = gg_watch_fd_connected(sess, e)) == -1) { | |
1562 | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1563 gg_debug(GG_DEBUG_MISC, "-- watch_fd_connected failed. errno = %d (%s)\n", errno, strerror(errno)); |
2393 | 1564 |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1565 if (errno == EAGAIN) { |
2393 | 1566 e->type = GG_EVENT_NONE; |
1567 res = 0; | |
1568 } else | |
1569 res = -1; | |
1570 } | |
1571 break; | |
1572 } | |
1573 } | |
1574 | |
1575 if (res == -1) { | |
1576 free(e); | |
1577 e = NULL; | |
1578 } | |
1579 | |
1580 return e; | |
1581 } | |
2846
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1582 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1583 /* |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1584 * Local variables: |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1585 * c-indentation-style: k&r |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1586 * c-basic-offset: 8 |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1587 * indent-tabs-mode: notnil |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1588 * End: |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1589 * |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1590 * vim: shiftwidth=8: |
4b3f17ca66bf
[gaim-migrate @ 2859]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2792
diff
changeset
|
1591 */ |