ftpio.c (60051) | ftpio.c (62649) |
---|---|
1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * 9 * Major Changelog: 10 * 11 * Jordan K. Hubbard 12 * 17 Jan 1996 13 * 14 * Turned inside out. Now returns xfers as new file ids, not as a special 15 * `state' of FTP_t 16 * | 1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * 9 * Major Changelog: 10 * 11 * Jordan K. Hubbard 12 * 17 Jan 1996 13 * 14 * Turned inside out. Now returns xfers as new file ids, not as a special 15 * `state' of FTP_t 16 * |
17 * $FreeBSD: head/lib/libftpio/ftpio.c 60051 2000-05-05 17:02:32Z billf $ | 17 * $FreeBSD: head/lib/libftpio/ftpio.c 62649 2000-07-05 19:34:43Z ume $ |
18 * 19 */ 20 21#include <sys/types.h> 22#include <sys/socket.h> 23 24#include <netinet/in.h> 25 --- 27 unchanged lines hidden (view full) --- 53static int ftp_read_method(void *n, char *buf, int nbytes); 54static int ftp_write_method(void *n, const char *buf, int nbytes); 55static int ftp_close_method(void *n); 56static int writes(int fd, char *s); 57static __inline char *get_a_line(FTP_t ftp); 58static int get_a_number(FTP_t ftp, char **q); 59static int botch(char *func, char *botch_state); 60static int cmd(FTP_t ftp, const char *fmt, ...); | 18 * 19 */ 20 21#include <sys/types.h> 22#include <sys/socket.h> 23 24#include <netinet/in.h> 25 --- 27 unchanged lines hidden (view full) --- 53static int ftp_read_method(void *n, char *buf, int nbytes); 54static int ftp_write_method(void *n, const char *buf, int nbytes); 55static int ftp_close_method(void *n); 56static int writes(int fd, char *s); 57static __inline char *get_a_line(FTP_t ftp); 58static int get_a_number(FTP_t ftp, char **q); 59static int botch(char *func, char *botch_state); 60static int cmd(FTP_t ftp, const char *fmt, ...); |
61static int ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int verbose); | 61static int ftp_login_session(FTP_t ftp, char *host, int af, char *user, char *passwd, int port, int verbose); |
62static int ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto); 63static int ftp_close(FTP_t ftp); 64static int get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ret); 65static void ftp_timeout(int sig); 66static void ftp_set_timeout(void); 67static void ftp_clear_timeout(void); | 62static int ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto); 63static int ftp_close(FTP_t ftp); 64static int get_url_info(char *url_in, char *host_ret, int *port_ret, char *name_ret); 65static void ftp_timeout(int sig); 66static void ftp_set_timeout(void); 67static void ftp_clear_timeout(void); |
68static void ai_unmapped(struct addrinfo *); |
|
68 69 70/* Global status variable - ick */ 71int FtpTimedOut; 72 73/* FTP happy status codes */ 74#define FTP_GENERALLY_HAPPY 200 75#define FTP_ASCII_HAPPY FTP_GENERALLY_HAPPY 76#define FTP_BINARY_HAPPY FTP_GENERALLY_HAPPY 77#define FTP_PORT_HAPPY FTP_GENERALLY_HAPPY 78#define FTP_HAPPY_COMMENT 220 79#define FTP_QUIT_HAPPY 221 80#define FTP_TRANSFER_HAPPY 226 81#define FTP_PASSIVE_HAPPY 227 | 69 70 71/* Global status variable - ick */ 72int FtpTimedOut; 73 74/* FTP happy status codes */ 75#define FTP_GENERALLY_HAPPY 200 76#define FTP_ASCII_HAPPY FTP_GENERALLY_HAPPY 77#define FTP_BINARY_HAPPY FTP_GENERALLY_HAPPY 78#define FTP_PORT_HAPPY FTP_GENERALLY_HAPPY 79#define FTP_HAPPY_COMMENT 220 80#define FTP_QUIT_HAPPY 221 81#define FTP_TRANSFER_HAPPY 226 82#define FTP_PASSIVE_HAPPY 227 |
83#define FTP_LPASSIVE_HAPPY 228 84#define FTP_EPASSIVE_HAPPY 229 |
|
82#define FTP_CHDIR_HAPPY 250 83 84/* FTP unhappy status codes */ 85#define FTP_TIMED_OUT 421 86 87/* 88 * XXX 89 * gross! evil! bad! We really need an access primitive for cookie in stdio itself. --- 172 unchanged lines hidden (view full) --- 262 return fp2; 263 return NULL; 264} 265 266/* Returns a standard FILE pointer type representing an open control connection */ 267FILE * 268ftpLogin(char *host, char *user, char *passwd, int port, int verbose, int *retcode) 269{ | 85#define FTP_CHDIR_HAPPY 250 86 87/* FTP unhappy status codes */ 88#define FTP_TIMED_OUT 421 89 90/* 91 * XXX 92 * gross! evil! bad! We really need an access primitive for cookie in stdio itself. --- 172 unchanged lines hidden (view full) --- 265 return fp2; 266 return NULL; 267} 268 269/* Returns a standard FILE pointer type representing an open control connection */ 270FILE * 271ftpLogin(char *host, char *user, char *passwd, int port, int verbose, int *retcode) 272{ |
273#ifdef INET6 274 return ftpLoginAf(host, AF_UNSPEC, user, passwd, port, verbose, retcode); 275#else 276 return ftpLoginAf(host, AF_INET, user, passwd, port, verbose, retcode); 277#endif 278} 279 280FILE * 281ftpLoginAf(char *host, int af, char *user, char *passwd, int port, int verbose, int *retcode) 282{ |
|
270 FTP_t n; 271 FILE *fp; 272 273 if (retcode) 274 *retcode = 0; 275 if (networkInit() != SUCCESS) 276 return NULL; 277 278 n = ftp_new(); 279 fp = NULL; | 283 FTP_t n; 284 FILE *fp; 285 286 if (retcode) 287 *retcode = 0; 288 if (networkInit() != SUCCESS) 289 return NULL; 290 291 n = ftp_new(); 292 fp = NULL; |
280 if (n && ftp_login_session(n, host, user, passwd, port, verbose) == SUCCESS) { | 293 if (n && ftp_login_session(n, host, af, user, passwd, port, verbose) == SUCCESS) { |
281 fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */ 282 fp->_file = n->fd_ctrl; 283 } 284 if (retcode) { 285 if (!n) 286 *retcode = (FtpTimedOut ? FTP_TIMED_OUT : -1); 287 /* Poor attempt at mapping real errnos to FTP error codes */ 288 else switch(n->error) { --- 29 unchanged lines hidden (view full) --- 318int 319ftpPassive(FILE *fp, int st) 320{ 321 FTP_t ftp = fcookie(fp); 322 int i; 323 324 if (ftp->is_passive == st) 325 return SUCCESS; | 294 fp = funopen(n, ftp_read_method, ftp_write_method, NULL, ftp_close_method); /* BSD 4.4 function! */ 295 fp->_file = n->fd_ctrl; 296 } 297 if (retcode) { 298 if (!n) 299 *retcode = (FtpTimedOut ? FTP_TIMED_OUT : -1); 300 /* Poor attempt at mapping real errnos to FTP error codes */ 301 else switch(n->error) { --- 29 unchanged lines hidden (view full) --- 331int 332ftpPassive(FILE *fp, int st) 333{ 334 FTP_t ftp = fcookie(fp); 335 int i; 336 337 if (ftp->is_passive == st) 338 return SUCCESS; |
326 i = cmd(ftp, "PASV"); 327 if (i < 0) 328 return i; 329 if (i != FTP_PASSIVE_HAPPY) 330 return FAILURE; | 339 switch (ftp->addrtype) { 340 case AF_INET: 341 i = cmd(ftp, "PASV"); 342 if (i < 0) 343 return i; 344 if (i != FTP_PASSIVE_HAPPY) 345 return FAILURE; 346 break; 347 case AF_INET6: 348 i = cmd(ftp, "EPSV"); 349 if (i < 0) 350 return i; 351 if (i != FTP_EPASSIVE_HAPPY) { 352 i = cmd(ftp, "LPSV"); 353 if (i < 0) 354 return i; 355 if (i != FTP_LPASSIVE_HAPPY) 356 return FAILURE; 357 } 358 break; 359 } |
331 ftp->is_passive = !ftp->is_passive; 332 return SUCCESS; 333} 334 335FILE * 336ftpGetURL(char *url, char *user, char *passwd, int *retcode) 337{ | 360 ftp->is_passive = !ftp->is_passive; 361 return SUCCESS; 362} 363 364FILE * 365ftpGetURL(char *url, char *user, char *passwd, int *retcode) 366{ |
367#ifdef INET6 368 return ftpGetURLAf(url, AF_UNSPEC, user, passwd, retcode); 369#else 370 return ftpGetURLAf(url, AF_INET, user, passwd, retcode); 371#endif 372} 373 374FILE * 375ftpGetURLAf(char *url, int af, char *user, char *passwd, int *retcode) 376{ |
|
338 char host[255], name[255]; 339 int port; 340 FILE *fp2; 341 static FILE *fp = NULL; 342 static char *prev_host; 343 344 if (retcode) 345 *retcode = 0; --- 13 unchanged lines hidden (view full) --- 359 } 360 else { 361 /* It's a different host now, flush old */ 362 fclose(fp); 363 free(prev_host); 364 prev_host = NULL; 365 } 366 } | 377 char host[255], name[255]; 378 int port; 379 FILE *fp2; 380 static FILE *fp = NULL; 381 static char *prev_host; 382 383 if (retcode) 384 *retcode = 0; --- 13 unchanged lines hidden (view full) --- 398 } 399 else { 400 /* It's a different host now, flush old */ 401 fclose(fp); 402 free(prev_host); 403 prev_host = NULL; 404 } 405 } |
367 fp = ftpLogin(host, user, passwd, port, 0, retcode); | 406 fp = ftpLoginAf(host, af, user, passwd, port, 0, retcode); |
368 if (fp) { 369 fp2 = ftpGet(fp, name, NULL); 370 if (!fp2) { 371 /* Connection timed out or was no longer valid */ 372 if (retcode) 373 *retcode = ftpErrno(fp); 374 fclose(fp); 375 fp = NULL; --- 4 unchanged lines hidden (view full) --- 380 } 381 } 382 return NULL; 383} 384 385FILE * 386ftpPutURL(char *url, char *user, char *passwd, int *retcode) 387{ | 407 if (fp) { 408 fp2 = ftpGet(fp, name, NULL); 409 if (!fp2) { 410 /* Connection timed out or was no longer valid */ 411 if (retcode) 412 *retcode = ftpErrno(fp); 413 fclose(fp); 414 fp = NULL; --- 4 unchanged lines hidden (view full) --- 419 } 420 } 421 return NULL; 422} 423 424FILE * 425ftpPutURL(char *url, char *user, char *passwd, int *retcode) 426{ |
427#ifdef INET6 428 return ftpPutURLAf(url, AF_UNSPEC, user, passwd, retcode); 429#else 430 return ftpPutURLAf(url, AF_INET, user, passwd, retcode); 431#endif 432 433} 434 435FILE * 436ftpPutURLAf(char *url, int af, char *user, char *passwd, int *retcode) 437{ |
|
388 char host[255], name[255]; 389 int port; 390 static FILE *fp = NULL; 391 FILE *fp2; 392 393 if (retcode) 394 *retcode = 0; 395 if (fp) { /* Close previous managed connection */ 396 fclose(fp); 397 fp = NULL; 398 } 399 if (get_url_info(url, host, &port, name) == SUCCESS) { | 438 char host[255], name[255]; 439 int port; 440 static FILE *fp = NULL; 441 FILE *fp2; 442 443 if (retcode) 444 *retcode = 0; 445 if (fp) { /* Close previous managed connection */ 446 fclose(fp); 447 fp = NULL; 448 } 449 if (get_url_info(url, host, &port, name) == SUCCESS) { |
400 fp = ftpLogin(host, user, passwd, port, 0, retcode); | 450 fp = ftpLoginAf(host, af, user, passwd, port, 0, retcode); |
401 if (fp) { 402 fp2 = ftpPut(fp, name); 403 if (!fp2) { 404 if (retcode) 405 *retcode = ftpErrno(fp); 406 fclose(fp); 407 fp = NULL; 408 } --- 258 unchanged lines hidden (view full) --- 667 return FTP_TIMED_OUT; 668 return FAILURE; 669 } 670 while ((i = get_a_number(ftp, NULL)) == FTP_HAPPY_COMMENT); 671 return i; 672} 673 674static int | 451 if (fp) { 452 fp2 = ftpPut(fp, name); 453 if (!fp2) { 454 if (retcode) 455 *retcode = ftpErrno(fp); 456 fclose(fp); 457 fp = NULL; 458 } --- 258 unchanged lines hidden (view full) --- 717 return FTP_TIMED_OUT; 718 return FAILURE; 719 } 720 while ((i = get_a_number(ftp, NULL)) == FTP_HAPPY_COMMENT); 721 return i; 722} 723 724static int |
675ftp_login_session(FTP_t ftp, char *host, char *user, char *passwd, int port, int verbose) | 725ftp_login_session(FTP_t ftp, char *host, int af, 726 char *user, char *passwd, int port, int verbose) |
676{ | 727{ |
677 struct hostent *he = NULL; 678 struct sockaddr_in sin; | 728 char pbuf[10]; 729 struct addrinfo hints, *res, *res0; 730 int err; |
679 int s; | 731 int s; |
680 unsigned long temp; | |
681 int i; 682 683 if (networkInit() != SUCCESS) 684 return FAILURE; 685 686 if (ftp->con_state != init) { 687 ftp_close(ftp); 688 ftp->error = -1; --- 4 unchanged lines hidden (view full) --- 693 user = "ftp"; 694 695 if (!passwd) 696 passwd = "setup@"; 697 698 if (!port) 699 port = 21; 700 | 732 int i; 733 734 if (networkInit() != SUCCESS) 735 return FAILURE; 736 737 if (ftp->con_state != init) { 738 ftp_close(ftp); 739 ftp->error = -1; --- 4 unchanged lines hidden (view full) --- 744 user = "ftp"; 745 746 if (!passwd) 747 passwd = "setup@"; 748 749 if (!port) 750 port = 21; 751 |
701 temp = inet_addr(host); 702 if (temp != INADDR_NONE) { 703 ftp->addrtype = sin.sin_family = AF_INET; 704 sin.sin_addr.s_addr = temp; | 752 snprintf(pbuf, sizeof(pbuf), "%d", port); 753 memset(&hints, 0, sizeof(hints)); 754 hints.ai_family = af; 755 hints.ai_socktype = SOCK_STREAM; 756 hints.ai_protocol = 0; 757 err = getaddrinfo(host, pbuf, &hints, &res0); 758 if (err) { 759 ftp->error = 0; 760 return FAILURE; |
705 } | 761 } |
706 else { 707 he = gethostbyname(host); 708 if (!he) { 709 ftp->error = 0; 710 return FAILURE; 711 } 712 ftp->addrtype = sin.sin_family = he->h_addrtype; 713 bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); 714 } | |
715 | 762 |
716 sin.sin_port = htons(port); | 763 s = -1; 764 for (res = res0; res; res = res->ai_next) { 765 ai_unmapped(res); 766 ftp->addrtype = res->ai_family; |
717 | 767 |
718 if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) { 719 ftp->error = -1; 720 return FAILURE; 721 } | 768 if ((s = socket(res->ai_family, res->ai_socktype, 769 res->ai_protocol)) < 0) 770 continue; |
722 | 771 |
723 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { 724 (void)close(s); | 772 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { 773 (void)close(s); 774 s = -1; 775 continue; 776 } 777 778 break; 779 } 780 freeaddrinfo(res0); 781 if (s < 0) { |
725 ftp->error = errno; 726 return FAILURE; 727 } 728 729 ftp->fd_ctrl = s; 730 ftp->con_state = isopen; 731 ftp->is_verbose = verbose; 732 --- 7 unchanged lines hidden (view full) --- 740 return FAILURE; 741 } 742 return SUCCESS; 743} 744 745static int 746ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto) 747{ | 782 ftp->error = errno; 783 return FAILURE; 784 } 785 786 ftp->fd_ctrl = s; 787 ftp->con_state = isopen; 788 ftp->is_verbose = verbose; 789 --- 7 unchanged lines hidden (view full) --- 797 return FAILURE; 798 } 799 return SUCCESS; 800} 801 802static int 803ftp_file_op(FTP_t ftp, char *operation, char *file, FILE **fp, char *mode, off_t *seekto) 804{ |
748 int i,s; | 805 int i,l,s; |
749 char *q; 750 unsigned char addr[64]; | 806 char *q; 807 unsigned char addr[64]; |
751 struct sockaddr_in sin; 752 u_long a; | 808 union sockaddr_cmn { 809 struct sockaddr_in sin4; 810 struct sockaddr_in6 sin6; 811 } sin; 812 char *cmdstr; |
753 754 if (!fp) 755 return FAILURE; 756 *fp = NULL; 757 758 if (ftp->con_state != isopen) 759 return botch("ftp_file_op", "open"); 760 761 if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) { 762 ftp->error = errno; 763 return FAILURE; 764 } 765 766 if (ftp->is_passive) { | 813 814 if (!fp) 815 return FAILURE; 816 *fp = NULL; 817 818 if (ftp->con_state != isopen) 819 return botch("ftp_file_op", "open"); 820 821 if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) { 822 ftp->error = errno; 823 return FAILURE; 824 } 825 826 if (ftp->is_passive) { |
767 if (ftp->is_verbose) 768 fprintf(stderr, "Sending PASV\n"); 769 if (writes(ftp->fd_ctrl, "PASV\r\n")) { 770 ftp_close(ftp); 771 if (FtpTimedOut) 772 ftp->error = FTP_TIMED_OUT; 773 return FTP_TIMED_OUT; | 827 if (ftp->addrtype == AF_INET) { 828 if (ftp->is_verbose) 829 fprintf(stderr, "Sending PASV\n"); 830 if (writes(ftp->fd_ctrl, "PASV\r\n")) { 831 ftp_close(ftp); 832 if (FtpTimedOut) 833 ftp->error = FTP_TIMED_OUT; 834 return FTP_TIMED_OUT; 835 } 836 i = get_a_number(ftp, &q); 837 if (check_code(ftp, i, FTP_PASSIVE_HAPPY)) { 838 ftp_close(ftp); 839 return i; 840 } 841 cmdstr = "PASV"; 842 } else { 843 if (ftp->is_verbose) 844 fprintf(stderr, "Sending EPSV\n"); 845 if (writes(ftp->fd_ctrl, "EPSV\r\n")) { 846 ftp_close(ftp); 847 if (FtpTimedOut) 848 ftp->error = FTP_TIMED_OUT; 849 return FTP_TIMED_OUT; 850 } 851 i = get_a_number(ftp, &q); 852 if (check_code(ftp, i, FTP_EPASSIVE_HAPPY)) { 853 if (ftp->is_verbose) 854 fprintf(stderr, "Sending LPSV\n"); 855 if (writes(ftp->fd_ctrl, "LPSV\r\n")) { 856 ftp_close(ftp); 857 if (FtpTimedOut) 858 ftp->error = FTP_TIMED_OUT; 859 return FTP_TIMED_OUT; 860 } 861 i = get_a_number(ftp, &q); 862 if (check_code(ftp, i, FTP_LPASSIVE_HAPPY)) { 863 ftp_close(ftp); 864 return i; 865 } 866 cmdstr = "LPSV"; 867 } else 868 cmdstr = "EPSV"; |
774 } | 869 } |
775 i = get_a_number(ftp, &q); 776 if (check_code(ftp, i, FTP_PASSIVE_HAPPY)) { 777 ftp_close(ftp); 778 return i; 779 } 780 while (*q && !isdigit(*q)) | 870 while (*q && *q != '(') /* ) */ |
781 q++; 782 if (!*q) { 783 ftp_close(ftp); 784 return FAILURE; 785 } | 871 q++; 872 if (!*q) { 873 ftp_close(ftp); 874 return FAILURE; 875 } |
786 q--; 787 for (i = 0; i < 6; i++) { | 876 if (strcmp(cmdstr, "PASV") == 0 || strcmp(cmdstr, "LPSV") == 0) { 877 l = (ftp->addrtype == AF_INET ? 6 : 21); 878 for (i = 0; i < l; i++) { 879 q++; 880 addr[i] = strtol(q, &q, 10); 881 } 882 883 sin.sin4.sin_family = ftp->addrtype; 884 if (ftp->addrtype == AF_INET6) { 885 sin.sin6.sin6_len = sizeof(struct sockaddr_in6); 886 bcopy(addr + 2, (char *)&sin.sin6.sin6_addr, 16); 887 bcopy(addr + 19, (char *)&sin.sin6.sin6_port, 2); 888 } else { 889 sin.sin4.sin_len = sizeof(struct sockaddr_in); 890 bcopy(addr, (char *)&sin.sin4.sin_addr, 4); 891 bcopy(addr + 4, (char *)&sin.sin4.sin_port, 2); 892 } 893 } else if (strcmp(cmdstr, "EPSV") == 0) { 894 int port; 895 int sinlen; |
788 q++; | 896 q++; |
789 addr[i] = strtol(q, &q, 10); | 897 if (sscanf(q, "%c%c%c%d%c", &addr[0], &addr[1], &addr[2], 898 &port, &addr[3]) != 5 899 || addr[0] != addr[1] || addr[0] != addr[2] || addr[0] != addr[3]) { 900 ftp_close(ftp); 901 return FAILURE; 902 } 903 sinlen = sizeof(sin); 904 if (getpeername(ftp->fd_ctrl, (struct sockaddr *)&sin, &sinlen) < 0) { 905 ftp_close(ftp); 906 return FAILURE; 907 } 908 switch (sin.sin4.sin_family) { 909 case AF_INET: 910 sin.sin4.sin_port = htons(port); 911 break; 912 case AF_INET6: 913 sin.sin6.sin6_port = htons(port); 914 break; 915 default: 916 ftp_close(ftp); 917 return FAILURE; 918 } |
790 } 791 | 919 } 920 |
792 sin.sin_family = ftp->addrtype; 793 bcopy(addr, (char *)&sin.sin_addr, 4); 794 bcopy(addr + 4, (char *)&sin.sin_port, 2); 795 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | 921 if (connect(s, (struct sockaddr *)&sin, sin.sin4.sin_len) < 0) { |
796 (void)close(s); 797 return FAILURE; 798 } 799 800 if (seekto && *seekto) { 801 i = cmd(ftp, "REST %d", *seekto); 802 if (i < 0 || FTP_TIMEOUT(i)) { 803 close(s); --- 8 unchanged lines hidden (view full) --- 812 ftp->error = i; 813 return i; 814 } 815 *fp = fdopen(s, mode); 816 } 817 else { 818 int fd,portrange; 819 | 922 (void)close(s); 923 return FAILURE; 924 } 925 926 if (seekto && *seekto) { 927 i = cmd(ftp, "REST %d", *seekto); 928 if (i < 0 || FTP_TIMEOUT(i)) { 929 close(s); --- 8 unchanged lines hidden (view full) --- 938 ftp->error = i; 939 return i; 940 } 941 *fp = fdopen(s, mode); 942 } 943 else { 944 int fd,portrange; 945 |
946#ifdef IPV6_PORTRANGE 947 if (ftp->addrtype == AF_INET6) { 948 portrange = IPV6_PORTRANGE_HIGH; 949 if (setsockopt(s, IPPROTO_IPV6, IPV6_PORTRANGE, (char *) 950 &portrange, sizeof(portrange)) < 0) { 951 close(s); 952 return FAILURE; 953 } 954 } 955#endif |
|
820#ifdef IP_PORTRANGE | 956#ifdef IP_PORTRANGE |
821 portrange = IP_PORTRANGE_HIGH; 822 if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, (char *) 823 &portrange, sizeof(portrange)) < 0) { 824 close(s); 825 return FAILURE; 826 }; | 957 if (ftp->addrtype == AF_INET) { 958 portrange = IP_PORTRANGE_HIGH; 959 if (setsockopt(s, IPPROTO_IP, IP_PORTRANGE, (char *) 960 &portrange, sizeof(portrange)) < 0) { 961 close(s); 962 return FAILURE; 963 } 964 } |
827#endif 828 829 i = sizeof sin; 830 getsockname(ftp->fd_ctrl, (struct sockaddr *)&sin, &i); | 965#endif 966 967 i = sizeof sin; 968 getsockname(ftp->fd_ctrl, (struct sockaddr *)&sin, &i); |
831 sin.sin_port = 0; 832 i = sizeof sin; | 969 sin.sin4.sin_port = 0; 970 i = ((struct sockaddr *)&sin)->sa_len; |
833 if (bind(s, (struct sockaddr *)&sin, i) < 0) { 834 close(s); 835 return FAILURE; 836 } | 971 if (bind(s, (struct sockaddr *)&sin, i) < 0) { 972 close(s); 973 return FAILURE; 974 } |
975 i = sizeof sin; |
|
837 getsockname(s,(struct sockaddr *)&sin,&i); 838 if (listen(s, 1) < 0) { 839 close(s); 840 return FAILURE; 841 } | 976 getsockname(s,(struct sockaddr *)&sin,&i); 977 if (listen(s, 1) < 0) { 978 close(s); 979 return FAILURE; 980 } |
842 a = ntohl(sin.sin_addr.s_addr); 843 i = cmd(ftp, "PORT %d,%d,%d,%d,%d,%d", 844 (a >> 24) & 0xff, 845 (a >> 16) & 0xff, 846 (a >> 8) & 0xff, 847 a & 0xff, 848 (ntohs(sin.sin_port) >> 8) & 0xff, 849 ntohs(sin.sin_port) & 0xff); 850 if (check_code(ftp, i, FTP_PORT_HAPPY)) { 851 close(s); 852 return i; | 981 if (sin.sin4.sin_family == AF_INET) { 982 u_long a; 983 a = ntohl(sin.sin4.sin_addr.s_addr); 984 i = cmd(ftp, "PORT %d,%d,%d,%d,%d,%d", 985 (a >> 24) & 0xff, 986 (a >> 16) & 0xff, 987 (a >> 8) & 0xff, 988 a & 0xff, 989 (ntohs(sin.sin4.sin_port) >> 8) & 0xff, 990 ntohs(sin.sin4.sin_port) & 0xff); 991 if (check_code(ftp, i, FTP_PORT_HAPPY)) { 992 close(s); 993 return i; 994 } 995 } else { 996#define UC(b) (((int)b)&0xff) 997 char *a; 998 char hname[INET6_ADDRSTRLEN]; 999 1000 if (getnameinfo((struct sockaddr *)&sin, sin.sin6.sin6_len, 1001 hname, sizeof(hname), 1002 NULL, 0, NI_NUMERICHOST) != 0) { 1003 goto try_lprt; 1004 } 1005 i = cmd(ftp, "EPRT |%d|%s|%d|", 2, hname, 1006 htons(sin.sin6.sin6_port)); 1007 if (check_code(ftp, i, FTP_PORT_HAPPY)) { 1008try_lprt: 1009 a = (char *)&sin.sin6.sin6_addr; 1010 i = cmd(ftp, 1011"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", 1012 6, 16, 1013 UC(a[0]),UC(a[1]),UC(a[2]),UC(a[3]), 1014 UC(a[4]),UC(a[5]),UC(a[6]),UC(a[7]), 1015 UC(a[8]),UC(a[9]),UC(a[10]),UC(a[11]), 1016 UC(a[12]),UC(a[13]),UC(a[14]),UC(a[15]), 1017 2, 1018 (ntohs(sin.sin4.sin_port) >> 8) & 0xff, 1019 ntohs(sin.sin4.sin_port) & 0xff); 1020 if (check_code(ftp, i, FTP_PORT_HAPPY)) { 1021 close(s); 1022 return i; 1023 } 1024 } |
853 } 854 if (seekto && *seekto) { 855 i = cmd(ftp, "REST %d", *seekto); 856 if (i < 0 || FTP_TIMEOUT(i)) { 857 close(s); 858 ftp->error = i; 859 return i; 860 } --- 15 unchanged lines hidden (view full) --- 876 close(s); 877 *fp = fdopen(fd, mode); 878 } 879 if (*fp) 880 return SUCCESS; 881 else 882 return FAILURE; 883} | 1025 } 1026 if (seekto && *seekto) { 1027 i = cmd(ftp, "REST %d", *seekto); 1028 if (i < 0 || FTP_TIMEOUT(i)) { 1029 close(s); 1030 ftp->error = i; 1031 return i; 1032 } --- 15 unchanged lines hidden (view full) --- 1048 close(s); 1049 *fp = fdopen(fd, mode); 1050 } 1051 if (*fp) 1052 return SUCCESS; 1053 else 1054 return FAILURE; 1055} |
1056 1057static void 1058ai_unmapped(struct addrinfo *ai) 1059{ 1060 struct sockaddr_in6 *sin6; 1061 struct sockaddr_in sin; 1062 1063 if (ai->ai_family != AF_INET6) 1064 return; 1065 if (ai->ai_addrlen != sizeof(struct sockaddr_in6) || 1066 sizeof(sin) > ai->ai_addrlen) 1067 return; 1068 sin6 = (struct sockaddr_in6 *)ai->ai_addr; 1069 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 1070 return; 1071 1072 memset(&sin, 0, sizeof(sin)); 1073 sin.sin_family = AF_INET; 1074 sin.sin_len = sizeof(struct sockaddr_in); 1075 memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], 1076 sizeof(sin.sin_addr)); 1077 sin.sin_port = sin6->sin6_port; 1078 1079 ai->ai_family = AF_INET; 1080 memcpy(ai->ai_addr, &sin, sin.sin_len); 1081 ai->ai_addrlen = sin.sin_len; 1082} |
|