Пример #1
0
static int ps_files_cleanup_dir(const char *dirname, zend_long maxlifetime)
{
	DIR *dir;
	char dentry[sizeof(struct dirent) + MAXPATHLEN];
	struct dirent *entry = (struct dirent *) &dentry;
	zend_stat_t sbuf;
	char buf[MAXPATHLEN];
	time_t now;
	int nrdels = 0;
	size_t dirname_len;

	dir = opendir(dirname);
	if (!dir) {
		php_error_docref(NULL, E_NOTICE, "ps_files_cleanup_dir: opendir(%s) failed: %s (%d)", dirname, strerror(errno), errno);
		return (0);
	}

	time(&now);

	dirname_len = strlen(dirname);

	if (dirname_len >= MAXPATHLEN) {
		php_error_docref(NULL, E_NOTICE, "ps_files_cleanup_dir: dirname(%s) is too long", dirname);
		closedir(dir);
		return (0);
	}

	/* Prepare buffer (dirname never changes) */
	memcpy(buf, dirname, dirname_len);
	buf[dirname_len] = PHP_DIR_SEPARATOR;

	while (php_readdir_r(dir, (struct dirent *) dentry, &entry) == 0 && entry) {
		/* does the file start with our prefix? */
		if (!strncmp(entry->d_name, FILE_PREFIX, sizeof(FILE_PREFIX) - 1)) {
			size_t entry_len = strlen(entry->d_name);

			/* does it fit into our buffer? */
			if (entry_len + dirname_len + 2 < MAXPATHLEN) {
				/* create the full path.. */
				memcpy(buf + dirname_len + 1, entry->d_name, entry_len);

				/* NUL terminate it and */
				buf[dirname_len + entry_len + 1] = '\0';

				/* check whether its last access was more than maxlifetime ago */
				if (VCWD_STAT(buf, &sbuf) == 0 &&
						(now - sbuf.st_mtime) > maxlifetime) {
					VCWD_UNLINK(buf);
					nrdels++;
				}
			}
		}
	}

	closedir(dir);

	return (nrdels);
}
Пример #2
0
PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*selector) (const struct dirent *entry), int (*compare) (const struct dirent **a, const struct dirent **b))
{
	DIR *dirp = NULL;
	struct dirent **vector = NULL;
	int vector_size = 0;
	int nfiles = 0;
	char entry[sizeof(struct dirent)+MAXPATHLEN];
	struct dirent *dp = (struct dirent *)&entry;

	if (namelist == NULL) {
		return -1;
	}

	if (!(dirp = opendir(dirname))) {
		return -1;
	}

	while (!php_readdir_r(dirp, (struct dirent *)entry, &dp) && dp) {
		int dsize = 0;
		struct dirent *newdp = NULL;

		if (selector && (*selector)(dp) == 0) {
			continue;
		}

		if (nfiles == vector_size) {
			struct dirent **newv;
			if (vector_size == 0) {
				vector_size = 10;
			} else { 
				vector_size *= 2;
			}

			newv = (struct dirent **) realloc (vector, vector_size * sizeof (struct dirent *));
			if (!newv) {
				return -1;
			}
			vector = newv;
		}

		dsize = sizeof (struct dirent) + ((strlen(dp->d_name) + 1) * sizeof(char));
		newdp = (struct dirent *) malloc(dsize);

		if (newdp == NULL) {
			goto fail;
		}

		vector[nfiles++] = (struct dirent *) memcpy(newdp, dp, dsize);
	}

	closedir(dirp);

	*namelist = vector;

	if (compare) {
		qsort (*namelist, nfiles, sizeof(struct dirent *), compare);
	}

	return nfiles;

fail:
	while (nfiles-- > 0) {
		free(vector[nfiles]);
	}
	free(vector);
	return -1;	
}
Пример #3
0
static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
{
	pval **arg;
	php_dir *dirp;
	DIRLS_FETCH();
	
	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
		WRONG_PARAM_COUNT;
	}
	convert_to_string_ex(arg);

	if (php_check_open_basedir((*arg)->value.str.val)) {
		RETURN_FALSE;
	}
	
	dirp = emalloc(sizeof(php_dir));

	dirp->dir = VCWD_OPENDIR((*arg)->value.str.val);

#ifdef PHP_WIN32
	if (!dirp->dir || dirp->dir->finished) {
		if (dirp->dir) {
			closedir(dirp->dir);
		}
#else
	if (!dirp->dir) {
#endif
		efree(dirp);
		php_error(E_WARNING, "OpenDir: %s (errno %d)", strerror(errno), errno);
		RETURN_FALSE;
	}

	dirp->id = zend_list_insert(dirp,le_dirp);

	php_set_default_dir(dirp->id DIRLS_CC);

	if (createobject) {
		object_init_ex(return_value, dir_class_entry_ptr);
		add_property_stringl(return_value, "path", (*arg)->value.str.val, (*arg)->value.str.len, 1);
		add_property_resource(return_value, "handle", dirp->id);
		zend_list_addref(dirp->id);
	} else {
		RETURN_RESOURCE(dirp->id);
	}
}

/* }}} */
/* {{{ proto int opendir(string path)
   Open a directory and return a dir_handle */

PHP_FUNCTION(opendir)
{
	_php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
}

/* }}} */
/* {{{ proto class dir(string directory)
   Directory class with properties, handle and class and methods read, rewind and close */

PHP_FUNCTION(getdir)
{
	_php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
}

/* }}} */
/* {{{ proto void closedir([int dir_handle])
   Close directory connection identified by the dir_handle */

PHP_FUNCTION(closedir)
{
	pval **id, **tmp, *myself;
	php_dir *dirp;
	DIRLS_FETCH();

	FETCH_DIRP();

	zend_list_delete(dirp->id);

	if (dirp->id == DIRG(default_dir)) {
		php_set_default_dir(-1 DIRLS_CC);
	}
}

/* }}} */

#if defined(HAVE_CHROOT) && !defined(ZTS)
/* {{{ proto int chroot(string directory)
   Change root directory */

PHP_FUNCTION(chroot)
{
	pval **arg;
	int ret;
	
	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
		WRONG_PARAM_COUNT;
	}
	convert_to_string_ex(arg);

	ret = chroot((*arg)->value.str.val);
	
	if (ret != 0) {
		php_error(E_WARNING, "chroot: %s (errno %d)", strerror(errno), errno);
		RETURN_FALSE;
	}

	ret = chdir("/");
	
	if (ret != 0) {
		php_error(E_WARNING, "chdir: %s (errno %d)", strerror(errno), errno);
		RETURN_FALSE;
	}

	RETURN_TRUE;
}

/* }}} */
#endif

/* {{{ proto int chdir(string directory)
   Change the current directory */

PHP_FUNCTION(chdir)
{
	pval **arg;
	int ret;
	PLS_FETCH();
	
	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) {
		WRONG_PARAM_COUNT;
	}
	convert_to_string_ex(arg);

	if (PG(safe_mode) && !php_checkuid((*arg)->value.str.val, NULL, CHECKUID_ALLOW_ONLY_DIR)) {
		RETURN_FALSE;
	}
	ret = VCWD_CHDIR((*arg)->value.str.val);
	
	if (ret != 0) {
		php_error(E_WARNING, "ChDir: %s (errno %d)", strerror(errno), errno);
		RETURN_FALSE;
	}

	RETURN_TRUE;
}

/* }}} */
/* {{{ proto string getcwd(void)
   Gets the current directory */

PHP_FUNCTION(getcwd)
{
	char path[MAXPATHLEN];
	char *ret=NULL;
	
	if (ZEND_NUM_ARGS() != 0) {
		WRONG_PARAM_COUNT;
	}

#if HAVE_GETCWD
	ret = VCWD_GETCWD(path, MAXPATHLEN);
#elif HAVE_GETWD
	ret = VCWD_GETWD(path);
/*
 * #warning is not ANSI C
 * #else
 * #warning no proper getcwd support for your site
 */
#endif

	if (ret) {
		RETURN_STRING(path,1);
	} else {
		RETURN_FALSE;
	}
}

/* }}} */
/* {{{ proto void rewinddir([int dir_handle])
   Rewind dir_handle back to the start */

PHP_FUNCTION(rewinddir)
{
	pval **id, **tmp, *myself;
	php_dir *dirp;
	DIRLS_FETCH();
	
	FETCH_DIRP();

	rewinddir(dirp->dir);
}
/* }}} */
/* {{{ proto string readdir([int dir_handle])
   Read directory entry from dir_handle */

PHP_NAMED_FUNCTION(php_if_readdir)
{
	pval **id, **tmp, *myself;
	php_dir *dirp;
	char entry[sizeof(struct dirent)+MAXPATHLEN];
	struct dirent *result = (struct dirent *)&entry; /* patch for libc5 readdir problems */
	DIRLS_FETCH();

	FETCH_DIRP();

	if (php_readdir_r(dirp->dir, (struct dirent *) entry, &result) == 0 && result) {
		RETURN_STRINGL(result->d_name, strlen(result->d_name), 1);
	}
	RETURN_FALSE;
}