Mercurial > pidgin
comparison src/proxy.c @ 3630:9682c0e022c6
[gaim-migrate @ 3753]
Yeah this will probably break a lot of shit knowing my luck. But hey, I really don't care what people thnk.
committer: Tailor Script <tailor@pidgin.im>
| author | Rob Flynn <gaim@robflynn.com> |
|---|---|
| date | Fri, 11 Oct 2002 03:14:01 +0000 |
| parents | 8d0fa912ecaf |
| children | 988485669631 |
comparison
equal
deleted
inserted
replaced
| 3629:afc5bb164c5a | 3630:9682c0e022c6 |
|---|---|
| 28 #endif | 28 #endif |
| 29 #include <stdio.h> | 29 #include <stdio.h> |
| 30 #include <stdlib.h> | 30 #include <stdlib.h> |
| 31 #include <string.h> | 31 #include <string.h> |
| 32 #include <sys/types.h> | 32 #include <sys/types.h> |
| 33 | |
| 34 #ifndef _WIN32 | |
| 33 #include <sys/socket.h> | 35 #include <sys/socket.h> |
| 34 #include <netdb.h> | 36 #include <netdb.h> |
| 35 #include <netinet/in.h> | 37 #include <netinet/in.h> |
| 36 #include <arpa/inet.h> | 38 #include <arpa/inet.h> |
| 37 #include <unistd.h> | 39 #include <unistd.h> |
| 40 #else | |
| 41 #include <winsock.h> | |
| 42 #endif | |
| 43 | |
| 38 #include <fcntl.h> | 44 #include <fcntl.h> |
| 39 #include <errno.h> | 45 #include <errno.h> |
| 40 #include "gaim.h" | 46 #include "gaim.h" |
| 41 #include "proxy.h" | 47 #include "proxy.h" |
| 48 | |
| 49 #ifdef _WIN32 | |
| 50 #include "win32dep.h" | |
| 51 #endif | |
| 42 | 52 |
| 43 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) | 53 #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) |
| 44 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) | 54 #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) |
| 45 | 55 |
| 46 char proxyhost[128] = { 0 }; | 56 char proxyhost[128] = { 0 }; |
| 121 | 131 |
| 122 static struct sockaddr_in *gaim_gethostbyname(char *host, int port) | 132 static struct sockaddr_in *gaim_gethostbyname(char *host, int port) |
| 123 { | 133 { |
| 124 static struct sockaddr_in sin; | 134 static struct sockaddr_in sin; |
| 125 | 135 |
| 136 #ifndef _WIN32 | |
| 126 if (!inet_aton(host, &sin.sin_addr)) { | 137 if (!inet_aton(host, &sin.sin_addr)) { |
| 138 #else | |
| 139 if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { | |
| 140 #endif | |
| 127 struct hostent *hp; | 141 struct hostent *hp; |
| 128 if (!(hp = gethostbyname(host))) { | 142 if(!(hp = gethostbyname(host))) { |
| 143 #ifndef _WIN32 | |
| 129 debug_printf("gaim_gethostbyname(\"%s\", %d) failed: %s", | 144 debug_printf("gaim_gethostbyname(\"%s\", %d) failed: %s", |
| 130 host, port, hstrerror(h_errno)); | 145 host, port, hstrerror(h_errno)); |
| 146 #else | |
| 147 debug_printf("gaim_gethostbyname(\"%s\", %d) failed: Error %d", | |
| 148 host, port, WSAGetLastError()); | |
| 149 #endif | |
| 131 return NULL; | 150 return NULL; |
| 132 } | 151 } |
| 133 memset(&sin, 0, sizeof(struct sockaddr_in)); | 152 memset(&sin, 0, sizeof(struct sockaddr_in)); |
| 134 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); | 153 memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length); |
| 135 sin.sin_family = hp->h_addrtype; | 154 sin.sin_family = hp->h_addrtype; |
| 142 | 161 |
| 143 static void no_one_calls(gpointer data, gint source, GaimInputCondition cond) | 162 static void no_one_calls(gpointer data, gint source, GaimInputCondition cond) |
| 144 { | 163 { |
| 145 struct PHB *phb = data; | 164 struct PHB *phb = data; |
| 146 unsigned int len; | 165 unsigned int len; |
| 166 #ifdef _WIN32 | |
| 167 int werror = WSAETIMEDOUT; | |
| 168 u_long imode; | |
| 169 #else | |
| 147 int error = ETIMEDOUT; | 170 int error = ETIMEDOUT; |
| 171 #endif | |
| 148 debug_printf("Connected\n"); | 172 debug_printf("Connected\n"); |
| 173 #ifdef _WIN32 | |
| 174 len = sizeof(werror); | |
| 175 if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 176 closesocket(source); | |
| 177 gaim_input_remove(phb->inpa); | |
| 178 phb->func(phb->data, -1, GAIM_INPUT_READ); | |
| 179 g_free(phb); | |
| 180 return; | |
| 181 } else | |
| 182 WSASetLastError(werror); | |
| 183 imode=0; | |
| 184 ioctlsocket(source, FIONBIO, &imode); | |
| 185 #else | |
| 149 len = sizeof(error); | 186 len = sizeof(error); |
| 150 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 187 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 151 close(source); | 188 close(source); |
| 152 gaim_input_remove(phb->inpa); | 189 gaim_input_remove(phb->inpa); |
| 153 phb->func(phb->data, -1, GAIM_INPUT_READ); | 190 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 154 g_free(phb); | 191 g_free(phb); |
| 155 return; | 192 return; |
| 156 } | 193 } |
| 157 fcntl(source, F_SETFL, 0); | 194 fcntl(source, F_SETFL, 0); |
| 195 #endif | |
| 158 gaim_input_remove(phb->inpa); | 196 gaim_input_remove(phb->inpa); |
| 159 phb->func(phb->data, source, GAIM_INPUT_READ); | 197 phb->func(phb->data, source, GAIM_INPUT_READ); |
| 160 g_free(phb); | 198 g_free(phb); |
| 161 } | 199 } |
| 162 | 200 |
| 173 | 211 |
| 174 static int proxy_connect_none(char *host, unsigned short port, struct PHB *phb) | 212 static int proxy_connect_none(char *host, unsigned short port, struct PHB *phb) |
| 175 { | 213 { |
| 176 struct sockaddr_in *sin; | 214 struct sockaddr_in *sin; |
| 177 int fd = -1; | 215 int fd = -1; |
| 178 | 216 #ifdef _WIN32 |
| 217 u_long imode; | |
| 218 int w_errno; | |
| 219 #endif | |
| 179 debug_printf("connecting to %s:%d with no proxy\n", host, port); | 220 debug_printf("connecting to %s:%d with no proxy\n", host, port); |
| 180 | 221 |
| 181 if (!(sin = gaim_gethostbyname(host, port))) { | 222 if (!(sin = gaim_gethostbyname(host, port))) { |
| 182 debug_printf("gethostbyname failed\n"); | 223 debug_printf("gethostbyname failed\n"); |
| 183 g_free(phb); | 224 g_free(phb); |
| 187 if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { | 228 if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) { |
| 188 debug_printf("unable to create socket\n"); | 229 debug_printf("unable to create socket\n"); |
| 189 g_free(phb); | 230 g_free(phb); |
| 190 return -1; | 231 return -1; |
| 191 } | 232 } |
| 192 | 233 #ifdef _WIN32 |
| 234 imode=1; | |
| 235 ioctlsocket(fd, FIONBIO, &imode); | |
| 236 #else | |
| 193 fcntl(fd, F_SETFL, O_NONBLOCK); | 237 fcntl(fd, F_SETFL, O_NONBLOCK); |
| 238 #endif | |
| 194 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { | 239 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { |
| 240 #ifdef _WIN32 | |
| 241 w_errno = WSAGetLastError(); | |
| 242 if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR) || (w_errno == WSAEWOULDBLOCK)) { | |
| 243 #else | |
| 195 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 244 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 245 #endif | |
| 196 debug_printf("Connect would have blocked\n"); | 246 debug_printf("Connect would have blocked\n"); |
| 197 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); | 247 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); |
| 198 } else { | 248 } else { |
| 249 #ifdef _WIN32 | |
| 250 debug_printf("connect failed (errno %d)\n", w_errno); | |
| 251 closesocket(fd); | |
| 252 #else | |
| 199 debug_printf("connect failed (errno %d)\n", errno); | 253 debug_printf("connect failed (errno %d)\n", errno); |
| 200 close(fd); | 254 close(fd); |
| 255 #endif | |
| 201 g_free(phb); | 256 g_free(phb); |
| 202 return -1; | 257 return -1; |
| 203 } | 258 } |
| 204 } else { | 259 } else { |
| 260 #ifdef _WIN32 | |
| 261 int werror = WSAETIMEDOUT; | |
| 262 unsigned int len; | |
| 263 u_long imode; | |
| 264 | |
| 265 debug_printf("Connect didn't block\n"); | |
| 266 len = sizeof(werror); | |
| 267 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 268 debug_printf("getsockopt failed\n"); | |
| 269 closesocket(fd); | |
| 270 g_free(phb); | |
| 271 return -1; | |
| 272 } else | |
| 273 WSASetLastError(werror); | |
| 274 imode=0; | |
| 275 ioctlsocket(fd, FIONBIO, &imode); | |
| 276 #else | |
| 205 unsigned int len; | 277 unsigned int len; |
| 206 int error = ETIMEDOUT; | 278 int error = ETIMEDOUT; |
| 207 debug_printf("Connect didn't block\n"); | 279 debug_printf("Connect didn't block\n"); |
| 208 len = sizeof(error); | 280 len = sizeof(error); |
| 209 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 281 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 211 close(fd); | 283 close(fd); |
| 212 g_free(phb); | 284 g_free(phb); |
| 213 return -1; | 285 return -1; |
| 214 } | 286 } |
| 215 fcntl(fd, F_SETFL, 0); | 287 fcntl(fd, F_SETFL, 0); |
| 288 #endif | |
| 216 phb->port = fd; /* bleh */ | 289 phb->port = fd; /* bleh */ |
| 217 g_timeout_add(50, clean_connect, phb); /* we do this because we never | 290 g_timeout_add(50, clean_connect, phb); /* we do this because we never |
| 218 want to call our callback | 291 want to call our callback |
| 219 before we return. */ | 292 before we return. */ |
| 220 } | 293 } |
| 232 struct PHB *phb = data; | 305 struct PHB *phb = data; |
| 233 char inputline[8192]; | 306 char inputline[8192]; |
| 234 | 307 |
| 235 gaim_input_remove(phb->inpa); | 308 gaim_input_remove(phb->inpa); |
| 236 | 309 |
| 310 #ifdef _WIN32 | |
| 311 while ((nlc != 2) && (recv(source, &inputline[pos++], 1, 0) == 1)) { | |
| 312 #else | |
| 237 while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { | 313 while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { |
| 314 #endif | |
| 238 if (inputline[pos - 1] == '\n') | 315 if (inputline[pos - 1] == '\n') |
| 239 nlc++; | 316 nlc++; |
| 240 else if (inputline[pos - 1] != '\r') | 317 else if (inputline[pos - 1] != '\r') |
| 241 nlc = 0; | 318 nlc = 0; |
| 242 } | 319 } |
| 250 g_free(phb->host); | 327 g_free(phb->host); |
| 251 g_free(phb); | 328 g_free(phb); |
| 252 return; | 329 return; |
| 253 } | 330 } |
| 254 | 331 |
| 332 #ifdef _WIN32 | |
| 333 closesocket(source); | |
| 334 #else | |
| 255 close(source); | 335 close(source); |
| 336 #endif | |
| 256 phb->func(phb->data, -1, GAIM_INPUT_READ); | 337 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 257 g_free(phb->host); | 338 g_free(phb->host); |
| 258 g_free(phb); | 339 g_free(phb); |
| 259 return; | 340 return; |
| 260 } | 341 } |
| 262 static void http_canwrite(gpointer data, gint source, GaimInputCondition cond) | 343 static void http_canwrite(gpointer data, gint source, GaimInputCondition cond) |
| 263 { | 344 { |
| 264 char cmd[384]; | 345 char cmd[384]; |
| 265 struct PHB *phb = data; | 346 struct PHB *phb = data; |
| 266 unsigned int len; | 347 unsigned int len; |
| 348 #ifdef _WIN32 | |
| 349 int w_error = WSAETIMEDOUT; | |
| 350 u_long imode = 0; | |
| 351 #else | |
| 267 int error = ETIMEDOUT; | 352 int error = ETIMEDOUT; |
| 353 #endif | |
| 268 debug_printf("Connected\n"); | 354 debug_printf("Connected\n"); |
| 269 if (phb->inpa > 0) | 355 if (phb->inpa > 0) |
| 270 gaim_input_remove(phb->inpa); | 356 gaim_input_remove(phb->inpa); |
| 357 #ifdef _WIN32 | |
| 358 len = sizeof(w_error); | |
| 359 if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&w_error, &len) < 0) { | |
| 360 closesocket(source); | |
| 361 #else | |
| 271 len = sizeof(error); | 362 len = sizeof(error); |
| 272 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 363 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 273 close(source); | 364 close(source); |
| 274 phb->func(phb->data, -1, GAIM_INPUT_READ); | 365 #endif |
| 275 g_free(phb->host); | 366 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 276 g_free(phb); | 367 g_free(phb->host); |
| 277 return; | 368 g_free(phb); |
| 369 return; | |
| 370 #ifdef _WIN32 | |
| 371 } else | |
| 372 WSASetLastError( w_error ); | |
| 373 ioctlsocket(source, FIONBIO, &imode); | |
| 374 #else | |
| 278 } | 375 } |
| 279 fcntl(source, F_SETFL, 0); | 376 fcntl(source, F_SETFL, 0); |
| 280 | 377 #endif |
| 281 g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, | 378 g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, |
| 282 phb->host, phb->port); | 379 phb->host, phb->port); |
| 283 if (send(source, cmd, strlen(cmd), 0) < 0) { | 380 if (send(source, cmd, strlen(cmd), 0) < 0) { |
| 284 close(source); | 381 #ifdef _WIN32 |
| 382 closesocket(source); | |
| 383 #else | |
| 384 close(source); | |
| 385 #endif | |
| 285 phb->func(phb->data, -1, GAIM_INPUT_READ); | 386 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 286 g_free(phb->host); | 387 g_free(phb->host); |
| 287 g_free(phb); | 388 g_free(phb); |
| 288 return; | 389 return; |
| 289 } | 390 } |
| 294 t2 = tobase64(t1); | 395 t2 = tobase64(t1); |
| 295 g_free(t1); | 396 g_free(t1); |
| 296 g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); | 397 g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); |
| 297 g_free(t2); | 398 g_free(t2); |
| 298 if (send(source, cmd, strlen(cmd), 0) < 0) { | 399 if (send(source, cmd, strlen(cmd), 0) < 0) { |
| 400 #ifdef _WIN32 | |
| 401 closesocket(source); | |
| 402 #else | |
| 299 close(source); | 403 close(source); |
| 404 #endif | |
| 300 phb->func(phb->data, -1, GAIM_INPUT_READ); | 405 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 301 g_free(phb->host); | 406 g_free(phb->host); |
| 302 g_free(phb); | 407 g_free(phb); |
| 303 return; | 408 return; |
| 304 } | 409 } |
| 305 } | 410 } |
| 306 | 411 |
| 307 g_snprintf(cmd, sizeof(cmd), "\r\n"); | 412 g_snprintf(cmd, sizeof(cmd), "\r\n"); |
| 308 if (send(source, cmd, strlen(cmd), 0) < 0) { | 413 if (send(source, cmd, strlen(cmd), 0) < 0) { |
| 309 close(source); | 414 #ifdef _WIN32 |
| 415 closesocket(source); | |
| 416 #else | |
| 417 close(source); | |
| 418 #endif | |
| 310 phb->func(phb->data, -1, GAIM_INPUT_READ); | 419 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 311 g_free(phb->host); | 420 g_free(phb->host); |
| 312 g_free(phb); | 421 g_free(phb); |
| 313 return; | 422 return; |
| 314 } | 423 } |
| 318 | 427 |
| 319 static int proxy_connect_http(char *host, unsigned short port, struct PHB *phb) | 428 static int proxy_connect_http(char *host, unsigned short port, struct PHB *phb) |
| 320 { | 429 { |
| 321 struct sockaddr_in *sin; | 430 struct sockaddr_in *sin; |
| 322 int fd = -1; | 431 int fd = -1; |
| 432 #ifdef _WIN32 | |
| 433 u_long imode; | |
| 434 #endif | |
| 323 | 435 |
| 324 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); | 436 debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); |
| 325 | 437 |
| 326 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { | 438 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { |
| 327 g_free(phb); | 439 g_free(phb); |
| 334 } | 446 } |
| 335 | 447 |
| 336 phb->host = g_strdup(host); | 448 phb->host = g_strdup(host); |
| 337 phb->port = port; | 449 phb->port = port; |
| 338 | 450 |
| 451 #ifdef _WIN32 | |
| 452 imode = 1; | |
| 453 ioctlsocket(fd, FIONBIO, &imode); | |
| 454 #else | |
| 339 fcntl(fd, F_SETFL, O_NONBLOCK); | 455 fcntl(fd, F_SETFL, O_NONBLOCK); |
| 456 #endif | |
| 340 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { | 457 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { |
| 458 #ifdef _WIN32 | |
| 459 int w_errno = WSAGetLastError(); | |
| 460 if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR)) { | |
| 461 #else | |
| 341 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 462 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 463 #endif | |
| 342 debug_printf("Connect would have blocked\n"); | 464 debug_printf("Connect would have blocked\n"); |
| 343 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); | 465 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); |
| 344 } else { | 466 } else { |
| 467 #ifdef _WIN32 | |
| 468 closesocket(fd); | |
| 469 #else | |
| 345 close(fd); | 470 close(fd); |
| 471 #endif | |
| 346 g_free(phb->host); | 472 g_free(phb->host); |
| 347 g_free(phb); | 473 g_free(phb); |
| 348 return -1; | 474 return -1; |
| 349 } | 475 } |
| 350 } else { | 476 } else { |
| 351 unsigned int len; | 477 unsigned int len; |
| 478 #ifdef _WIN32 | |
| 479 int werror = WSAETIMEDOUT; | |
| 480 u_long imode; | |
| 481 #else | |
| 352 int error = ETIMEDOUT; | 482 int error = ETIMEDOUT; |
| 483 #endif | |
| 353 debug_printf("Connect didn't block\n"); | 484 debug_printf("Connect didn't block\n"); |
| 485 #ifdef _WIN32 | |
| 486 len = sizeof(werror); | |
| 487 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 488 closesocket(fd); | |
| 489 #else | |
| 354 len = sizeof(error); | 490 len = sizeof(error); |
| 355 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 491 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 356 close(fd); | 492 close(fd); |
| 493 #endif | |
| 357 g_free(phb->host); | 494 g_free(phb->host); |
| 358 g_free(phb); | 495 g_free(phb); |
| 359 return -1; | 496 return -1; |
| 497 #ifdef _WIN32 | |
| 498 } else | |
| 499 WSASetLastError(werror); | |
| 500 imode=0; | |
| 501 ioctlsocket(fd, FIONBIO, &imode); | |
| 502 #else | |
| 360 } | 503 } |
| 361 fcntl(fd, F_SETFL, 0); | 504 fcntl(fd, F_SETFL, 0); |
| 505 #endif | |
| 362 http_canwrite(phb, fd, GAIM_INPUT_WRITE); | 506 http_canwrite(phb, fd, GAIM_INPUT_WRITE); |
| 363 } | 507 } |
| 364 | 508 |
| 365 return fd; | 509 return fd; |
| 366 } | 510 } |
| 371 struct PHB *phb = data; | 515 struct PHB *phb = data; |
| 372 | 516 |
| 373 gaim_input_remove(phb->inpa); | 517 gaim_input_remove(phb->inpa); |
| 374 | 518 |
| 375 memset(packet, 0, sizeof(packet)); | 519 memset(packet, 0, sizeof(packet)); |
| 520 #ifdef _WIN32 | |
| 521 if (recv(source, packet, 9, 0) >= 4 && packet[1] == 90) { | |
| 522 #else | |
| 376 if (read(source, packet, 9) >= 4 && packet[1] == 90) { | 523 if (read(source, packet, 9) >= 4 && packet[1] == 90) { |
| 524 #endif | |
| 377 phb->func(phb->data, source, GAIM_INPUT_READ); | 525 phb->func(phb->data, source, GAIM_INPUT_READ); |
| 378 g_free(phb->host); | 526 g_free(phb->host); |
| 379 g_free(phb); | 527 g_free(phb); |
| 380 return; | 528 return; |
| 381 } | 529 } |
| 382 | 530 |
| 531 #ifdef _WIN32 | |
| 532 closesocket(source); | |
| 533 #else | |
| 383 close(source); | 534 close(source); |
| 535 #endif | |
| 384 phb->func(phb->data, -1, GAIM_INPUT_READ); | 536 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 385 g_free(phb->host); | 537 g_free(phb->host); |
| 386 g_free(phb); | 538 g_free(phb); |
| 387 } | 539 } |
| 388 | 540 |
| 390 { | 542 { |
| 391 unsigned char packet[12]; | 543 unsigned char packet[12]; |
| 392 struct hostent *hp; | 544 struct hostent *hp; |
| 393 struct PHB *phb = data; | 545 struct PHB *phb = data; |
| 394 unsigned int len; | 546 unsigned int len; |
| 547 #ifdef _WIN32 | |
| 548 int werror = WSAETIMEDOUT; | |
| 549 u_long imode; | |
| 550 #else | |
| 395 int error = ETIMEDOUT; | 551 int error = ETIMEDOUT; |
| 552 #endif | |
| 396 debug_printf("Connected\n"); | 553 debug_printf("Connected\n"); |
| 397 if (phb->inpa > 0) | 554 if (phb->inpa > 0) |
| 398 gaim_input_remove(phb->inpa); | 555 gaim_input_remove(phb->inpa); |
| 556 #ifdef _WIN32 | |
| 557 len = sizeof(werror); | |
| 558 if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 559 closesocket(source); | |
| 560 #else | |
| 399 len = sizeof(error); | 561 len = sizeof(error); |
| 400 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 562 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 401 close(source); | 563 close(source); |
| 402 phb->func(phb->data, -1, GAIM_INPUT_READ); | 564 #endif |
| 403 g_free(phb->host); | 565 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 404 g_free(phb); | 566 g_free(phb->host); |
| 405 return; | 567 g_free(phb); |
| 568 return; | |
| 569 #ifdef _WIN32 | |
| 570 } else | |
| 571 WSASetLastError(werror); | |
| 572 imode=0; | |
| 573 ioctlsocket(source, FIONBIO, &imode); | |
| 574 #else | |
| 406 } | 575 } |
| 407 fcntl(source, F_SETFL, 0); | 576 fcntl(source, F_SETFL, 0); |
| 408 | 577 #endif |
| 409 /* XXX does socks4 not support host name lookups by the proxy? */ | 578 /* XXX does socks4 not support host name lookups by the proxy? */ |
| 410 if (!(hp = gethostbyname(phb->host))) { | 579 if (!(hp = gethostbyname(phb->host))) { |
| 411 close(source); | 580 #ifdef _WIN32 |
| 581 closesocket(source); | |
| 582 #else | |
| 583 close(source); | |
| 584 #endif | |
| 412 phb->func(phb->data, -1, GAIM_INPUT_READ); | 585 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 413 g_free(phb->host); | 586 g_free(phb->host); |
| 414 g_free(phb); | 587 g_free(phb); |
| 415 return; | 588 return; |
| 416 } | 589 } |
| 422 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; | 595 packet[4] = (unsigned char)(hp->h_addr_list[0])[0]; |
| 423 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; | 596 packet[5] = (unsigned char)(hp->h_addr_list[0])[1]; |
| 424 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; | 597 packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; |
| 425 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; | 598 packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; |
| 426 packet[8] = 0; | 599 packet[8] = 0; |
| 600 #ifdef _WIN32 | |
| 601 if (send(source, packet, 9, 0) != 9) { | |
| 602 closesocket(source); | |
| 603 #else | |
| 427 if (write(source, packet, 9) != 9) { | 604 if (write(source, packet, 9) != 9) { |
| 428 close(source); | 605 close(source); |
| 606 #endif | |
| 429 phb->func(phb->data, -1, GAIM_INPUT_READ); | 607 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 430 g_free(phb->host); | 608 g_free(phb->host); |
| 431 g_free(phb); | 609 g_free(phb); |
| 432 return; | 610 return; |
| 433 } | 611 } |
| 437 | 615 |
| 438 static int proxy_connect_socks4(char *host, unsigned short port, struct PHB *phb) | 616 static int proxy_connect_socks4(char *host, unsigned short port, struct PHB *phb) |
| 439 { | 617 { |
| 440 struct sockaddr_in *sin; | 618 struct sockaddr_in *sin; |
| 441 int fd = -1; | 619 int fd = -1; |
| 620 #ifdef _WIN32 | |
| 621 int werrno; | |
| 622 u_long imode; | |
| 623 #endif | |
| 442 | 624 |
| 443 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); | 625 debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); |
| 444 | 626 |
| 445 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { | 627 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { |
| 446 g_free(phb); | 628 g_free(phb); |
| 453 } | 635 } |
| 454 | 636 |
| 455 phb->host = g_strdup(host); | 637 phb->host = g_strdup(host); |
| 456 phb->port = port; | 638 phb->port = port; |
| 457 | 639 |
| 640 #ifdef _WIN32 | |
| 641 imode=1; | |
| 642 ioctlsocket(fd, FIONBIO, &imode); | |
| 643 #else | |
| 458 fcntl(fd, F_SETFL, O_NONBLOCK); | 644 fcntl(fd, F_SETFL, O_NONBLOCK); |
| 645 #endif | |
| 459 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { | 646 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { |
| 647 #ifdef _WIN32 | |
| 648 werrno = WSAGetLastError(); | |
| 649 if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { | |
| 650 #else | |
| 460 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 651 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 652 #endif | |
| 461 debug_printf("Connect would have blocked\n"); | 653 debug_printf("Connect would have blocked\n"); |
| 462 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); | 654 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); |
| 463 } else { | 655 } else { |
| 656 #ifdef _WIN32 | |
| 657 closesocket(fd); | |
| 658 #else | |
| 464 close(fd); | 659 close(fd); |
| 660 #endif | |
| 465 g_free(phb->host); | 661 g_free(phb->host); |
| 466 g_free(phb); | 662 g_free(phb); |
| 467 return -1; | 663 return -1; |
| 468 } | 664 } |
| 469 } else { | 665 } else { |
| 470 unsigned int len; | 666 unsigned int len; |
| 667 #ifdef _WIN32 | |
| 668 int werror = WSAETIMEDOUT; | |
| 669 u_long imode; | |
| 670 #else | |
| 471 int error = ETIMEDOUT; | 671 int error = ETIMEDOUT; |
| 672 #endif | |
| 472 debug_printf("Connect didn't block\n"); | 673 debug_printf("Connect didn't block\n"); |
| 674 #ifdef _WIN32 | |
| 675 len = sizeof(werror); | |
| 676 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 677 closesocket(fd); | |
| 678 #else | |
| 473 len = sizeof(error); | 679 len = sizeof(error); |
| 474 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 680 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 475 close(fd); | 681 close(fd); |
| 682 #endif | |
| 476 g_free(phb->host); | 683 g_free(phb->host); |
| 477 g_free(phb); | 684 g_free(phb); |
| 478 return -1; | 685 return -1; |
| 686 #ifdef _WIN32 | |
| 687 } else | |
| 688 WSASetLastError(werror); | |
| 689 imode=0; | |
| 690 ioctlsocket(fd, FIONBIO, &imode); | |
| 691 #else | |
| 479 } | 692 } |
| 480 fcntl(fd, F_SETFL, 0); | 693 fcntl(fd, F_SETFL, 0); |
| 694 #endif | |
| 481 s4_canwrite(phb, fd, GAIM_INPUT_WRITE); | 695 s4_canwrite(phb, fd, GAIM_INPUT_WRITE); |
| 482 } | 696 } |
| 483 | 697 |
| 484 return fd; | 698 return fd; |
| 485 } | 699 } |
| 490 struct PHB *phb = data; | 704 struct PHB *phb = data; |
| 491 | 705 |
| 492 gaim_input_remove(phb->inpa); | 706 gaim_input_remove(phb->inpa); |
| 493 debug_printf("able to read again\n"); | 707 debug_printf("able to read again\n"); |
| 494 | 708 |
| 709 #ifdef _WIN32 | |
| 710 if (recv(source, buf, 10, 0) < 10) { | |
| 711 #else | |
| 495 if (read(source, buf, 10) < 10) { | 712 if (read(source, buf, 10) < 10) { |
| 713 #endif | |
| 496 debug_printf("or not...\n"); | 714 debug_printf("or not...\n"); |
| 497 close(source); | 715 #ifdef _WIN32 |
| 716 closesocket(source); | |
| 717 #else | |
| 718 close(source); | |
| 719 #endif | |
| 498 phb->func(phb->data, -1, GAIM_INPUT_READ); | 720 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 499 g_free(phb->host); | 721 g_free(phb->host); |
| 500 g_free(phb); | 722 g_free(phb); |
| 501 return; | 723 return; |
| 502 } | 724 } |
| 503 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { | 725 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { |
| 504 debug_printf("bad data\n"); | 726 debug_printf("bad data\n"); |
| 505 close(source); | 727 #ifdef _WIN32 |
| 728 closesocket(source); | |
| 729 #else | |
| 730 close(source); | |
| 731 #endif | |
| 506 phb->func(phb->data, -1, GAIM_INPUT_READ); | 732 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 507 g_free(phb->host); | 733 g_free(phb->host); |
| 508 g_free(phb); | 734 g_free(phb); |
| 509 return; | 735 return; |
| 510 } | 736 } |
| 528 buf[4] = hlen; | 754 buf[4] = hlen; |
| 529 memcpy(buf + 5, phb->host, hlen); | 755 memcpy(buf + 5, phb->host, hlen); |
| 530 buf[5 + strlen(phb->host)] = phb->port >> 8; | 756 buf[5 + strlen(phb->host)] = phb->port >> 8; |
| 531 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; | 757 buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; |
| 532 | 758 |
| 759 #ifdef _WIN32 | |
| 760 if (send(source, buf, (5 + strlen(phb->host) + 2), 0) < (5 + strlen(phb->host) + 2)) { | |
| 761 closesocket(source); | |
| 762 #else | |
| 533 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { | 763 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { |
| 534 close(source); | 764 close(source); |
| 765 #endif | |
| 535 phb->func(phb->data, -1, GAIM_INPUT_READ); | 766 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 536 g_free(phb->host); | 767 g_free(phb->host); |
| 537 g_free(phb); | 768 g_free(phb); |
| 538 return; | 769 return; |
| 539 } | 770 } |
| 547 struct PHB *phb = data; | 778 struct PHB *phb = data; |
| 548 | 779 |
| 549 gaim_input_remove(phb->inpa); | 780 gaim_input_remove(phb->inpa); |
| 550 debug_printf("got auth response\n"); | 781 debug_printf("got auth response\n"); |
| 551 | 782 |
| 783 #ifdef _WIN32 | |
| 784 if (recv(source, buf, 2, 0) < 2) { | |
| 785 closesocket(source); | |
| 786 #else | |
| 552 if (read(source, buf, 2) < 2) { | 787 if (read(source, buf, 2) < 2) { |
| 553 close(source); | 788 close(source); |
| 789 #endif | |
| 554 phb->func(phb->data, -1, GAIM_INPUT_READ); | 790 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 555 g_free(phb->host); | 791 g_free(phb->host); |
| 556 g_free(phb); | 792 g_free(phb); |
| 557 return; | 793 return; |
| 558 } | 794 } |
| 559 | 795 |
| 560 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { | 796 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { |
| 561 close(source); | 797 #ifdef _WIN32 |
| 798 closesocket(source); | |
| 799 #else | |
| 800 close(source); | |
| 801 #endif | |
| 562 phb->func(phb->data, -1, GAIM_INPUT_READ); | 802 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 563 g_free(phb->host); | 803 g_free(phb->host); |
| 564 g_free(phb); | 804 g_free(phb); |
| 565 return; | 805 return; |
| 566 } | 806 } |
| 574 struct PHB *phb = data; | 814 struct PHB *phb = data; |
| 575 | 815 |
| 576 gaim_input_remove(phb->inpa); | 816 gaim_input_remove(phb->inpa); |
| 577 debug_printf("able to read\n"); | 817 debug_printf("able to read\n"); |
| 578 | 818 |
| 819 #ifdef _WIN32 | |
| 820 if (recv(source, buf, 2, 0) < 2) { | |
| 821 closesocket(source); | |
| 822 #else | |
| 579 if (read(source, buf, 2) < 2) { | 823 if (read(source, buf, 2) < 2) { |
| 580 close(source); | 824 close(source); |
| 825 #endif | |
| 581 phb->func(phb->data, -1, GAIM_INPUT_READ); | 826 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 582 g_free(phb->host); | 827 g_free(phb->host); |
| 583 g_free(phb); | 828 g_free(phb); |
| 584 return; | 829 return; |
| 585 } | 830 } |
| 586 | 831 |
| 587 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { | 832 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { |
| 588 close(source); | 833 #ifdef _WIN32 |
| 834 closesocket(source); | |
| 835 #else | |
| 836 close(source); | |
| 837 #endif | |
| 589 phb->func(phb->data, -1, GAIM_INPUT_READ); | 838 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 590 g_free(phb->host); | 839 g_free(phb->host); |
| 591 g_free(phb); | 840 g_free(phb); |
| 592 return; | 841 return; |
| 593 } | 842 } |
| 597 buf[0] = 0x01; /* version 1 */ | 846 buf[0] = 0x01; /* version 1 */ |
| 598 buf[1] = i; | 847 buf[1] = i; |
| 599 memcpy(buf + 2, proxyuser, i); | 848 memcpy(buf + 2, proxyuser, i); |
| 600 buf[2 + i] = j; | 849 buf[2 + i] = j; |
| 601 memcpy(buf + 2 + i + 1, proxypass, j); | 850 memcpy(buf + 2 + i + 1, proxypass, j); |
| 851 #ifdef _WIN32 | |
| 852 if (send(source, buf, 3 + i + j, 0) < 3 + i + j) { | |
| 853 closesocket(source); | |
| 854 #else | |
| 602 if (write(source, buf, 3 + i + j) < 3 + i + j) { | 855 if (write(source, buf, 3 + i + j) < 3 + i + j) { |
| 603 close(source); | 856 close(source); |
| 857 #endif | |
| 604 phb->func(phb->data, -1, GAIM_INPUT_READ); | 858 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 605 g_free(phb->host); | 859 g_free(phb->host); |
| 606 g_free(phb); | 860 g_free(phb); |
| 607 return; | 861 return; |
| 608 } | 862 } |
| 617 { | 871 { |
| 618 unsigned char buf[512]; | 872 unsigned char buf[512]; |
| 619 int i; | 873 int i; |
| 620 struct PHB *phb = data; | 874 struct PHB *phb = data; |
| 621 unsigned int len; | 875 unsigned int len; |
| 876 #ifdef _WIN32 | |
| 877 int werror = WSAETIMEDOUT; | |
| 878 u_long imode; | |
| 879 #else | |
| 622 int error = ETIMEDOUT; | 880 int error = ETIMEDOUT; |
| 881 #endif | |
| 623 debug_printf("Connected\n"); | 882 debug_printf("Connected\n"); |
| 624 if (phb->inpa > 0) | 883 if (phb->inpa > 0) |
| 625 gaim_input_remove(phb->inpa); | 884 gaim_input_remove(phb->inpa); |
| 885 #ifdef _WIN32 | |
| 886 len = sizeof(werror); | |
| 887 if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 888 closesocket(source); | |
| 889 #else | |
| 626 len = sizeof(error); | 890 len = sizeof(error); |
| 627 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 891 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 628 close(source); | 892 close(source); |
| 629 phb->func(phb->data, -1, GAIM_INPUT_READ); | 893 #endif |
| 630 g_free(phb->host); | 894 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 631 g_free(phb); | 895 g_free(phb->host); |
| 632 return; | 896 g_free(phb); |
| 897 return; | |
| 898 #ifdef _WIN32 | |
| 899 } else | |
| 900 WSASetLastError(werror); | |
| 901 imode=0; | |
| 902 ioctlsocket(source, FIONBIO, &imode); | |
| 903 #else | |
| 633 } | 904 } |
| 634 fcntl(source, F_SETFL, 0); | 905 fcntl(source, F_SETFL, 0); |
| 906 #endif | |
| 635 | 907 |
| 636 i = 0; | 908 i = 0; |
| 637 buf[0] = 0x05; /* SOCKS version 5 */ | 909 buf[0] = 0x05; /* SOCKS version 5 */ |
| 638 if (proxyuser[0]) { | 910 if (proxyuser[0]) { |
| 639 buf[1] = 0x02; /* two methods */ | 911 buf[1] = 0x02; /* two methods */ |
| 643 } else { | 915 } else { |
| 644 buf[1] = 0x01; | 916 buf[1] = 0x01; |
| 645 buf[2] = 0x00; | 917 buf[2] = 0x00; |
| 646 i = 3; | 918 i = 3; |
| 647 } | 919 } |
| 648 | 920 #ifdef _WIN32 |
| 921 if (send(source, buf, i, 0) < i) { | |
| 922 #else | |
| 649 if (write(source, buf, i) < i) { | 923 if (write(source, buf, i) < i) { |
| 924 #endif | |
| 650 debug_printf("unable to write\n"); | 925 debug_printf("unable to write\n"); |
| 651 close(source); | 926 #ifdef _WIN32 |
| 927 closesocket(source); | |
| 928 #else | |
| 929 close(source); | |
| 930 #endif | |
| 652 phb->func(phb->data, -1, GAIM_INPUT_READ); | 931 phb->func(phb->data, -1, GAIM_INPUT_READ); |
| 653 g_free(phb->host); | 932 g_free(phb->host); |
| 654 g_free(phb); | 933 g_free(phb); |
| 655 return; | 934 return; |
| 656 } | 935 } |
| 660 | 939 |
| 661 static int proxy_connect_socks5(char *host, unsigned short port, struct PHB *phb) | 940 static int proxy_connect_socks5(char *host, unsigned short port, struct PHB *phb) |
| 662 { | 941 { |
| 663 struct sockaddr_in *sin; | 942 struct sockaddr_in *sin; |
| 664 int fd = -1; | 943 int fd = -1; |
| 944 #ifdef _WIN32 | |
| 945 u_long imode; | |
| 946 int werrno; | |
| 947 #endif | |
| 665 | 948 |
| 666 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); | 949 debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); |
| 667 | 950 |
| 668 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { | 951 if (!(sin = gaim_gethostbyname(proxyhost, proxyport))) { |
| 669 g_free(phb); | 952 g_free(phb); |
| 676 } | 959 } |
| 677 | 960 |
| 678 phb->host = g_strdup(host); | 961 phb->host = g_strdup(host); |
| 679 phb->port = port; | 962 phb->port = port; |
| 680 | 963 |
| 964 #ifdef _WIN32 | |
| 965 imode=1; | |
| 966 ioctlsocket(fd, FIONBIO, &imode); | |
| 967 #else | |
| 681 fcntl(fd, F_SETFL, O_NONBLOCK); | 968 fcntl(fd, F_SETFL, O_NONBLOCK); |
| 969 #endif | |
| 682 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { | 970 if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { |
| 971 #ifdef _WIN32 | |
| 972 werrno = WSAGetLastError(); | |
| 973 if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { | |
| 974 #else | |
| 683 if ((errno == EINPROGRESS) || (errno == EINTR)) { | 975 if ((errno == EINPROGRESS) || (errno == EINTR)) { |
| 976 #endif | |
| 684 debug_printf("Connect would have blocked\n"); | 977 debug_printf("Connect would have blocked\n"); |
| 685 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); | 978 phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); |
| 686 } else { | 979 } else { |
| 980 #ifdef _WIN32 | |
| 981 closesocket(fd); | |
| 982 #else | |
| 687 close(fd); | 983 close(fd); |
| 984 #endif | |
| 688 g_free(phb->host); | 985 g_free(phb->host); |
| 689 g_free(phb); | 986 g_free(phb); |
| 690 return -1; | 987 return -1; |
| 691 } | 988 } |
| 692 } else { | 989 } else { |
| 693 unsigned int len; | 990 unsigned int len; |
| 991 #ifdef _WIN32 | |
| 992 int werror = WSAETIMEDOUT; | |
| 993 #else | |
| 694 int error = ETIMEDOUT; | 994 int error = ETIMEDOUT; |
| 995 #endif | |
| 695 debug_printf("Connect didn't block\n"); | 996 debug_printf("Connect didn't block\n"); |
| 997 #ifdef _WIN32 | |
| 998 len = sizeof(werror); | |
| 999 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { | |
| 1000 closesocket(fd); | |
| 1001 #else | |
| 696 len = sizeof(error); | 1002 len = sizeof(error); |
| 697 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { | 1003 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { |
| 698 close(fd); | 1004 close(fd); |
| 1005 #endif | |
| 699 g_free(phb->host); | 1006 g_free(phb->host); |
| 700 g_free(phb); | 1007 g_free(phb); |
| 701 return -1; | 1008 return -1; |
| 1009 #ifdef _WIN32 | |
| 1010 } else | |
| 1011 WSASetLastError(werror); | |
| 1012 imode=0; | |
| 1013 ioctlsocket(fd, FIONBIO, &imode); | |
| 1014 #else | |
| 702 } | 1015 } |
| 703 fcntl(fd, F_SETFL, 0); | 1016 fcntl(fd, F_SETFL, 0); |
| 1017 #endif | |
| 704 s5_canwrite(phb, fd, GAIM_INPUT_WRITE); | 1018 s5_canwrite(phb, fd, GAIM_INPUT_WRITE); |
| 705 } | 1019 } |
| 706 | 1020 |
| 707 return fd; | 1021 return fd; |
| 708 } | 1022 } |
| 715 | 1029 |
| 716 if (!host || !port || (port == -1) || !func) { | 1030 if (!host || !port || (port == -1) || !func) { |
| 717 g_free(phb); | 1031 g_free(phb); |
| 718 return -1; | 1032 return -1; |
| 719 } | 1033 } |
| 720 | 1034 #ifndef _WIN32 |
| 721 sethostent(1); | 1035 sethostent(1); |
| 722 | 1036 #endif |
| 723 if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1)) | 1037 if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1)) |
| 724 return proxy_connect_none(host, port, phb); | 1038 return proxy_connect_none(host, port, phb); |
| 725 else if (proxytype == PROXY_HTTP) | 1039 else if (proxytype == PROXY_HTTP) |
| 726 return proxy_connect_http(host, port, phb); | 1040 return proxy_connect_http(host, port, phb); |
| 727 else if (proxytype == PROXY_SOCKS4) | 1041 else if (proxytype == PROXY_SOCKS4) |
| 730 return proxy_connect_socks5(host, port, phb); | 1044 return proxy_connect_socks5(host, port, phb); |
| 731 | 1045 |
| 732 g_free(phb); | 1046 g_free(phb); |
| 733 return -1; | 1047 return -1; |
| 734 } | 1048 } |
| 1049 |
