⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exec.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.txt                                  |   | If you did not receive a copy of the PHP license and are unable to   |   | obtain it through the world-wide-web, please send a note to          |   | license@php.net so we can mail you a copy immediately.               |   +----------------------------------------------------------------------+   | Author: Rasmus Lerdorf                                               |   +----------------------------------------------------------------------+ *//* $Id: exec.c,v 1.84.2.15.2.4 2007/01/01 09:46:48 sebastian Exp $ */#include <stdio.h>#include "php.h"#include <ctype.h>#include "php_string.h"#include "safe_mode.h"#include "ext/standard/head.h"#include "ext/standard/file.h"#include "exec.h"#include "php_globals.h"#include "SAPI.h"#if HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#if HAVE_SIGNAL_H#include <signal.h>#endif#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif#if HAVE_SYS_STAT_H#include <sys/stat.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif/* {{{ php_make_safe_mode_command */static int php_make_safe_mode_command(char *cmd, char **safecmd TSRMLS_DC){	int lcmd, larg0, ldir, len, overflow_limit;	char *space, *sep, *arg0;	if (!PG(safe_mode)) {		*safecmd = estrdup(cmd);		return SUCCESS;	}	lcmd = strlen(cmd);	ldir = strlen(PG(safe_mode_exec_dir));	len = lcmd + ldir + 2;	overflow_limit = len;	arg0 = emalloc(len);		strcpy(arg0, cmd);		space = strchr(arg0, ' ');	if (space) {		*space = '\0';	}	larg0 = strlen(arg0);	if (strstr(arg0, "..")) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No '..' components allowed in path");		efree(arg0);		return FAILURE;	}	*safecmd = emalloc(len);	strcpy(*safecmd, PG(safe_mode_exec_dir));	overflow_limit -= ldir;		sep = strrchr(arg0, PHP_DIR_SEPARATOR);	if (sep) {		strcat(*safecmd, sep);		overflow_limit -= strlen(sep);	} else {		strcat(*safecmd, "/");		strcat(*safecmd, arg0);		overflow_limit -= larg0 + 1;	}	if (space) {		strncat(*safecmd, cmd + larg0, overflow_limit);	}	efree(arg0);	arg0 = php_escape_shell_cmd(*safecmd);	efree(*safecmd);	*safecmd = arg0;	return SUCCESS;}/* }}} *//* {{{ php_Exec * If type==0, only last line of output is returned (exec) * If type==1, all lines will be printed and last lined returned (system) * If type==2, all lines will be saved to given array (exec with &$array) * If type==3, output will be printed binary, no lines will be saved or returned (passthru) * */int php_Exec(int type, char *cmd, pval *array, pval *return_value TSRMLS_DC){	FILE *fp;	char *buf, *tmp=NULL;	int buflen = 0;	int t, l, output=1;	int overflow_limit, lcmd, ldir;	char *b, *c, *d=NULL;	php_stream *stream = NULL;	int pclose_return = 0;#if PHP_SIGCHILD	void (*sig_handler)();#endif	buf = (char *) emalloc(EXEC_INPUT_BUF);	if (!buf) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to emalloc %d bytes for exec buffer", EXEC_INPUT_BUF);		return -1;	}	buflen = EXEC_INPUT_BUF;	if (PG(safe_mode)) {		lcmd = strlen(cmd);		ldir = strlen(PG(safe_mode_exec_dir));		l = lcmd + ldir + 2;		overflow_limit = l;		c = strchr(cmd, ' ');		if (c) *c = '\0';		if (strstr(cmd, "..")) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "No '..' components allowed in path");			efree(buf);			return -1;		}		d = emalloc(l);		strcpy(d, PG(safe_mode_exec_dir));		overflow_limit -= ldir;		b = strrchr(cmd, PHP_DIR_SEPARATOR);		if (b) {			strcat(d, b);			overflow_limit -= strlen(b);		} else {			strcat(d, "/");			strcat(d, cmd);			overflow_limit-=(strlen(cmd)+1);		}		if (c) {			*c = ' ';			strncat(d, c, overflow_limit);		}		tmp = php_escape_shell_cmd(d);		efree(d);		d = tmp;#if PHP_SIGCHILD		sig_handler = signal (SIGCHLD, SIG_DFL);#endif#ifdef PHP_WIN32		fp = VCWD_POPEN(d, "rb");#else		fp = VCWD_POPEN(d, "r");#endif		if (!fp) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", d);			efree(d);			efree(buf);#if PHP_SIGCHILD			signal (SIGCHLD, sig_handler);#endif			return -1;		}	} else { /* not safe_mode */#if PHP_SIGCHILD		sig_handler = signal (SIGCHLD, SIG_DFL);#endif#ifdef PHP_WIN32		fp = VCWD_POPEN(cmd, "rb");#else		fp = VCWD_POPEN(cmd, "r");#endif		if (!fp) {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd);			efree(buf);#if PHP_SIGCHILD			signal (SIGCHLD, sig_handler);#endif			return -1;		}	}	buf[0] = '\0';	if (type==2) {		if (Z_TYPE_P(array) != IS_ARRAY) {			pval_destructor(array);			array_init(array);		}	}	/* we register the resource so that case of an aborted connection the 	 * fd gets pclosed	 */	stream = php_stream_fopen_from_pipe(fp, "rb");	if (type != 3) {		l=0;		while ( !feof(fp) || l != 0 ) {			l = 0;			/* Read a line or fill the buffer, whichever comes first */			do {				if ( buflen <= (l+1) ) {					buf = erealloc(buf, buflen + EXEC_INPUT_BUF);					if ( buf == NULL ) {						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to erealloc %d bytes for exec buffer", 								buflen + EXEC_INPUT_BUF);#if PHP_SIGCHILD						signal (SIGCHLD, sig_handler);#endif						return -1;					}					buflen += EXEC_INPUT_BUF;				}				if ( fgets(&(buf[l]), buflen - l, fp) == NULL ) {					/* eof */					break;				}				l += strlen(&(buf[l]));			} while ( (l > 0) && (buf[l-1] != '\n') );			if ( feof(fp) && (l == 0) ) {				break;			}					if (type == 1) {				if (output) PUTS(buf);				sapi_flush(TSRMLS_C);			}			else if (type == 2) {				/* strip trailing whitespaces */					l = strlen(buf);				t = l;				while (l-- && isspace(((unsigned char *)buf)[l]));				if (l < t) {					buf[l + 1] = '\0';				}				add_next_index_string(array, buf, 1);			}		}		/* strip trailing spaces */		l = strlen(buf);		t = l;		while (l && isspace(((unsigned char *)buf)[l - 1])) {			l--;		}		if (l < t) buf[l] = '\0';		/* Return last line from the shell command */		if (PG(magic_quotes_runtime)) {			int len;			tmp = php_addslashes(buf, 0, &len, 0 TSRMLS_CC);			RETVAL_STRINGL(tmp, len, 0);		} else {			RETVAL_STRINGL(buf, l, 1);		}	} else {		size_t b;		while((b = php_stream_read(stream, buf, EXEC_INPUT_BUF)) > 0) {			if (output) {				PHPWRITE(buf, b);			}		}	}	pclose_return = php_stream_close(stream); #if PHP_SIGCHILD	signal (SIGCHLD, sig_handler);#endif	if (d) {		efree(d);	}	efree(buf);	return pclose_return;}/* }}} *//* {{{ proto string exec(string command [, array output [, int return_value]])   Execute an external program */PHP_FUNCTION(exec){	pval **arg1, **arg2, **arg3;	int arg_count = ZEND_NUM_ARGS();	int ret;	if (arg_count < 1 || arg_count > 3 || zend_get_parameters_ex(arg_count, &arg1, &arg2, &arg3) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (!Z_STRLEN_PP(arg1)) {		PHP_EMPTY_EXEC_PARAM;	}		switch (arg_count) {		case 1:			ret = php_Exec(0, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC);			break;		case 2:			ret = php_Exec(2, Z_STRVAL_PP(arg1), *arg2, return_value TSRMLS_CC);			break;		case 3:			ret = php_Exec(2, Z_STRVAL_PP(arg1), *arg2, return_value TSRMLS_CC);			Z_TYPE_PP(arg3) = IS_LONG;			Z_LVAL_PP(arg3)=ret;			break;	}}/* }}} *//* {{{ proto int system(string command [, int return_value])   Execute an external program and display output */PHP_FUNCTION(system){	pval **arg1, **arg2;	int arg_count = ZEND_NUM_ARGS();	int ret;	if (arg_count < 1 || arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (!Z_STRLEN_PP(arg1)) {		PHP_EMPTY_EXEC_PARAM;	}		switch (arg_count) {		case 1:			ret = php_Exec(1, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC);			break;		case 2:			ret = php_Exec(1, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC);			Z_TYPE_PP(arg2) = IS_LONG;			Z_LVAL_PP(arg2)=ret;			break;	}}/* }}} *//* {{{ proto void passthru(string command [, int return_value])   Execute an external program and display raw output */PHP_FUNCTION(passthru){	pval **arg1, **arg2;	int arg_count = ZEND_NUM_ARGS();	int ret;	if (arg_count < 1 || arg_count > 2 || zend_get_parameters_ex(arg_count, &arg1, &arg2) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (!Z_STRLEN_PP(arg1)) {		PHP_EMPTY_EXEC_PARAM;	}		switch (arg_count) {		case 1:			ret = php_Exec(3, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC);			break;		case 2:			ret = php_Exec(3, Z_STRVAL_PP(arg1), NULL, return_value TSRMLS_CC);			Z_TYPE_PP(arg2) = IS_LONG;			Z_LVAL_PP(arg2)=ret;			break;	}}/* }}} *//* {{{ php_escape_shell_cmd   Escape all chars that could possibly be used to   break out of a shell command   This function emalloc's a string and returns the pointer.   Remember to efree it when done with it.   *NOT* safe for binary strings*/PHPAPI char *php_escape_shell_cmd(char *str) {	register int x, y, l;	char *cmd;	char *p = NULL;	l = strlen(str);	cmd = emalloc(2 * l + 1);		for (x = 0, y = 0; x < l; x++) {		switch (str[x]) {			case '"':			case '\'':#ifndef PHP_WIN32				if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {					/* noop */				} else if (p && *p == str[x]) {					p = NULL;				} else {					cmd[y++] = '\\';				}				cmd[y++] = str[x];				break;#endif			case '#': /* This is character-set independent */			case '&':			case ';':			case '`':			case '|':			case '*':			case '?':			case '~':			case '<':			case '>':			case '^':			case '(':			case ')':			case '[':			case ']':			case '{':			case '}':			case '$':			case '\\':			case '\x0A': /* excluding these two */			case '\xFF':#ifdef PHP_WIN32			/* since Windows does not allow us to escape these chars, just remove them */			case '%':				cmd[y++] = ' ';				break;#endif				cmd[y++] = '\\';				/* fall-through */			default:				cmd[y++] = str[x];		}	}	cmd[y] = '\0';	return cmd;}/* }}} *//* {{{ php_escape_shell_arg */PHPAPI char *php_escape_shell_arg(char *str) {	int x, y, l;	char *cmd;	y = 0;	l = strlen(str);		cmd = emalloc(4 * l + 3); /* worst case */#ifdef PHP_WIN32	cmd[y++] = '"';#else	cmd[y++] = '\'';#endif		for (x = 0; x < l; x++) {		switch (str[x]) {#ifdef PHP_WIN32		case '"':		case '%':			cmd[y++] = ' ';			break;#else		case '\'':			cmd[y++] = '\'';			cmd[y++] = '\\';			cmd[y++] = '\'';#endif			/* fall-through */		default:			cmd[y++] = str[x];		}	}#ifdef PHP_WIN32	cmd[y++] = '"';#else	cmd[y++] = '\'';#endif	cmd[y] = '\0';	return cmd;}/* }}} *//* {{{ proto string escapeshellcmd(string command)   Escape shell metacharacters */PHP_FUNCTION(escapeshellcmd){	pval **arg1;	char *cmd = NULL;	if (zend_get_parameters_ex(1, &arg1) == FAILURE) {		WRONG_PARAM_COUNT;	}		convert_to_string_ex(arg1);	if (Z_STRLEN_PP(arg1)) {		cmd = php_escape_shell_cmd(Z_STRVAL_PP(arg1));		RETVAL_STRING(cmd, 1);		efree(cmd);	}}/* }}} */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -