]> granicus.if.org Git - php/commitdiff
Added IPv6 support to php_fopen_url_wrap_ftp (EPSV and php_hostconnect())
authorStig Venaas <venaas@php.net>
Sat, 9 Sep 2000 21:29:37 +0000 (21:29 +0000)
committerStig Venaas <venaas@php.net>
Sat, 9 Sep 2000 21:29:37 +0000 (21:29 +0000)
main/fopen_wrappers.c

index 90d2d4f25559ecef7e510361b31ad73629a3afc8..eae53f70024223e94bf7511297c8ce1b6d7e9a2a 100644 (file)
@@ -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)