fetch.c (63005) | fetch.c (63015) |
---|---|
1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/usr.bin/fetch/fetch.c 63005 2000-07-12 08:29:52Z des $ | 28 * $FreeBSD: head/usr.bin/fetch/fetch.c 63015 2000-07-12 11:02:01Z des $ |
29 */ 30 31#include <sys/param.h> 32#include <sys/stat.h> 33#include <sys/socket.h> 34 35#include <ctype.h> 36#include <err.h> --- 34 unchanged lines hidden (view full) --- 71int s_flag; /* -s: show size, don't fetch */ 72off_t S_size; /* -S: require size to match */ 73int t_flag; /*! -t: workaround TCP bug */ 74int v_level = 1; /* -v: verbosity level */ 75int v_tty; /* stdout is a tty */ 76u_int w_secs; /* -w: retry delay */ 77int family = PF_UNSPEC; /* -[46]: address family to use */ 78 | 29 */ 30 31#include <sys/param.h> 32#include <sys/stat.h> 33#include <sys/socket.h> 34 35#include <ctype.h> 36#include <err.h> --- 34 unchanged lines hidden (view full) --- 71int s_flag; /* -s: show size, don't fetch */ 72off_t S_size; /* -S: require size to match */ 73int t_flag; /*! -t: workaround TCP bug */ 74int v_level = 1; /* -v: verbosity level */ 75int v_tty; /* stdout is a tty */ 76u_int w_secs; /* -w: retry delay */ 77int family = PF_UNSPEC; /* -[46]: address family to use */ 78 |
79int sigalrm; /* SIGALRM received */ 80int sigint; /* SIGINT received */ |
|
79 80u_int ftp_timeout; /* default timeout for FTP transfers */ 81u_int http_timeout; /* default timeout for HTTP transfers */ 82u_char *buf; /* transfer buffer */ 83 84 85void 86sig_handler(int sig) 87{ | 81 82u_int ftp_timeout; /* default timeout for FTP transfers */ 83u_int http_timeout; /* default timeout for HTTP transfers */ 84u_char *buf; /* transfer buffer */ 85 86 87void 88sig_handler(int sig) 89{ |
88 errx(1, "Transfer timed out"); | 90 switch (sig) { 91 case SIGALRM: 92 sigalrm = 1; 93 break; 94 case SIGINT: 95 sigint = 1; 96 break; 97 } |
89} 90 91struct xferstat { 92 char name[40]; 93 struct timeval start; 94 struct timeval end; 95 struct timeval last; 96 off_t size; --- 117 unchanged lines hidden (view full) --- 214 if (strcmp(url->scheme, "http") == 0) { 215 if (d_flag) 216 strcat(flags, "d"); 217 if (A_flag) 218 strcat(flags, "A"); 219 timeout = T_secs ? T_secs : http_timeout; 220 } 221 | 98} 99 100struct xferstat { 101 char name[40]; 102 struct timeval start; 103 struct timeval end; 104 struct timeval last; 105 off_t size; --- 117 unchanged lines hidden (view full) --- 223 if (strcmp(url->scheme, "http") == 0) { 224 if (d_flag) 225 strcat(flags, "d"); 226 if (A_flag) 227 strcat(flags, "A"); 228 timeout = T_secs ? T_secs : http_timeout; 229 } 230 |
222 /* 223 * Set the protocol timeout. 224 * This currently only works for FTP, so we still use 225 * alarm(timeout) further down. 226 */ | 231 /* set the protocol timeout. */ |
227 fetchTimeout = timeout; 228 229 /* stat remote file */ | 232 fetchTimeout = timeout; 233 234 /* stat remote file */ |
230 alarm(timeout); | |
231 if (fetchStat(url, &us, flags) == -1) 232 warnx("%s: size not known", path); | 235 if (fetchStat(url, &us, flags) == -1) 236 warnx("%s: size not known", path); |
233 alarm(timeout); | |
234 235 /* just print size */ 236 if (s_flag) { 237 if (us.size == -1) 238 printf("Unknown\n"); 239 else 240 printf("%lld\n", us.size); 241 goto success; --- 56 unchanged lines hidden (view full) --- 298 unlink(path); 299 goto failure; 300 } 301 302 /* start the counter */ 303 stat_start(&xs, path, us.size, count); 304 305 n = 0; | 237 238 /* just print size */ 239 if (s_flag) { 240 if (us.size == -1) 241 printf("Unknown\n"); 242 else 243 printf("%lld\n", us.size); 244 goto success; --- 56 unchanged lines hidden (view full) --- 301 unlink(path); 302 goto failure; 303 } 304 305 /* start the counter */ 306 stat_start(&xs, path, us.size, count); 307 308 n = 0; |
306 | 309 sigint = sigalrm = 0; |
307 if (us.size == -1) { 308 /* 309 * We have no idea how much data to expect, so do it byte by 310 * byte. This is incredibly inefficient, but there's not much 311 * we can do about it... :( 312 */ | 310 if (us.size == -1) { 311 /* 312 * We have no idea how much data to expect, so do it byte by 313 * byte. This is incredibly inefficient, but there's not much 314 * we can do about it... :( 315 */ |
313 while (1) { | 316 while (!sigint && !sigalrm) { |
314 if (timeout) 315 alarm(timeout); 316#ifdef STDIO_HACK 317 /* 318 * This is a non-portable hack, but it makes things go 319 * faster. Basically, if there is data in the input file's 320 * buffer, write it out; then fall through to the fgetc() 321 * which forces a refill. It saves a memcpy() and reduces --- 12 unchanged lines hidden (view full) --- 334#endif 335 if ((ch = fgetc(f)) == EOF || fputc(ch, of) == EOF) 336 break; 337 stat_update(&xs, count++); 338 n++; 339 } 340 } else { 341 /* we know exactly how much to transfer, so do it efficiently */ | 317 if (timeout) 318 alarm(timeout); 319#ifdef STDIO_HACK 320 /* 321 * This is a non-portable hack, but it makes things go 322 * faster. Basically, if there is data in the input file's 323 * buffer, write it out; then fall through to the fgetc() 324 * which forces a refill. It saves a memcpy() and reduces --- 12 unchanged lines hidden (view full) --- 337#endif 338 if ((ch = fgetc(f)) == EOF || fputc(ch, of) == EOF) 339 break; 340 stat_update(&xs, count++); 341 n++; 342 } 343 } else { 344 /* we know exactly how much to transfer, so do it efficiently */ |
342 for (size = B_size; count != us.size; n++) { | 345 for (size = B_size; count != us.size && !sigint && !sigalrm; n++) { |
343 if (us.size - count < B_size) 344 size = us.size - count; 345 if (timeout) 346 alarm(timeout); 347 if ((size = fread(buf, 1, size, f)) <= 0) 348 break; 349 stat_update(&xs, count += size); 350 if (fwrite(buf, size, 1, of) != 1) 351 break; 352 } 353 } | 346 if (us.size - count < B_size) 347 size = us.size - count; 348 if (timeout) 349 alarm(timeout); 350 if ((size = fread(buf, 1, size, f)) <= 0) 351 break; 352 stat_update(&xs, count += size); 353 if (fwrite(buf, size, 1, of) != 1) 354 break; 355 } 356 } |
354 | 357 |
355 if (timeout) 356 alarm(0); 357 358 stat_end(&xs); | 358 if (timeout) 359 alarm(0); 360 361 stat_end(&xs); |
359 | 362 |
360 /* check the status of our files */ 361 if (ferror(f)) 362 warn("%s", URL); 363 if (ferror(of)) 364 warn("%s", path); 365 if (ferror(f) || ferror(of)) { 366 if (!R_flag && !r_flag && !o_stdout) 367 unlink(path); --- 12 unchanged lines hidden (view full) --- 380 381 tv[0].tv_sec = (long)us.atime; 382 tv[1].tv_sec = (long)us.mtime; 383 tv[0].tv_usec = tv[1].tv_usec = 0; 384 if (utimes(path, tv)) 385 warn("%s: utimes()", path); 386 } 387 | 363 /* check the status of our files */ 364 if (ferror(f)) 365 warn("%s", URL); 366 if (ferror(of)) 367 warn("%s", path); 368 if (ferror(f) || ferror(of)) { 369 if (!R_flag && !r_flag && !o_stdout) 370 unlink(path); --- 12 unchanged lines hidden (view full) --- 383 384 tv[0].tv_sec = (long)us.atime; 385 tv[1].tv_sec = (long)us.mtime; 386 tv[0].tv_usec = tv[1].tv_usec = 0; 387 if (utimes(path, tv)) 388 warn("%s: utimes()", path); 389 } 390 |
388 /* check the file size */ 389 if (us.size != -1 && count < us.size) { | 391 /* did the transfer complete normally? */ 392 if (sigalrm) 393 warnx("transfer timed out"); 394 else if (sigint) 395 warnx("transfer interrupted"); 396 else if (us.size != -1 && count < us.size) { |
390 warnx("%s appears to be truncated: %lld/%lld bytes", 391 path, count, us.size); 392 goto failure; 393 } 394 395 success: | 397 warnx("%s appears to be truncated: %lld/%lld bytes", 398 path, count, us.size); 399 goto failure; 400 } 401 402 success: |
396 r = 0; | 403 r = (!sigalrm && !sigint); |
397 goto done; 398 failure: 399 r = -1; 400 goto done; 401 done: 402 if (f) 403 fclose(f); 404 if (of && of != stdout) --- 176 unchanged lines hidden (view full) --- 581 } 582 if ((s = getenv("HTTP_TIMEOUT")) != NULL) { 583 if (parseint(s, &http_timeout) == -1) { 584 warnx("HTTP_TIMEOUT is not a positive integer"); 585 http_timeout = 0; 586 } 587 } 588 | 404 goto done; 405 failure: 406 r = -1; 407 goto done; 408 done: 409 if (f) 410 fclose(f); 411 if (of && of != stdout) --- 176 unchanged lines hidden (view full) --- 588 } 589 if ((s = getenv("HTTP_TIMEOUT")) != NULL) { 590 if (parseint(s, &http_timeout) == -1) { 591 warnx("HTTP_TIMEOUT is not a positive integer"); 592 http_timeout = 0; 593 } 594 } 595 |
596 /* interrupt handling */ 597 signal(SIGINT, sig_handler); 598 |
|
589 /* output file */ 590 if (o_flag) { 591 if (strcmp(o_filename, "-") == 0) { 592 o_stdout = 1; 593 } else if (stat(o_filename, &sb) == -1) { 594 if (errno == ENOENT) { 595 if (argc > 1) 596 errx(EX_USAGE, "%s is not a directory", o_filename); --- 30 unchanged lines hidden (view full) --- 627 free(q); 628 } else { 629 e = fetch(*argv, o_filename); 630 } 631 } else { 632 e = fetch(*argv, p); 633 } 634 | 599 /* output file */ 600 if (o_flag) { 601 if (strcmp(o_filename, "-") == 0) { 602 o_stdout = 1; 603 } else if (stat(o_filename, &sb) == -1) { 604 if (errno == ENOENT) { 605 if (argc > 1) 606 errx(EX_USAGE, "%s is not a directory", o_filename); --- 30 unchanged lines hidden (view full) --- 637 free(q); 638 } else { 639 e = fetch(*argv, o_filename); 640 } 641 } else { 642 e = fetch(*argv, p); 643 } 644 |
645 if (sigint) 646 exit(1); 647 |
|
635 if (e == 0 && once_flag) 636 exit(0); 637 638 if (e) { 639 r = 1; 640 if ((fetchLastErrCode 641 && fetchLastErrCode != FETCH_UNAVAIL 642 && fetchLastErrCode != FETCH_MOVED --- 19 unchanged lines hidden --- | 648 if (e == 0 && once_flag) 649 exit(0); 650 651 if (e) { 652 r = 1; 653 if ((fetchLastErrCode 654 && fetchLastErrCode != FETCH_UNAVAIL 655 && fetchLastErrCode != FETCH_MOVED --- 19 unchanged lines hidden --- |