Пример #1
0
int tc_destroy(TokenCache *tc)
{
	register int i;
	TLS_VARS;

	for (i = 0; i < tc->count; i++) {
		pval_destructor(&tc->tokens[i].phplval _INLINE_TLS);
	}
	if (tc->tokens) {
		efree(tc->tokens);
	}
	return SUCCESS;
}
Пример #2
0
/*
 * 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)
{
	FILE *fp;
	char *buf, *tmp=NULL;
	int buflen = 0;
	int t, l, output=1;
	int overflow_limit, lcmd, ldir;
	int rsrc_id;
	char *b, *c, *d=NULL;
#if PHP_SIGCHILD
	void (*sig_handler)();
#endif
	PLS_FETCH();
	FLS_FETCH();

	buf = (char*) emalloc(EXEC_INPUT_BUF);
    if (!buf) {
		php_error(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(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(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(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
	 */

	rsrc_id = ZEND_REGISTER_RESOURCE(NULL, fp, php_file_le_popen());

	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(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();
			}
			else if (type == 2) {
				/* strip trailing whitespaces */	
				l = strlen(buf);
				t = l;
				while (l-- && isspace((int)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((int)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);
			RETVAL_STRINGL(tmp,len,0);
		} else {
			RETVAL_STRINGL(buf,l,1);
		}
	} else {
		int b, i;

		while ((b = fread(buf, 1, buflen, fp)) > 0) {
			for (i = 0; i < b; i++)
				if (output) (void)PUTC(buf[i]);
		}
	}

	/* the zend_list_delete will pclose our popen'ed process */
	zend_list_delete(rsrc_id); 

#if HAVE_SYS_WAIT_H
	if (WIFEXITED(FG(pclose_ret))) {
		FG(pclose_ret) = WEXITSTATUS(FG(pclose_ret));
	}
#endif
#if PHP_SIGCHILD
	signal (SIGCHLD, sig_handler);
#endif
	if (d) {
		efree(d);
	}
	efree(buf);
	return FG(pclose_ret);
}
Пример #3
0
/*
 * 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)
 *
 */
static int _Exec(int type, char *cmd, pval *array, pval *return_value)
{
	FILE *fp;
	char *buf, *tmp=NULL;
    int buflen=0;
	int t, l, ret, output=1;
	int overflow_limit, lcmd, ldir;
	char *b, *c, *d=NULL;
	TLS_VARS;

    buf = (char*) emalloc(EXEC_INPUT_BUF);
    if (!buf) {
		php3_error(E_WARNING, "Unable to emalloc %d bytes", EXEC_INPUT_BUF);
		return -1;
    }
    buflen = EXEC_INPUT_BUF;

#ifdef WIN32
	(void)AllocConsole(); /* We don't care if this fails. */
#endif

	if (php3_ini.safe_mode) {
		lcmd = strlen(cmd);
		ldir = strlen(php3_ini.safe_mode_exec_dir);
		l = lcmd + ldir + 2;
		overflow_limit = l;
		c = strchr(cmd, ' ');
		if (c) *c = '\0';
		if (strstr(cmd, "..")) {
			php3_error(E_WARNING, "No '..' components allowed in path");
            efree(buf);
			return -1;
		}
		d = emalloc(l);
		strcpy(d, php3_ini.safe_mode_exec_dir);
		overflow_limit -= ldir;
		b = strrchr(cmd, '/');
		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 = _php3_escapeshellcmd(d);
		efree(d);
		d = tmp;
#if WIN32|WINNT
		fp = popen(d, "rb");
#else
		fp = popen(d, "r");
#endif
		if (!fp) {
			php3_error(E_WARNING, "Unable to fork [%s]", d);
			efree(d);
            efree(buf);
			return -1;
		}
	} else { /* not safe_mode */
#if WIN32|WINNT
		fp = popen(cmd, "rb");
#else
		fp = popen(cmd, "r");
#endif
		if (!fp) {
			php3_error(E_WARNING, "Unable to fork [%s]", cmd);
            efree(buf);
			return -1;
		}
	}
	buf[0] = '\0';
	if (type == 1 || type == 3) {
		output=php3_header();
	}
	if (type==2) {
		if (array->type != IS_ARRAY) {
			pval_destructor(array _INLINE_TLS);
			array_init(array);
		}
	}
	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 ) {
						php3_error(E_WARNING, "Unable to erealloc %d bytes", 
								buflen + EXEC_INPUT_BUF);
						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);
#if APACHE
#  if MODULE_MAGIC_NUMBER > 19970110
				if (output) rflush(GLOBAL(php3_rqst));
#  else
				if (output) bflush(GLOBAL(php3_rqst)->connection->client);
#  endif
#endif
#if CGI_BINARY
				fflush(stdout);
#endif
#if FHTTPD
                               /* fhttpd doesn't flush */
#endif
#if USE_SAPI
				GLOBAL(sapi_rqst)->flush(GLOBAL(sapi_rqst)->scid);
#endif
			}
			else if (type == 2) {
				pval tmp;
			
				/* strip trailing whitespaces */	
				l = strlen(buf);
				t = l;
				while (l-- && isspace((int)buf[l]));
				if (l < t) buf[l + 1] = '\0';
				tmp.value.str.len = strlen(buf);
				tmp.value.str.val = estrndup(buf,tmp.value.str.len);
				tmp.type = IS_STRING;
				_php3_hash_next_index_insert(array->value.ht,(void *) &tmp, sizeof(pval), NULL);
			}
		}

		/* strip trailing spaces */
		l = strlen(buf);
		t = l;
		while (l && isspace((int)buf[--l]));
		if (l < t) buf[l + 1] = '\0';

		/* Return last line from the shell command */
		if(php3_ini.magic_quotes_runtime) {
			int len;
		
			tmp = _php3_addslashes(buf, 0, &len, 0);
			RETVAL_STRINGL(tmp,len,0);
		} else {
			RETVAL_STRINGL(buf,l+1,1);
		}
	} else {
		int b, i;

		while ((b = fread(buf, 1, buflen, fp)) > 0) {
			for (i = 0; i < b; i++)
				if (output) PUTC(buf[i]);
		}
	}

	ret = pclose(fp);
#ifdef HAVE_SYS_WAIT_H
	if (WIFEXITED(ret)) {
		ret = WEXITSTATUS(ret);
	}
#endif

	if (d) efree(d);
    efree(buf);
	return ret;
}