diff options
author | Stig Venaas <venaas@php.net> | 2000-09-09 21:29:37 +0000 |
---|---|---|
committer | Stig Venaas <venaas@php.net> | 2000-09-09 21:29:37 +0000 |
commit | d8a4a9b1dd535a76a34e4a1114a46fe2cd598a4c (patch) | |
tree | 3605de4107661f2afeb0faa056823b07ff848621 /main | |
parent | e6c77fde1d9d1181041f0687a73a22f41be701c5 (diff) | |
download | php-git-d8a4a9b1dd535a76a34e4a1114a46fe2cd598a4c.tar.gz |
Added IPv6 support to php_fopen_url_wrap_ftp (EPSV and php_hostconnect())
Diffstat (limited to 'main')
-rw-r--r-- | main/fopen_wrappers.c | 194 |
1 files changed, 70 insertions, 124 deletions
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 90d2d4f255..eae53f7002 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -630,7 +630,6 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, { FILE *fp=NULL; php_url *resource=NULL; - struct sockaddr_in server; char tmp_line[512]; unsigned short portno; char *scratch; @@ -652,30 +651,10 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, /* use port 21 if one wasn't specified */ if (resource->port == 0) resource->port = 21; - - *socketd = socket(AF_INET, SOCK_STREAM, 0); - if (*socketd == SOCK_ERR) { - SOCK_FCLOSE(*socketd); - *socketd = 0; - free_url(resource); - return NULL; - } - server.sin_family = AF_INET; - - if (lookup_hostname(resource->host, &server.sin_addr)) { - SOCK_FCLOSE(*socketd); - *socketd = 0; - free_url(resource); - return NULL; - } - server.sin_port = htons(resource->port); - - if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) { - SOCK_FCLOSE(*socketd); - *socketd = 0; - free_url(resource); - return NULL; - } + + *socketd = php_hostconnect(resource->host, resource->port, SOCK_STREAM, 0); + if (*socketd == -1) + goto errexit; #if 0 if ((fpc = fdopen(*socketd, "r+")) == NULL) { free_url(resource); @@ -692,12 +671,9 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, /* Start talking to ftp server */ result = php_get_ftp_result(*socketd); - if (result > 299 || result < 200) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } + if (result > 299 || result < 200) + goto errexit; + /* send the user name */ SOCK_WRITE("USER ", *socketd); if (resource->user != NULL) { @@ -730,28 +706,15 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, /* read the response */ result = php_get_ftp_result(*socketd); - if (result > 299 || result < 200) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } - } else if (result > 299 || result < 200) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; } + if (result > 299 || result < 200) + goto errexit; /* set the connection to be binary */ SOCK_WRITE("TYPE I\r\n", *socketd); result = php_get_ftp_result(*socketd); - if (result > 299 || result < 200) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } + if (result > 299 || result < 200) + goto errexit; /* find out the size of the file (verifying it exists) */ SOCK_WRITE("SIZE ", *socketd); @@ -783,69 +746,66 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, } /* set up the passive connection */ - SOCK_WRITE("PASV\r\n", *socketd); + + /* We try EPSV first, needed for IPv6 and works on some IPv4 servers */ + SOCK_WRITE("EPSV\r\n", *socketd); while (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) && !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) && isdigit((int) tmp_line[2]) && tmp_line[3] == ' ')); - - /* make sure we got a 227 response */ - if (strncmp(tmp_line, "227", 3)) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } - /* parse pasv command (129,80,95,25,13,221) */ - tpath = tmp_line; - - /* skip over the "227 Some message " part */ - for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); - if (!*tpath) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } - /* skip over the host ip, we just assume it's the same */ - for (i = 0; i < 4; i++) { - for (; isdigit((int) *tpath); tpath++); - if (*tpath == ',') { + + /* check if we got a 229 response */ + if (strncmp(tmp_line, "229", 3)) { + /* EPSV failed, let's try PASV */ + SOCK_WRITE("PASV\r\n", *socketd); + while (SOCK_FGETS(tmp_line, sizeof(tmp_line)-1, *socketd) && + !(isdigit((int) tmp_line[0]) && isdigit((int) tmp_line[1]) && + isdigit((int) tmp_line[2]) && tmp_line[3] == ' ')); + /* make sure we got a 227 response */ + if (strncmp(tmp_line, "227", 3)) + goto errexit; + /* parse pasv command (129,80,95,25,13,221) */ + tpath = tmp_line; + /* skip over the "227 Some message " part */ + for (tpath += 4; *tpath && !isdigit((int) *tpath); tpath++); + if (!*tpath) + goto errexit; + /* skip over the host ip, we just assume it's the same */ + for (i = 0; i < 4; i++) { + for (; isdigit((int) *tpath); tpath++); + if (*tpath != ',') + goto errexit; tpath++; - } else { - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; } - } - - /* pull out the MSB of the port */ - portno = (unsigned short) strtol(tpath, &ttpath, 10) * 256; - if (ttpath == NULL) { - /* didn't get correct response from PASV */ - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } - tpath = ttpath; - if (*tpath == ',') { + /* pull out the MSB of the port */ + portno = (unsigned short) strtol(tpath, &ttpath, 10) * 256; + if (ttpath == NULL) { + /* didn't get correct response from PASV */ + goto errexit; + } + tpath = ttpath; + if (*tpath != ',') + goto errexit; tpath++; + /* pull out the LSB of the port */ + portno += (unsigned short) strtol(tpath, &ttpath, 10); } else { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; + /* parse epsv command (|||6446|) */ + for (i = 0, tpath = tmp_line + 4; *tpath; tpath++) { + if (*tpath == '|') { + i++; + if (i == 3) + break; + } + } + if (i < 3) + goto errexit; + /* pull out the port */ + portno = (unsigned short) strtol(tpath + 1, &ttpath, 10); } - /* pull out the LSB of the port */ - portno += (unsigned short) strtol(tpath, &ttpath, 10); - if (ttpath == NULL) { - /* didn't get correct response from PASV */ - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; + /* didn't get correct response from EPSV/PASV */ + goto errexit; } if (mode[0] == 'r') { @@ -866,29 +826,9 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, SOCK_FCLOSE(*socketd); /* open the data channel */ - *socketd = socket(AF_INET, SOCK_STREAM, 0); - if (*socketd == SOCK_ERR) { - SOCK_FCLOSE(*socketd); - *socketd = 0; - free_url(resource); - return NULL; - } - server.sin_family = AF_INET; - - if (lookup_hostname(resource->host, &server.sin_addr)) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } - server.sin_port = htons(portno); - - if (connect(*socketd, (struct sockaddr *) &server, sizeof(server)) == SOCK_CONN_ERR) { - free_url(resource); - SOCK_FCLOSE(*socketd); - *socketd = 0; - return NULL; - } + *socketd = php_hostconnect(resource->host, portno, SOCK_STREAM, 0); + if (*socketd == -1) + goto errexit; #if 0 if (mode[0] == 'r') { if ((fp = fdopen(*socketd, "r+")) == NULL) { @@ -912,6 +852,12 @@ static FILE *php_fopen_url_wrap_http(const char *path, char *mode, int options, free_url(resource); *issock = 1; return (fp); + + errexit: + free_url(resource); + SOCK_FCLOSE(*socketd); + *socketd = 0; + return NULL; } static FILE *php_fopen_url_wrap_php(const char *path, char *mode, int options, int *issock, int *socketd, char **opened_path) |