comparison src/protocols/gg/lib/libgadu.c @ 11546:3c536224f0d0

[gaim-migrate @ 13801] Update gg to compile and seem to work on win32. The win32 thread implementation in libgg has not been tested *at all*, but I think that the gaim tie-in is all synchronous anyway (yes, it hangs up the UI wonderfully whendoing stuff). I should probably look into getting some of this stuff back into libgg committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Wed, 14 Sep 2005 19:10:39 +0000
parents cf15c1cdcfbd
children 8724718d387f
comparison
equal deleted inserted replaced
11545:85abf1deac05 11546:3c536224f0d0
1 /* $Id: libgadu.c 13582 2005-08-28 22:46:01Z boler $ */ 1 /* $Id: libgadu.c 13801 2005-09-14 19:10:39Z datallah $ */
2 2
3 /* 3 /*
4 * (C) Copyright 2001-2003 Wojtek Kaniewski <wojtekka@irc.pl> 4 * (C) Copyright 2001-2003 Wojtek Kaniewski <wojtekka@irc.pl>
5 * Robert J. Woźny <speedy@ziew.org> 5 * Robert J. Woźny <speedy@ziew.org>
6 * Arkadiusz Miśkiewicz <arekm@pld-linux.org> 6 * Arkadiusz Miśkiewicz <arekm@pld-linux.org>
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
21 * USA. 21 * USA.
22 */ 22 */
23 23
24 #include <sys/types.h> 24 #include <sys/types.h>
25 #ifndef _WIN32
25 #include <sys/wait.h> 26 #include <sys/wait.h>
26 #include <sys/socket.h> 27 #include <sys/socket.h>
27 #include <netinet/in.h> 28 #include <netinet/in.h>
28 #include <arpa/inet.h> 29 #include <arpa/inet.h>
29 #ifdef sun 30 #ifdef sun
30 # include <sys/filio.h> 31 # include <sys/filio.h>
31 #endif 32 #endif
33 #else
34 #include <io.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #define SHUT_RDWR SD_BOTH
38 #endif
32 39
33 #include "libgadu-config.h" 40 #include "libgadu-config.h"
34 41
35 #include <errno.h> 42 #include <errno.h>
43 #ifndef _WIN32
36 #include <netdb.h> 44 #include <netdb.h>
45 #endif
37 #ifdef __GG_LIBGADU_HAVE_PTHREAD 46 #ifdef __GG_LIBGADU_HAVE_PTHREAD
38 # include <pthread.h> 47 # include <pthread.h>
39 #endif 48 #endif
40 #include <stdarg.h> 49 #include <stdarg.h>
41 #include <stdio.h> 50 #include <stdio.h>
70 #ifndef lint 79 #ifndef lint
71 static char rcsid[] 80 static char rcsid[]
72 #ifdef __GNUC__ 81 #ifdef __GNUC__
73 __attribute__ ((unused)) 82 __attribute__ ((unused))
74 #endif 83 #endif
75 = "$Id: libgadu.c 13582 2005-08-28 22:46:01Z boler $"; 84 = "$Id: libgadu.c 13801 2005-09-14 19:10:39Z datallah $";
76 #endif 85 #endif
77 86
78 /* 87 /*
79 * gg_libgadu_version() 88 * gg_libgadu_version()
80 * 89 *
167 } 176 }
168 177
169 return y; 178 return y;
170 } 179 }
171 180
181 #ifndef _WIN32
182
172 /* 183 /*
173 * gg_resolve() // funkcja wewnętrzna 184 * gg_resolve() // funkcja wewnętrzna
174 * 185 *
175 * tworzy potok, forkuje się i w drugim procesie zaczyna resolvować 186 * tworzy potok, forkuje się i w drugim procesie zaczyna resolvować
176 * podanego hosta. zapisuje w sesji deskryptor potoku. jeśli coś tam 187 * podanego hosta. zapisuje w sesji deskryptor potoku. jeśli coś tam
229 *fd = pipes[0]; 240 *fd = pipes[0];
230 *pid = res; 241 *pid = res;
231 242
232 return 0; 243 return 0;
233 } 244 }
245 #endif
234 246
235 #ifdef __GG_LIBGADU_HAVE_PTHREAD 247 #ifdef __GG_LIBGADU_HAVE_PTHREAD
236 248
237 struct gg_resolve_pthread_data { 249 struct gg_resolve_pthread_data {
238 char *hostname; 250 char *hostname;
353 errno = new_errno; 365 errno = new_errno;
354 366
355 return -1; 367 return -1;
356 } 368 }
357 369
370 #elif defined _WIN32
371
372 struct gg_resolve_win32thread_data {
373 char *hostname;
374 int fd;
375 };
376
377 static DWORD WINAPI gg_resolve_win32thread_thread(LPVOID arg)
378 {
379 struct gg_resolve_win32thread_data *d = arg;
380 struct in_addr a;
381
382 if ((a.s_addr = inet_addr(d->hostname)) == INADDR_NONE) {
383 struct in_addr *hn;
384
385 if (!(hn = gg_gethostbyname(d->hostname)))
386 a.s_addr = INADDR_NONE;
387 else {
388 a.s_addr = hn->s_addr;
389 free(hn);
390 }
391 }
392
393 write(d->fd, &a, sizeof(a));
394 close(d->fd);
395
396 free(d->hostname);
397 d->hostname = NULL;
398
399 free(d);
400
401 return 0;
402 }
403
404
405 int gg_resolve_win32thread(int *fd, void **resolver, const char *hostname)
406 {
407 struct gg_resolve_win32thread_data *d = NULL;
408 HANDLE h;
409 DWORD dwTId;
410 int pipes[2], new_errno;
411
412 gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve_win32thread(%p, %p, \"%s\");\n", fd, resolver, hostname);
413
414 if (!resolver || !fd || !hostname) {
415 gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() invalid arguments\n");
416 errno = EFAULT;
417 return -1;
418 }
419
420 if (pipe(pipes) == -1) {
421 gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
422 return -1;
423 }
424
425 if (!(d = malloc(sizeof(*d)))) {
426 gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
427 new_errno = GetLastError();
428 goto cleanup;
429 }
430
431 d->hostname = NULL;
432
433 if (!(d->hostname = strdup(hostname))) {
434 gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() out of memory\n");
435 new_errno = GetLastError();
436 goto cleanup;
437 }
438
439 d->fd = pipes[1];
440
441 h = CreateThread(NULL, 0, gg_resolve_win32thread_thread,
442 d, 0, &dwTId);
443
444 if (h == NULL) {
445 gg_debug(GG_DEBUG_MISC, "// gg_resolve_win32thread() unable to create thread\n");
446 new_errno = GetLastError();
447 goto cleanup;
448 }
449
450 *resolver = h;
451 *fd = pipes[0];
452
453 return 0;
454
455 cleanup:
456 if (d) {
457 free(d->hostname);
458 free(d);
459 }
460
461 close(pipes[0]);
462 close(pipes[1]);
463
464 errno = new_errno;
465
466 return -1;
467
468 }
358 #endif 469 #endif
359 470
360 /* 471 /*
361 * gg_read() // funkcja pomocnicza 472 * gg_read() // funkcja pomocnicza
362 * 473 *
877 988
878 return sess; 989 return sess;
879 } 990 }
880 991
881 if (!sess->server_addr || gg_proxy_enabled) { 992 if (!sess->server_addr || gg_proxy_enabled) {
882 #ifndef __GG_LIBGADU_HAVE_PTHREAD 993 #ifdef __GG_LIBGADU_HAVE_PTHREAD
994 if (gg_resolve_pthread(&sess->fd, &sess->resolver, hostname)) {
995 #elif defined _WIN32
996 if (gg_resolve_win32thread(&sess->fd, &sess->resolver, hostname)) {
997 #else
883 if (gg_resolve(&sess->fd, &sess->pid, hostname)) { 998 if (gg_resolve(&sess->fd, &sess->pid, hostname)) {
884 #else
885 if (gg_resolve_pthread(&sess->fd, &sess->resolver, hostname)) {
886 #endif 999 #endif
887 gg_debug(GG_DEBUG_MISC, "// gg_login() resolving failed (errno=%d, %s)\n", errno, strerror(errno)); 1000 gg_debug(GG_DEBUG_MISC, "// gg_login() resolving failed (errno=%d, %s)\n", errno, strerror(errno));
888 goto fail; 1001 goto fail;
889 } 1002 }
890 } else { 1003 } else {
948 if (sess->resolver) { 1061 if (sess->resolver) {
949 pthread_cancel(*((pthread_t*) sess->resolver)); 1062 pthread_cancel(*((pthread_t*) sess->resolver));
950 free(sess->resolver); 1063 free(sess->resolver);
951 sess->resolver = NULL; 1064 sess->resolver = NULL;
952 } 1065 }
1066 #elif defined _WIN32
1067 if (sess->resolver) {
1068 HANDLE h = sess->resolver;
1069 TerminateThread(h, 0);
1070 CloseHandle(h);
1071 sess->resolver = NULL;
1072 }
953 #else 1073 #else
954 if (sess->pid != -1) 1074 if (sess->pid != -1)
955 waitpid(sess->pid, NULL, WNOHANG); 1075 waitpid(sess->pid, NULL, WNOHANG);
956 #endif 1076 #endif
957 1077
1093 1213
1094 #ifdef __GG_LIBGADU_HAVE_PTHREAD 1214 #ifdef __GG_LIBGADU_HAVE_PTHREAD
1095 if (sess->resolver) { 1215 if (sess->resolver) {
1096 pthread_cancel(*((pthread_t*) sess->resolver)); 1216 pthread_cancel(*((pthread_t*) sess->resolver));
1097 free(sess->resolver); 1217 free(sess->resolver);
1218 sess->resolver = NULL;
1219 }
1220 #elif defined _WIN32
1221 if (sess->resolver) {
1222 HANDLE h = sess->resolver;
1223 TerminateThread(h, 0);
1224 CloseHandle(h);
1098 sess->resolver = NULL; 1225 sess->resolver = NULL;
1099 } 1226 }
1100 #else 1227 #else
1101 if (sess->pid != -1) { 1228 if (sess->pid != -1) {
1102 waitpid(sess->pid, NULL, WNOHANG); 1229 waitpid(sess->pid, NULL, WNOHANG);