comparison libgaim/proxy.c @ 14262:baff095b146c

[gaim-migrate @ 16944] Rename GaimProxyConnectInfo to GaimProxyConnectData, and change the variables from connect_info to connect_data. Sorry, but I wanted to get this right before it becomes permanent. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 21 Aug 2006 05:25:44 +0000
parents f189327b9968
children 4ae3c2913c3e
comparison
equal deleted inserted replaced
14261:bb060cdc23d1 14262:baff095b146c
37 #include "ntlm.h" 37 #include "ntlm.h"
38 #include "prefs.h" 38 #include "prefs.h"
39 #include "proxy.h" 39 #include "proxy.h"
40 #include "util.h" 40 #include "util.h"
41 41
42 struct _GaimProxyConnectInfo { 42 struct _GaimProxyConnectData {
43 GaimProxyConnectFunction connect_cb; 43 GaimProxyConnectFunction connect_cb;
44 gpointer data; 44 gpointer data;
45 char *host; 45 char *host;
46 int port; 46 int port;
47 int fd; 47 int fd;
85 /* 85 /*
86 * TODO: Once all callers of gaim_proxy_connect() are keeping track 86 * TODO: Once all callers of gaim_proxy_connect() are keeping track
87 * of the return value from that function this linked list 87 * of the return value from that function this linked list
88 * will no longer be needed. 88 * will no longer be needed.
89 */ 89 */
90 static GSList *connect_infos = NULL; 90 static GSList *connect_datas = NULL;
91 91
92 static void try_connect(GaimProxyConnectInfo *connect_info); 92 static void try_connect(GaimProxyConnectData *connect_data);
93 93
94 /************************************************************************** 94 /**************************************************************************
95 * Proxy structure API 95 * Proxy structure API
96 **************************************************************************/ 96 **************************************************************************/
97 GaimProxyInfo * 97 GaimProxyInfo *
279 * address fails. We close the socket, remove the watcher and get 279 * address fails. We close the socket, remove the watcher and get
280 * rid of input and output buffers. Normally try_connect() will 280 * rid of input and output buffers. Normally try_connect() will
281 * be called immediately after this. 281 * be called immediately after this.
282 */ 282 */
283 static void 283 static void
284 gaim_proxy_connect_info_disconnect(GaimProxyConnectInfo *connect_info) 284 gaim_proxy_connect_data_disconnect(GaimProxyConnectData *connect_data)
285 { 285 {
286 if (connect_info->inpa > 0) 286 if (connect_data->inpa > 0)
287 { 287 {
288 gaim_input_remove(connect_info->inpa); 288 gaim_input_remove(connect_data->inpa);
289 connect_info->inpa = 0; 289 connect_data->inpa = 0;
290 } 290 }
291 291
292 if (connect_info->fd >= 0) 292 if (connect_data->fd >= 0)
293 { 293 {
294 close(connect_info->fd); 294 close(connect_data->fd);
295 connect_info->fd = -1; 295 connect_data->fd = -1;
296 } 296 }
297 297
298 g_free(connect_info->write_buffer); 298 g_free(connect_data->write_buffer);
299 connect_info->write_buffer = NULL; 299 connect_data->write_buffer = NULL;
300 300
301 g_free(connect_info->read_buffer); 301 g_free(connect_data->read_buffer);
302 connect_info->read_buffer = NULL; 302 connect_data->read_buffer = NULL;
303 } 303 }
304 304
305 static void 305 static void
306 gaim_proxy_connect_info_destroy(GaimProxyConnectInfo *connect_info) 306 gaim_proxy_connect_data_destroy(GaimProxyConnectData *connect_data)
307 { 307 {
308 gaim_proxy_connect_info_disconnect(connect_info); 308 gaim_proxy_connect_data_disconnect(connect_data);
309 309
310 connect_infos = g_slist_remove(connect_infos, connect_info); 310 connect_datas = g_slist_remove(connect_datas, connect_data);
311 311
312 if (connect_info->query_data != NULL) 312 if (connect_data->query_data != NULL)
313 gaim_dnsquery_destroy(connect_info->query_data); 313 gaim_dnsquery_destroy(connect_data->query_data);
314 314
315 while (connect_info->hosts != NULL) 315 while (connect_data->hosts != NULL)
316 { 316 {
317 /* Discard the length... */ 317 /* Discard the length... */
318 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); 318 connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
319 /* Free the address... */ 319 /* Free the address... */
320 g_free(connect_info->hosts->data); 320 g_free(connect_data->hosts->data);
321 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); 321 connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
322 } 322 }
323 323
324 g_free(connect_info->host); 324 g_free(connect_data->host);
325 g_free(connect_info); 325 g_free(connect_data);
326 } 326 }
327 327
328 static void 328 static void
329 gaim_proxy_connect_info_connected(GaimProxyConnectInfo *connect_info) 329 gaim_proxy_connect_data_connected(GaimProxyConnectData *connect_data)
330 { 330 {
331 connect_info->connect_cb(connect_info->data, connect_info->fd, NULL); 331 connect_data->connect_cb(connect_data->data, connect_data->fd, NULL);
332 332
333 /* 333 /*
334 * We've passed the file descriptor to the protocol, so it's no longer 334 * We've passed the file descriptor to the protocol, so it's no longer
335 * our responsibility, and we should be careful not to free it when 335 * our responsibility, and we should be careful not to free it when
336 * we destroy the connect_info. 336 * we destroy the connect_data.
337 */ 337 */
338 connect_info->fd = -1; 338 connect_data->fd = -1;
339 339
340 gaim_proxy_connect_info_destroy(connect_info); 340 gaim_proxy_connect_data_destroy(connect_data);
341 } 341 }
342 342
343 /** 343 /**
344 * @param error An error message explaining why the connection 344 * @param error An error message explaining why the connection
345 * failed. This will be passed to the callback function 345 * failed. This will be passed to the callback function
348 /* 348 /*
349 * TODO: Make sure all callers of this function pass a really really 349 * TODO: Make sure all callers of this function pass a really really
350 * good error_message. 350 * good error_message.
351 */ 351 */
352 static void 352 static void
353 gaim_proxy_connect_info_error(GaimProxyConnectInfo *connect_info, const gchar *error_message) 353 gaim_proxy_connect_data_error(GaimProxyConnectData *connect_data, const gchar *error_message)
354 { 354 {
355 connect_info->connect_cb(connect_info->data, -1, error_message); 355 connect_data->connect_cb(connect_data->data, -1, error_message);
356 gaim_proxy_connect_info_destroy(connect_info); 356 gaim_proxy_connect_data_destroy(connect_data);
357 } 357 }
358 358
359 static void 359 static void
360 no_one_calls(gpointer data, gint source, GaimInputCondition cond) 360 no_one_calls(gpointer data, gint source, GaimInputCondition cond)
361 { 361 {
362 GaimProxyConnectInfo *connect_info = data; 362 GaimProxyConnectData *connect_data = data;
363 socklen_t len; 363 socklen_t len;
364 int error=0, ret; 364 int error=0, ret;
365 365
366 gaim_debug_info("proxy", "Connected.\n"); 366 gaim_debug_info("proxy", "Connected.\n");
367 367
376 * 376 *
377 * (error == EINPROGRESS can happen after a select because the kernel can 377 * (error == EINPROGRESS can happen after a select because the kernel can
378 * be overly optimistic sometimes. select is just a hint that you might be 378 * be overly optimistic sometimes. select is just a hint that you might be
379 * able to do something.) 379 * able to do something.)
380 */ 380 */
381 ret = getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len); 381 ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
382 if (ret == 0 && error == EINPROGRESS) 382 if (ret == 0 && error == EINPROGRESS)
383 return; /* we'll be called again later */ 383 return; /* we'll be called again later */
384 if (ret < 0 || error != 0) { 384 if (ret < 0 || error != 0) {
385 if (ret!=0) 385 if (ret!=0)
386 error = errno; 386 error = errno;
387 387
388 gaim_debug_error("proxy", 388 gaim_debug_error("proxy",
389 "getsockopt SO_ERROR check: %s\n", strerror(error)); 389 "getsockopt SO_ERROR check: %s\n", strerror(error));
390 390
391 gaim_proxy_connect_info_disconnect(connect_info); 391 gaim_proxy_connect_data_disconnect(connect_data);
392 try_connect(connect_info); 392 try_connect(connect_data);
393 return; 393 return;
394 } 394 }
395 395
396 gaim_input_remove(connect_info->inpa); 396 gaim_input_remove(connect_data->inpa);
397 connect_info->inpa = 0; 397 connect_data->inpa = 0;
398 398
399 gaim_proxy_connect_info_connected(connect_info); 399 gaim_proxy_connect_data_connected(connect_data);
400 } 400 }
401 401
402 static gboolean 402 static gboolean
403 clean_connect(gpointer data) 403 clean_connect(gpointer data)
404 { 404 {
405 GaimProxyConnectInfo *connect_info; 405 GaimProxyConnectData *connect_data;
406 406
407 connect_info = data; 407 connect_data = data;
408 gaim_proxy_connect_info_connected(connect_info); 408 gaim_proxy_connect_data_connected(connect_data);
409 409
410 return FALSE; 410 return FALSE;
411 } 411 }
412 412
413 static int 413 static int
414 proxy_connect_none(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 414 proxy_connect_none(GaimProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
415 { 415 {
416 gaim_debug_info("proxy", "Connecting to %s:%d with no proxy\n", 416 gaim_debug_info("proxy", "Connecting to %s:%d with no proxy\n",
417 connect_info->host, connect_info->port); 417 connect_data->host, connect_data->port);
418 418
419 connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); 419 connect_data->fd = socket(addr->sa_family, SOCK_STREAM, 0);
420 if (connect_info->fd < 0) 420 if (connect_data->fd < 0)
421 { 421 {
422 gaim_debug_error("proxy", 422 gaim_debug_error("proxy",
423 "Unable to create socket: %s\n", strerror(errno)); 423 "Unable to create socket: %s\n", strerror(errno));
424 return -1; 424 return -1;
425 } 425 }
426 fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); 426 fcntl(connect_data->fd, F_SETFL, O_NONBLOCK);
427 #ifndef _WIN32 427 #ifndef _WIN32
428 fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); 428 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
429 #endif 429 #endif
430 430
431 if (connect(connect_info->fd, (struct sockaddr *)addr, addrlen) != 0) 431 if (connect(connect_data->fd, (struct sockaddr *)addr, addrlen) != 0)
432 { 432 {
433 if ((errno == EINPROGRESS) || (errno == EINTR)) { 433 if ((errno == EINPROGRESS) || (errno == EINTR)) {
434 gaim_debug_info("proxy", "Connection in progress\n"); 434 gaim_debug_info("proxy", "Connection in progress\n");
435 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, no_one_calls, connect_info); 435 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, no_one_calls, connect_data);
436 } 436 }
437 else { 437 else {
438 gaim_debug_error("proxy", 438 gaim_debug_error("proxy",
439 "Connect failed: %s\n", strerror(errno)); 439 "Connect failed: %s\n", strerror(errno));
440 close(connect_info->fd); 440 close(connect_data->fd);
441 connect_info->fd = -1; 441 connect_data->fd = -1;
442 return -1; 442 return -1;
443 } 443 }
444 } 444 }
445 else 445 else
446 { 446 {
449 */ 449 */
450 socklen_t len; 450 socklen_t len;
451 int error = ETIMEDOUT; 451 int error = ETIMEDOUT;
452 gaim_debug_info("proxy", "Connected immediately.\n"); 452 gaim_debug_info("proxy", "Connected immediately.\n");
453 len = sizeof(error); 453 len = sizeof(error);
454 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) 454 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0)
455 { 455 {
456 gaim_debug_error("proxy", "getsockopt failed.\n"); 456 gaim_debug_error("proxy", "getsockopt failed.\n");
457 close(connect_info->fd); 457 close(connect_data->fd);
458 connect_info->fd = -1; 458 connect_data->fd = -1;
459 return -1; 459 return -1;
460 } 460 }
461 461
462 /* 462 /*
463 * We want to call the "connected" callback eventually, but we 463 * We want to call the "connected" callback eventually, but we
464 * don't want to call it before we return, just in case. 464 * don't want to call it before we return, just in case.
465 */ 465 */
466 gaim_timeout_add(10, clean_connect, connect_info); 466 gaim_timeout_add(10, clean_connect, connect_data);
467 } 467 }
468 468
469 return connect_info->fd; 469 return connect_data->fd;
470 } 470 }
471 471
472 static void 472 static void
473 proxy_do_write(gpointer data, gint source, GaimInputCondition cond) 473 proxy_do_write(gpointer data, gint source, GaimInputCondition cond)
474 { 474 {
475 GaimProxyConnectInfo *connect_info = data; 475 GaimProxyConnectData *connect_data = data;
476 const guchar *request = connect_info->write_buffer + connect_info->written_len; 476 const guchar *request = connect_data->write_buffer + connect_data->written_len;
477 gsize request_len = connect_info->write_buf_len - connect_info->written_len; 477 gsize request_len = connect_data->write_buf_len - connect_data->written_len;
478 478
479 int ret = write(connect_info->fd, request, request_len); 479 int ret = write(connect_data->fd, request, request_len);
480 480
481 if(ret < 0 && errno == EAGAIN) 481 if(ret < 0 && errno == EAGAIN)
482 return; 482 return;
483 else if(ret < 0) { 483 else if(ret < 0) {
484 gaim_proxy_connect_info_disconnect(connect_info); 484 gaim_proxy_connect_data_disconnect(connect_data);
485 try_connect(connect_info); 485 try_connect(connect_data);
486 return; 486 return;
487 } else if (ret < request_len) { 487 } else if (ret < request_len) {
488 connect_info->written_len += ret; 488 connect_data->written_len += ret;
489 return; 489 return;
490 } 490 }
491 491
492 gaim_input_remove(connect_info->inpa); 492 gaim_input_remove(connect_data->inpa);
493 g_free(connect_info->write_buffer); 493 g_free(connect_data->write_buffer);
494 connect_info->write_buffer = NULL; 494 connect_data->write_buffer = NULL;
495 495
496 /* register the response handler for the response */ 496 /* register the response handler for the response */
497 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_READ, connect_info->read_cb, connect_info); 497 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_READ, connect_data->read_cb, connect_data);
498 } 498 }
499 499
500 #define HTTP_GOODSTRING "HTTP/1.0 200" 500 #define HTTP_GOODSTRING "HTTP/1.0 200"
501 #define HTTP_GOODSTRING2 "HTTP/1.1 200" 501 #define HTTP_GOODSTRING2 "HTTP/1.1 200"
502 502
504 static void 504 static void
505 http_canread(gpointer data, gint source, GaimInputCondition cond) 505 http_canread(gpointer data, gint source, GaimInputCondition cond)
506 { 506 {
507 int len, headers_len, status = 0; 507 int len, headers_len, status = 0;
508 gboolean error; 508 gboolean error;
509 GaimProxyConnectInfo *connect_info = data; 509 GaimProxyConnectData *connect_data = data;
510 guchar *p; 510 guchar *p;
511 gsize max_read; 511 gsize max_read;
512 gchar *msg; 512 gchar *msg;
513 513
514 if(connect_info->read_buffer == NULL) { 514 if(connect_data->read_buffer == NULL) {
515 connect_info->read_buf_len = 8192; 515 connect_data->read_buf_len = 8192;
516 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 516 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
517 connect_info->read_len = 0; 517 connect_data->read_len = 0;
518 } 518 }
519 519
520 p = connect_info->read_buffer + connect_info->read_len; 520 p = connect_data->read_buffer + connect_data->read_len;
521 max_read = connect_info->read_buf_len - connect_info->read_len - 1; 521 max_read = connect_data->read_buf_len - connect_data->read_len - 1;
522 522
523 len = read(connect_info->fd, p, max_read); 523 len = read(connect_data->fd, p, max_read);
524 if(len < 0 && errno == EAGAIN) 524 if(len < 0 && errno == EAGAIN)
525 return; 525 return;
526 else if(len <= 0) { 526 else if(len <= 0) {
527 gaim_proxy_connect_info_error(connect_info, _("Lost connection with server for an unknown reason.")); 527 gaim_proxy_connect_data_error(connect_data, _("Lost connection with server for an unknown reason."));
528 return; 528 return;
529 } else { 529 } else {
530 connect_info->read_len += len; 530 connect_data->read_len += len;
531 } 531 }
532 p[len] = '\0'; 532 p[len] = '\0';
533 533
534 if((p = (guchar *)g_strstr_len((const gchar *)connect_info->read_buffer, connect_info->read_len, "\r\n\r\n"))) { 534 if((p = (guchar *)g_strstr_len((const gchar *)connect_data->read_buffer, connect_data->read_len, "\r\n\r\n"))) {
535 *p = '\0'; 535 *p = '\0';
536 headers_len = (p - connect_info->read_buffer) + 4; 536 headers_len = (p - connect_data->read_buffer) + 4;
537 } else if(len == max_read) 537 } else if(len == max_read)
538 headers_len = len; 538 headers_len = len;
539 else 539 else
540 return; 540 return;
541 541
542 error = strncmp((const char *)connect_info->read_buffer, "HTTP/", 5) != 0; 542 error = strncmp((const char *)connect_data->read_buffer, "HTTP/", 5) != 0;
543 if (!error) 543 if (!error)
544 { 544 {
545 int major; 545 int major;
546 p = connect_info->read_buffer + 5; 546 p = connect_data->read_buffer + 5;
547 major = strtol((const char *)p, (char **)&p, 10); 547 major = strtol((const char *)p, (char **)&p, 10);
548 error = (major == 0) || (*p != '.'); 548 error = (major == 0) || (*p != '.');
549 if(!error) { 549 if(!error) {
550 int minor; 550 int minor;
551 p++; 551 p++;
558 } 558 }
559 } 559 }
560 } 560 }
561 561
562 /* Read the contents */ 562 /* Read the contents */
563 p = (guchar *)g_strrstr((const gchar *)connect_info->read_buffer, "Content-Length: "); 563 p = (guchar *)g_strrstr((const gchar *)connect_data->read_buffer, "Content-Length: ");
564 if (p != NULL) 564 if (p != NULL)
565 { 565 {
566 gchar *tmp; 566 gchar *tmp;
567 int len = 0; 567 int len = 0;
568 char tmpc; 568 char tmpc;
573 len = atoi((const char *)p); 573 len = atoi((const char *)p);
574 if(tmp) 574 if(tmp)
575 *tmp = '\r'; 575 *tmp = '\r';
576 576
577 /* Compensate for what has already been read */ 577 /* Compensate for what has already been read */
578 len -= connect_info->read_len - headers_len; 578 len -= connect_data->read_len - headers_len;
579 /* I'm assuming that we're doing this to prevent the server from 579 /* I'm assuming that we're doing this to prevent the server from
580 complaining / breaking since we don't read the whole page */ 580 complaining / breaking since we don't read the whole page */
581 while(len--) { 581 while(len--) {
582 /* TODO: deal with EAGAIN (and other errors) better */ 582 /* TODO: deal with EAGAIN (and other errors) better */
583 if (read(connect_info->fd, &tmpc, 1) < 0 && errno != EAGAIN) 583 if (read(connect_data->fd, &tmpc, 1) < 0 && errno != EAGAIN)
584 break; 584 break;
585 } 585 }
586 } 586 }
587 587
588 if (error) 588 if (error)
589 { 589 {
590 msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", 590 msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n",
591 connect_info->read_buffer); 591 connect_data->read_buffer);
592 gaim_proxy_connect_info_error(connect_info, msg); 592 gaim_proxy_connect_data_error(connect_data, msg);
593 g_free(msg); 593 g_free(msg);
594 return; 594 return;
595 } 595 }
596 else if (status != 200) 596 else if (status != 200)
597 { 597 {
598 gaim_debug_error("proxy", 598 gaim_debug_error("proxy",
599 "Proxy server replied with:\n%s\n", 599 "Proxy server replied with:\n%s\n",
600 connect_info->read_buffer); 600 connect_data->read_buffer);
601 601
602 602
603 if(status == 407 /* Proxy Auth */) { 603 if(status == 407 /* Proxy Auth */) {
604 gchar *ntlm; 604 gchar *ntlm;
605 if((ntlm = g_strrstr((const gchar *)connect_info->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */ 605 if((ntlm = g_strrstr((const gchar *)connect_data->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */
606 gchar *tmp = ntlm; 606 gchar *tmp = ntlm;
607 guint8 *nonce; 607 guint8 *nonce;
608 gchar *domain = (gchar*)gaim_proxy_info_get_username(connect_info->gpi); 608 gchar *domain = (gchar*)gaim_proxy_info_get_username(connect_data->gpi);
609 gchar *username; 609 gchar *username;
610 gchar *request; 610 gchar *request;
611 gchar *response; 611 gchar *response;
612 username = strchr(domain, '\\'); 612 username = strchr(domain, '\\');
613 if (username == NULL) 613 if (username == NULL)
614 { 614 {
615 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); 615 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status);
616 gaim_proxy_connect_info_error(connect_info, msg); 616 gaim_proxy_connect_data_error(connect_data, msg);
617 g_free(msg); 617 g_free(msg);
618 return; 618 return;
619 } 619 }
620 *username = '\0'; 620 *username = '\0';
621 username++; 621 username++;
622 ntlm += strlen("Proxy-Authenticate: NTLM "); 622 ntlm += strlen("Proxy-Authenticate: NTLM ");
623 while(*tmp != '\r' && *tmp != '\0') tmp++; 623 while(*tmp != '\r' && *tmp != '\0') tmp++;
624 *tmp = '\0'; 624 *tmp = '\0';
625 nonce = gaim_ntlm_parse_type2(ntlm, NULL); 625 nonce = gaim_ntlm_parse_type2(ntlm, NULL);
626 response = gaim_ntlm_gen_type3(username, 626 response = gaim_ntlm_gen_type3(username,
627 (gchar*) gaim_proxy_info_get_password(connect_info->gpi), 627 (gchar*) gaim_proxy_info_get_password(connect_data->gpi),
628 (gchar*) gaim_proxy_info_get_host(connect_info->gpi), 628 (gchar*) gaim_proxy_info_get_host(connect_data->gpi),
629 domain, nonce, NULL); 629 domain, nonce, NULL);
630 username--; 630 username--;
631 *username = '\\'; 631 *username = '\\';
632 request = g_strdup_printf( 632 request = g_strdup_printf(
633 "CONNECT %s:%d HTTP/1.1\r\n" 633 "CONNECT %s:%d HTTP/1.1\r\n"
634 "Host: %s:%d\r\n" 634 "Host: %s:%d\r\n"
635 "Proxy-Authorization: NTLM %s\r\n" 635 "Proxy-Authorization: NTLM %s\r\n"
636 "Proxy-Connection: Keep-Alive\r\n\r\n", 636 "Proxy-Connection: Keep-Alive\r\n\r\n",
637 connect_info->host, connect_info->port, connect_info->host, 637 connect_data->host, connect_data->port, connect_data->host,
638 connect_info->port, response); 638 connect_data->port, response);
639 g_free(response); 639 g_free(response);
640 640
641 gaim_input_remove(connect_info->inpa); 641 gaim_input_remove(connect_data->inpa);
642 g_free(connect_info->read_buffer); 642 g_free(connect_data->read_buffer);
643 connect_info->read_buffer = NULL; 643 connect_data->read_buffer = NULL;
644 644
645 connect_info->write_buffer = (guchar *)request; 645 connect_data->write_buffer = (guchar *)request;
646 connect_info->write_buf_len = strlen(request); 646 connect_data->write_buf_len = strlen(request);
647 connect_info->written_len = 0; 647 connect_data->written_len = 0;
648 648
649 connect_info->read_cb = http_canread; 649 connect_data->read_cb = http_canread;
650 650
651 connect_info->inpa = gaim_input_add(connect_info->fd, 651 connect_data->inpa = gaim_input_add(connect_data->fd,
652 GAIM_INPUT_WRITE, proxy_do_write, connect_info); 652 GAIM_INPUT_WRITE, proxy_do_write, connect_data);
653 653
654 proxy_do_write(connect_info, connect_info->fd, cond); 654 proxy_do_write(connect_data, connect_data->fd, cond);
655 return; 655 return;
656 } else if((ntlm = g_strrstr((const char *)connect_info->read_buffer, "Proxy-Authenticate: NTLM"))) { /* Empty message */ 656 } else if((ntlm = g_strrstr((const char *)connect_data->read_buffer, "Proxy-Authenticate: NTLM"))) { /* Empty message */
657 gchar request[2048]; 657 gchar request[2048];
658 gchar *domain = (gchar*) gaim_proxy_info_get_username(connect_info->gpi); 658 gchar *domain = (gchar*) gaim_proxy_info_get_username(connect_data->gpi);
659 gchar *username; 659 gchar *username;
660 int request_len; 660 int request_len;
661 username = strchr(domain, '\\'); 661 username = strchr(domain, '\\');
662 if (username == NULL) 662 if (username == NULL)
663 { 663 {
664 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); 664 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status);
665 gaim_proxy_connect_info_error(connect_info, msg); 665 gaim_proxy_connect_data_error(connect_data, msg);
666 g_free(msg); 666 g_free(msg);
667 return; 667 return;
668 } 668 }
669 *username = '\0'; 669 *username = '\0';
670 670
671 request_len = g_snprintf(request, sizeof(request), 671 request_len = g_snprintf(request, sizeof(request),
672 "CONNECT %s:%d HTTP/1.1\r\n" 672 "CONNECT %s:%d HTTP/1.1\r\n"
673 "Host: %s:%d\r\n", 673 "Host: %s:%d\r\n",
674 connect_info->host, connect_info->port, 674 connect_data->host, connect_data->port,
675 connect_info->host, connect_info->port); 675 connect_data->host, connect_data->port);
676 676
677 g_return_if_fail(request_len < sizeof(request)); 677 g_return_if_fail(request_len < sizeof(request));
678 request_len += g_snprintf(request + request_len, 678 request_len += g_snprintf(request + request_len,
679 sizeof(request) - request_len, 679 sizeof(request) - request_len,
680 "Proxy-Authorization: NTLM %s\r\n" 680 "Proxy-Authorization: NTLM %s\r\n"
681 "Proxy-Connection: Keep-Alive\r\n\r\n", 681 "Proxy-Connection: Keep-Alive\r\n\r\n",
682 gaim_ntlm_gen_type1( 682 gaim_ntlm_gen_type1(
683 (gchar*) gaim_proxy_info_get_host(connect_info->gpi), 683 (gchar*) gaim_proxy_info_get_host(connect_data->gpi),
684 domain)); 684 domain));
685 *username = '\\'; 685 *username = '\\';
686 686
687 gaim_input_remove(connect_info->inpa); 687 gaim_input_remove(connect_data->inpa);
688 g_free(connect_info->read_buffer); 688 g_free(connect_data->read_buffer);
689 connect_info->read_buffer = NULL; 689 connect_data->read_buffer = NULL;
690 690
691 connect_info->write_buffer = g_memdup(request, request_len); 691 connect_data->write_buffer = g_memdup(request, request_len);
692 connect_info->write_buf_len = request_len; 692 connect_data->write_buf_len = request_len;
693 connect_info->written_len = 0; 693 connect_data->written_len = 0;
694 694
695 connect_info->read_cb = http_canread; 695 connect_data->read_cb = http_canread;
696 696
697 connect_info->inpa = gaim_input_add(connect_info->fd, 697 connect_data->inpa = gaim_input_add(connect_data->fd,
698 GAIM_INPUT_WRITE, proxy_do_write, connect_info); 698 GAIM_INPUT_WRITE, proxy_do_write, connect_data);
699 699
700 proxy_do_write(connect_info, connect_info->fd, cond); 700 proxy_do_write(connect_data, connect_data->fd, cond);
701 return; 701 return;
702 } else { 702 } else {
703 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); 703 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status);
704 gaim_proxy_connect_info_error(connect_info, msg); 704 gaim_proxy_connect_data_error(connect_data, msg);
705 g_free(msg); 705 g_free(msg);
706 return; 706 return;
707 } 707 }
708 } 708 }
709 if(status == 403 /* Forbidden */ ) { 709 if(status == 403 /* Forbidden */ ) {
710 msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), connect_info->port); 710 msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), connect_data->port);
711 gaim_proxy_connect_info_error(connect_info, msg); 711 gaim_proxy_connect_data_error(connect_data, msg);
712 g_free(msg); 712 g_free(msg);
713 } else { 713 } else {
714 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); 714 msg = g_strdup_printf(_("HTTP proxy connection error %d"), status);
715 gaim_proxy_connect_info_error(connect_info, msg); 715 gaim_proxy_connect_data_error(connect_data, msg);
716 g_free(msg); 716 g_free(msg);
717 } 717 }
718 } else { 718 } else {
719 gaim_input_remove(connect_info->inpa); 719 gaim_input_remove(connect_data->inpa);
720 connect_info->inpa = 0; 720 connect_data->inpa = 0;
721 g_free(connect_info->read_buffer); 721 g_free(connect_data->read_buffer);
722 connect_info->read_buffer = NULL; 722 connect_data->read_buffer = NULL;
723 gaim_debug_info("proxy", "HTTP proxy connection established\n"); 723 gaim_debug_info("proxy", "HTTP proxy connection established\n");
724 gaim_proxy_connect_info_connected(connect_info); 724 gaim_proxy_connect_data_connected(connect_data);
725 return; 725 return;
726 } 726 }
727 } 727 }
728 728
729 729
731 static void 731 static void
732 http_canwrite(gpointer data, gint source, GaimInputCondition cond) 732 http_canwrite(gpointer data, gint source, GaimInputCondition cond)
733 { 733 {
734 char request[8192]; 734 char request[8192];
735 int request_len = 0; 735 int request_len = 0;
736 GaimProxyConnectInfo *connect_info = data; 736 GaimProxyConnectData *connect_data = data;
737 socklen_t len; 737 socklen_t len;
738 int error = ETIMEDOUT; 738 int error = ETIMEDOUT;
739 739
740 gaim_debug_info("http proxy", "Connected.\n"); 740 gaim_debug_info("http proxy", "Connected.\n");
741 741
742 if (connect_info->inpa > 0) 742 if (connect_data->inpa > 0)
743 { 743 {
744 gaim_input_remove(connect_info->inpa); 744 gaim_input_remove(connect_data->inpa);
745 connect_info->inpa = 0; 745 connect_data->inpa = 0;
746 } 746 }
747 747
748 len = sizeof(error); 748 len = sizeof(error);
749 749
750 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 750 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
751 gaim_proxy_connect_info_disconnect(connect_info); 751 gaim_proxy_connect_data_disconnect(connect_data);
752 try_connect(connect_info); 752 try_connect(connect_data);
753 return; 753 return;
754 } 754 }
755 755
756 gaim_debug_info("proxy", "using CONNECT tunnelling for %s:%d\n", 756 gaim_debug_info("proxy", "using CONNECT tunnelling for %s:%d\n",
757 connect_info->host, connect_info->port); 757 connect_data->host, connect_data->port);
758 request_len = g_snprintf(request, sizeof(request), 758 request_len = g_snprintf(request, sizeof(request),
759 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", 759 "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n",
760 connect_info->host, connect_info->port, connect_info->host, connect_info->port); 760 connect_data->host, connect_data->port, connect_data->host, connect_data->port);
761 761
762 if (gaim_proxy_info_get_username(connect_info->gpi) != NULL) { 762 if (gaim_proxy_info_get_username(connect_data->gpi) != NULL) {
763 char *t1, *t2; 763 char *t1, *t2;
764 t1 = g_strdup_printf("%s:%s", 764 t1 = g_strdup_printf("%s:%s",
765 gaim_proxy_info_get_username(connect_info->gpi), 765 gaim_proxy_info_get_username(connect_data->gpi),
766 gaim_proxy_info_get_password(connect_info->gpi) ? 766 gaim_proxy_info_get_password(connect_data->gpi) ?
767 gaim_proxy_info_get_password(connect_info->gpi) : ""); 767 gaim_proxy_info_get_password(connect_data->gpi) : "");
768 t2 = gaim_base64_encode((const guchar *)t1, strlen(t1)); 768 t2 = gaim_base64_encode((const guchar *)t1, strlen(t1));
769 g_free(t1); 769 g_free(t1);
770 g_return_if_fail(request_len < sizeof(request)); 770 g_return_if_fail(request_len < sizeof(request));
771 771
772 request_len += g_snprintf(request + request_len, 772 request_len += g_snprintf(request + request_len,
773 sizeof(request) - request_len, 773 sizeof(request) - request_len,
774 "Proxy-Authorization: Basic %s\r\n" 774 "Proxy-Authorization: Basic %s\r\n"
775 "Proxy-Authorization: NTLM %s\r\n" 775 "Proxy-Authorization: NTLM %s\r\n"
776 "Proxy-Connection: Keep-Alive\r\n", t2, 776 "Proxy-Connection: Keep-Alive\r\n", t2,
777 gaim_ntlm_gen_type1( 777 gaim_ntlm_gen_type1(
778 (gchar*)gaim_proxy_info_get_host(connect_info->gpi),"")); 778 (gchar*)gaim_proxy_info_get_host(connect_data->gpi),""));
779 g_free(t2); 779 g_free(t2);
780 } 780 }
781 781
782 g_return_if_fail(request_len < sizeof(request)); 782 g_return_if_fail(request_len < sizeof(request));
783 strcpy(request + request_len, "\r\n"); 783 strcpy(request + request_len, "\r\n");
784 request_len += 2; 784 request_len += 2;
785 connect_info->write_buffer = g_memdup(request, request_len); 785 connect_data->write_buffer = g_memdup(request, request_len);
786 connect_info->write_buf_len = request_len; 786 connect_data->write_buf_len = request_len;
787 connect_info->written_len = 0; 787 connect_data->written_len = 0;
788 788
789 connect_info->read_cb = http_canread; 789 connect_data->read_cb = http_canread;
790 790
791 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, 791 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, proxy_do_write,
792 connect_info); 792 connect_data);
793 793
794 proxy_do_write(connect_info, connect_info->fd, cond); 794 proxy_do_write(connect_data, connect_data->fd, cond);
795 } 795 }
796 796
797 static int 797 static int
798 proxy_connect_http(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 798 proxy_connect_http(GaimProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
799 { 799 {
800 gaim_debug_info("http proxy", 800 gaim_debug_info("http proxy",
801 "Connecting to %s:%d via %s:%d using HTTP\n", 801 "Connecting to %s:%d via %s:%d using HTTP\n",
802 (connect_info->host ? connect_info->host : "(null)"), connect_info->port, 802 (connect_data->host ? connect_data->host : "(null)"), connect_data->port,
803 (gaim_proxy_info_get_host(connect_info->gpi) ? gaim_proxy_info_get_host(connect_info->gpi) : "(null)"), 803 (gaim_proxy_info_get_host(connect_data->gpi) ? gaim_proxy_info_get_host(connect_data->gpi) : "(null)"),
804 gaim_proxy_info_get_port(connect_info->gpi)); 804 gaim_proxy_info_get_port(connect_data->gpi));
805 805
806 connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); 806 connect_data->fd = socket(addr->sa_family, SOCK_STREAM, 0);
807 if (connect_info->fd < 0) 807 if (connect_data->fd < 0)
808 return -1; 808 return -1;
809 809
810 fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); 810 fcntl(connect_data->fd, F_SETFL, O_NONBLOCK);
811 #ifndef _WIN32 811 #ifndef _WIN32
812 fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); 812 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
813 #endif 813 #endif
814 814
815 if (connect(connect_info->fd, addr, addrlen) != 0) 815 if (connect(connect_data->fd, addr, addrlen) != 0)
816 { 816 {
817 if ((errno == EINPROGRESS) || (errno == EINTR)) { 817 if ((errno == EINPROGRESS) || (errno == EINTR)) {
818 gaim_debug_info("http proxy", "Connection in progress\n"); 818 gaim_debug_info("http proxy", "Connection in progress\n");
819 819
820 if (connect_info->port != 80) { 820 if (connect_data->port != 80) {
821 /* we need to do CONNECT first */ 821 /* we need to do CONNECT first */
822 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, 822 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE,
823 http_canwrite, connect_info); 823 http_canwrite, connect_data);
824 } else { 824 } else {
825 gaim_debug_info("proxy", "HTTP proxy connection established\n"); 825 gaim_debug_info("proxy", "HTTP proxy connection established\n");
826 gaim_proxy_connect_info_connected(connect_info); 826 gaim_proxy_connect_data_connected(connect_data);
827 } 827 }
828 } else { 828 } else {
829 close(connect_info->fd); 829 close(connect_data->fd);
830 connect_info->fd = -1; 830 connect_data->fd = -1;
831 return -1; 831 return -1;
832 } 832 }
833 } 833 }
834 else { 834 else {
835 socklen_t len; 835 socklen_t len;
836 int error = ETIMEDOUT; 836 int error = ETIMEDOUT;
837 837
838 gaim_debug_info("http proxy", "Connected immediately.\n"); 838 gaim_debug_info("http proxy", "Connected immediately.\n");
839 839
840 len = sizeof(error); 840 len = sizeof(error);
841 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) 841 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0)
842 { 842 {
843 close(connect_info->fd); 843 close(connect_data->fd);
844 connect_info->fd = -1; 844 connect_data->fd = -1;
845 return -1; 845 return -1;
846 } 846 }
847 http_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 847 http_canwrite(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
848 } 848 }
849 849
850 return connect_info->fd; 850 return connect_data->fd;
851 } 851 }
852 852
853 853
854 static void 854 static void
855 s4_canread(gpointer data, gint source, GaimInputCondition cond) 855 s4_canread(gpointer data, gint source, GaimInputCondition cond)
856 { 856 {
857 GaimProxyConnectInfo *connect_info = data; 857 GaimProxyConnectData *connect_data = data;
858 guchar *buf; 858 guchar *buf;
859 int len, max_read; 859 int len, max_read;
860 860
861 /* This is really not going to block under normal circumstances, but to 861 /* This is really not going to block under normal circumstances, but to
862 * be correct, we deal with the unlikely scenario */ 862 * be correct, we deal with the unlikely scenario */
863 863
864 if (connect_info->read_buffer == NULL) { 864 if (connect_data->read_buffer == NULL) {
865 connect_info->read_buf_len = 12; 865 connect_data->read_buf_len = 12;
866 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 866 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
867 connect_info->read_len = 0; 867 connect_data->read_len = 0;
868 } 868 }
869 869
870 buf = connect_info->read_buffer + connect_info->read_len; 870 buf = connect_data->read_buffer + connect_data->read_len;
871 max_read = connect_info->read_buf_len - connect_info->read_len; 871 max_read = connect_data->read_buf_len - connect_data->read_len;
872 872
873 len = read(connect_info->fd, buf, max_read); 873 len = read(connect_data->fd, buf, max_read);
874 874
875 if ((len < 0 && errno == EAGAIN) || (len > 0 && len + connect_info->read_len < 4)) 875 if ((len < 0 && errno == EAGAIN) || (len > 0 && len + connect_data->read_len < 4))
876 return; 876 return;
877 else if (len + connect_info->read_len >= 4) { 877 else if (len + connect_data->read_len >= 4) {
878 if (connect_info->read_buffer[1] == 90) { 878 if (connect_data->read_buffer[1] == 90) {
879 gaim_proxy_connect_info_connected(connect_info); 879 gaim_proxy_connect_data_connected(connect_data);
880 return; 880 return;
881 } 881 }
882 } 882 }
883 883
884 gaim_proxy_connect_info_disconnect(connect_info); 884 gaim_proxy_connect_data_disconnect(connect_data);
885 try_connect(connect_info); 885 try_connect(connect_data);
886 } 886 }
887 887
888 static void 888 static void
889 s4_canwrite(gpointer data, gint source, GaimInputCondition cond) 889 s4_canwrite(gpointer data, gint source, GaimInputCondition cond)
890 { 890 {
891 unsigned char packet[9]; 891 unsigned char packet[9];
892 struct hostent *hp; 892 struct hostent *hp;
893 GaimProxyConnectInfo *connect_info = data; 893 GaimProxyConnectData *connect_data = data;
894 socklen_t len; 894 socklen_t len;
895 int error = ETIMEDOUT; 895 int error = ETIMEDOUT;
896 896
897 gaim_debug_info("socks4 proxy", "Connected.\n"); 897 gaim_debug_info("socks4 proxy", "Connected.\n");
898 898
899 if (connect_info->inpa > 0) 899 if (connect_data->inpa > 0)
900 { 900 {
901 gaim_input_remove(connect_info->inpa); 901 gaim_input_remove(connect_data->inpa);
902 connect_info->inpa = 0; 902 connect_data->inpa = 0;
903 } 903 }
904 904
905 len = sizeof(error); 905 len = sizeof(error);
906 906
907 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 907 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
908 gaim_proxy_connect_info_disconnect(connect_info); 908 gaim_proxy_connect_data_disconnect(connect_data);
909 try_connect(connect_info); 909 try_connect(connect_data);
910 return; 910 return;
911 } 911 }
912 912
913 /* 913 /*
914 * The socks4 spec doesn't include support for doing host name 914 * The socks4 spec doesn't include support for doing host name
917 * server supports this, it would need to be implemented 917 * server supports this, it would need to be implemented
918 * with an option, or some detection mechanism - in the 918 * with an option, or some detection mechanism - in the
919 * meantime, stick with plain old SOCKS4. 919 * meantime, stick with plain old SOCKS4.
920 */ 920 */
921 /* TODO: This needs to be non-blocking! */ 921 /* TODO: This needs to be non-blocking! */
922 hp = gethostbyname(connect_info->host); 922 hp = gethostbyname(connect_data->host);
923 if (hp == NULL) { 923 if (hp == NULL) {
924 gaim_proxy_connect_info_disconnect(connect_info); 924 gaim_proxy_connect_data_disconnect(connect_data);
925 try_connect(connect_info); 925 try_connect(connect_data);
926 return; 926 return;
927 } 927 }
928 928
929 packet[0] = 4; 929 packet[0] = 4;
930 packet[1] = 1; 930 packet[1] = 1;
931 packet[2] = connect_info->port >> 8; 931 packet[2] = connect_data->port >> 8;
932 packet[3] = connect_info->port & 0xff; 932 packet[3] = connect_data->port & 0xff;
933 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; 933 packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
934 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; 934 packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
935 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; 935 packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
936 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; 936 packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
937 packet[8] = 0; 937 packet[8] = 0;
938 938
939 connect_info->write_buffer = g_memdup(packet, sizeof(packet)); 939 connect_data->write_buffer = g_memdup(packet, sizeof(packet));
940 connect_info->write_buf_len = sizeof(packet); 940 connect_data->write_buf_len = sizeof(packet);
941 connect_info->written_len = 0; 941 connect_data->written_len = 0;
942 connect_info->read_cb = s4_canread; 942 connect_data->read_cb = s4_canread;
943 943
944 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); 944 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_data);
945 945
946 proxy_do_write(connect_info, connect_info->fd, cond); 946 proxy_do_write(connect_data, connect_data->fd, cond);
947 } 947 }
948 948
949 static int 949 static int
950 proxy_connect_socks4(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 950 proxy_connect_socks4(GaimProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
951 { 951 {
952 gaim_debug_info("socks4 proxy", 952 gaim_debug_info("socks4 proxy",
953 "Connecting to %s:%d via %s:%d using SOCKS4\n", 953 "Connecting to %s:%d via %s:%d using SOCKS4\n",
954 connect_info->host, connect_info->port, 954 connect_data->host, connect_data->port,
955 gaim_proxy_info_get_host(connect_info->gpi), 955 gaim_proxy_info_get_host(connect_data->gpi),
956 gaim_proxy_info_get_port(connect_info->gpi)); 956 gaim_proxy_info_get_port(connect_data->gpi));
957 957
958 connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); 958 connect_data->fd = socket(addr->sa_family, SOCK_STREAM, 0);
959 if (connect_info->fd < 0) 959 if (connect_data->fd < 0)
960 return -1; 960 return -1;
961 961
962 fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); 962 fcntl(connect_data->fd, F_SETFL, O_NONBLOCK);
963 #ifndef _WIN32 963 #ifndef _WIN32
964 fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); 964 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
965 #endif 965 #endif
966 966
967 if (connect(connect_info->fd, addr, addrlen) != 0) 967 if (connect(connect_data->fd, addr, addrlen) != 0)
968 { 968 {
969 if ((errno == EINPROGRESS) || (errno == EINTR)) { 969 if ((errno == EINPROGRESS) || (errno == EINTR)) {
970 gaim_debug_info("socks4 proxy", "Connection in progress.\n"); 970 gaim_debug_info("socks4 proxy", "Connection in progress.\n");
971 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, s4_canwrite, connect_info); 971 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, s4_canwrite, connect_data);
972 } 972 }
973 else { 973 else {
974 close(connect_info->fd); 974 close(connect_data->fd);
975 connect_info->fd = -1; 975 connect_data->fd = -1;
976 return -1; 976 return -1;
977 } 977 }
978 } else { 978 } else {
979 socklen_t len; 979 socklen_t len;
980 int error = ETIMEDOUT; 980 int error = ETIMEDOUT;
981 981
982 gaim_debug_info("socks4 proxy", "Connected immediately.\n"); 982 gaim_debug_info("socks4 proxy", "Connected immediately.\n");
983 983
984 len = sizeof(error); 984 len = sizeof(error);
985 985
986 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) 986 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0)
987 { 987 {
988 close(connect_info->fd); 988 close(connect_data->fd);
989 connect_info->fd = -1; 989 connect_data->fd = -1;
990 return -1; 990 return -1;
991 } 991 }
992 992
993 s4_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 993 s4_canwrite(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
994 } 994 }
995 995
996 return connect_info->fd; 996 return connect_data->fd;
997 } 997 }
998 998
999 static void 999 static void
1000 s5_canread_again(gpointer data, gint source, GaimInputCondition cond) 1000 s5_canread_again(gpointer data, gint source, GaimInputCondition cond)
1001 { 1001 {
1002 guchar *dest, *buf; 1002 guchar *dest, *buf;
1003 GaimProxyConnectInfo *connect_info = data; 1003 GaimProxyConnectData *connect_data = data;
1004 int len; 1004 int len;
1005 1005
1006 if (connect_info->read_buffer == NULL) { 1006 if (connect_data->read_buffer == NULL) {
1007 connect_info->read_buf_len = 512; 1007 connect_data->read_buf_len = 512;
1008 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1008 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
1009 connect_info->read_len = 0; 1009 connect_data->read_len = 0;
1010 } 1010 }
1011 1011
1012 dest = connect_info->read_buffer + connect_info->read_len; 1012 dest = connect_data->read_buffer + connect_data->read_len;
1013 buf = connect_info->read_buffer; 1013 buf = connect_data->read_buffer;
1014 1014
1015 gaim_debug_info("socks5 proxy", "Able to read again.\n"); 1015 gaim_debug_info("socks5 proxy", "Able to read again.\n");
1016 1016
1017 len = read(connect_info->fd, dest, (connect_info->read_buf_len - connect_info->read_len)); 1017 len = read(connect_data->fd, dest, (connect_data->read_buf_len - connect_data->read_len));
1018 if(len < 0 && errno == EAGAIN) 1018 if(len < 0 && errno == EAGAIN)
1019 return; 1019 return;
1020 else if(len <= 0) { 1020 else if(len <= 0) {
1021 gaim_debug_warning("socks5 proxy", "or not...\n"); 1021 gaim_debug_warning("socks5 proxy", "or not...\n");
1022 gaim_proxy_connect_info_disconnect(connect_info); 1022 gaim_proxy_connect_data_disconnect(connect_data);
1023 try_connect(connect_info); 1023 try_connect(connect_data);
1024 return; 1024 return;
1025 } 1025 }
1026 connect_info->read_len += len; 1026 connect_data->read_len += len;
1027 1027
1028 if(connect_info->read_len < 4) 1028 if(connect_data->read_len < 4)
1029 return; 1029 return;
1030 1030
1031 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 1031 if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
1032 if ((buf[0] == 0x05) && (buf[1] < 0x09)) 1032 if ((buf[0] == 0x05) && (buf[1] < 0x09))
1033 gaim_debug_error("socks5 proxy", socks5errors[buf[1]]); 1033 gaim_debug_error("socks5 proxy", socks5errors[buf[1]]);
1034 else 1034 else
1035 gaim_debug_error("socks5 proxy", "Bad data.\n"); 1035 gaim_debug_error("socks5 proxy", "Bad data.\n");
1036 gaim_proxy_connect_info_disconnect(connect_info); 1036 gaim_proxy_connect_data_disconnect(connect_data);
1037 try_connect(connect_info); 1037 try_connect(connect_data);
1038 return; 1038 return;
1039 } 1039 }
1040 1040
1041 /* Skip past BND.ADDR */ 1041 /* Skip past BND.ADDR */
1042 switch(buf[3]) { 1042 switch(buf[3]) {
1043 case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */ 1043 case 0x01: /* the address is a version-4 IP address, with a length of 4 octets */
1044 if(connect_info->read_len < 4 + 4) 1044 if(connect_data->read_len < 4 + 4)
1045 return; 1045 return;
1046 buf += 4 + 4; 1046 buf += 4 + 4;
1047 break; 1047 break;
1048 case 0x03: /* the address field contains a fully-qualified domain name. The first 1048 case 0x03: /* the address field contains a fully-qualified domain name. The first
1049 octet of the address field contains the number of octets of name that 1049 octet of the address field contains the number of octets of name that
1050 follow, there is no terminating NUL octet. */ 1050 follow, there is no terminating NUL octet. */
1051 if(connect_info->read_len < 4 + 1) 1051 if(connect_data->read_len < 4 + 1)
1052 return; 1052 return;
1053 buf += 4 + 1; 1053 buf += 4 + 1;
1054 if(connect_info->read_len < 4 + 1 + buf[0]) 1054 if(connect_data->read_len < 4 + 1 + buf[0])
1055 return; 1055 return;
1056 buf += buf[0]; 1056 buf += buf[0];
1057 break; 1057 break;
1058 case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */ 1058 case 0x04: /* the address is a version-6 IP address, with a length of 16 octets */
1059 if(connect_info->read_len < 4 + 16) 1059 if(connect_data->read_len < 4 + 16)
1060 return; 1060 return;
1061 buf += 4 + 16; 1061 buf += 4 + 16;
1062 break; 1062 break;
1063 } 1063 }
1064 1064
1065 if(connect_info->read_len < (buf - connect_info->read_buffer) + 2) 1065 if(connect_data->read_len < (buf - connect_data->read_buffer) + 2)
1066 return; 1066 return;
1067 1067
1068 /* Skip past BND.PORT */ 1068 /* Skip past BND.PORT */
1069 buf += 2; 1069 buf += 2;
1070 1070
1071 gaim_proxy_connect_info_connected(connect_info); 1071 gaim_proxy_connect_data_connected(connect_data);
1072 } 1072 }
1073 1073
1074 static void 1074 static void
1075 s5_sendconnect(gpointer data, int source) 1075 s5_sendconnect(gpointer data, int source)
1076 { 1076 {
1077 GaimProxyConnectInfo *connect_info = data; 1077 GaimProxyConnectData *connect_data = data;
1078 int hlen = strlen(connect_info->host); 1078 int hlen = strlen(connect_data->host);
1079 connect_info->write_buf_len = 5 + hlen + 2; 1079 connect_data->write_buf_len = 5 + hlen + 2;
1080 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1080 connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
1081 connect_info->written_len = 0; 1081 connect_data->written_len = 0;
1082 1082
1083 connect_info->write_buffer[0] = 0x05; 1083 connect_data->write_buffer[0] = 0x05;
1084 connect_info->write_buffer[1] = 0x01; /* CONNECT */ 1084 connect_data->write_buffer[1] = 0x01; /* CONNECT */
1085 connect_info->write_buffer[2] = 0x00; /* reserved */ 1085 connect_data->write_buffer[2] = 0x00; /* reserved */
1086 connect_info->write_buffer[3] = 0x03; /* address type -- host name */ 1086 connect_data->write_buffer[3] = 0x03; /* address type -- host name */
1087 connect_info->write_buffer[4] = hlen; 1087 connect_data->write_buffer[4] = hlen;
1088 memcpy(connect_info->write_buffer + 5, connect_info->host, hlen); 1088 memcpy(connect_data->write_buffer + 5, connect_data->host, hlen);
1089 connect_info->write_buffer[5 + hlen] = connect_info->port >> 8; 1089 connect_data->write_buffer[5 + hlen] = connect_data->port >> 8;
1090 connect_info->write_buffer[5 + hlen + 1] = connect_info->port & 0xff; 1090 connect_data->write_buffer[5 + hlen + 1] = connect_data->port & 0xff;
1091 1091
1092 connect_info->read_cb = s5_canread_again; 1092 connect_data->read_cb = s5_canread_again;
1093 1093
1094 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); 1094 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_data);
1095 proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1095 proxy_do_write(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1096 } 1096 }
1097 1097
1098 static void 1098 static void
1099 s5_readauth(gpointer data, gint source, GaimInputCondition cond) 1099 s5_readauth(gpointer data, gint source, GaimInputCondition cond)
1100 { 1100 {
1101 GaimProxyConnectInfo *connect_info = data; 1101 GaimProxyConnectData *connect_data = data;
1102 int len; 1102 int len;
1103 1103
1104 if (connect_info->read_buffer == NULL) { 1104 if (connect_data->read_buffer == NULL) {
1105 connect_info->read_buf_len = 2; 1105 connect_data->read_buf_len = 2;
1106 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1106 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
1107 connect_info->read_len = 0; 1107 connect_data->read_len = 0;
1108 } 1108 }
1109 1109
1110 gaim_debug_info("socks5 proxy", "Got auth response.\n"); 1110 gaim_debug_info("socks5 proxy", "Got auth response.\n");
1111 1111
1112 len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, 1112 len = read(connect_data->fd, connect_data->read_buffer + connect_data->read_len,
1113 connect_info->read_buf_len - connect_info->read_len); 1113 connect_data->read_buf_len - connect_data->read_len);
1114 if(len < 0 && errno == EAGAIN) 1114 if(len < 0 && errno == EAGAIN)
1115 return; 1115 return;
1116 else if(len <= 0) { 1116 else if(len <= 0) {
1117 gaim_proxy_connect_info_disconnect(connect_info); 1117 gaim_proxy_connect_data_disconnect(connect_data);
1118 try_connect(connect_info); 1118 try_connect(connect_data);
1119 return; 1119 return;
1120 } 1120 }
1121 connect_info->read_len += len; 1121 connect_data->read_len += len;
1122 1122
1123 if (connect_info->read_len < 2) 1123 if (connect_data->read_len < 2)
1124 return; 1124 return;
1125 1125
1126 gaim_input_remove(connect_info->inpa); 1126 gaim_input_remove(connect_data->inpa);
1127 connect_info->inpa = 0; 1127 connect_data->inpa = 0;
1128 1128
1129 if ((connect_info->read_buffer[0] != 0x01) || (connect_info->read_buffer[1] != 0x00)) { 1129 if ((connect_data->read_buffer[0] != 0x01) || (connect_data->read_buffer[1] != 0x00)) {
1130 gaim_proxy_connect_info_disconnect(connect_info); 1130 gaim_proxy_connect_data_disconnect(connect_data);
1131 try_connect(connect_info); 1131 try_connect(connect_data);
1132 return; 1132 return;
1133 } 1133 }
1134 1134
1135 g_free(connect_info->read_buffer); 1135 g_free(connect_data->read_buffer);
1136 connect_info->read_buffer = NULL; 1136 connect_data->read_buffer = NULL;
1137 1137
1138 s5_sendconnect(connect_info, connect_info->fd); 1138 s5_sendconnect(connect_data, connect_data->fd);
1139 } 1139 }
1140 1140
1141 static void 1141 static void
1142 hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response) 1142 hmacmd5_chap(const unsigned char * challenge, int challen, const char * passwd, unsigned char * response)
1143 { 1143 {
1184 1184
1185 static void 1185 static void
1186 s5_readchap(gpointer data, gint source, GaimInputCondition cond) 1186 s5_readchap(gpointer data, gint source, GaimInputCondition cond)
1187 { 1187 {
1188 guchar *cmdbuf, *buf; 1188 guchar *cmdbuf, *buf;
1189 GaimProxyConnectInfo *connect_info = data; 1189 GaimProxyConnectData *connect_data = data;
1190 int len, navas, currentav; 1190 int len, navas, currentav;
1191 1191
1192 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n"); 1192 gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Got CHAP response.\n");
1193 1193
1194 if (connect_info->read_buffer == NULL) { 1194 if (connect_data->read_buffer == NULL) {
1195 connect_info->read_buf_len = 20; 1195 connect_data->read_buf_len = 20;
1196 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1196 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
1197 connect_info->read_len = 0; 1197 connect_data->read_len = 0;
1198 } 1198 }
1199 1199
1200 len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, 1200 len = read(connect_data->fd, connect_data->read_buffer + connect_data->read_len,
1201 connect_info->read_buf_len - connect_info->read_len); 1201 connect_data->read_buf_len - connect_data->read_len);
1202 1202
1203 if(len < 0 && errno == EAGAIN) 1203 if(len < 0 && errno == EAGAIN)
1204 return; 1204 return;
1205 else if(len <= 0) { 1205 else if(len <= 0) {
1206 gaim_proxy_connect_info_disconnect(connect_info); 1206 gaim_proxy_connect_data_disconnect(connect_data);
1207 try_connect(connect_info); 1207 try_connect(connect_data);
1208 return; 1208 return;
1209 } 1209 }
1210 connect_info->read_len += len; 1210 connect_data->read_len += len;
1211 1211
1212 if (connect_info->read_len < 2) 1212 if (connect_data->read_len < 2)
1213 return; 1213 return;
1214 1214
1215 cmdbuf = connect_info->read_buffer; 1215 cmdbuf = connect_data->read_buffer;
1216 1216
1217 if (*cmdbuf != 0x01) { 1217 if (*cmdbuf != 0x01) {
1218 gaim_proxy_connect_info_disconnect(connect_info); 1218 gaim_proxy_connect_data_disconnect(connect_data);
1219 try_connect(connect_info); 1219 try_connect(connect_data);
1220 return; 1220 return;
1221 } 1221 }
1222 cmdbuf++; 1222 cmdbuf++;
1223 1223
1224 navas = *cmdbuf; 1224 navas = *cmdbuf;
1225 cmdbuf++; 1225 cmdbuf++;
1226 1226
1227 for (currentav = 0; currentav < navas; currentav++) { 1227 for (currentav = 0; currentav < navas; currentav++) {
1228 if (connect_info->read_len - (cmdbuf - connect_info->read_buffer) < 2) 1228 if (connect_data->read_len - (cmdbuf - connect_data->read_buffer) < 2)
1229 return; 1229 return;
1230 if (connect_info->read_len - (cmdbuf - connect_info->read_buffer) < cmdbuf[1]) 1230 if (connect_data->read_len - (cmdbuf - connect_data->read_buffer) < cmdbuf[1])
1231 return; 1231 return;
1232 buf = cmdbuf + 2; 1232 buf = cmdbuf + 2;
1233 switch (cmdbuf[0]) { 1233 switch (cmdbuf[0]) {
1234 case 0x00: 1234 case 0x00:
1235 /* Did auth work? */ 1235 /* Did auth work? */
1236 if (buf[0] == 0x00) { 1236 if (buf[0] == 0x00) {
1237 gaim_input_remove(connect_info->inpa); 1237 gaim_input_remove(connect_data->inpa);
1238 connect_info->inpa = 0; 1238 connect_data->inpa = 0;
1239 g_free(connect_info->read_buffer); 1239 g_free(connect_data->read_buffer);
1240 connect_info->read_buffer = NULL; 1240 connect_data->read_buffer = NULL;
1241 /* Success */ 1241 /* Success */
1242 s5_sendconnect(connect_info, connect_info->fd); 1242 s5_sendconnect(connect_data, connect_data->fd);
1243 return; 1243 return;
1244 } else { 1244 } else {
1245 /* Failure */ 1245 /* Failure */
1246 gaim_debug_warning("proxy", 1246 gaim_debug_warning("proxy",
1247 "socks5 CHAP authentication " 1247 "socks5 CHAP authentication "
1248 "failed. Disconnecting..."); 1248 "failed. Disconnecting...");
1249 gaim_proxy_connect_info_disconnect(connect_info); 1249 gaim_proxy_connect_data_disconnect(connect_data);
1250 try_connect(connect_info); 1250 try_connect(connect_data);
1251 return; 1251 return;
1252 } 1252 }
1253 break; 1253 break;
1254 case 0x03: 1254 case 0x03:
1255 /* Server wants our credentials */ 1255 /* Server wants our credentials */
1256 1256
1257 connect_info->write_buf_len = 16 + 4; 1257 connect_data->write_buf_len = 16 + 4;
1258 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1258 connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
1259 connect_info->written_len = 0; 1259 connect_data->written_len = 0;
1260 1260
1261 hmacmd5_chap(buf, cmdbuf[1], 1261 hmacmd5_chap(buf, cmdbuf[1],
1262 gaim_proxy_info_get_password(connect_info->gpi), 1262 gaim_proxy_info_get_password(connect_data->gpi),
1263 connect_info->write_buffer + 4); 1263 connect_data->write_buffer + 4);
1264 connect_info->write_buffer[0] = 0x01; 1264 connect_data->write_buffer[0] = 0x01;
1265 connect_info->write_buffer[1] = 0x01; 1265 connect_data->write_buffer[1] = 0x01;
1266 connect_info->write_buffer[2] = 0x04; 1266 connect_data->write_buffer[2] = 0x04;
1267 connect_info->write_buffer[3] = 0x10; 1267 connect_data->write_buffer[3] = 0x10;
1268 1268
1269 gaim_input_remove(connect_info->inpa); 1269 gaim_input_remove(connect_data->inpa);
1270 g_free(connect_info->read_buffer); 1270 g_free(connect_data->read_buffer);
1271 connect_info->read_buffer = NULL; 1271 connect_data->read_buffer = NULL;
1272 1272
1273 connect_info->read_cb = s5_readchap; 1273 connect_data->read_cb = s5_readchap;
1274 1274
1275 connect_info->inpa = gaim_input_add(connect_info->fd, 1275 connect_data->inpa = gaim_input_add(connect_data->fd,
1276 GAIM_INPUT_WRITE, proxy_do_write, connect_info); 1276 GAIM_INPUT_WRITE, proxy_do_write, connect_data);
1277 1277
1278 proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1278 proxy_do_write(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1279 break; 1279 break;
1280 case 0x11: 1280 case 0x11:
1281 /* Server wants to select an algorithm */ 1281 /* Server wants to select an algorithm */
1282 if (buf[0] != 0x85) { 1282 if (buf[0] != 0x85) {
1283 /* Only currently support HMAC-MD5 */ 1283 /* Only currently support HMAC-MD5 */
1285 "Server tried to select an " 1285 "Server tried to select an "
1286 "algorithm that we did not advertise " 1286 "algorithm that we did not advertise "
1287 "as supporting. This is a violation " 1287 "as supporting. This is a violation "
1288 "of the socks5 CHAP specification. " 1288 "of the socks5 CHAP specification. "
1289 "Disconnecting..."); 1289 "Disconnecting...");
1290 gaim_proxy_connect_info_disconnect(connect_info); 1290 gaim_proxy_connect_data_disconnect(connect_data);
1291 try_connect(connect_info); 1291 try_connect(connect_data);
1292 return; 1292 return;
1293 } 1293 }
1294 break; 1294 break;
1295 } 1295 }
1296 cmdbuf = buf + cmdbuf[1]; 1296 cmdbuf = buf + cmdbuf[1];
1301 } 1301 }
1302 1302
1303 static void 1303 static void
1304 s5_canread(gpointer data, gint source, GaimInputCondition cond) 1304 s5_canread(gpointer data, gint source, GaimInputCondition cond)
1305 { 1305 {
1306 GaimProxyConnectInfo *connect_info = data; 1306 GaimProxyConnectData *connect_data = data;
1307 int len; 1307 int len;
1308 1308
1309 if (connect_info->read_buffer == NULL) { 1309 if (connect_data->read_buffer == NULL) {
1310 connect_info->read_buf_len = 2; 1310 connect_data->read_buf_len = 2;
1311 connect_info->read_buffer = g_malloc(connect_info->read_buf_len); 1311 connect_data->read_buffer = g_malloc(connect_data->read_buf_len);
1312 connect_info->read_len = 0; 1312 connect_data->read_len = 0;
1313 } 1313 }
1314 1314
1315 gaim_debug_info("socks5 proxy", "Able to read.\n"); 1315 gaim_debug_info("socks5 proxy", "Able to read.\n");
1316 1316
1317 len = read(connect_info->fd, connect_info->read_buffer + connect_info->read_len, 1317 len = read(connect_data->fd, connect_data->read_buffer + connect_data->read_len,
1318 connect_info->read_buf_len - connect_info->read_len); 1318 connect_data->read_buf_len - connect_data->read_len);
1319 if(len < 0 && errno == EAGAIN) 1319 if(len < 0 && errno == EAGAIN)
1320 return; 1320 return;
1321 else if(len <= 0) { 1321 else if(len <= 0) {
1322 gaim_proxy_connect_info_disconnect(connect_info); 1322 gaim_proxy_connect_data_disconnect(connect_data);
1323 try_connect(connect_info); 1323 try_connect(connect_data);
1324 return; 1324 return;
1325 } 1325 }
1326 connect_info->read_len += len; 1326 connect_data->read_len += len;
1327 1327
1328 if (connect_info->read_len < 2) 1328 if (connect_data->read_len < 2)
1329 return; 1329 return;
1330 1330
1331 gaim_input_remove(connect_info->inpa); 1331 gaim_input_remove(connect_data->inpa);
1332 connect_info->inpa = 0; 1332 connect_data->inpa = 0;
1333 1333
1334 if ((connect_info->read_buffer[0] != 0x05) || (connect_info->read_buffer[1] == 0xff)) { 1334 if ((connect_data->read_buffer[0] != 0x05) || (connect_data->read_buffer[1] == 0xff)) {
1335 gaim_proxy_connect_info_disconnect(connect_info); 1335 gaim_proxy_connect_data_disconnect(connect_data);
1336 try_connect(connect_info); 1336 try_connect(connect_data);
1337 return; 1337 return;
1338 } 1338 }
1339 1339
1340 if (connect_info->read_buffer[1] == 0x02) { 1340 if (connect_data->read_buffer[1] == 0x02) {
1341 gsize i, j; 1341 gsize i, j;
1342 const char *u, *p; 1342 const char *u, *p;
1343 1343
1344 u = gaim_proxy_info_get_username(connect_info->gpi); 1344 u = gaim_proxy_info_get_username(connect_data->gpi);
1345 p = gaim_proxy_info_get_password(connect_info->gpi); 1345 p = gaim_proxy_info_get_password(connect_data->gpi);
1346 1346
1347 i = (u == NULL) ? 0 : strlen(u); 1347 i = (u == NULL) ? 0 : strlen(u);
1348 j = (p == NULL) ? 0 : strlen(p); 1348 j = (p == NULL) ? 0 : strlen(p);
1349 1349
1350 connect_info->write_buf_len = 1 + 1 + i + 1 + j; 1350 connect_data->write_buf_len = 1 + 1 + i + 1 + j;
1351 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1351 connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
1352 connect_info->written_len = 0; 1352 connect_data->written_len = 0;
1353 1353
1354 connect_info->write_buffer[0] = 0x01; /* version 1 */ 1354 connect_data->write_buffer[0] = 0x01; /* version 1 */
1355 connect_info->write_buffer[1] = i; 1355 connect_data->write_buffer[1] = i;
1356 if (u != NULL) 1356 if (u != NULL)
1357 memcpy(connect_info->write_buffer + 2, u, i); 1357 memcpy(connect_data->write_buffer + 2, u, i);
1358 connect_info->write_buffer[2 + i] = j; 1358 connect_data->write_buffer[2 + i] = j;
1359 if (p != NULL) 1359 if (p != NULL)
1360 memcpy(connect_info->write_buffer + 2 + i + 1, p, j); 1360 memcpy(connect_data->write_buffer + 2 + i + 1, p, j);
1361 1361
1362 g_free(connect_info->read_buffer); 1362 g_free(connect_data->read_buffer);
1363 connect_info->read_buffer = NULL; 1363 connect_data->read_buffer = NULL;
1364 1364
1365 connect_info->read_cb = s5_readauth; 1365 connect_data->read_cb = s5_readauth;
1366 1366
1367 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, 1367 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE,
1368 proxy_do_write, connect_info); 1368 proxy_do_write, connect_data);
1369 1369
1370 proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1370 proxy_do_write(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1371 1371
1372 return; 1372 return;
1373 } else if (connect_info->read_buffer[1] == 0x03) { 1373 } else if (connect_data->read_buffer[1] == 0x03) {
1374 gsize userlen; 1374 gsize userlen;
1375 userlen = strlen(gaim_proxy_info_get_username(connect_info->gpi)); 1375 userlen = strlen(gaim_proxy_info_get_username(connect_data->gpi));
1376 1376
1377 connect_info->write_buf_len = 7 + userlen; 1377 connect_data->write_buf_len = 7 + userlen;
1378 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1378 connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
1379 connect_info->written_len = 0; 1379 connect_data->written_len = 0;
1380 1380
1381 connect_info->write_buffer[0] = 0x01; 1381 connect_data->write_buffer[0] = 0x01;
1382 connect_info->write_buffer[1] = 0x02; 1382 connect_data->write_buffer[1] = 0x02;
1383 connect_info->write_buffer[2] = 0x11; 1383 connect_data->write_buffer[2] = 0x11;
1384 connect_info->write_buffer[3] = 0x01; 1384 connect_data->write_buffer[3] = 0x01;
1385 connect_info->write_buffer[4] = 0x85; 1385 connect_data->write_buffer[4] = 0x85;
1386 connect_info->write_buffer[5] = 0x02; 1386 connect_data->write_buffer[5] = 0x02;
1387 connect_info->write_buffer[6] = userlen; 1387 connect_data->write_buffer[6] = userlen;
1388 memcpy(connect_info->write_buffer + 7, 1388 memcpy(connect_data->write_buffer + 7,
1389 gaim_proxy_info_get_username(connect_info->gpi), userlen); 1389 gaim_proxy_info_get_username(connect_data->gpi), userlen);
1390 1390
1391 g_free(connect_info->read_buffer); 1391 g_free(connect_data->read_buffer);
1392 connect_info->read_buffer = NULL; 1392 connect_data->read_buffer = NULL;
1393 1393
1394 connect_info->read_cb = s5_readchap; 1394 connect_data->read_cb = s5_readchap;
1395 1395
1396 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, 1396 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE,
1397 proxy_do_write, connect_info); 1397 proxy_do_write, connect_data);
1398 1398
1399 proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1399 proxy_do_write(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1400 1400
1401 return; 1401 return;
1402 } else { 1402 } else {
1403 g_free(connect_info->read_buffer); 1403 g_free(connect_data->read_buffer);
1404 connect_info->read_buffer = NULL; 1404 connect_data->read_buffer = NULL;
1405 1405
1406 s5_sendconnect(connect_info, connect_info->fd); 1406 s5_sendconnect(connect_data, connect_data->fd);
1407 } 1407 }
1408 } 1408 }
1409 1409
1410 static void 1410 static void
1411 s5_canwrite(gpointer data, gint source, GaimInputCondition cond) 1411 s5_canwrite(gpointer data, gint source, GaimInputCondition cond)
1412 { 1412 {
1413 unsigned char buf[5]; 1413 unsigned char buf[5];
1414 int i; 1414 int i;
1415 GaimProxyConnectInfo *connect_info = data; 1415 GaimProxyConnectData *connect_data = data;
1416 socklen_t len; 1416 socklen_t len;
1417 int error = ETIMEDOUT; 1417 int error = ETIMEDOUT;
1418 1418
1419 gaim_debug_info("socks5 proxy", "Connected.\n"); 1419 gaim_debug_info("socks5 proxy", "Connected.\n");
1420 1420
1421 if (connect_info->inpa > 0) 1421 if (connect_data->inpa > 0)
1422 { 1422 {
1423 gaim_input_remove(connect_info->inpa); 1423 gaim_input_remove(connect_data->inpa);
1424 connect_info->inpa = 0; 1424 connect_data->inpa = 0;
1425 } 1425 }
1426 1426
1427 len = sizeof(error); 1427 len = sizeof(error);
1428 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 1428 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
1429 gaim_proxy_connect_info_disconnect(connect_info); 1429 gaim_proxy_connect_data_disconnect(connect_data);
1430 try_connect(connect_info); 1430 try_connect(connect_data);
1431 return; 1431 return;
1432 } 1432 }
1433 1433
1434 i = 0; 1434 i = 0;
1435 buf[0] = 0x05; /* SOCKS version 5 */ 1435 buf[0] = 0x05; /* SOCKS version 5 */
1436 1436
1437 if (gaim_proxy_info_get_username(connect_info->gpi) != NULL) { 1437 if (gaim_proxy_info_get_username(connect_data->gpi) != NULL) {
1438 buf[1] = 0x03; /* three methods */ 1438 buf[1] = 0x03; /* three methods */
1439 buf[2] = 0x00; /* no authentication */ 1439 buf[2] = 0x00; /* no authentication */
1440 buf[3] = 0x03; /* CHAP authentication */ 1440 buf[3] = 0x03; /* CHAP authentication */
1441 buf[4] = 0x02; /* username/password authentication */ 1441 buf[4] = 0x02; /* username/password authentication */
1442 i = 5; 1442 i = 5;
1445 buf[1] = 0x01; 1445 buf[1] = 0x01;
1446 buf[2] = 0x00; 1446 buf[2] = 0x00;
1447 i = 3; 1447 i = 3;
1448 } 1448 }
1449 1449
1450 connect_info->write_buf_len = i; 1450 connect_data->write_buf_len = i;
1451 connect_info->write_buffer = g_malloc(connect_info->write_buf_len); 1451 connect_data->write_buffer = g_malloc(connect_data->write_buf_len);
1452 memcpy(connect_info->write_buffer, buf, i); 1452 memcpy(connect_data->write_buffer, buf, i);
1453 1453
1454 connect_info->read_cb = s5_canread; 1454 connect_data->read_cb = s5_canread;
1455 1455
1456 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_info); 1456 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, proxy_do_write, connect_data);
1457 proxy_do_write(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1457 proxy_do_write(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1458 } 1458 }
1459 1459
1460 static int 1460 static int
1461 proxy_connect_socks5(GaimProxyConnectInfo *connect_info, struct sockaddr *addr, socklen_t addrlen) 1461 proxy_connect_socks5(GaimProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
1462 { 1462 {
1463 gaim_debug_info("socks5 proxy", 1463 gaim_debug_info("socks5 proxy",
1464 "Connecting to %s:%d via %s:%d using SOCKS5\n", 1464 "Connecting to %s:%d via %s:%d using SOCKS5\n",
1465 connect_info->host, connect_info->port, 1465 connect_data->host, connect_data->port,
1466 gaim_proxy_info_get_host(connect_info->gpi), 1466 gaim_proxy_info_get_host(connect_data->gpi),
1467 gaim_proxy_info_get_port(connect_info->gpi)); 1467 gaim_proxy_info_get_port(connect_data->gpi));
1468 1468
1469 connect_info->fd = socket(addr->sa_family, SOCK_STREAM, 0); 1469 connect_data->fd = socket(addr->sa_family, SOCK_STREAM, 0);
1470 if (connect_info->fd < 0) 1470 if (connect_data->fd < 0)
1471 return -1; 1471 return -1;
1472 1472
1473 fcntl(connect_info->fd, F_SETFL, O_NONBLOCK); 1473 fcntl(connect_data->fd, F_SETFL, O_NONBLOCK);
1474 #ifndef _WIN32 1474 #ifndef _WIN32
1475 fcntl(connect_info->fd, F_SETFD, FD_CLOEXEC); 1475 fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
1476 #endif 1476 #endif
1477 1477
1478 if (connect(connect_info->fd, addr, addrlen) != 0) 1478 if (connect(connect_data->fd, addr, addrlen) != 0)
1479 { 1479 {
1480 if ((errno == EINPROGRESS) || (errno == EINTR)) { 1480 if ((errno == EINPROGRESS) || (errno == EINTR)) {
1481 gaim_debug_info("socks5 proxy", "Connection in progress\n"); 1481 gaim_debug_info("socks5 proxy", "Connection in progress\n");
1482 connect_info->inpa = gaim_input_add(connect_info->fd, GAIM_INPUT_WRITE, s5_canwrite, connect_info); 1482 connect_data->inpa = gaim_input_add(connect_data->fd, GAIM_INPUT_WRITE, s5_canwrite, connect_data);
1483 } 1483 }
1484 else { 1484 else {
1485 close(connect_info->fd); 1485 close(connect_data->fd);
1486 connect_info->fd = -1; 1486 connect_data->fd = -1;
1487 return -1; 1487 return -1;
1488 } 1488 }
1489 } 1489 }
1490 else { 1490 else {
1491 socklen_t len; 1491 socklen_t len;
1493 1493
1494 gaim_debug_info("socks5 proxy", "Connected immediately.\n"); 1494 gaim_debug_info("socks5 proxy", "Connected immediately.\n");
1495 1495
1496 len = sizeof(error); 1496 len = sizeof(error);
1497 1497
1498 if (getsockopt(connect_info->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0) 1498 if (getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0)
1499 { 1499 {
1500 close(connect_info->fd); 1500 close(connect_data->fd);
1501 connect_info->fd = -1; 1501 connect_data->fd = -1;
1502 return -1; 1502 return -1;
1503 } 1503 }
1504 1504
1505 s5_canwrite(connect_info, connect_info->fd, GAIM_INPUT_WRITE); 1505 s5_canwrite(connect_data, connect_data->fd, GAIM_INPUT_WRITE);
1506 } 1506 }
1507 1507
1508 return connect_info->fd; 1508 return connect_data->fd;
1509 } 1509 }
1510 1510
1511 /** 1511 /**
1512 * This function iterates through a list of IP addresses and attempts 1512 * This function iterates through a list of IP addresses and attempts
1513 * to connect to each one. This is called after the hostname is 1513 * to connect to each one. This is called after the hostname is
1514 * resolved, and if a connection attempt fails. 1514 * resolved, and if a connection attempt fails.
1515 */ 1515 */
1516 static void try_connect(GaimProxyConnectInfo *connect_info) 1516 static void try_connect(GaimProxyConnectData *connect_data)
1517 { 1517 {
1518 size_t addrlen; 1518 size_t addrlen;
1519 struct sockaddr *addr; 1519 struct sockaddr *addr;
1520 int ret = -1; 1520 int ret = -1;
1521 1521
1522 if (connect_info->hosts == NULL) 1522 if (connect_data->hosts == NULL)
1523 { 1523 {
1524 gaim_proxy_connect_info_error(connect_info, _("Could not resolve host name")); 1524 gaim_proxy_connect_data_error(connect_data, _("Could not resolve host name"));
1525 return; 1525 return;
1526 } 1526 }
1527 1527
1528 while (connect_info->hosts) 1528 while (connect_data->hosts)
1529 { 1529 {
1530 addrlen = GPOINTER_TO_INT(connect_info->hosts->data); 1530 addrlen = GPOINTER_TO_INT(connect_data->hosts->data);
1531 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); 1531 connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
1532 addr = connect_info->hosts->data; 1532 addr = connect_data->hosts->data;
1533 connect_info->hosts = g_slist_remove(connect_info->hosts, connect_info->hosts->data); 1533 connect_data->hosts = g_slist_remove(connect_data->hosts, connect_data->hosts->data);
1534 1534
1535 switch (gaim_proxy_info_get_type(connect_info->gpi)) { 1535 switch (gaim_proxy_info_get_type(connect_data->gpi)) {
1536 case GAIM_PROXY_NONE: 1536 case GAIM_PROXY_NONE:
1537 ret = proxy_connect_none(connect_info, addr, addrlen); 1537 ret = proxy_connect_none(connect_data, addr, addrlen);
1538 break; 1538 break;
1539 1539
1540 case GAIM_PROXY_HTTP: 1540 case GAIM_PROXY_HTTP:
1541 ret = proxy_connect_http(connect_info, addr, addrlen); 1541 ret = proxy_connect_http(connect_data, addr, addrlen);
1542 break; 1542 break;
1543 1543
1544 case GAIM_PROXY_SOCKS4: 1544 case GAIM_PROXY_SOCKS4:
1545 ret = proxy_connect_socks4(connect_info, addr, addrlen); 1545 ret = proxy_connect_socks4(connect_data, addr, addrlen);
1546 break; 1546 break;
1547 1547
1548 case GAIM_PROXY_SOCKS5: 1548 case GAIM_PROXY_SOCKS5:
1549 ret = proxy_connect_socks5(connect_info, addr, addrlen); 1549 ret = proxy_connect_socks5(connect_data, addr, addrlen);
1550 break; 1550 break;
1551 1551
1552 case GAIM_PROXY_USE_ENVVAR: 1552 case GAIM_PROXY_USE_ENVVAR:
1553 ret = proxy_connect_http(connect_info, addr, addrlen); 1553 ret = proxy_connect_http(connect_data, addr, addrlen);
1554 break; 1554 break;
1555 1555
1556 default: 1556 default:
1557 break; 1557 break;
1558 } 1558 }
1562 if (ret >= 0) 1562 if (ret >= 0)
1563 break; 1563 break;
1564 } 1564 }
1565 1565
1566 if (ret < 0) { 1566 if (ret < 0) {
1567 gaim_proxy_connect_info_error(connect_info, _("Unable to establish a connection")); 1567 gaim_proxy_connect_data_error(connect_data, _("Unable to establish a connection"));
1568 } 1568 }
1569 } 1569 }
1570 1570
1571 static void 1571 static void
1572 connection_host_resolved(GSList *hosts, gpointer data, 1572 connection_host_resolved(GSList *hosts, gpointer data,
1573 const char *error_message) 1573 const char *error_message)
1574 { 1574 {
1575 GaimProxyConnectInfo *connect_info; 1575 GaimProxyConnectData *connect_data;
1576 1576
1577 connect_info = data; 1577 connect_data = data;
1578 connect_info->query_data = NULL; 1578 connect_data->query_data = NULL;
1579 1579
1580 if (error_message != NULL) 1580 if (error_message != NULL)
1581 { 1581 {
1582 gchar *tmp; 1582 gchar *tmp;
1583 tmp = g_strdup_printf("Error while resolving hostname: %s\n", error_message); 1583 tmp = g_strdup_printf("Error while resolving hostname: %s\n", error_message);
1584 gaim_proxy_connect_info_error(connect_info, tmp); 1584 gaim_proxy_connect_data_error(connect_data, tmp);
1585 g_free(tmp); 1585 g_free(tmp);
1586 return; 1586 return;
1587 } 1587 }
1588 1588
1589 connect_info->hosts = hosts; 1589 connect_data->hosts = hosts;
1590 1590
1591 try_connect(connect_info); 1591 try_connect(connect_data);
1592 } 1592 }
1593 1593
1594 GaimProxyInfo * 1594 GaimProxyInfo *
1595 gaim_proxy_get_setup(GaimAccount *account) 1595 gaim_proxy_get_setup(GaimAccount *account)
1596 { 1596 {
1655 } 1655 }
1656 1656
1657 return gpi; 1657 return gpi;
1658 } 1658 }
1659 1659
1660 GaimProxyConnectInfo * 1660 GaimProxyConnectData *
1661 gaim_proxy_connect(GaimAccount *account, const char *host, int port, 1661 gaim_proxy_connect(GaimAccount *account, const char *host, int port,
1662 GaimProxyConnectFunction connect_cb, gpointer data) 1662 GaimProxyConnectFunction connect_cb, gpointer data)
1663 { 1663 {
1664 const char *connecthost = host; 1664 const char *connecthost = host;
1665 int connectport = port; 1665 int connectport = port;
1666 GaimProxyConnectInfo *connect_info; 1666 GaimProxyConnectData *connect_data;
1667 1667
1668 g_return_val_if_fail(host != NULL, NULL); 1668 g_return_val_if_fail(host != NULL, NULL);
1669 g_return_val_if_fail(port > 0, NULL); 1669 g_return_val_if_fail(port > 0, NULL);
1670 g_return_val_if_fail(connect_cb != NULL, NULL); 1670 g_return_val_if_fail(connect_cb != NULL, NULL);
1671 1671
1672 connect_info = g_new0(GaimProxyConnectInfo, 1); 1672 connect_data = g_new0(GaimProxyConnectData, 1);
1673 connect_info->fd = -1; 1673 connect_data->fd = -1;
1674 connect_info->connect_cb = connect_cb; 1674 connect_data->connect_cb = connect_cb;
1675 connect_info->data = data; 1675 connect_data->data = data;
1676 connect_info->host = g_strdup(host); 1676 connect_data->host = g_strdup(host);
1677 connect_info->port = port; 1677 connect_data->port = port;
1678 connect_info->gpi = gaim_proxy_get_setup(account); 1678 connect_data->gpi = gaim_proxy_get_setup(account);
1679 1679
1680 if ((gaim_proxy_info_get_type(connect_info->gpi) != GAIM_PROXY_NONE) && 1680 if ((gaim_proxy_info_get_type(connect_data->gpi) != GAIM_PROXY_NONE) &&
1681 (gaim_proxy_info_get_host(connect_info->gpi) == NULL || 1681 (gaim_proxy_info_get_host(connect_data->gpi) == NULL ||
1682 gaim_proxy_info_get_port(connect_info->gpi) <= 0)) { 1682 gaim_proxy_info_get_port(connect_data->gpi) <= 0)) {
1683 1683
1684 gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid.")); 1684 gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid."));
1685 gaim_proxy_connect_info_destroy(connect_info); 1685 gaim_proxy_connect_data_destroy(connect_data);
1686 return NULL; 1686 return NULL;
1687 } 1687 }
1688 1688
1689 switch (gaim_proxy_info_get_type(connect_info->gpi)) 1689 switch (gaim_proxy_info_get_type(connect_data->gpi))
1690 { 1690 {
1691 case GAIM_PROXY_NONE: 1691 case GAIM_PROXY_NONE:
1692 break; 1692 break;
1693 1693
1694 case GAIM_PROXY_HTTP: 1694 case GAIM_PROXY_HTTP:
1695 case GAIM_PROXY_SOCKS4: 1695 case GAIM_PROXY_SOCKS4:
1696 case GAIM_PROXY_SOCKS5: 1696 case GAIM_PROXY_SOCKS5:
1697 case GAIM_PROXY_USE_ENVVAR: 1697 case GAIM_PROXY_USE_ENVVAR:
1698 connecthost = gaim_proxy_info_get_host(connect_info->gpi); 1698 connecthost = gaim_proxy_info_get_host(connect_data->gpi);
1699 connectport = gaim_proxy_info_get_port(connect_info->gpi); 1699 connectport = gaim_proxy_info_get_port(connect_data->gpi);
1700 break; 1700 break;
1701 1701
1702 default: 1702 default:
1703 gaim_proxy_connect_info_destroy(connect_info); 1703 gaim_proxy_connect_data_destroy(connect_data);
1704 return NULL; 1704 return NULL;
1705 } 1705 }
1706 1706
1707 connect_info->query_data = gaim_dnsquery_a(connecthost, 1707 connect_data->query_data = gaim_dnsquery_a(connecthost,
1708 connectport, connection_host_resolved, connect_info); 1708 connectport, connection_host_resolved, connect_data);
1709 if (connect_info->query_data == NULL) 1709 if (connect_data->query_data == NULL)
1710 { 1710 {
1711 gaim_proxy_connect_info_destroy(connect_info); 1711 gaim_proxy_connect_data_destroy(connect_data);
1712 return NULL; 1712 return NULL;
1713 } 1713 }
1714 1714
1715 connect_infos = g_slist_prepend(connect_infos, connect_info); 1715 connect_datas = g_slist_prepend(connect_datas, connect_data);
1716 1716
1717 return connect_info; 1717 return connect_data;
1718 } 1718 }
1719 1719
1720 /* 1720 /*
1721 * Combine some of this code with gaim_proxy_connect() 1721 * Combine some of this code with gaim_proxy_connect()
1722 */ 1722 */
1723 GaimProxyConnectInfo * 1723 GaimProxyConnectData *
1724 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, 1724 gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port,
1725 GaimProxyConnectFunction connect_cb, gpointer data) 1725 GaimProxyConnectFunction connect_cb, gpointer data)
1726 { 1726 {
1727 GaimProxyConnectInfo *connect_info; 1727 GaimProxyConnectData *connect_data;
1728 1728
1729 g_return_val_if_fail(host != NULL, NULL); 1729 g_return_val_if_fail(host != NULL, NULL);
1730 g_return_val_if_fail(port > 0, NULL); 1730 g_return_val_if_fail(port > 0, NULL);
1731 g_return_val_if_fail(connect_cb != NULL, NULL); 1731 g_return_val_if_fail(connect_cb != NULL, NULL);
1732 1732
1733 connect_info = g_new0(GaimProxyConnectInfo, 1); 1733 connect_data = g_new0(GaimProxyConnectData, 1);
1734 connect_info->fd = -1; 1734 connect_data->fd = -1;
1735 connect_info->connect_cb = connect_cb; 1735 connect_data->connect_cb = connect_cb;
1736 connect_info->data = data; 1736 connect_data->data = data;
1737 connect_info->host = g_strdup(host); 1737 connect_data->host = g_strdup(host);
1738 connect_info->port = port; 1738 connect_data->port = port;
1739 connect_info->gpi = gpi; 1739 connect_data->gpi = gpi;
1740 1740
1741 connect_info->query_data = 1741 connect_data->query_data =
1742 gaim_dnsquery_a(gaim_proxy_info_get_host(gpi), 1742 gaim_dnsquery_a(gaim_proxy_info_get_host(gpi),
1743 gaim_proxy_info_get_port(gpi), 1743 gaim_proxy_info_get_port(gpi),
1744 connection_host_resolved, connect_info); 1744 connection_host_resolved, connect_data);
1745 if (connect_info->query_data == NULL) 1745 if (connect_data->query_data == NULL)
1746 { 1746 {
1747 gaim_proxy_connect_info_destroy(connect_info); 1747 gaim_proxy_connect_data_destroy(connect_data);
1748 return NULL; 1748 return NULL;
1749 } 1749 }
1750 1750
1751 connect_infos = g_slist_prepend(connect_infos, connect_info); 1751 connect_datas = g_slist_prepend(connect_datas, connect_data);
1752 1752
1753 return connect_info; 1753 return connect_data;
1754 } 1754 }
1755 1755
1756 void 1756 void
1757 gaim_proxy_connect_cancel(GaimProxyConnectInfo *connect_info) 1757 gaim_proxy_connect_cancel(GaimProxyConnectData *connect_data)
1758 { 1758 {
1759 gaim_proxy_connect_info_destroy(connect_info); 1759 gaim_proxy_connect_data_destroy(connect_data);
1760 } 1760 }
1761 1761
1762 static void 1762 static void
1763 proxy_pref_cb(const char *name, GaimPrefType type, 1763 proxy_pref_cb(const char *name, GaimPrefType type,
1764 gconstpointer value, gpointer data) 1764 gconstpointer value, gpointer data)
1832 } 1832 }
1833 1833
1834 void 1834 void
1835 gaim_proxy_uninit(void) 1835 gaim_proxy_uninit(void)
1836 { 1836 {
1837 while (connect_infos != NULL) 1837 while (connect_datas != NULL)
1838 gaim_proxy_connect_info_destroy(connect_infos->data); 1838 gaim_proxy_connect_data_destroy(connect_datas->data);
1839 } 1839 }