mirror of
https://github.com/php-win-ext/pecl-expect.git
synced 2026-03-24 05:02:05 +01:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
403fa58b6f | ||
|
|
832872beac | ||
|
|
3fb8cf045d | ||
|
|
60eb6b9f16 | ||
|
|
cc2e72e3d2 | ||
|
|
d19b005e00 | ||
|
|
9d83d267c2 | ||
|
|
0fdba09ee3 | ||
|
|
7423b65a2e | ||
|
|
9ff8bd236f | ||
|
|
962f488073 | ||
|
|
7e6b652293 | ||
|
|
6fafe17e77 | ||
|
|
18ea03b802 | ||
|
|
a291a8ff3b | ||
|
|
48d03837f9 | ||
|
|
5fdde4afbf | ||
|
|
98a048f820 | ||
|
|
c02699dde7 | ||
|
|
8133790622 | ||
|
|
178e5c07c5 | ||
|
|
9b925ac532 | ||
|
|
4411953272 | ||
|
|
f80a041dac | ||
|
|
ea50047133 | ||
|
|
e16b06dede | ||
|
|
80e342cf6b | ||
|
|
3e030e95e6 | ||
|
|
e4b08ad2de | ||
|
|
ce1a540073 | ||
|
|
f85ba457db | ||
|
|
b7d18cfbb9 | ||
|
|
c5895a300f | ||
|
|
925378d4ae | ||
|
|
4e2f9109e1 | ||
|
|
f6251794c5 | ||
|
|
2246eef8d7 | ||
|
|
50ecf39bfd | ||
|
|
41baa86ee3 | ||
|
|
c206870203 | ||
|
|
1ac4b57036 | ||
|
|
f2d7fbb1d1 | ||
|
|
d7abe0572c | ||
|
|
e33a147aef | ||
|
|
17d7c347b8 | ||
|
|
549a25aae3 |
68
LICENSE
Normal file
68
LICENSE
Normal file
@@ -0,0 +1,68 @@
|
||||
--------------------------------------------------------------------
|
||||
The PHP License, version 3.01
|
||||
Copyright (c) 1999 - 2014 The PHP Group. All rights reserved.
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, is permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The name "PHP" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission. For
|
||||
written permission, please contact group@php.net.
|
||||
|
||||
4. Products derived from this software may not be called "PHP", nor
|
||||
may "PHP" appear in their name, without prior written permission
|
||||
from group@php.net. You may indicate that your software works in
|
||||
conjunction with PHP by saying "Foo for PHP" instead of calling
|
||||
it "PHP Foo" or "phpfoo"
|
||||
|
||||
5. The PHP Group may publish revised and/or new versions of the
|
||||
license from time to time. Each version will be given a
|
||||
distinguishing version number.
|
||||
Once covered code has been published under a particular version
|
||||
of the license, you may always continue to use it under the terms
|
||||
of that version. You may also choose to use such covered code
|
||||
under the terms of any subsequent version of the license
|
||||
published by the PHP Group. No one other than the PHP Group has
|
||||
the right to modify the terms applicable to covered code created
|
||||
under this License.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes PHP software, freely available from
|
||||
<http://www.php.net/software/>".
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
|
||||
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
|
||||
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the PHP Group.
|
||||
|
||||
The PHP Group can be contacted via Email at group@php.net.
|
||||
|
||||
For more information on the PHP Group and the PHP project,
|
||||
please see <http://www.php.net>.
|
||||
|
||||
PHP includes the Zend Engine, freely available at
|
||||
<http://www.zend.com>.
|
||||
39
config.m4
39
config.m4
@@ -5,21 +5,46 @@ dnl
|
||||
PHP_ARG_WITH(expect,for expect support,
|
||||
[ --with-expect[=DIR] Include expect support (requires libexpect >= 5.43.0).])
|
||||
|
||||
PHP_ARG_WITH(tcldir,specify path to Tcl needed by expect,
|
||||
[ --with-tcldir[=DIR] Specify path to Tcl config script (tclConfig.sh).])
|
||||
|
||||
if test "$PHP_EXPECT" != "no"; then
|
||||
for i in $PHP_EXPECT /usr/local /usr ; do
|
||||
if test -f $i/include/expect.h; then
|
||||
LIBEXPECT_DIR=$i
|
||||
|
||||
for i in $PHP_EXPECT/include/expect.h $PHP_EXPECT/include/*/expect.h \
|
||||
/usr/local/include/expect.h /usr/local/include/*/expect.h \
|
||||
/usr/include/expect.h /usr/include/*/expect.h ;
|
||||
do
|
||||
if test -f $i; then
|
||||
LIBEXPECT_INCLUDE_DIR=`dirname $i`
|
||||
LIBEXPECT_DIR=`dirname $LIBEXPECT_INCLUDE_DIR`
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -z "$LIBEXPECT_DIR"; then
|
||||
AC_MSG_ERROR(expect extension requires libexpect version >= 5.43.0)
|
||||
AC_MSG_CHECKING(for tcl version)
|
||||
for i in $PHP_TCLDIR/tclConfig.sh \
|
||||
/usr/lib/tcl*/tclConfig.sh \
|
||||
/usr/lib64/tcl*/tclConfig.sh \
|
||||
/usr/$PHP_LIBDIR/tcl*/tclConfig.sh \
|
||||
/usr/local/lib/tcl*/tclConfig.sh \
|
||||
/System/Library/Frameworks/Tcl.framework/Versions/Current/tclConfig.sh;
|
||||
do
|
||||
if test -f $i; then
|
||||
. $i
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -n "$TCL_VERSION" ; then
|
||||
AC_MSG_RESULT($TCL_VERSION in $TCL_PREFIX)
|
||||
else
|
||||
AC_MSG_ERROR([not found])
|
||||
fi
|
||||
|
||||
PHP_ADD_LIBRARY_WITH_PATH(expect, $LIBEXPECT_DIR/lib, EXPECT_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($LIBEXPECT_DIR/include)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(tcl$TCL_VERSION, $TCL_PREFIX/$PHP_LIBDIR, EXPECT_SHARED_LIBADD)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(expect, $LIBEXPECT_DIR/$PHP_LIBDIR, EXPECT_SHARED_LIBADD)
|
||||
PHP_ADD_INCLUDE($LIBEXPECT_INCLUDE_DIR)
|
||||
|
||||
PHP_NEW_EXTENSION(expect, expect.c expect_fopen_wrapper.c, $ext_shared)
|
||||
PHP_SUBST(EXPECT_SHARED_LIBADD)
|
||||
fi
|
||||
|
||||
|
||||
327
expect.c
327
expect.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 5, 7 and 8 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -12,23 +12,39 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Michael Spector <michael@zend.com> |
|
||||
| Author: Michael Spector <michael@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $ Id: $ */
|
||||
|
||||
#include "php_expect.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_expect_popen, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, command)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_expect_expectl, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, stream)
|
||||
ZEND_ARG_INFO(0, expect_cases)
|
||||
ZEND_ARG_INFO(1, match)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
/* {{{ expect_functions[] */
|
||||
function_entry expect_functions[] = {
|
||||
PHP_FE(expect_popen, NULL)
|
||||
PHP_FE(expect_expectl, NULL)
|
||||
zend_function_entry expect_functions[] = {
|
||||
PHP_FE(expect_popen, arginfo_expect_popen)
|
||||
PHP_FE(expect_expectl, arginfo_expect_expectl)
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(expect)
|
||||
static PHP_GINIT_FUNCTION(expect);
|
||||
static PHP_GSHUTDOWN_FUNCTION(expect);
|
||||
|
||||
/* {{{ expect_module_entry
|
||||
*/
|
||||
zend_module_entry expect_module_entry = {
|
||||
@@ -40,8 +56,12 @@ zend_module_entry expect_module_entry = {
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(expect),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
PHP_EXPECT_VERSION,
|
||||
PHP_MODULE_GLOBALS(expect),
|
||||
PHP_GINIT(expect),
|
||||
PHP_GSHUTDOWN(expect),
|
||||
NULL,
|
||||
STANDARD_MODULE_PROPERTIES_EX
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
@@ -49,13 +69,53 @@ zend_module_entry expect_module_entry = {
|
||||
ZEND_GET_MODULE(expect)
|
||||
#endif
|
||||
|
||||
/* {{{ php_expect_init_globals
|
||||
*/
|
||||
static PHP_GINIT_FUNCTION(expect)
|
||||
{
|
||||
expect_globals->logfile_stream = NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_expect_destroy_globals
|
||||
*/
|
||||
static PHP_GSHUTDOWN_FUNCTION(expect)
|
||||
{
|
||||
if (expect_globals->logfile_stream) {
|
||||
php_stream_close(expect_globals->logfile_stream);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_INI_MH
|
||||
* */
|
||||
static PHP_INI_MH(OnSetExpectTimeout)
|
||||
{
|
||||
if (new_value) {
|
||||
exp_timeout = atoi(new_value);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
exp_timeout = atoi(ZSTR_VAL(new_value));
|
||||
#else
|
||||
exp_timeout = atoi(new_value);
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_INI_MH
|
||||
* */
|
||||
static PHP_INI_MH(OnSetExpectMatchMax)
|
||||
{
|
||||
if (new_value) {
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
exp_match_max = atoi(ZSTR_VAL(new_value));
|
||||
#else
|
||||
exp_match_max = atoi(new_value);
|
||||
#endif
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -65,12 +125,24 @@ static PHP_INI_MH(OnSetExpectTimeout)
|
||||
static PHP_INI_MH(OnSetExpectLogUser)
|
||||
{
|
||||
if (new_value) {
|
||||
if (strncasecmp("on", new_value, sizeof("on"))) {
|
||||
exp_loguser = atoi(new_value);
|
||||
} else {
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (strncasecmp("on", ZSTR_VAL(new_value), sizeof("on")) == 0
|
||||
|| strncasecmp("true", ZSTR_VAL(new_value), sizeof("true")) == 0
|
||||
|| strncasecmp("yes", ZSTR_VAL(new_value), sizeof("yes")) == 0
|
||||
|| strncasecmp("1", ZSTR_VAL(new_value), sizeof("1")) == 0) {
|
||||
#else
|
||||
if (strncasecmp("on", new_value, sizeof("on")) == 0
|
||||
|| strncasecmp("true", new_value, sizeof("true")) == 0
|
||||
|| strncasecmp("yes", new_value, sizeof("yes")) == 0
|
||||
|| strncasecmp("1", new_value, sizeof("1")) == 0) {
|
||||
#endif
|
||||
exp_loguser = 1;
|
||||
} else {
|
||||
exp_loguser = 0;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -79,12 +151,30 @@ static PHP_INI_MH(OnSetExpectLogUser)
|
||||
* */
|
||||
static PHP_INI_MH(OnSetExpectLogFile)
|
||||
{
|
||||
if (EXPECT_G(logfile_stream)) {
|
||||
php_stream_close(EXPECT_G(logfile_stream));
|
||||
}
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (ZSTR_LEN(new_value) > 0) {
|
||||
php_stream* stream = php_stream_open_wrapper (ZSTR_VAL(new_value), "a", 0, NULL);
|
||||
#else
|
||||
if (new_value_length > 0) {
|
||||
exp_logfile = fopen (new_value, "a");
|
||||
if (!exp_logfile) {
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "could not open log file for writting");
|
||||
php_stream* stream = php_stream_open_wrapper (new_value, "a", 0, NULL);
|
||||
#endif
|
||||
if (!stream) {
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "could not open log file for writing");
|
||||
return FAILURE;
|
||||
}
|
||||
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
|
||||
if (php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void **) &exp_logfile, REPORT_ERRORS) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
EXPECT_G(logfile_stream) = stream;
|
||||
exp_logfile_all = 1;
|
||||
} else {
|
||||
EXPECT_G(logfile_stream) = NULL;
|
||||
exp_logfile = NULL;
|
||||
exp_logfile_all = 0;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -95,6 +185,7 @@ PHP_INI_BEGIN()
|
||||
PHP_INI_ENTRY("expect.timeout", "10", PHP_INI_ALL, OnSetExpectTimeout)
|
||||
PHP_INI_ENTRY_EX("expect.loguser", "1", PHP_INI_ALL, OnSetExpectLogUser, php_ini_boolean_displayer_cb)
|
||||
PHP_INI_ENTRY("expect.logfile", "", PHP_INI_ALL, OnSetExpectLogFile)
|
||||
PHP_INI_ENTRY("expect.match_max", "5000", PHP_INI_ALL, OnSetExpectMatchMax)
|
||||
PHP_INI_END()
|
||||
|
||||
|
||||
@@ -111,6 +202,18 @@ PHP_MINIT_FUNCTION(expect)
|
||||
REGISTER_LONG_CONSTANT("EXP_FULLBUFFER", EXP_FULLBUFFER, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_INI_ENTRIES();
|
||||
|
||||
Tcl_Interp *interp = Tcl_CreateInterp();
|
||||
if (Tcl_Init(interp) == TCL_ERROR) {
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR,
|
||||
"Unable to initialize TCL interpreter: %s", Tcl_GetStringResult (interp));
|
||||
return FAILURE;
|
||||
}
|
||||
if (Expect_Init(interp) == TCL_ERROR) {
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR,
|
||||
"Unable to initialize Expect: %s", Tcl_GetStringResult (interp));
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -133,7 +236,8 @@ PHP_MSHUTDOWN_FUNCTION(expect)
|
||||
PHP_MINFO_FUNCTION(expect)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_row(2, "Expect support", "enabled");
|
||||
php_info_print_table_header(2, "Expect support", "enabled");
|
||||
php_info_print_table_row(2, "Version", PHP_EXPECT_VERSION);
|
||||
php_info_print_table_row(2, "Stream wrapper support", "expect://");
|
||||
php_info_print_table_end();
|
||||
|
||||
@@ -147,125 +251,270 @@ PHP_MINFO_FUNCTION(expect)
|
||||
*/
|
||||
PHP_FUNCTION(expect_popen)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zend_string *command = NULL;
|
||||
#else
|
||||
char *command = NULL;
|
||||
#endif
|
||||
int command_len;
|
||||
FILE *fp;
|
||||
php_stream *stream = NULL;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval z_pid;
|
||||
#else
|
||||
zval *z_pid;
|
||||
#endif
|
||||
|
||||
if (ZEND_NUM_ARGS() != 1) { WRONG_PARAM_COUNT; }
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "S", &command) == FAILURE) {
|
||||
#else
|
||||
if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "s", &command, &command_len) == FAILURE) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if ((fp = exp_popen (ZSTR_VAL(command))) != NULL) {
|
||||
#else
|
||||
if ((fp = exp_popen (command)) != NULL) {
|
||||
#endif
|
||||
stream = php_stream_fopen_from_pipe (fp, "");
|
||||
}
|
||||
if (!stream) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
ZVAL_LONG (&z_pid, exp_pid);
|
||||
#else
|
||||
MAKE_STD_ZVAL (z_pid);
|
||||
ZVAL_LONG (z_pid, exp_pid);
|
||||
#endif
|
||||
stream->wrapperdata = z_pid;
|
||||
|
||||
php_stream_to_zval(stream, return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{
|
||||
* proto mixed expect_expectl (resource stream, array expect_cases)
|
||||
* proto mixed expect_expectl (resource stream, array expect_cases [, array match])
|
||||
*/
|
||||
PHP_FUNCTION(expect_expectl)
|
||||
{
|
||||
struct exp_case *ecases, *ec;
|
||||
zval *z_stream, *z_cases, **z_case, **z_value;
|
||||
struct exp_case *ecases, *ecases_ptr, matchedcase;
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval *z_stream, *z_cases, *z_match=NULL, *z_case, *z_value;
|
||||
#else
|
||||
zval *z_stream, *z_cases, *z_match=NULL, **z_case, **z_value;
|
||||
#endif
|
||||
php_stream *stream;
|
||||
int fd, argc;
|
||||
ulong key;
|
||||
|
||||
if (ZEND_NUM_ARGS() != 2) { WRONG_PARAM_COUNT; }
|
||||
if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3) { WRONG_PARAM_COUNT; }
|
||||
|
||||
if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ra", &z_stream, &z_cases) == FAILURE) {
|
||||
if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ra|z/", &z_stream, &z_cases, &z_match) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
php_stream_from_zval (stream, z_stream);
|
||||
#else
|
||||
php_stream_from_zval (stream, &z_stream);
|
||||
if (php_stream_cast (stream, PHP_STREAM_AS_FD, (void*)&fd, 1) != SUCCESS || fd < 0) {
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "couldn't cast expect stream to a file descriptor");
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (!&(stream->wrapperdata)) {
|
||||
#else
|
||||
if (!stream->wrapperdata) {
|
||||
#endif
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "supplied argument is not a valid stream resource");
|
||||
return;
|
||||
}
|
||||
|
||||
if (php_stream_cast (stream, PHP_STREAM_AS_FD, (void*)&fd, REPORT_ERRORS) != SUCCESS || fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
argc = zend_hash_num_elements (Z_ARRVAL_P(z_cases));
|
||||
ecases = (struct exp_case*) safe_emalloc (argc + 1, sizeof(struct exp_case), 0);
|
||||
ecases_ptr = ecases;
|
||||
|
||||
ec = ecases;
|
||||
zend_hash_internal_pointer_reset (Z_ARRVAL_P(z_cases));
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
while ((z_case = zend_hash_get_current_data (Z_ARRVAL_P(z_cases))) != NULL)
|
||||
{
|
||||
zval *z_pattern, *z_exp_type;
|
||||
zend_hash_get_current_key(Z_ARRVAL_P(z_cases), NULL, &key);
|
||||
|
||||
if (Z_TYPE_P(z_case) != IS_ARRAY) {
|
||||
#else
|
||||
while (zend_hash_get_current_data (Z_ARRVAL_P(z_cases), (void **)&z_case) == SUCCESS)
|
||||
{
|
||||
zval **z_pattern, **z_exp_type;
|
||||
zend_hash_get_current_key(Z_ARRVAL_P(z_cases), NULL, &key, 0);
|
||||
|
||||
if (Z_TYPE_PP(z_case) != IS_ARRAY) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "expect case must be an array");
|
||||
return;
|
||||
}
|
||||
|
||||
ec->re = NULL;
|
||||
ec->type = exp_glob;
|
||||
ecases_ptr->re = NULL;
|
||||
ecases_ptr->type = exp_glob;
|
||||
|
||||
/* Gather pattern */
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if ((z_pattern = zend_hash_index_find(Z_ARRVAL_P(z_case), 0)) == NULL) {
|
||||
#else
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(z_case), 0, (void **)&z_pattern) != SUCCESS) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "missing parameter for pattern at index: 0");
|
||||
return;
|
||||
}
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (Z_TYPE_P(z_pattern) != IS_STRING) {
|
||||
#else
|
||||
if (Z_TYPE_PP(z_pattern) != IS_STRING) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "pattern must be of string type");
|
||||
return;
|
||||
}
|
||||
ec->pattern = Z_STRVAL_PP(z_pattern);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
ecases_ptr->pattern = Z_STRVAL_P(z_pattern);
|
||||
#else
|
||||
ecases_ptr->pattern = Z_STRVAL_PP(z_pattern);
|
||||
#endif
|
||||
|
||||
/* Gather value */
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(z_case), 1) == NULL) {
|
||||
#else
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(z_case), 1, (void **)&z_value) != SUCCESS) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "missing parameter for value at index: 1");
|
||||
return;
|
||||
}
|
||||
ec->value = key;
|
||||
ecases_ptr->value = key;
|
||||
|
||||
/* Gather expression type (optional, default: EXPECT_GLOB) */
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if ((z_exp_type = zend_hash_index_find(Z_ARRVAL_P(z_case), 2)) != NULL) {
|
||||
if (Z_TYPE_P(z_exp_type) != IS_LONG) {
|
||||
#else
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(z_case), 2, (void **)&z_exp_type) == SUCCESS) {
|
||||
if (Z_TYPE_PP(z_exp_type) != IS_LONG) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "expression type must be an integer constant");
|
||||
return;
|
||||
}
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if (Z_LVAL_P(z_exp_type) != exp_glob && Z_LVAL_P(z_exp_type) != exp_exact && Z_LVAL_P(z_exp_type) != exp_regexp) {
|
||||
#else
|
||||
if (Z_LVAL_PP(z_exp_type) != exp_glob && Z_LVAL_PP(z_exp_type) != exp_exact && Z_LVAL_PP(z_exp_type) != exp_regexp) {
|
||||
#endif
|
||||
efree (ecases);
|
||||
php_error_docref (NULL TSRMLS_CC, E_ERROR, "expression type must be either EXPECT_GLOB, EXPECT_EXACT or EXPECT_REGEXP");
|
||||
return;
|
||||
}
|
||||
ec->type = Z_LVAL_PP(z_exp_type);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
ecases_ptr->type = Z_LVAL_P(z_exp_type);
|
||||
#else
|
||||
ecases_ptr->type = Z_LVAL_PP(z_exp_type);
|
||||
#endif
|
||||
}
|
||||
|
||||
ec++;
|
||||
ecases_ptr++;
|
||||
zend_hash_move_forward(Z_ARRVAL_P(z_cases));
|
||||
}
|
||||
ec->type = exp_end;
|
||||
ecases_ptr->pattern = NULL;
|
||||
ecases_ptr->re = NULL;
|
||||
ecases_ptr->value = 0;
|
||||
ecases_ptr->type = exp_end;
|
||||
|
||||
key = exp_expectv (fd, ecases);
|
||||
int exp_retval = exp_expectv (fd, ecases);
|
||||
int case_found = 0;
|
||||
if (exp_retval >= 0) {
|
||||
key = exp_retval;
|
||||
|
||||
if (zend_hash_index_find (Z_ARRVAL_P(z_cases), key, (void **)&z_case) == SUCCESS) {
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(z_case), 1, (void **)&z_value) == SUCCESS) {
|
||||
*return_value = **z_value;
|
||||
zval_copy_ctor (return_value);
|
||||
int exp_match_len = exp_match_end - exp_match;
|
||||
if (z_match && exp_match && exp_match_len > 0) {
|
||||
char *tmp = (char *)emalloc (sizeof(char) * (exp_match_len + 1));
|
||||
strlcpy (tmp, exp_match, exp_match_len + 1);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
z_match = zend_try_array_init(z_match);
|
||||
if (!z_match) {
|
||||
return;
|
||||
}
|
||||
add_index_string(z_match, 0, tmp);
|
||||
#else
|
||||
zval_dtor (z_match);
|
||||
array_init(z_match);
|
||||
add_index_string(z_match, 0, tmp, 1);
|
||||
#endif
|
||||
/* Get case that was matched */
|
||||
matchedcase = ecases[key];
|
||||
/* If there are subpattern matches ... */
|
||||
if (matchedcase.re != NULL && matchedcase.re->startp != NULL) {
|
||||
int i;
|
||||
/* iterate across all possible 9 subpatterns (a limitation of libexpect)
|
||||
and add matching substring to matches array */
|
||||
for (i = 1; i <= 9; i++) {
|
||||
if (matchedcase.re->startp[i] != NULL) {
|
||||
int sub_match_len = matchedcase.re->endp[i] - matchedcase.re->startp[i];
|
||||
char *sub_match = (char *)emalloc (sizeof(char) * (sub_match_len + 1));
|
||||
strlcpy (sub_match, matchedcase.re->startp[i], sub_match_len + 1);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
add_next_index_string(z_match, sub_match);
|
||||
#else
|
||||
add_next_index_string(z_match, sub_match, 1);
|
||||
#endif
|
||||
efree (sub_match);
|
||||
}
|
||||
}
|
||||
}
|
||||
efree (tmp);
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if ((z_case = zend_hash_index_find (Z_ARRVAL_P(z_cases), key)) != NULL) {
|
||||
if ((z_value = zend_hash_index_find(Z_ARRVAL_P(z_case), 1)) != NULL) {
|
||||
*return_value = *z_value;
|
||||
#else
|
||||
if (zend_hash_index_find (Z_ARRVAL_P(z_cases), key, (void **)&z_case) == SUCCESS) {
|
||||
if (zend_hash_index_find(Z_ARRVAL_PP(z_case), 1, (void **)&z_value) == SUCCESS) {
|
||||
*return_value = **z_value;
|
||||
#endif
|
||||
zval_copy_ctor (return_value);
|
||||
case_found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
RETURN_LONG (key);
|
||||
}
|
||||
|
||||
// Free compiled patterns:
|
||||
ecases_ptr = ecases;
|
||||
while (ecases_ptr != NULL && ecases_ptr->type != exp_end) {
|
||||
if (ecases_ptr->re != NULL) {
|
||||
free(ecases_ptr->re);
|
||||
}
|
||||
ecases_ptr++;
|
||||
}
|
||||
efree (ecases);
|
||||
|
||||
if (!case_found) {
|
||||
RETURN_LONG(exp_retval);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 5 and 7 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -12,7 +12,7 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Michael Spector <michael@zend.com> |
|
||||
| Author: Michael Spector <michael@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@@ -21,26 +21,66 @@
|
||||
#include "php.h"
|
||||
#include "php_expect.h"
|
||||
#include "php_streams.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
php_stream *php_expect_stream_opener (php_stream_wrapper *wrapper, char *command, char *mode, int options,
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
php_stream *php_expect_stream_open (php_stream_wrapper *wrapper, const char *command, const char *mode, int options,
|
||||
zend_string **opened_command, php_stream_context *context STREAMS_DC TSRMLS_DC)
|
||||
#else
|
||||
php_stream *php_expect_stream_open (php_stream_wrapper *wrapper, char *command, char *mode, int options,
|
||||
char **opened_command, php_stream_context *context STREAMS_DC TSRMLS_DC)
|
||||
#endif
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if (strncasecmp("expect://", command, sizeof("expect://")-1) == 0) {
|
||||
command += sizeof("expect://")-1;
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
if ((fp = exp_popen((char*)command)) != NULL) {
|
||||
#else
|
||||
if ((fp = exp_popen(command)) != NULL) {
|
||||
return php_stream_fopen_from_pipe (fp, "");
|
||||
#endif
|
||||
php_stream* stream = php_stream_fopen_from_pipe (fp, mode);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval z_pid;
|
||||
ZVAL_LONG (&z_pid, exp_pid);
|
||||
#else
|
||||
zval *z_pid;
|
||||
MAKE_STD_ZVAL (z_pid);
|
||||
ZVAL_LONG (z_pid, exp_pid);
|
||||
#endif
|
||||
stream->wrapperdata = z_pid;
|
||||
return stream;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int php_expect_stream_close (php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC)
|
||||
{
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval* z_pid = &(stream->wrapperdata);
|
||||
#else
|
||||
zval* z_pid = stream->wrapperdata;
|
||||
#endif
|
||||
int s = 0;
|
||||
waitpid (Z_LVAL_P(z_pid), &s, 0);
|
||||
#if PHP_MAJOR_VERSION >= 7
|
||||
zval_ptr_dtor (z_pid);
|
||||
php_stream_free(stream, PHP_STREAM_FREE_CLOSE);
|
||||
#else
|
||||
zval_ptr_dtor (&z_pid);
|
||||
stream->wrapperdata = NULL;
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
static php_stream_wrapper_ops php_expect_wrapper_ops = {
|
||||
php_expect_stream_opener,
|
||||
NULL, /* close */
|
||||
php_expect_stream_open,
|
||||
php_expect_stream_close, /* close */
|
||||
NULL, /* stat */
|
||||
NULL, /* stat_url */
|
||||
NULL, /* opendir */
|
||||
|
||||
94
package.xml
94
package.xml
@@ -1,33 +1,63 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
|
||||
<package>
|
||||
<name>expect</name>
|
||||
<summary>PHP extension for expect library</summary>
|
||||
<description>This extension allows to interact with processes through PTY, using expect library.</description>
|
||||
<license>PHP License</license>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>michael</user>
|
||||
<name>Michael Spector</name>
|
||||
<email>michael@php.net</email>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
|
||||
<release>
|
||||
<version>0.2</version>
|
||||
<date>2005-11-12</date>
|
||||
<state>beta</state>
|
||||
<notes>Fixed #5941</notes>
|
||||
</release>
|
||||
|
||||
<filelist>
|
||||
<dir role="doc" name="/">
|
||||
<file role="src">config.m4</file>
|
||||
<file role="src">expect.dsp</file>
|
||||
<file role="src">config.w32</file>
|
||||
<file role="src">expect.c</file>
|
||||
<file role="src">expect_fopen_wrapper.c</file>
|
||||
<file role="src">php_expect.h</file>
|
||||
</dir>
|
||||
</filelist>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
|
||||
http://pear.php.net/dtd/tasks-1.0.xsd
|
||||
http://pear.php.net/dtd/package-2.0
|
||||
http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<name>expect</name>
|
||||
<channel>pecl.php.net</channel>
|
||||
<summary>PHP extension for expect library</summary>
|
||||
<description>This extension allows to interact with processes through PTY, using expect library.
|
||||
</description>
|
||||
<lead>
|
||||
<name>Michael Spector</name>
|
||||
<user>michael</user>
|
||||
<email>michael@php.net</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2020-01-13</date>
|
||||
<time>18:00:00</time>
|
||||
<version>
|
||||
<release>0.4.0</release>
|
||||
<api>0.4.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<license uri="http://www.php.net/license">PHP License</license>
|
||||
<notes>
|
||||
Added LICENSE. Fixed RPM build for 64bit.
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
<file name="config.m4" role="src" />
|
||||
<file name="config.w32" role="src" />
|
||||
<file name="expect.c" role="src" />
|
||||
<file name="expect.dsp" role="src" />
|
||||
<file name="expect_fopen_wrapper.c" role="src" />
|
||||
<file name="php_expect.h" role="src" />
|
||||
<file name="LICENSE" role="doc" />
|
||||
<dir name="tests">
|
||||
<file name="bug12268.phpt" role="test" />
|
||||
<file name="bug22566.phpt" role="test" />
|
||||
<file name="bug6996.phpt" role="test" />
|
||||
<file name="expect_expectl.phpt" role="test" />
|
||||
<file name="expect_popen.phpt" role="test" />
|
||||
<file name="expect_wrapper.phpt" role="test" />
|
||||
</dir>
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>4.0.0</min>
|
||||
<max>8.99.99</max>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0b1</min>
|
||||
</pearinstaller>
|
||||
</required>
|
||||
</dependencies>
|
||||
<providesextension>expect</providesextension>
|
||||
<extsrcrelease />
|
||||
</package>
|
||||
|
||||
30
php_expect.h
30
php_expect.h
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
| PHP Version 5, 7 and 8 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
@@ -12,7 +12,7 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Michael Spector <michael@zend.com> |
|
||||
| Author: Michael Spector <michael@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@@ -30,11 +30,15 @@
|
||||
#include <SAPI.h>
|
||||
#include <ext/standard/info.h>
|
||||
|
||||
#include <tcl.h>
|
||||
#include <expect_tcl.h>
|
||||
#include <expect.h>
|
||||
|
||||
extern zend_module_entry expect_module_entry;
|
||||
#define phpext_expect_ptr &expect_module_entry
|
||||
|
||||
#define PHP_EXPECT_VERSION "0.4.0"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_EXPECT_API __declspec(dllexport)
|
||||
#else
|
||||
@@ -50,10 +54,32 @@ PHP_FUNCTION(expect_expectl);
|
||||
|
||||
extern php_stream_wrapper php_expect_wrapper;
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(expect)
|
||||
php_stream* logfile_stream;
|
||||
ZEND_END_MODULE_GLOBALS(expect)
|
||||
|
||||
#ifdef ZTS
|
||||
#define EXPECT_G(v) TSRMG(expect_globals_id, zend_expect_globals *, v)
|
||||
#else
|
||||
#define EXPECT_G(v) (expect_globals.v)
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif /* ZTS */
|
||||
|
||||
|
||||
#if ZEND_MODULE_API_NO >= 20190128
|
||||
#ifndef TSRMLS_CC
|
||||
#define TSRMLS_CC
|
||||
#endif
|
||||
#ifndef TSRMLS_DC
|
||||
#define TSRMLS_DC
|
||||
#endif
|
||||
#ifndef TSRMLS_FETCH
|
||||
#define TSRMLS_FETCH()
|
||||
#endif
|
||||
#endif
|
||||
#endif /* PHP_EXPECT_H */
|
||||
|
||||
/*
|
||||
|
||||
24
tests/bug12268.phpt
Normal file
24
tests/bug12268.phpt
Normal file
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
PECL Bug #12268 CGI
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("expect") || php_sapi_name() == 'cli') print "skip"; ?>
|
||||
--INI--
|
||||
expect.loguser=0
|
||||
expect.logfile=php://output
|
||||
--FILE--
|
||||
<?php
|
||||
if (php_sapi_name() == 'cli') exit;
|
||||
|
||||
$stream = expect_popen("echo Hello");
|
||||
|
||||
ob_start();
|
||||
|
||||
expect_expectl ($stream, array());
|
||||
|
||||
$r = ob_get_contents();
|
||||
fclose ($stream);
|
||||
|
||||
print "Output: $r";
|
||||
?>
|
||||
--EXPECT--
|
||||
Output: Hello
|
||||
16
tests/bug22566.phpt
Normal file
16
tests/bug22566.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
PECL Bug #22566 CGI
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("expect")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(ini_set('expect.timeout', 3));
|
||||
var_dump(ini_set('expect.match_max', '2000'));
|
||||
var_dump(ini_get('expect.timeout'));
|
||||
var_dump(ini_get('expect.match_max'));
|
||||
?>
|
||||
--EXPECT--
|
||||
string(2) "10"
|
||||
string(4) "5000"
|
||||
string(1) "3"
|
||||
string(4) "2000"
|
||||
14
tests/bug6996.phpt
Normal file
14
tests/bug6996.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
PECL Bug #6996
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("expect")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$stream = popen ("expect://echo 2>/dev/null", "r");
|
||||
|
||||
expect_expectl ($stream, array());
|
||||
|
||||
fclose ($stream);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: expect_expectl(): supplied argument is not a valid stream resource in %s on line %d
|
||||
Reference in New Issue
Block a user