mirror of
https://github.com/php/php-src.git
synced 2026-04-11 01:53:36 +02:00
Added IPv6 support to php_fopen_url_wrap_ftp (EPSV and php_hostconnect())
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user