]>
Commit | Line | Data |
---|---|---|
16300b58 | 1 | |
30a4f2a8 | 2 | /* |
f8230a8d | 3 | * $Id: client.cc,v 1.109 2005/05/26 09:44:30 hno Exp $ |
30a4f2a8 | 4 | * |
5 | * DEBUG: section 0 WWW Client | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
2b6662ba | 8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
e25c139f | 9 | * ---------------------------------------------------------- |
30a4f2a8 | 10 | * |
2b6662ba | 11 | * Squid is the result of efforts by numerous individuals from |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
30a4f2a8 | 19 | * |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
24 | * | |
25 | * This program is distributed in the hope that it will be useful, | |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
29 | * | |
30 | * You should have received a copy of the GNU General Public License | |
31 | * along with this program; if not, write to the Free Software | |
cbdec147 | 32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
e25c139f | 33 | * |
30a4f2a8 | 34 | */ |
090089c4 | 35 | |
44a47c6e | 36 | #include "squid.h" |
090089c4 | 37 | |
38 | #ifndef BUFSIZ | |
39 | #define BUFSIZ 8192 | |
40 | #endif | |
41 | ||
42 | /* Local functions */ | |
a2c963ae | 43 | static int client_comm_bind(int, const char *); |
62e76326 | 44 | |
a2c963ae | 45 | static int client_comm_connect(int, const char *, u_short, struct timeval *); |
f5b8bbc4 | 46 | static void usage(const char *progname); |
62e76326 | 47 | |
899bab3f | 48 | static int Now(struct timeval *); |
e6ccf245 | 49 | static SIGHDLR catchSignal; |
54220df8 | 50 | static SIGHDLR pipe_handler; |
d6d09e02 | 51 | static void set_our_signal(void); |
0ef0f1de | 52 | #ifndef _SQUID_MSWIN_ |
20cbfe5a | 53 | static ssize_t myread(int fd, void *buf, size_t len); |
54 | static ssize_t mywrite(int fd, void *buf, size_t len); | |
0ef0f1de | 55 | #endif |
cca89eeb | 56 | static int put_fd; |
57 | static char *put_file = NULL; | |
62e76326 | 58 | |
b6c6bcef | 59 | static struct stat sb; |
60 | int total_bytes = 0; | |
20cbfe5a | 61 | int io_timeout = 120; |
090089c4 | 62 | |
b8d8561b | 63 | static void |
0ee4272b | 64 | usage(const char *progname) |
090089c4 | 65 | { |
0ee4272b | 66 | fprintf(stderr, |
62e76326 | 67 | "Usage: %s [-arsv] [-i IMS] [-h remote host] [-l local host] [-p port] [-m method] [-t count] [-I ping-interval] [-H 'strings'] [-T timeout] url\n" |
68 | "Options:\n" | |
69 | " -P file PUT request.\n" | |
70 | " -a Do NOT include Accept: header.\n" | |
71 | " -r Force cache to reload URL.\n" | |
72 | " -s Silent. Do not print data to stdout.\n" | |
73 | " -v Verbose. Print outgoing message to stderr.\n" | |
74 | " -i IMS If-Modified-Since time (in Epoch seconds).\n" | |
75 | " -h host Retrieve URL from cache on hostname. Default is localhost.\n" | |
76 | " -l host Specify a local IP address to bind to. Default is none.\n" | |
77 | " -p port Port number of cache. Default is %d.\n" | |
78 | " -m method Request method, default is GET.\n" | |
79 | " -t count Trace count cache-hops\n" | |
80 | " -g count Ping mode, \"count\" iterations (0 to loop until interrupted).\n" | |
81 | " -I interval Ping interval in seconds (default 1 second).\n" | |
82 | " -H 'string' Extra headers to send. Use '\\n' for new lines.\n" | |
83 | " -T timeout Timeout value (seconds) for read/write operations.\n" | |
84 | " -u user Proxy authentication username\n" | |
85 | " -w password Proxy authentication password\n" | |
86 | " -U user WWW authentication username\n" | |
87 | " -W password WWW authentication password\n", | |
88 | progname, CACHE_HTTP_PORT); | |
090089c4 | 89 | exit(1); |
90 | } | |
91 | ||
899bab3f | 92 | static int interrupted = 0; |
b8d8561b | 93 | int |
94 | main(int argc, char *argv[]) | |
090089c4 | 95 | { |
96 | int conn, c, len, bytesWritten; | |
97 | int port, to_stdout, reload; | |
899bab3f | 98 | int ping, pcount; |
599eadbe | 99 | int keep_alive = 0; |
88738790 | 100 | int opt_noaccept = 0; |
63259c34 | 101 | int opt_verbose = 0; |
a2c963ae | 102 | const char *hostname, *localhost; |
f8230a8d | 103 | char url[BUFSIZ], msg[49152], buf[BUFSIZ]; |
104 | char extra_hdrs[32768]; | |
0ee4272b | 105 | const char *method = "GET"; |
090089c4 | 106 | extern char *optarg; |
234967c9 | 107 | time_t ims = 0; |
b3b64e58 | 108 | int max_forwards = -1; |
62e76326 | 109 | |
899bab3f | 110 | struct timeval tv1, tv2; |
111 | int i = 0, loops; | |
112 | long ping_int; | |
113 | long ping_min = 0, ping_max = 0, ping_sum = 0, ping_mean = 0; | |
a78886fc | 114 | char *proxy_user = NULL; |
115 | char *proxy_password = NULL; | |
116 | char *www_user = NULL; | |
117 | char *www_password = NULL; | |
090089c4 | 118 | |
119 | /* set the defaults */ | |
2c08acd9 | 120 | hostname = "localhost"; |
121 | localhost = NULL; | |
63259c34 | 122 | extra_hdrs[0] = '\0'; |
090089c4 | 123 | port = CACHE_HTTP_PORT; |
124 | to_stdout = 1; | |
125 | reload = 0; | |
899bab3f | 126 | ping = 0; |
127 | pcount = 0; | |
128 | ping_int = 1 * 1000; | |
090089c4 | 129 | |
130 | if (argc < 2) { | |
62e76326 | 131 | usage(argv[0]); /* need URL */ |
090089c4 | 132 | } else if (argc >= 2) { |
62e76326 | 133 | strncpy(url, argv[argc - 1], BUFSIZ); |
134 | url[BUFSIZ - 1] = '\0'; | |
135 | ||
136 | if (url[0] == '-') | |
137 | usage(argv[0]); | |
138 | ||
139 | while ((c = getopt(argc, argv, "ah:l:P:i:km:p:rsvt:g:p:I:H:T:u:U:w:W:?")) != -1) | |
140 | switch (c) { | |
141 | ||
142 | case 'a': | |
143 | opt_noaccept = 1; | |
144 | break; | |
145 | ||
146 | case 'h': /* remote host */ | |
147 | ||
148 | if (optarg != NULL) | |
149 | hostname = optarg; | |
150 | ||
151 | break; | |
152 | ||
153 | case 'l': /* local host */ | |
154 | if (optarg != NULL) | |
155 | localhost = optarg; | |
156 | ||
157 | break; | |
158 | ||
159 | case 's': /* silent */ | |
160 | to_stdout = 0; | |
161 | ||
162 | break; | |
163 | ||
164 | case 'k': /* backward compat */ | |
165 | keep_alive = 1; | |
166 | ||
167 | break; | |
168 | ||
169 | case 'r': /* reload */ | |
170 | reload = 1; | |
171 | ||
172 | break; | |
173 | ||
174 | case 'p': /* port number */ | |
175 | sscanf(optarg, "%d", &port); | |
176 | ||
177 | if (port < 1) | |
178 | port = CACHE_HTTP_PORT; /* default */ | |
179 | ||
180 | break; | |
181 | ||
182 | case 'P': | |
183 | put_file = xstrdup(optarg); | |
184 | ||
185 | break; | |
186 | ||
187 | case 'i': /* IMS */ | |
188 | ims = (time_t) atoi(optarg); | |
189 | ||
190 | break; | |
191 | ||
192 | case 'm': | |
193 | method = xstrdup(optarg); | |
194 | ||
195 | break; | |
196 | ||
197 | case 't': | |
198 | method = xstrdup("TRACE"); | |
199 | ||
200 | max_forwards = atoi(optarg); | |
201 | ||
202 | break; | |
203 | ||
204 | case 'g': | |
205 | ping = 1; | |
206 | ||
207 | pcount = atoi(optarg); | |
208 | ||
209 | to_stdout = 0; | |
210 | ||
211 | break; | |
212 | ||
213 | case 'I': | |
214 | if ((ping_int = atoi(optarg) * 1000) <= 0) | |
215 | usage(argv[0]); | |
216 | ||
217 | break; | |
218 | ||
219 | case 'H': | |
220 | if (strlen(optarg)) { | |
221 | char *t; | |
222 | strncpy(extra_hdrs, optarg, sizeof(extra_hdrs)); | |
223 | ||
224 | while ((t = strstr(extra_hdrs, "\\n"))) | |
225 | *t = '\r', *(t + 1) = '\n'; | |
226 | } | |
227 | ||
228 | break; | |
229 | ||
230 | case 'T': | |
231 | io_timeout = atoi(optarg); | |
232 | break; | |
233 | ||
234 | case 'u': | |
235 | proxy_user = optarg; | |
236 | break; | |
237 | ||
238 | case 'w': | |
239 | proxy_password = optarg; | |
240 | break; | |
241 | ||
242 | case 'U': | |
243 | www_user = optarg; | |
244 | break; | |
245 | ||
246 | case 'W': | |
247 | www_password = optarg; | |
248 | break; | |
249 | ||
250 | case 'v': | |
251 | /* undocumented: may increase verb-level by giving more -v's */ | |
252 | opt_verbose++; | |
253 | break; | |
254 | ||
255 | case '?': /* usage */ | |
256 | ||
257 | default: | |
258 | usage(argv[0]); | |
259 | break; | |
260 | } | |
090089c4 | 261 | } |
62e76326 | 262 | |
0ef0f1de | 263 | #ifdef _SQUID_MSWIN_ |
264 | { | |
62e76326 | 265 | WSADATA wsaData; |
266 | WSAStartup(2, &wsaData); | |
0ef0f1de | 267 | } |
268 | #endif | |
090089c4 | 269 | /* Build the HTTP request */ |
8a9b6b94 | 270 | if (strncmp(url, "mgr:", 4) == 0) { |
62e76326 | 271 | char *t = xstrdup(url + 4); |
272 | snprintf(url, BUFSIZ, "cache_object://%s/%s", hostname, t); | |
273 | xfree(t); | |
8a9b6b94 | 274 | } |
62e76326 | 275 | |
cca89eeb | 276 | if (put_file) { |
62e76326 | 277 | put_fd = open(put_file, O_RDONLY); |
278 | set_our_signal(); | |
279 | ||
280 | if (put_fd < 0) { | |
281 | fprintf(stderr, "%s: can't open file (%s)\n", argv[0], | |
282 | xstrerror()); | |
283 | exit(-1); | |
284 | } | |
285 | ||
ec4daaa5 | 286 | #ifdef _SQUID_WIN32_ |
62e76326 | 287 | setmode(put_fd, O_BINARY); |
288 | ||
c4aefe96 | 289 | #endif |
62e76326 | 290 | |
291 | fstat(put_fd, &sb); | |
cca89eeb | 292 | } |
62e76326 | 293 | |
042461c3 | 294 | snprintf(msg, BUFSIZ, "%s %s HTTP/1.0\r\n", method, url); |
62e76326 | 295 | |
090089c4 | 296 | if (reload) { |
62e76326 | 297 | snprintf(buf, BUFSIZ, "Pragma: no-cache\r\n"); |
298 | strcat(msg, buf); | |
234967c9 | 299 | } |
62e76326 | 300 | |
16300b58 | 301 | if (put_fd > 0) { |
62e76326 | 302 | snprintf(buf, BUFSIZ, "Content-length: %d\r\n", (int) sb.st_size); |
303 | strcat(msg, buf); | |
cca89eeb | 304 | } |
62e76326 | 305 | |
88738790 | 306 | if (opt_noaccept == 0) { |
62e76326 | 307 | snprintf(buf, BUFSIZ, "Accept: */*\r\n"); |
308 | strcat(msg, buf); | |
88738790 | 309 | } |
62e76326 | 310 | |
234967c9 | 311 | if (ims) { |
62e76326 | 312 | snprintf(buf, BUFSIZ, "If-Modified-Since: %s\r\n", mkrfc1123(ims)); |
313 | strcat(msg, buf); | |
090089c4 | 314 | } |
62e76326 | 315 | |
b3b64e58 | 316 | if (max_forwards > -1) { |
62e76326 | 317 | snprintf(buf, BUFSIZ, "Max-Forwards: %d\r\n", max_forwards); |
318 | strcat(msg, buf); | |
b3b64e58 | 319 | } |
62e76326 | 320 | |
a78886fc | 321 | if (proxy_user) { |
62e76326 | 322 | char *user = proxy_user; |
323 | char *password = proxy_password; | |
230c091c | 324 | #if HAVE_GETPASS |
62e76326 | 325 | |
326 | if (!password) | |
327 | password = getpass("Proxy password: "); | |
328 | ||
230c091c | 329 | #endif |
62e76326 | 330 | |
331 | if (!password) { | |
332 | fprintf(stderr, "ERROR: Proxy password missing\n"); | |
333 | exit(1); | |
334 | } | |
335 | ||
336 | snprintf(buf, BUFSIZ, "%s:%s", user, password); | |
a394841f | 337 | snprintf(buf, BUFSIZ, "Proxy-Authorization: Basic %s\r\n", base64_encode(buf)); |
62e76326 | 338 | strcat(msg, buf); |
a78886fc | 339 | } |
62e76326 | 340 | |
a78886fc | 341 | if (www_user) { |
62e76326 | 342 | char *user = www_user; |
343 | char *password = www_password; | |
230c091c | 344 | #if HAVE_GETPASS |
62e76326 | 345 | |
346 | if (!password) | |
347 | password = getpass("WWW password: "); | |
348 | ||
230c091c | 349 | #endif |
62e76326 | 350 | |
351 | if (!password) { | |
352 | fprintf(stderr, "ERROR: WWW password missing\n"); | |
353 | exit(1); | |
354 | } | |
355 | ||
356 | snprintf(buf, BUFSIZ, "%s:%s", user, password); | |
a394841f | 357 | snprintf(buf, BUFSIZ, "Authorization: Basic %s\r\n", base64_encode(buf)); |
62e76326 | 358 | strcat(msg, buf); |
a78886fc | 359 | } |
62e76326 | 360 | |
599eadbe | 361 | if (keep_alive) { |
62e76326 | 362 | if (port != 80) |
363 | snprintf(buf, BUFSIZ, "Proxy-Connection: keep-alive\r\n"); | |
364 | else | |
365 | snprintf(buf, BUFSIZ, "Connection: keep-alive\r\n"); | |
366 | ||
367 | strcat(msg, buf); | |
599eadbe | 368 | } |
62e76326 | 369 | |
63259c34 | 370 | strcat(msg, extra_hdrs); |
042461c3 | 371 | snprintf(buf, BUFSIZ, "\r\n"); |
234967c9 | 372 | strcat(msg, buf); |
090089c4 | 373 | |
63259c34 | 374 | if (opt_verbose) |
62e76326 | 375 | fprintf(stderr, "headers: '%s'\n", msg); |
63259c34 | 376 | |
899bab3f | 377 | if (ping) { |
378 | #if HAVE_SIGACTION | |
62e76326 | 379 | |
380 | struct sigaction sa, osa; | |
381 | ||
382 | if (sigaction(SIGINT, NULL, &osa) == 0 && osa.sa_handler == SIG_DFL) { | |
383 | sa.sa_handler = catchSignal; | |
384 | sa.sa_flags = 0; | |
385 | sigemptyset(&sa.sa_mask); | |
386 | (void) sigaction(SIGINT, &sa, NULL); | |
387 | } | |
388 | ||
899bab3f | 389 | #else |
62e76326 | 390 | void (*osig) (int); |
391 | ||
392 | if ((osig = signal(SIGINT, catchSignal)) != SIG_DFL) | |
393 | (void) signal(SIGINT, osig); | |
394 | ||
899bab3f | 395 | #endif |
62e76326 | 396 | |
899bab3f | 397 | } |
62e76326 | 398 | |
899bab3f | 399 | loops = ping ? pcount : 1; |
62e76326 | 400 | |
899bab3f | 401 | for (i = 0; loops == 0 || i < loops; i++) { |
62e76326 | 402 | int fsize = 0; |
403 | /* Connect to the server */ | |
404 | ||
405 | if ((conn = socket(PF_INET, SOCK_STREAM, 0)) < 0) { | |
406 | perror("client: socket"); | |
407 | exit(1); | |
408 | } | |
409 | ||
410 | if (localhost && client_comm_bind(conn, localhost) < 0) { | |
411 | perror("client: bind"); | |
412 | exit(1); | |
413 | } | |
414 | ||
415 | if (client_comm_connect(conn, hostname, port, ping ? &tv1 : NULL) < 0) { | |
416 | if (errno == 0) { | |
417 | fprintf(stderr, "client: ERROR: Cannot connect to %s:%d: Host unknown.\n", hostname, port); | |
418 | } else { | |
419 | char tbuf[BUFSIZ]; | |
420 | snprintf(tbuf, BUFSIZ, "client: ERROR: Cannot connect to %s:%d", | |
421 | hostname, port); | |
422 | perror(tbuf); | |
423 | } | |
424 | ||
425 | exit(1); | |
426 | } | |
427 | ||
428 | /* Send the HTTP request */ | |
0ef0f1de | 429 | #ifdef _SQUID_MSWIN_ |
411c6ea3 | 430 | bytesWritten = send(conn, (const void *) msg, strlen(msg), 0); |
62e76326 | 431 | |
0ef0f1de | 432 | #else |
62e76326 | 433 | |
434 | bytesWritten = mywrite(conn, msg, strlen(msg)); | |
435 | ||
0ef0f1de | 436 | #endif |
62e76326 | 437 | |
438 | if (bytesWritten < 0) { | |
439 | perror("client: ERROR: write"); | |
440 | exit(1); | |
441 | } else if ((unsigned) bytesWritten != strlen(msg)) { | |
442 | fprintf(stderr, "client: ERROR: Cannot send request?: %s\n", msg); | |
443 | exit(1); | |
444 | } | |
445 | ||
446 | if (put_file) { | |
447 | int x; | |
448 | lseek(put_fd, 0, SEEK_SET); | |
0ef0f1de | 449 | #ifdef _SQUID_MSWIN_ |
62e76326 | 450 | |
451 | while ((x = read(put_fd, buf, sizeof(buf))) > 0) { | |
452 | x = write(conn, buf, x); | |
0ef0f1de | 453 | #else |
62e76326 | 454 | |
455 | while ((x = myread(put_fd, buf, sizeof(buf))) > 0) { | |
456 | x = mywrite(conn, buf, x); | |
0ef0f1de | 457 | #endif |
62e76326 | 458 | |
459 | total_bytes += x; | |
460 | ||
461 | if (x <= 0) | |
462 | break; | |
463 | } | |
464 | ||
465 | if (x != 0) | |
466 | fprintf(stderr, "client: ERROR: Cannot send file.\n"); | |
467 | } | |
468 | ||
469 | /* Read the data */ | |
54220df8 | 470 | |
0ef0f1de | 471 | #ifdef _SQUID_MSWIN_ |
62e76326 | 472 | setmode(1, O_BINARY); |
473 | ||
411c6ea3 | 474 | while ((len = recv(conn, (void *) buf, sizeof(buf), 0)) > 0) { |
0ef0f1de | 475 | #else |
62e76326 | 476 | |
477 | while ((len = myread(conn, buf, sizeof(buf))) > 0) { | |
0ef0f1de | 478 | #endif |
62e76326 | 479 | fsize += len; |
480 | ||
481 | if (to_stdout) | |
482 | fwrite(buf, len, 1, stdout); | |
483 | } | |
484 | ||
0ef0f1de | 485 | #ifdef _SQUID_MSWIN_ |
62e76326 | 486 | setmode(1, O_TEXT); |
487 | ||
0ef0f1de | 488 | #endif |
62e76326 | 489 | |
490 | (void) close(conn); /* done with socket */ | |
491 | ||
492 | if (interrupted) | |
493 | break; | |
494 | ||
495 | if (ping) { | |
496 | ||
497 | struct tm *tmp; | |
498 | time_t t2s; | |
499 | long elapsed_msec; | |
500 | ||
501 | (void) Now(&tv2); | |
502 | elapsed_msec = tvSubMsec(tv1, tv2); | |
503 | t2s = tv2.tv_sec; | |
504 | tmp = localtime(&t2s); | |
505 | fprintf(stderr, "%d-%02d-%02d %02d:%02d:%02d [%d]: %ld.%03ld secs, %f KB/s\n", | |
506 | tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, | |
507 | tmp->tm_hour, tmp->tm_min, tmp->tm_sec, i + 1, | |
508 | elapsed_msec / 1000, elapsed_msec % 1000, | |
509 | elapsed_msec ? (double) fsize / elapsed_msec : -1.0); | |
510 | ||
511 | if (i == 0 || elapsed_msec < ping_min) | |
512 | ping_min = elapsed_msec; | |
513 | ||
514 | if (i == 0 || elapsed_msec > ping_max) | |
515 | ping_max = elapsed_msec; | |
516 | ||
517 | ping_sum += elapsed_msec; | |
518 | ||
519 | /* Delay until next "ping_int" boundary */ | |
520 | if ((loops == 0 || i + 1 < loops) && elapsed_msec < ping_int) { | |
521 | ||
522 | struct timeval tvs; | |
523 | long msec_left = ping_int - elapsed_msec; | |
524 | ||
525 | tvs.tv_sec = msec_left / 1000; | |
526 | tvs.tv_usec = (msec_left % 1000) * 1000; | |
527 | select(0, NULL, NULL, NULL, &tvs); | |
528 | } | |
529 | } | |
090089c4 | 530 | } |
899bab3f | 531 | |
532 | if (ping && i) { | |
62e76326 | 533 | ping_mean = ping_sum / i; |
534 | fprintf(stderr, "%d requests, round-trip (secs) min/avg/max = " | |
535 | "%ld.%03ld/%ld.%03ld/%ld.%03ld\n", i, | |
536 | ping_min / 1000, ping_min % 1000, ping_mean / 1000, ping_mean % 1000, | |
537 | ping_max / 1000, ping_max % 1000); | |
090089c4 | 538 | } |
62e76326 | 539 | |
090089c4 | 540 | exit(0); |
541 | /*NOTREACHED */ | |
983061ed | 542 | return 0; |
090089c4 | 543 | } |
544 | ||
2c08acd9 | 545 | static int |
62e76326 | 546 | client_comm_bind(int sock, const char *local_host) { |
547 | ||
2c08acd9 | 548 | static const struct hostent *hp = NULL; |
62e76326 | 549 | |
2c08acd9 | 550 | static struct sockaddr_in from_addr; |
551 | ||
552 | /* Set up the source socket address from which to send. */ | |
62e76326 | 553 | |
2c08acd9 | 554 | if (hp == NULL) { |
62e76326 | 555 | from_addr.sin_family = AF_INET; |
556 | ||
557 | if ((hp = gethostbyname(local_host)) == 0) { | |
558 | return (-1); | |
559 | } | |
2c08acd9 | 560 | |
62e76326 | 561 | xmemcpy(&from_addr.sin_addr, hp->h_addr, hp->h_length); |
562 | from_addr.sin_port = 0; | |
2c08acd9 | 563 | } |
62e76326 | 564 | |
2c08acd9 | 565 | return bind(sock, (struct sockaddr *) &from_addr, sizeof(struct sockaddr_in)); |
566 | } | |
567 | ||
b8d8561b | 568 | static int |
62e76326 | 569 | |
570 | client_comm_connect(int sock, const char *dest_host, u_short dest_port, struct timeval *tvp) { | |
571 | ||
899bab3f | 572 | static const struct hostent *hp = NULL; |
62e76326 | 573 | |
090089c4 | 574 | static struct sockaddr_in to_addr; |
575 | ||
576 | /* Set up the destination socket address for message to send to. */ | |
090089c4 | 577 | |
62e76326 | 578 | if (hp == NULL) |
579 | { | |
580 | to_addr.sin_family = AF_INET; | |
581 | ||
582 | if ((hp = gethostbyname(dest_host)) == 0) { | |
583 | return (-1); | |
584 | } | |
585 | ||
586 | xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length); | |
587 | to_addr.sin_port = htons(dest_port); | |
090089c4 | 588 | } |
62e76326 | 589 | |
899bab3f | 590 | if (tvp) |
62e76326 | 591 | (void) Now(tvp); |
592 | ||
090089c4 | 593 | return connect(sock, (struct sockaddr *) &to_addr, sizeof(struct sockaddr_in)); |
594 | } | |
899bab3f | 595 | |
596 | static int | |
62e76326 | 597 | |
598 | Now(struct timeval *tp) { | |
899bab3f | 599 | #if GETTIMEOFDAY_NO_TZP |
600 | return gettimeofday(tp); | |
601 | #else | |
62e76326 | 602 | |
899bab3f | 603 | return gettimeofday(tp, NULL); |
604 | #endif | |
605 | } /* ARGSUSED */ | |
606 | ||
607 | static void | |
62e76326 | 608 | catchSignal(int sig) { |
899bab3f | 609 | interrupted = 1; |
610 | fprintf(stderr, "Interrupted.\n"); | |
611 | } | |
b6c6bcef | 612 | |
5446b331 | 613 | static void |
62e76326 | 614 | pipe_handler(int sig) { |
b6c6bcef | 615 | fprintf(stderr, "SIGPIPE received.\n"); |
54220df8 | 616 | } |
617 | ||
618 | static void | |
62e76326 | 619 | set_our_signal(void) { |
54220df8 | 620 | #if HAVE_SIGACTION |
62e76326 | 621 | |
54220df8 | 622 | struct sigaction sa; |
623 | sa.sa_handler = pipe_handler; | |
624 | sa.sa_flags = SA_RESTART; | |
625 | sigemptyset(&sa.sa_mask); | |
62e76326 | 626 | |
54220df8 | 627 | if (sigaction(SIGPIPE, &sa, NULL) < 0) { |
62e76326 | 628 | fprintf(stderr, "Cannot set PIPE signal.\n"); |
629 | exit(-1); | |
54220df8 | 630 | } |
62e76326 | 631 | |
54220df8 | 632 | #else |
633 | signal(SIGPIPE, pipe_handler); | |
62e76326 | 634 | |
54220df8 | 635 | #endif |
636 | ||
637 | } | |
20cbfe5a | 638 | |
0ef0f1de | 639 | #ifndef _SQUID_MSWIN_ |
20cbfe5a | 640 | static ssize_t |
62e76326 | 641 | myread(int fd, void *buf, size_t len) { |
20cbfe5a | 642 | alarm(io_timeout); |
643 | return read(fd, buf, len); | |
644 | } | |
645 | ||
646 | static ssize_t | |
62e76326 | 647 | mywrite(int fd, void *buf, size_t len) { |
20cbfe5a | 648 | alarm(io_timeout); |
649 | return write(fd, buf, len); | |
650 | } | |
62e76326 | 651 | |
0ef0f1de | 652 | #endif |