PHP_FE(parse_ini_file, NULL)
PHP_FE(is_uploaded_file, NULL)
+ PHP_FE(move_uploaded_file, NULL)
/* functions from reg.c */
PHP_FE(ereg, third_argument_force_ref)
PHP_FUNCTION(move_uploaded_file)
{
zval **path, **new_path;
+ zend_bool successful=0;
SLS_FETCH();
if (!SG(rfc1867_uploaded_files)) {
RETURN_FALSE;
}
+ V_UNLINK(Z_STRVAL_PP(new_path));
if (rename(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path))==0) {
- RETURN_TRUE;
+ successful=1;
+ } else if (php_copy_file(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path))==SUCCESS) {
+ V_UNLINK(Z_STRVAL_PP(path));
+ successful=1;
}
- if (php_copy_file(Z_STRVAL_PP(path), Z_STRVAL_PP(new_path))==SUCCESS) {
- unlink(Z_STRVAL_PP(path));
- RETURN_TRUE;
+ if (successful) {
+ zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1);
+ } else {
+ php_error(E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path));
}
-
- php_error(E_WARNING, "Unable to move '%s' to '%s'", Z_STRVAL_PP(path), Z_STRVAL_PP(new_path));
-
- RETURN_FALSE;
+ RETURN_BOOL(successful);
}
PHP_FUNCTION(unregister_tick_function);
PHP_FUNCTION(is_uploaded_file);
+PHP_FUNCTION(move_uploaded_file);
/* From the INI parser */
PHP_FUNCTION(parse_ini_file);
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
+ | Stig Bakken <ssb@fast.no> |
+ | Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
| PHP 4.0 patches by Thies C. Arntzen (thies@digicol.de) |
+----------------------------------------------------------------------+
*/
static void _file_fopen_dtor(FILE *pipe);
static void _file_popen_dtor(FILE *pipe);
static void _file_socket_dtor(int *sock);
-static void _file_upload_dtor(char *file);
/* sharing globals is *evil* */
-static int le_fopen,le_popen, le_socket, le_uploads;
+static int le_fopen, le_popen, le_socket;
/* }}} */
-/* {{{ tempnam */
+/* {{{ php_open_temporary_file */
+
+/* Loosely based on a tempnam() implementation by UCLA */
-#ifndef HAVE_TEMPNAM
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
# endif
#endif
-char *tempnam(const char *dir, const char *pfx)
+static FILE *php_do_open_temporary_file(char *path, const char *pfx, char **opened_path_p)
+{
+ char *trailing_slash;
+ FILE *fp;
+ char *opened_path;
+
+ if (!path) {
+ return NULL;
+ }
+
+ if (!(opened_path = emalloc(MAXPATHLEN))) {
+ return NULL;
+ }
+
+ if (*path+strlen(path)-1 == '/') {
+ trailing_slash = "";
+ } else {
+ trailing_slash = "/";
+ }
+
+ (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx);
+
+#ifdef PHP_WIN32
+ if (GetTempFileName(path, pfx, 0, opened_path)) {
+ fp = V_FOPEN(opened_path, "wb");
+ } else {
+ fp = NULL;
+ }
+#elif defined(HAVE_MKSTEMP)
+ fd = mkstemp(opened_path);
+ if (fd==-1) {
+ fp = NULL;
+ } else {
+ fp = fdopen(fd, "wb");
+ }
+#else
+ if (mktemp(opened_path)) {
+ fp = V_FOPEN(opened_path, "wb");
+ } else {
+ fp = NULL;
+ }
+#endif
+ if (!fp || !opened_path_p) {
+ efree(opened_path);
+ } else {
+ *opened_path_p = opened_path;
+ }
+ return fp;
+}
+
+/* Unlike tempnam(), the supplied dir argument takes precedence
+ * over the TMPDIR environment variable
+ * This function should do its best to return a file pointer to a newly created
+ * unique file, on every platform.
+ */
+FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p)
{
- int save_errno;
- char *f, *name;
static char path_tmp[] = "/tmp";
+ FILE *fp;
- if (!(name = emalloc(MAXPATHLEN))) {
- return(NULL);
- }
if (!pfx) {
pfx = "tmp.";
}
-
- if (f = getenv("TMPDIR")) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
+
+ if (opened_path_p) {
+ *opened_path_p = NULL;
+ }
+
+ if ((fp=php_do_open_temporary_file((char *) dir, pfx, opened_path_p))) {
+ return fp;
+ }
+
+ if ((fp=php_do_open_temporary_file(getenv("TMPDIR"), pfx, opened_path_p))) {
+ return fp;
+ }
+#if PHP_WIN32
+ {
+ char *TempPath;
+
+ TempPath = (char *) emalloc(MAXPATHLEN);
+ if (GetTempPath(MAXPATHLEN, TempPath)) {
+ fp = php_do_open_temporary_file(TempPath, pfx, opened_path_p);
+ }
+ efree(TempPath);
+ return fp;
+ }
+#else
+ if ((fp=php_do_open_temporary_file(P_tmpdir, pfx, opened_path_p))) {
+ return fp;
}
-
- if (f = (char *)dir) {
- (void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
- *(f + strlen(f) - 1) == '/'? "": "/", pfx);
- if (f = mktemp(name))
- return(f);
- }
-
- f = P_tmpdir;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- f = path_tmp;
- (void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
- if (f = mktemp(name))
- return(f);
-
- save_errno = errno;
- efree(name);
- errno = save_errno;
- return(NULL);
-}
+ if ((fp=php_do_open_temporary_file(path_tmp, pfx, opened_path_p))) {
+ return fp;
+ }
#endif
+ return NULL;
+}
+
+
/* }}} */
/* {{{ Module-Stuff */
}
-static void _file_upload_dtor(char *file)
-{
- V_UNLINK(file);
-}
-
-
static void _file_fopen_dtor(FILE *fp)
{
fclose(fp);
}
-PHPAPI int php_file_le_uploads(void) /* XXX doe we really want this???? */
-{
- return le_uploads;
-}
-
-
#ifdef ZTS
static void php_file_init_globals(php_file_globals *file_globals)
{
le_fopen = register_list_destructors(_file_fopen_dtor, NULL);
le_popen = register_list_destructors(_file_popen_dtor, NULL);
le_socket = register_list_destructors(_file_socket_dtor, NULL);
- le_uploads = register_list_destructors(_file_upload_dtor, NULL);
#ifdef ZTS
file_globals_id = ts_allocate_id(sizeof(php_file_globals), (ts_allocate_ctor) php_file_init_globals, NULL);
{
pval **arg1, **arg2;
char *d;
- char *t;
+ char *opened_path;
char p[64];
+ FILE *fp;
if (ARG_COUNT(ht) != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
d = estrndup((*arg1)->value.str.val,(*arg1)->value.str.len);
strlcpy(p,(*arg2)->value.str.val,sizeof(p));
- t = tempnam(d,p);
- efree(d);
- if(!t) {
- RETURN_FALSE;
+
+ if ((fp = php_open_temporary_file(d, p, &opened_path))) {
+ fclose(fp);
+ RETVAL_STRING(opened_path, 0);
+ } else {
+ RETVAL_FALSE;
}
- RETURN_STRING(t,1);
+ efree(d);
}
/* }}} */
PHPAPI int php_file_le_fopen(void);
PHPAPI int php_file_le_popen(void);
PHPAPI int php_file_le_socket(void);
-PHPAPI int php_file_le_uploads(void);
PHPAPI int php_copy_file(char *src, char *dest);
+PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p);
#endif /* FILE_H */
{
zval **name, **sizeX, **sizeY, **frameRate, **r, **g, **b;
char *na, *tmpna;
+ zend_bool free_na;
SWFLS_FETCH();
if (ZEND_NUM_ARGS() != 7 ||
tmpna = Z_STRVAL_PP(name);
if (strcasecmp("php://stdout", tmpna) == 0) {
- na = tempnam(NULL, "php_swf_stdout");
+ FILE *fp;
+
+ fp = php_open_temporary_file(NULL, "php_swf_stdout", &na);
+ if (!fp) {
+ free_na = 0;
+ RETURN_FALSE;
+ }
unlink((const char *)na);
-
+ fclose(fp);
+ free_na = 1;
SWFG(use_file) = 0;
} else {
na = tmpna;
}
#ifdef VIRTUAL_DIR
- if (virtual_filepath(na, &na)) {
+ if (virtual_filepath(na, &tmpna)) {
+ if (free_na) {
+ efree(na);
+ }
return;
}
+ if (free_na) {
+ efree(na);
+ }
+ na = tmpna;
#endif
if (!SWFG(use_file))
SWFG(tmpfile_name) = na;
sapi_module.deactivate(SLS_C);
}
if (SG(rfc1867_uploaded_files)) {
- zend_hash_destroy(SG(rfc1867_uploaded_files));
- FREE_HASHTABLE(SG(rfc1867_uploaded_files));
+ destroy_uploaded_files_hash(SLS_C);
}
}
#include <stdio.h>
#include "php.h"
#include "ext/standard/php_standard.h"
-#include "ext/standard/file.h" /* for php_file_le_uploads() */
#include "zend_globals.h"
#include "php_globals.h"
#include "php_variables.h"
}
+static void free_filename(char **filename)
+{
+ efree(*filename);
+}
+
+
+static int unlink_filename(char **filename)
+{
+ V_UNLINK(*filename);
+ return 0;
+}
+
+
+void destroy_uploaded_files_hash(SLS_D)
+{
+ zend_hash_apply(SG(rfc1867_uploaded_files), (apply_func_t) unlink_filename);
+ zend_hash_destroy(SG(rfc1867_uploaded_files));
+ FREE_HASHTABLE(SG(rfc1867_uploaded_files));
+}
+
/*
* Split raw mime stream up into appropriate components
*/
static void php_mime_split(char *buf, int cnt, char *boundary, zval *array_ptr SLS_DC)
{
- char *ptr, *loc, *loc2, *loc3, *s, *name, *filename, *u, *fn;
+ char *ptr, *loc, *loc2, *loc3, *s, *name, *filename, *u, *temp_filename;
int len, state = 0, Done = 0, rem, urem;
int eolsize;
long bytes, max_file_size = 0;
FILE *fp;
int itype, is_arr_upload=0, arr_len=0;
zval *http_post_files=NULL;
+ zend_bool upload_successful;
+ zend_bool magic_quotes_gpc;
ELS_FETCH();
PLS_FETCH();
zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0);
ALLOC_HASHTABLE(SG(rfc1867_uploaded_files));
- zend_hash_init(SG(rfc1867_uploaded_files), 5, NULL, NULL, 0);
+ zend_hash_init(SG(rfc1867_uploaded_files), 5, NULL, (dtor_func_t) free_filename, 0);
ALLOC_ZVAL(http_post_files);
array_init(http_post_files);
SAFE_RETURN;
}
bytes = 0;
- fn = tempnam(PG(upload_tmp_dir), "php");
+
+ fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &temp_filename);
+ if (!fp) {
+ php_error(E_WARNING, "File upload error - unable to create a temporary file");
+ SAFE_RETURN;
+ }
if ((loc - ptr - 4) > PG(upload_max_filesize)) {
php_error(E_WARNING, "Max file size of %ld bytes exceeded - file [%s] not saved", PG(upload_max_filesize),namebuf);
- fn = "none";
+ upload_successful = 0;
} else if (max_file_size && ((loc - ptr - 4) > max_file_size)) {
php_error(E_WARNING, "Max file size exceeded - file [%s] not saved", namebuf);
- fn = "none";
+ upload_successful = 0;
} else if ((loc - ptr - 4) <= 0) {
- fn = "none";
+ upload_successful = 0;
} else {
- fp = V_FOPEN(fn, "wb");
- if (!fp) {
- php_error(E_WARNING, "File Upload Error - Unable to open temporary file [%s]", fn);
- SAFE_RETURN;
- }
bytes = fwrite(ptr, 1, loc - ptr - 4, fp);
- fclose(fp);
- zend_list_insert(fn,php_file_le_uploads()); /* Tell PHP about the file so the destructor can unlink it later */
if (bytes < (loc - ptr - 4)) {
php_error(E_WARNING, "Only %d bytes were written, expected to write %ld", bytes, loc - ptr - 4);
}
+ upload_successful = 1;
}
+ fclose(fp);
add_protected_variable(namebuf PLS_CC);
- safe_php_register_variable(namebuf, fn, NULL, 1 ELS_CC PLS_CC);
- {
- int dummy=1;
-
- zend_hash_add(SG(rfc1867_uploaded_files), namebuf, strlen(namebuf)+1, &dummy, sizeof(int), NULL);
+ if (!upload_successful) {
+ efree(temp_filename);
+ temp_filename = "none";
+ } else {
+ zend_hash_add(SG(rfc1867_uploaded_files), temp_filename, strlen(temp_filename)+1, &temp_filename, sizeof(char *), NULL);
}
+ magic_quotes_gpc = PG(magic_quotes_gpc);
+ PG(magic_quotes_gpc) = 0;
+ safe_php_register_variable(namebuf, temp_filename, NULL, 1 ELS_CC PLS_CC);
/* Add $foo[tmp_name] */
if(is_arr_upload) {
sprintf(lbuf, "%s[tmp_name][%s]", abuf, arr_index);
sprintf(lbuf, "%s[tmp_name]", namebuf);
}
add_protected_variable(lbuf PLS_CC);
- register_http_post_files_variable(lbuf, fn, http_post_files, 1 ELS_CC PLS_CC);
+ register_http_post_files_variable(lbuf, temp_filename, http_post_files, 1 ELS_CC PLS_CC);
+ PG(magic_quotes_gpc) = magic_quotes_gpc;
+
{
zval file_size;
#define FILE_UPLOAD_INPUT_BUFFER_SIZE 8192
+void destroy_uploaded_files_hash(SLS_D);
+
#endif /* RFC1867_H */