Back to index

php5  5.3.10
Functions | Variables
php_fopen_wrappers.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

php_stream * php_stream_url_wrap_http (php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
php_stream * php_stream_url_wrap_ftp (php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)

Variables

PHPAPI php_stream_wrapper php_stream_http_wrapper
PHPAPI php_stream_wrapper php_stream_ftp_wrapper
php_stream_wrapper php_stream_php_wrapper
php_stream_wrapper php_plain_files_wrapper

Function Documentation

php_stream* php_stream_url_wrap_ftp ( php_stream_wrapper *  wrapper,
char *  path,
char *  mode,
int  options,
char **  opened_path,
php_stream_context *context STREAMS_DC  TSRMLS_DC 
)

Definition at line 414 of file ftp_fopen_wrapper.c.

{
       php_stream *stream = NULL, *datastream = NULL;
       php_url *resource = NULL;
       char tmp_line[512];
       char ip[sizeof("123.123.123.123")];
       unsigned short portno;
       char *hoststart = NULL;
       int result = 0, use_ssl, use_ssl_on_data=0;
       php_stream *reuseid=NULL;
       size_t file_size = 0;
       zval **tmpzval;
       int allow_overwrite = 0;
       int read_write = 0;
       char *transport;
       int transport_len;

       tmp_line[0] = '\0';

       if (strpbrk(mode, "r+")) {
              read_write = 1; /* Open for reading */
       }
       if (strpbrk(mode, "wa+")) {
              if (read_write) {
                     php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "FTP does not support simultaneous read/write connections");
                     return NULL;
              }
              if (strchr(mode, 'a')) {
                     read_write = 3; /* Open for Appending */
              } else {
                     read_write = 2; /* Open for writting */
              }
       }
       if (!read_write) {
              /* No mode specified? */
              php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unknown file open mode");
              return NULL;
       }

       if (context &&
              php_stream_context_get_option(context, "ftp", "proxy", &tmpzval) == SUCCESS) {
              if (read_write == 1) {
                     /* Use http wrapper to proxy ftp request */
                     return php_stream_url_wrap_http(wrapper, path, mode, options, opened_path, context STREAMS_CC TSRMLS_CC);
              } else {
                     /* ftp proxy is read-only */
                     php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "FTP proxy may only be used in read mode");
                     return NULL;
              }
       }

       stream = php_ftp_fopen_connect(wrapper, path, mode, options, opened_path, context, &reuseid, &resource, &use_ssl, &use_ssl_on_data TSRMLS_CC);
       if (!stream) {
              goto errexit;
       }

       /* set the connection to be binary */
       php_stream_write_string(stream, "TYPE I\r\n");
       result = GET_FTP_RESULT(stream);
       if (result > 299 || result < 200)
              goto errexit;
       
       /* find out the size of the file (verifying it exists) */
       php_stream_printf(stream TSRMLS_CC, "SIZE %s\r\n", resource->path);
       
       /* read the response */
       result = GET_FTP_RESULT(stream);
       if (read_write == 1) {
              /* Read Mode */
              char *sizestr;
              
              /* when reading file, it must exist */
              if (result > 299 || result < 200) {
                     errno = ENOENT;
                     goto errexit;
              }
              
              sizestr = strchr(tmp_line, ' ');
              if (sizestr) {
                     sizestr++;
                     file_size = atoi(sizestr);
                     php_stream_notify_file_size(context, file_size, tmp_line, result);
              }      
       } else if (read_write == 2) {
              /* when writing file (but not appending), it must NOT exist, unless a context option exists which allows it */
              if (context && php_stream_context_get_option(context, "ftp", "overwrite", &tmpzval) == SUCCESS) {
                     allow_overwrite = Z_LVAL_PP(tmpzval);
              }
              if (result <= 299 && result >= 200) {
                     if (allow_overwrite) {
                            /* Context permits overwritting file, 
                               so we just delete whatever's there in preparation */
                            php_stream_printf(stream TSRMLS_CC, "DELE %s\r\n", resource->path);
                            result = GET_FTP_RESULT(stream);
                            if (result >= 300 || result <= 199) {
                                   goto errexit;
                            }
                     } else {
                            php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Remote file already exists and overwrite context option not specified");
                            errno = EEXIST;
                            goto errexit;
                     }
              }
       }

       /* set up the passive connection */
       portno = php_fopen_do_pasv(stream, ip, sizeof(ip), &hoststart TSRMLS_CC);

       if (!portno) {
              goto errexit;
       }

       /* Send RETR/STOR command */
       if (read_write == 1) {
              /* set resume position if applicable */
              if (context &&
                     php_stream_context_get_option(context, "ftp", "resume_pos", &tmpzval) == SUCCESS &&
                     Z_TYPE_PP(tmpzval) == IS_LONG &&
                     Z_LVAL_PP(tmpzval) > 0) {
                     php_stream_printf(stream TSRMLS_CC, "REST %ld\r\n", Z_LVAL_PP(tmpzval));
                     result = GET_FTP_RESULT(stream);
                     if (result < 300 || result > 399) {                     
                            php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to resume from offset %ld", Z_LVAL_PP(tmpzval));
                            goto errexit;
                     }
              }

              /* retrieve file */
              memcpy(tmp_line, "RETR", sizeof("RETR"));
       } else if (read_write == 2) {
              /* Write new file */
              memcpy(tmp_line, "STOR", sizeof("STOR"));
       } else {
              /* Append */
              memcpy(tmp_line, "APPE", sizeof("APPE"));
       } 
       php_stream_printf(stream TSRMLS_CC, "%s %s\r\n", tmp_line, (resource->path != NULL ? resource->path : "/"));
       
       /* open the data channel */
       if (hoststart == NULL) {
              hoststart = resource->host;
       }
       transport_len = spprintf(&transport, 0, "tcp://%s:%d", hoststart, portno);
       datastream = php_stream_xport_create(transport, transport_len, REPORT_ERRORS, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, NULL, context, NULL, NULL);
       efree(transport);
       if (datastream == NULL) {
              goto errexit;
       }

       result = GET_FTP_RESULT(stream);
       if (result != 150 && result != 125) {
              /* Could not retrieve or send the file 
               * this data will only be sent to us after connection on the data port was initiated.
               */
              php_stream_close(datastream);
              datastream = NULL;
              goto errexit; 
       }
       
       php_stream_context_set(datastream, context);
       php_stream_notify_progress_init(context, 0, file_size);

       if (use_ssl_on_data && (php_stream_xport_crypto_setup(datastream,
                     STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
                     php_stream_xport_crypto_enable(datastream, 1 TSRMLS_CC) < 0)) {

              php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode");
              php_stream_close(datastream);
              datastream = NULL;
              goto errexit;
       }

       /* remember control stream */      
       datastream->wrapperthis = stream;

       php_url_free(resource);
       return datastream;

errexit:
       if (resource) {
              php_url_free(resource);
       }
       if (stream) {
              php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, result);
              php_stream_close(stream);
       }
       if (tmp_line[0] != '\0')
              php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "FTP server reports %s", tmp_line);
       return NULL;
}

Here is the call graph for this function:

php_stream* php_stream_url_wrap_http ( php_stream_wrapper *  wrapper,
char *  path,
char *  mode,
int  options,
char **  opened_path,
php_stream_context *context STREAMS_DC  TSRMLS_DC 
)

Definition at line 922 of file http_fopen_wrapper.c.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

php_stream_wrapper php_plain_files_wrapper

Definition at line 1302 of file plain_wrapper.c.

PHPAPI php_stream_wrapper php_stream_ftp_wrapper

Definition at line 1191 of file ftp_fopen_wrapper.c.

PHPAPI php_stream_wrapper php_stream_http_wrapper

Definition at line 950 of file http_fopen_wrapper.c.

php_stream_wrapper php_stream_php_wrapper

Definition at line 381 of file php_fopen_wrapper.c.