| 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 } |
| 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) |