ftp.c (84203) | ftp.c (85093) |
---|---|
1/*- 2 * Copyright (c) 1998 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 --- 13 unchanged lines hidden (view full) --- 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 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1998 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 --- 13 unchanged lines hidden (view full) --- 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 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/lib/libfetch/ftp.c 84203 2001-09-30 21:36:09Z dillon $"); | 30__FBSDID("$FreeBSD: head/lib/libfetch/ftp.c 85093 2001-10-18 08:29:26Z des $"); |
31 32/* 33 * Portions of this code were taken from or based on ftpio.c: 34 * 35 * ---------------------------------------------------------------------------- 36 * "THE BEER-WARE LICENSE" (Revision 42): 37 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 38 * can do whatever you want with this stuff. If we meet some day, and you think --- 223 unchanged lines hidden (view full) --- 262 us->size = us->size * 10 + *ln - '0'; 263 if (*ln && !isspace(*ln)) { 264 _ftp_seterr(FTP_PROTOCOL_ERROR); 265 us->size = -1; 266 return -1; 267 } 268 if (us->size == 0) 269 us->size = -1; | 31 32/* 33 * Portions of this code were taken from or based on ftpio.c: 34 * 35 * ---------------------------------------------------------------------------- 36 * "THE BEER-WARE LICENSE" (Revision 42): 37 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 38 * can do whatever you want with this stuff. If we meet some day, and you think --- 223 unchanged lines hidden (view full) --- 262 us->size = us->size * 10 + *ln - '0'; 263 if (*ln && !isspace(*ln)) { 264 _ftp_seterr(FTP_PROTOCOL_ERROR); 265 us->size = -1; 266 return -1; 267 } 268 if (us->size == 0) 269 us->size = -1; |
270 DEBUG(fprintf(stderr, "size: [\033[1m%lld\033[m]\n", us->size)); | 270 DEBUG(fprintf(stderr, "size: [\033[1m%lld\033[m]\n", (long long)us->size)); |
271 272 if ((e = _ftp_cmd(cd, "MDTM %s", s)) != FTP_FILE_STATUS) { 273 _ftp_seterr(e); 274 return -1; 275 } 276 for (ln = last_reply + 4; *ln && isspace(*ln); ln++) 277 /* nothing */ ; 278 switch (strspn(ln, "0123456789")) { --- 101 unchanged lines hidden (view full) --- 380 if (w >= 0) 381 return w; 382 if (errno != EINTR) 383 io->err = errno; 384 return -1; 385} 386 387static fpos_t | 271 272 if ((e = _ftp_cmd(cd, "MDTM %s", s)) != FTP_FILE_STATUS) { 273 _ftp_seterr(e); 274 return -1; 275 } 276 for (ln = last_reply + 4; *ln && isspace(*ln); ln++) 277 /* nothing */ ; 278 switch (strspn(ln, "0123456789")) { --- 101 unchanged lines hidden (view full) --- 380 if (w >= 0) 381 return w; 382 if (errno != EINTR) 383 io->err = errno; 384 return -1; 385} 386 387static fpos_t |
388_ftp_seekfn(void *v, fpos_t pos, int whence) | 388_ftp_seekfn(void *v, fpos_t pos __unused, int whence __unused) |
389{ 390 struct ftpio *io; 391 392 io = (struct ftpio *)v; 393 if (io == NULL) { 394 errno = EBADF; 395 return -1; 396 } --- 48 unchanged lines hidden (view full) --- 445 446/* 447 * Transfer file 448 */ 449static FILE * 450_ftp_transfer(int cd, const char *oper, const char *file, 451 int mode, off_t offset, const char *flags) 452{ | 389{ 390 struct ftpio *io; 391 392 io = (struct ftpio *)v; 393 if (io == NULL) { 394 errno = EBADF; 395 return -1; 396 } --- 48 unchanged lines hidden (view full) --- 445 446/* 447 * Transfer file 448 */ 449static FILE * 450_ftp_transfer(int cd, const char *oper, const char *file, 451 int mode, off_t offset, const char *flags) 452{ |
453 struct sockaddr_storage sin; | 453 struct sockaddr_storage sa; |
454 struct sockaddr_in6 *sin6; 455 struct sockaddr_in *sin4; 456 int low, pasv, verbose; 457 int e, sd = -1; 458 socklen_t l; 459 char *s; 460 FILE *df; 461 462 /* check flags */ 463 low = CHECK_FLAG('l'); 464 pasv = CHECK_FLAG('p'); 465 verbose = CHECK_FLAG('v'); 466 467 /* passive mode */ 468 if (!pasv) 469 pasv = ((s = getenv("FTP_PASSIVE_MODE")) != NULL && 470 strncasecmp(s, "no", 2) != 0); 471 472 /* find our own address, bind, and listen */ | 454 struct sockaddr_in6 *sin6; 455 struct sockaddr_in *sin4; 456 int low, pasv, verbose; 457 int e, sd = -1; 458 socklen_t l; 459 char *s; 460 FILE *df; 461 462 /* check flags */ 463 low = CHECK_FLAG('l'); 464 pasv = CHECK_FLAG('p'); 465 verbose = CHECK_FLAG('v'); 466 467 /* passive mode */ 468 if (!pasv) 469 pasv = ((s = getenv("FTP_PASSIVE_MODE")) != NULL && 470 strncasecmp(s, "no", 2) != 0); 471 472 /* find our own address, bind, and listen */ |
473 l = sizeof sin; 474 if (getsockname(cd, (struct sockaddr *)&sin, &l) == -1) | 473 l = sizeof sa; 474 if (getsockname(cd, (struct sockaddr *)&sa, &l) == -1) |
475 goto sysouch; | 475 goto sysouch; |
476 if (sin.ss_family == AF_INET6) 477 unmappedaddr((struct sockaddr_in6 *)&sin); | 476 if (sa.ss_family == AF_INET6) 477 unmappedaddr((struct sockaddr_in6 *)&sa); |
478 479 /* open data socket */ | 478 479 /* open data socket */ |
480 if ((sd = socket(sin.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { | 480 if ((sd = socket(sa.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { |
481 _fetch_syserr(); 482 return NULL; 483 } 484 485 if (pasv) { 486 u_char addr[64]; 487 char *ln, *p; | 481 _fetch_syserr(); 482 return NULL; 483 } 484 485 if (pasv) { 486 u_char addr[64]; 487 char *ln, *p; |
488 int i; | 488 unsigned int i; |
489 int port; 490 491 /* send PASV command */ 492 if (verbose) 493 _fetch_info("setting passive mode"); | 489 int port; 490 491 /* send PASV command */ 492 if (verbose) 493 _fetch_info("setting passive mode"); |
494 switch (sin.ss_family) { | 494 switch (sa.ss_family) { |
495 case AF_INET: 496 if ((e = _ftp_cmd(cd, "PASV")) != FTP_PASSIVE_MODE) 497 goto ouch; 498 break; 499 case AF_INET6: 500 if ((e = _ftp_cmd(cd, "EPSV")) != FTP_EPASSIVE_MODE) { 501 if (e == -1) 502 goto ouch; --- 47 unchanged lines hidden (view full) --- 550 } 551 552 /* seek to required offset */ 553 if (offset) 554 if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) 555 goto sysouch; 556 557 /* construct sockaddr for data socket */ | 495 case AF_INET: 496 if ((e = _ftp_cmd(cd, "PASV")) != FTP_PASSIVE_MODE) 497 goto ouch; 498 break; 499 case AF_INET6: 500 if ((e = _ftp_cmd(cd, "EPSV")) != FTP_EPASSIVE_MODE) { 501 if (e == -1) 502 goto ouch; --- 47 unchanged lines hidden (view full) --- 550 } 551 552 /* seek to required offset */ 553 if (offset) 554 if (_ftp_cmd(cd, "REST %lu", (u_long)offset) != FTP_FILE_OK) 555 goto sysouch; 556 557 /* construct sockaddr for data socket */ |
558 l = sizeof sin; 559 if (getpeername(cd, (struct sockaddr *)&sin, &l) == -1) | 558 l = sizeof sa; 559 if (getpeername(cd, (struct sockaddr *)&sa, &l) == -1) |
560 goto sysouch; | 560 goto sysouch; |
561 if (sin.ss_family == AF_INET6) 562 unmappedaddr((struct sockaddr_in6 *)&sin); 563 switch (sin.ss_family) { | 561 if (sa.ss_family == AF_INET6) 562 unmappedaddr((struct sockaddr_in6 *)&sa); 563 switch (sa.ss_family) { |
564 case AF_INET6: | 564 case AF_INET6: |
565 sin6 = (struct sockaddr_in6 *)&sin; | 565 sin6 = (struct sockaddr_in6 *)&sa; |
566 if (e == FTP_EPASSIVE_MODE) 567 sin6->sin6_port = htons(port); 568 else { 569 bcopy(addr + 2, (char *)&sin6->sin6_addr, 16); 570 bcopy(addr + 19, (char *)&sin6->sin6_port, 2); 571 } 572 break; 573 case AF_INET: | 566 if (e == FTP_EPASSIVE_MODE) 567 sin6->sin6_port = htons(port); 568 else { 569 bcopy(addr + 2, (char *)&sin6->sin6_addr, 16); 570 bcopy(addr + 19, (char *)&sin6->sin6_port, 2); 571 } 572 break; 573 case AF_INET: |
574 sin4 = (struct sockaddr_in *)&sin; | 574 sin4 = (struct sockaddr_in *)&sa; |
575 if (e == FTP_EPASSIVE_MODE) 576 sin4->sin_port = htons(port); 577 else { 578 bcopy(addr, (char *)&sin4->sin_addr, 4); 579 bcopy(addr + 4, (char *)&sin4->sin_port, 2); 580 } 581 break; 582 default: 583 e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ 584 break; 585 } 586 587 /* connect to data port */ 588 if (verbose) 589 _fetch_info("opening data connection"); | 575 if (e == FTP_EPASSIVE_MODE) 576 sin4->sin_port = htons(port); 577 else { 578 bcopy(addr, (char *)&sin4->sin_addr, 4); 579 bcopy(addr + 4, (char *)&sin4->sin_port, 2); 580 } 581 break; 582 default: 583 e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ 584 break; 585 } 586 587 /* connect to data port */ 588 if (verbose) 589 _fetch_info("opening data connection"); |
590 if (connect(sd, (struct sockaddr *)&sin, sin.ss_len) == -1) | 590 if (connect(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) |
591 goto sysouch; 592 593 /* make the server initiate the transfer */ 594 if (verbose) 595 _fetch_info("initiating transfer"); 596 e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); 597 if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) 598 goto ouch; 599 600 } else { 601 u_int32_t a; 602 u_short p; 603 int arg, d; 604 char *ap; 605 char hname[INET6_ADDRSTRLEN]; 606 | 591 goto sysouch; 592 593 /* make the server initiate the transfer */ 594 if (verbose) 595 _fetch_info("initiating transfer"); 596 e = _ftp_cmd(cd, "%s %s", oper, _ftp_filename(file)); 597 if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) 598 goto ouch; 599 600 } else { 601 u_int32_t a; 602 u_short p; 603 int arg, d; 604 char *ap; 605 char hname[INET6_ADDRSTRLEN]; 606 |
607 switch (sin.ss_family) { | 607 switch (sa.ss_family) { |
608 case AF_INET6: | 608 case AF_INET6: |
609 ((struct sockaddr_in6 *)&sin)->sin6_port = 0; | 609 ((struct sockaddr_in6 *)&sa)->sin6_port = 0; |
610#ifdef IPV6_PORTRANGE 611 arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH; 612 if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE, 613 (char *)&arg, sizeof(arg)) == -1) 614 goto sysouch; 615#endif 616 break; 617 case AF_INET: | 610#ifdef IPV6_PORTRANGE 611 arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH; 612 if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE, 613 (char *)&arg, sizeof(arg)) == -1) 614 goto sysouch; 615#endif 616 break; 617 case AF_INET: |
618 ((struct sockaddr_in *)&sin)->sin_port = 0; | 618 ((struct sockaddr_in *)&sa)->sin_port = 0; |
619 arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH; 620 if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, 621 (char *)&arg, sizeof arg) == -1) 622 goto sysouch; 623 break; 624 } 625 if (verbose) 626 _fetch_info("binding data socket"); | 619 arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH; 620 if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, 621 (char *)&arg, sizeof arg) == -1) 622 goto sysouch; 623 break; 624 } 625 if (verbose) 626 _fetch_info("binding data socket"); |
627 if (bind(sd, (struct sockaddr *)&sin, sin.ss_len) == -1) | 627 if (bind(sd, (struct sockaddr *)&sa, sa.ss_len) == -1) |
628 goto sysouch; 629 if (listen(sd, 1) == -1) 630 goto sysouch; 631 632 /* find what port we're on and tell the server */ | 628 goto sysouch; 629 if (listen(sd, 1) == -1) 630 goto sysouch; 631 632 /* find what port we're on and tell the server */ |
633 if (getsockname(sd, (struct sockaddr *)&sin, &l) == -1) | 633 if (getsockname(sd, (struct sockaddr *)&sa, &l) == -1) |
634 goto sysouch; | 634 goto sysouch; |
635 switch (sin.ss_family) { | 635 switch (sa.ss_family) { |
636 case AF_INET: | 636 case AF_INET: |
637 sin4 = (struct sockaddr_in *)&sin; | 637 sin4 = (struct sockaddr_in *)&sa; |
638 a = ntohl(sin4->sin_addr.s_addr); 639 p = ntohs(sin4->sin_port); 640 e = _ftp_cmd(cd, "PORT %d,%d,%d,%d,%d,%d", 641 (a >> 24) & 0xff, (a >> 16) & 0xff, 642 (a >> 8) & 0xff, a & 0xff, 643 (p >> 8) & 0xff, p & 0xff); 644 break; 645 case AF_INET6: 646#define UC(b) (((int)b)&0xff) 647 e = -1; | 638 a = ntohl(sin4->sin_addr.s_addr); 639 p = ntohs(sin4->sin_port); 640 e = _ftp_cmd(cd, "PORT %d,%d,%d,%d,%d,%d", 641 (a >> 24) & 0xff, (a >> 16) & 0xff, 642 (a >> 8) & 0xff, a & 0xff, 643 (p >> 8) & 0xff, p & 0xff); 644 break; 645 case AF_INET6: 646#define UC(b) (((int)b)&0xff) 647 e = -1; |
648 sin6 = (struct sockaddr_in6 *)&sin; 649 if (getnameinfo((struct sockaddr *)&sin, sin.ss_len, | 648 sin6 = (struct sockaddr_in6 *)&sa; 649 if (getnameinfo((struct sockaddr *)&sa, sa.ss_len, |
650 hname, sizeof(hname), 651 NULL, 0, NI_NUMERICHOST) == 0) { 652 e = _ftp_cmd(cd, "EPRT |%d|%s|%d|", 2, hname, 653 htons(sin6->sin6_port)); 654 if (e == -1) 655 goto ouch; 656 } 657 if (e != FTP_OK) { --- 55 unchanged lines hidden (view full) --- 713} 714 715/* 716 * Authenticate 717 */ 718static int 719_ftp_authenticate(int cd, struct url *url, struct url *purl) 720{ | 650 hname, sizeof(hname), 651 NULL, 0, NI_NUMERICHOST) == 0) { 652 e = _ftp_cmd(cd, "EPRT |%d|%s|%d|", 2, hname, 653 htons(sin6->sin6_port)); 654 if (e == -1) 655 goto ouch; 656 } 657 if (e != FTP_OK) { --- 55 unchanged lines hidden (view full) --- 713} 714 715/* 716 * Authenticate 717 */ 718static int 719_ftp_authenticate(int cd, struct url *url, struct url *purl) 720{ |
721 char *user, *pwd, *logname; | 721 const char *user, *pwd, *logname; |
722 char pbuf[MAXHOSTNAMELEN + MAXLOGNAME + 1]; 723 int e, len; 724 725 /* XXX FTP_AUTH, and maybe .netrc */ 726 727 /* send user name and password */ 728 user = url->user; 729 if (!user || !*user) --- 293 unchanged lines hidden (view full) --- 1023 /* stat file */ 1024 return _ftp_stat(cd, url->doc, us); 1025} 1026 1027/* 1028 * List a directory 1029 */ 1030struct url_ent * | 722 char pbuf[MAXHOSTNAMELEN + MAXLOGNAME + 1]; 723 int e, len; 724 725 /* XXX FTP_AUTH, and maybe .netrc */ 726 727 /* send user name and password */ 728 user = url->user; 729 if (!user || !*user) --- 293 unchanged lines hidden (view full) --- 1023 /* stat file */ 1024 return _ftp_stat(cd, url->doc, us); 1025} 1026 1027/* 1028 * List a directory 1029 */ 1030struct url_ent * |
1031fetchListFTP(struct url *url, const char *flags) | 1031fetchListFTP(struct url *url __unused, const char *flags __unused) |
1032{ 1033 warnx("fetchListFTP(): not implemented"); 1034 return NULL; 1035} | 1032{ 1033 warnx("fetchListFTP(): not implemented"); 1034 return NULL; 1035} |