Mam jakiś strumień "stream" z funkcji wrapper->wops->stream_opener (stream=wrapper->wops->stream_opener(argumenty)).
Jak pobrać wielkość pliku?
Mój obecny kod (main/streams/streams.c w funkcji php_stream_open_wrapper_ex):
/* START max file size mod */
int size = CO TU WPISAĆ?
int max_size = PG(upload_max_filesize);
if (size > max_size && (options & REPORT_ERRORS)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to open stream: max file size is 3MB");
if (opened_path && *opened_path) {
efree(*opened_path);
*opened_path = NULL;
}
return false;
}
/* END max file size mod */
Cały kod funkcji php_stream_open_wrapper_ex:
/* {{{ php_stream_open_wrapper_ex */
PHPAPI php_stream *_php_stream_open_wrapper_ex(char *path, char *mode, int options,
char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
{
php_stream *stream = NULL;
php_stream_wrapper *wrapper = NULL;
char *path_to_open;
int persistent = options & STREAM_OPEN_PERSISTENT;
char *resolved_path = NULL;
char *copy_of_path = NULL;
if (opened_path) {
*opened_path = NULL;
}
if (!path || !*path) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename cannot be empty");
return NULL;
}
if (options & USE_PATH) {
resolved_path = zend_resolve_path(path, strlen(path) TSRMLS_CC);
if (resolved_path) {
path = resolved_path;
/* we've found this file, don't re-check include_path or run realpath */
options |= STREAM_ASSUME_REALPATH;
options &= ~USE_PATH;
}
}
path_to_open = path;
wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC);
if (options & STREAM_USE_URL && (!wrapper || !wrapper->is_url)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function may only be used against URLs");
if (resolved_path) {
efree(resolved_path);
}
return NULL;
}
if (wrapper) {
if (!wrapper->wops->stream_opener) {
php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC,
"wrapper does not support stream open");
} else {
/* refcount++ to make sure the context doesn't get destroyed
* if open() fails and stream is closed */
if (context) {
zend_list_addref(context->rsrc_id);
}
stream = wrapper->wops->stream_opener(wrapper,
path_to_open, mode, options ^ REPORT_ERRORS,
opened_path, context STREAMS_REL_CC TSRMLS_CC);
/* if open() succeeded and context was not used, do refcount--
* XXX if a wrapper didn't actually use context (no way to know that)
* and open() failed, refcount will stay increased */
if (context && stream && !stream->context) {
zend_list_delete(context->rsrc_id);
}
}
/* if the caller asked for a persistent stream but the wrapper did not
* return one, force an error here */
if (stream && (options & STREAM_OPEN_PERSISTENT) && !stream->is_persistent) {
php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC,
"wrapper does not support persistent streams");
php_stream_close(stream);
stream = NULL;
}
if (stream) {
stream->wrapper = wrapper;
}
}
if (stream) {
if (opened_path && !*opened_path && resolved_path) {
*opened_path = resolved_path;
resolved_path = NULL;
}
if (stream->orig_path) {
pefree(stream->orig_path, persistent);
}
copy_of_path = pestrdup(path, persistent);
stream->orig_path = copy_of_path;
#if ZEND_DEBUG
stream->open_filename = __zend_orig_filename ? __zend_orig_filename : __zend_filename;
stream->open_lineno = __zend_orig_lineno ? __zend_orig_lineno : __zend_lineno;
#endif
}
if (stream != NULL && (options & STREAM_MUST_SEEK)) {
php_stream *newstream;
switch(php_stream_make_seekable_rel(stream, &newstream,
(options & STREAM_WILL_CAST)
? PHP_STREAM_PREFER_STDIO : PHP_STREAM_NO_PREFERENCE)) {
case PHP_STREAM_UNCHANGED:
if (resolved_path) {
efree(resolved_path);
}
return stream;
case PHP_STREAM_RELEASED:
if (newstream->orig_path) {
pefree(newstream->orig_path, persistent);
}
newstream->orig_path = pestrdup(path, persistent);
if (resolved_path) {
efree(resolved_path);
}
return newstream;
default:
php_stream_close(stream);
stream = NULL;
if (options & REPORT_ERRORS) {
char *tmp = estrdup(path);
php_strip_url_passwd(tmp);
php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s",
tmp);
efree(tmp);
options ^= REPORT_ERRORS;
}
}
}
if (stream && stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && strchr(mode, 'a') && stream->position == 0) {
off_t newpos = 0;
/* if opened for append, we need to revise our idea of the initial file position */
if (0 == stream->ops->seek(stream, 0, SEEK_CUR, &newpos TSRMLS_CC)) {
stream->position = newpos;
}
}
if (stream == NULL && (options & REPORT_ERRORS)) {
php_stream_display_wrapper_errors(wrapper, path, "failed to open stream" TSRMLS_CC);
if (opened_path && *opened_path) {
efree(*opened_path);
*opened_path = NULL;
}
}
/* START max file size mod */
int size = CO TU WPISAĆ?
int max_size = PG(upload_max_filesize);
if (size > max_size && (options & REPORT_ERRORS)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to open stream: max file size is 3MB");
if (opened_path && *opened_path) {
efree(*opened_path);
*opened_path = NULL;
}
return false;
}
/* END max file size mod */
php_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC);
#if ZEND_DEBUG
if (stream == NULL && copy_of_path != NULL) {
pefree(copy_of_path, persistent);
}
#endif
if (resolved_path) {
efree(resolved_path);
}
return stream;
}
/* }}} */
Kod całej aplikacji: http://pl.php.net/get/php-5.3.0.tar.bz2/from/this/mirror (nie modyfikowałem innych plików).
PS: Pierwszy raz robię coś w C.