summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorStig Venaas <venaas@php.net>2000-09-09 21:29:37 +0000
committerStig Venaas <venaas@php.net>2000-09-09 21:29:37 +0000
commitd8a4a9b1dd535a76a34e4a1114a46fe2cd598a4c (patch)
tree3605de4107661f2afeb0faa056823b07ff848621 /main
parente6c77fde1d9d1181041f0687a73a22f41be701c5 (diff)
downloadphp-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.c194
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)