summaryrefslogtreecommitdiff
path: root/php
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2016-04-25 21:32:42 -0700
committerRuss Allbery <eagle@eyrie.org>2016-04-25 21:32:42 -0700
commit7c468600907a6f07dc3cb847f03c3e02901a4994 (patch)
tree75234f5705ea46b4fcf0d9996286ae500a824ba1 /php
parentf10b9e510510332867839712da4b13e60aa4de82 (diff)
Port PHP extension to PHP 7
The PHP bindings have been ported to PHP 7, based on work by Nish Aravamudan. The PHP 7 API is sufficiently different that this was done by forking the PHP code and creating a new version for PHP 7 and later, chosing which extension to compile based on the discovered version of PHP. Currently, there is no functionality difference, but the PHP 5 extension should be considered frozen and may not get any new features. It will eventually be removed in a future version of remctl when PHP 7 is sufficiently widespread.
Diffstat (limited to 'php')
-rw-r--r--php/config.m4.in8
-rw-r--r--php/php5_remctl.c541
-rw-r--r--php/php_remctl.c116
3 files changed, 601 insertions, 64 deletions
diff --git a/php/config.m4.in b/php/config.m4.in
index 9132b1e..32f26a1 100644
--- a/php/config.m4.in
+++ b/php/config.m4.in
@@ -1,9 +1,11 @@
-dnl remctl PECL extension for PHP configuration -*- autoconf -*-
+dnl remctl PECL extension for PHP configuration.
+dnl -*- autoconf -*-
dnl
dnl Provides additional configuration hooks for the PHP module build system.
dnl This file is used by the phpize frameowrk.
dnl
dnl Originally written by Andrew Mortensen <admorten@umich.edu>, 2008
+dnl Copyright 2015 Russ Allbery <eagle@eyrie.org>
dnl Copyright 2008 Andrew Mortensen <admorten@umich.edu>
dnl Copyright 2008
dnl The Board of Trustees of the Leland Stanford Junior University
@@ -16,6 +18,8 @@ PHP_ARG_ENABLE([remctl], [whether to enable remctl PHP extension],
dnl The @...@ variables are substituted by the top-level configure. Yes, this
dnl is a little odd, but it seems to work.
AS_IF([test "$PHP_REMCTL" != no],
- [PHP_NEW_EXTENSION([remctl], [php_remctl.c], [$ext_shared])
+ [AS_CASE([`$PHP_CONFIG --version`],
+ [5*], [PHP_NEW_EXTENSION([remctl], [php5_remctl.c], [$ext_shared])],
+ [*], [PHP_NEW_EXTENSION([remctl], [php_remctl.c], [$ext_shared])])
PHP_ADD_INCLUDE([@abs_top_srcdir@])
LDFLAGS="$LDFLAGS -L@abs_top_builddir@/client/.libs -lremctl"])
diff --git a/php/php5_remctl.c b/php/php5_remctl.c
new file mode 100644
index 0000000..5fe6ce8
--- /dev/null
+++ b/php/php5_remctl.c
@@ -0,0 +1,541 @@
+/*
+ * remctl PECL extension for PHP 5
+ *
+ * Provides bindings for PHP very similar to the libremctl library for C or
+ * the Net::Remctl bindings for Perl. This is an older version for PHP 5.
+ * See php_remctl.c for PHP 7 and later.
+ *
+ * This file is frozen and probably won't add any new features. It will be
+ * dropped in some future version of remctl when PHP 7 support is widespread
+ * enough. The API changes were sufficiently wide-ranging that trying to
+ * maintain one unified version with a ton of #ifdefs didn't seem practical.
+ *
+ * Originally written by Andrew Mortensen <admorten@umich.edu>, 2008
+ * Copyirght 2016 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008 Andrew Mortensen <admorten@umich.edu>
+ * Copyright 2008, 2011, 2012, 2014
+ * The Board of Trustees of the Leland Stanford Junior University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#include <client/remctl.h>
+
+#include <php.h>
+#include <php_remctl.h>
+
+static int le_remctl_internal;
+
+static zend_function_entry remctl_functions[] = {
+ ZEND_FE(remctl, NULL)
+ ZEND_FE(remctl_new, NULL)
+ ZEND_FE(remctl_set_ccache, NULL)
+ ZEND_FE(remctl_set_source_ip, NULL)
+ ZEND_FE(remctl_set_timeout, NULL)
+ ZEND_FE(remctl_open, NULL)
+ ZEND_FE(remctl_close, NULL)
+ ZEND_FE(remctl_command, NULL)
+ ZEND_FE(remctl_output, NULL)
+ ZEND_FE(remctl_noop, NULL)
+ ZEND_FE(remctl_error, NULL)
+ { NULL, NULL, NULL, 0, 0 }
+};
+
+zend_module_entry remctl_module_entry = {
+ STANDARD_MODULE_HEADER,
+ PHP_REMCTL_EXTNAME,
+ remctl_functions,
+ PHP_MINIT(remctl),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ PHP_REMCTL_VERSION,
+ STANDARD_MODULE_PROPERTIES
+};
+
+#ifdef COMPILE_DL_REMCTL
+ZEND_GET_MODULE(remctl)
+#endif
+
+/*
+ * Destructor for a remctl object. Close the underlying connection.
+ */
+static void
+php_remctl_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+ struct remctl *r = (struct remctl *) rsrc->ptr;
+
+ if (r != NULL)
+ remctl_close(r);
+}
+
+
+/*
+ * Initialize the module and register the destructor. Stores the resource
+ * number of the module in le_remctl_internal.
+ */
+PHP_MINIT_FUNCTION(remctl)
+{
+ le_remctl_internal =
+ zend_register_list_destructors_ex(php_remctl_dtor, NULL,
+ PHP_REMCTL_RES_NAME, module_number);
+ return SUCCESS;
+}
+
+
+/*
+ * The simplified interface. Make a call and return the results as an
+ * object.
+ */
+ZEND_FUNCTION(remctl)
+{
+ zval *cmd_array, **data;
+ void **data_ref;
+ HashTable *hash;
+ HashPosition pos;
+ char *host, *principal = NULL;
+ const char **command = NULL;
+ long port;
+ int hlen, plen, count, i, status;
+ int success = 0;
+ struct remctl_result *result = NULL;
+
+ /*
+ * Read the arguments (host, port, principal, and command) and check their
+ * validity. Host and command are required, so all arguments must be
+ * provided, but an empty string can be passed in as the principal.
+ */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slsa", &host,
+ &hlen, &port, &principal, &plen, &cmd_array);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl: invalid parameters\n");
+ RETURN_NULL();
+ }
+ if (hlen == 0) {
+ zend_error(E_WARNING, "remctl: host must be a valid string\n");
+ RETURN_NULL();
+ }
+ if (plen == 0)
+ principal = NULL;
+ hash = Z_ARRVAL_P(cmd_array);
+ count = zend_hash_num_elements(hash);
+ if (count < 1) {
+ zend_error(E_WARNING, "remctl: command must not be empty\n");
+ RETURN_NULL();
+ }
+
+ /*
+ * Convert the command array into the char ** needed by libremctl. This
+ * is less than ideal because we make another copy of all of the
+ * arguments. There should be some way to do this without making a copy.
+ */
+ command = ecalloc(count + 1, sizeof(char *));
+ if (command == NULL) {
+ zend_error(E_WARNING, "remctl: ecalloc failed\n");
+ RETURN_NULL();
+ }
+ i = 0;
+ zend_hash_internal_pointer_reset_ex(hash, &pos);
+ data_ref = (void **) &data;
+ while (zend_hash_get_current_data_ex(hash, data_ref, &pos) == SUCCESS) {
+ if (Z_TYPE_PP(data) != IS_STRING) {
+ zend_error(E_WARNING, "remctl: command contains non-string\n");
+ goto cleanup;
+ }
+ if (i >= count) {
+ zend_error(E_WARNING, "remctl: internal error: incorrect count\n");
+ goto cleanup;
+ }
+ command[i] = estrndup(Z_STRVAL_PP(data), Z_STRLEN_PP(data));
+ if (command[i] == NULL) {
+ zend_error(E_WARNING, "remctl: estrndup failed\n");
+ count = i;
+ goto cleanup;
+ }
+ i++;
+ zend_hash_move_forward_ex(hash, &pos);
+ }
+ command[count] = NULL;
+
+ /* Run the actual remctl call. */
+ result = remctl(host, port, principal, command);
+ if (result == NULL) {
+ zend_error(E_WARNING, "remctl: %s\n", strerror(errno));
+ goto cleanup;
+ }
+
+ /*
+ * Convert the remctl result to an object. return_value is defined for us
+ * by Zend.
+ */
+ if (object_init(return_value) != SUCCESS) {
+ zend_error(E_WARNING, "remctl: object_init failed\n");
+ goto cleanup;
+ }
+ if (result->error == NULL)
+ add_property_string(return_value, "error", "", 1);
+ else
+ add_property_string(return_value, "error", result->error, 1);
+ add_property_stringl(return_value, "stdout", result->stdout_buf,
+ result->stdout_len, 1);
+ add_property_long(return_value, "stdout_len", result->stdout_len);
+ add_property_stringl(return_value, "stderr", result->stderr_buf,
+ result->stderr_len, 1);
+ add_property_long(return_value, "stderr_len", result->stderr_len);
+ add_property_long(return_value, "status", result->status);
+ success = 1;
+
+cleanup:
+ if (command != NULL) {
+ for (i = 0; i < count; i++)
+ efree((char *) command[i]);
+ efree(command);
+ }
+ if (result != NULL)
+ remctl_result_free(result);
+ if (!success)
+ RETURN_NULL();
+}
+
+
+/*
+ * Now the full interface. First, the constructor.
+ */
+ZEND_FUNCTION(remctl_new)
+{
+ struct remctl *r;
+
+ r = remctl_new();
+ if (r == NULL) {
+ zend_error(E_WARNING, "remctl_new: %s", strerror(errno));
+ RETURN_NULL();
+ }
+ ZEND_REGISTER_RESOURCE(return_value, r, le_remctl_internal);
+}
+
+
+/*
+ * Set the credential cache for subsequent connections with remctl_open.
+ */
+ZEND_FUNCTION(remctl_set_ccache)
+{
+ struct remctl *r;
+ zval *zrem;
+ char *ccache;
+ int clen, status;
+
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zrem,
+ &ccache, &clen);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_set_ccache: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+ if (!remctl_set_ccache(r, ccache))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Set the source IP for subsequent connections with remctl_open.
+ */
+ZEND_FUNCTION(remctl_set_source_ip)
+{
+ struct remctl *r;
+ zval *zrem;
+ char *source;
+ int slen, status;
+
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zrem,
+ &source, &slen);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_set_source_ip: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+ if (!remctl_set_source_ip(r, source))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Set the timeout for subsequent operations.
+ */
+ZEND_FUNCTION(remctl_set_timeout)
+{
+ struct remctl *r;
+ zval *zrem;
+ long timeout;
+ int status;
+
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zrem,
+ &timeout);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_set_timeout: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+ if (!remctl_set_timeout(r, timeout))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Open a connection to the remote host. Only the host parameter is required;
+ * the rest are optional. PHP may require something be passed in for
+ * principal, but the empty string is taken to mean "use the library default."
+ */
+ZEND_FUNCTION(remctl_open)
+{
+ struct remctl *r;
+ zval *zrem;
+ char *host;
+ char *principal = NULL;
+ long port = 0;
+ int hlen, plen, status;
+
+ /* Parse and verify arguments. */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ls", &zrem,
+ &host, &hlen, &port, &principal, &plen);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_open: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ if (plen == 0)
+ principal = NULL;
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+
+ /* Now we have all the arguments and can do the real work. */
+ if (!remctl_open(r, host, port, principal))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Send a command to the remote server.
+ */
+ZEND_FUNCTION(remctl_command)
+{
+ struct remctl *r;
+ zval *zrem, *cmd_array, **data;
+ void **data_ref;
+ HashTable *hash;
+ HashPosition pos;
+ struct iovec *cmd_vec = NULL;
+ int i, count, status;
+ int success = 0;
+
+ /* Parse and verify arguments. */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zrem,
+ &cmd_array);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_command: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+ hash = Z_ARRVAL_P(cmd_array);
+ count = zend_hash_num_elements(hash);
+ if (count < 1) {
+ zend_error(E_WARNING, "remctl_command: command must not be empty\n");
+ RETURN_NULL();
+ }
+
+ /*
+ * Transform the PHP array into an array of struct iovec. This is less
+ * than ideal because it makes another copy of all of the data. There
+ * should be some way to do this without copying.
+ */
+ cmd_vec = ecalloc(count, sizeof(struct iovec));
+ if (cmd_vec == NULL) {
+ zend_error(E_WARNING, "remctl_command: ecalloc failed\n");
+ RETURN_FALSE;
+ }
+ i = 0;
+ zend_hash_internal_pointer_reset_ex(hash, &pos);
+ data_ref = (void **) &data;
+ while (zend_hash_get_current_data_ex(hash, data_ref, &pos) == SUCCESS) {
+ if (Z_TYPE_PP(data) != IS_STRING) {
+ zend_error(E_WARNING,
+ "remctl_command: command contains non-string\n");
+ goto cleanup;
+ }
+ if (i >= count) {
+ zend_error(E_WARNING,
+ "remctl_command: internal error: incorrect count\n");
+ goto cleanup;
+ }
+ cmd_vec[i].iov_base = emalloc(Z_STRLEN_PP(data) + 1);
+ if (cmd_vec[i].iov_base == NULL) {
+ zend_error(E_WARNING, "remctl_command: emalloc failed\n");
+ count = i;
+ goto cleanup;
+ }
+ cmd_vec[i].iov_len = Z_STRLEN_PP(data);
+ memcpy(cmd_vec[i].iov_base, Z_STRVAL_PP(data), cmd_vec[i].iov_len);
+ i++;
+ zend_hash_move_forward_ex(hash, &pos);
+ }
+
+ /* Finally, we can do the work. */
+ if (!remctl_commandv(r, cmd_vec, count))
+ goto cleanup;
+ success = 1;
+
+cleanup:
+ if (cmd_vec != NULL) {
+ for (i = 0; i < count; i++)
+ efree(cmd_vec[i].iov_base);
+ efree(cmd_vec);
+ }
+ if (!success)
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Get an output token from the server and return it as an object.
+ */
+ZEND_FUNCTION(remctl_output)
+{
+ struct remctl *r;
+ struct remctl_output *output;
+ zval *zrem;
+ int status;
+
+ /* Parse and verify arguments. */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zrem);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_output: invalid parameters\n");
+ RETURN_NULL();
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+
+ /* Get the output token. */
+ output = remctl_output(r);
+ if (output == NULL)
+ RETURN_NULL();
+
+ /*
+ * Populate an object with the output results. return_value is defined
+ * for us by Zend.
+ */
+ if (object_init(return_value) != SUCCESS) {
+ zend_error(E_WARNING, "remctl_output: object_init failed\n");
+ RETURN_NULL();
+ }
+ switch (output->type) {
+ case REMCTL_OUT_OUTPUT:
+ add_property_string(return_value, "type", "output", 1);
+ add_property_stringl(return_value, "data", output->data,
+ output->length, 1);
+ add_property_long(return_value, "stream", output->stream);
+ break;
+ case REMCTL_OUT_ERROR:
+ add_property_string(return_value, "type", "error", 1);
+ add_property_stringl(return_value, "data", output->data,
+ output->length, 1);
+ add_property_long(return_value, "error", output->error);
+ break;
+ case REMCTL_OUT_STATUS:
+ add_property_string(return_value, "type", "status", 1);
+ add_property_long(return_value, "status", output->status);
+ break;
+ case REMCTL_OUT_DONE:
+ add_property_string(return_value, "type", "done", 1);
+ break;
+ }
+}
+
+
+/*
+ * Sends a NOOP message to the server and reads the reply.
+ */
+ZEND_FUNCTION(remctl_noop)
+{
+ struct remctl *r;
+ zval *zrem;
+ int status;
+
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zrem);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_noop: invalid parameters\n");
+ RETURN_FALSE;
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+ if (!remctl_noop(r))
+ RETURN_FALSE;
+ RETURN_TRUE;
+}
+
+
+/*
+ * Returns the error message from a previously failed remctl call.
+ */
+ZEND_FUNCTION(remctl_error)
+{
+ struct remctl *r;
+ zval *zrem;
+ const char *error;
+ int status;
+
+ /* Parse and verify arguments. */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zrem);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_error: invalid parameters\n");
+ RETURN_NULL();
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+
+ /* Do the work. */
+ error = remctl_error(r);
+ RETURN_STRING((char *) error, 1);
+}
+
+
+/*
+ * Close the connection. This isn't strictly necessary since the destructor
+ * will close the connection for us, but it's part of the interface.
+ */
+ZEND_FUNCTION(remctl_close)
+{
+ struct remctl *r;
+ zval *zrem;
+ int status;
+
+ /* Parse and verify arguments. */
+ status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zrem);
+ if (status == FAILURE) {
+ zend_error(E_WARNING, "remctl_error: invalid parameters\n");
+ RETURN_NULL();
+ }
+ ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
+
+ /* This delete invokes php_remctl_dtor, which calls remctl_close. */
+ zend_list_delete(Z_LVAL_P(zrem));
+ RETURN_TRUE;
+}
diff --git a/php/php_remctl.c b/php/php_remctl.c
index 7e21f48..570ac13 100644
--- a/php/php_remctl.c
+++ b/php/php_remctl.c
@@ -1,10 +1,11 @@
/*
- * remctl PECL extension for PHP
+ * remctl PECL extension for PHP 7 and later
*
* Provides bindings for PHP very similar to the libremctl library for C or
* the Net::Remctl bindings for Perl.
*
* Originally written by Andrew Mortensen <admorten@umich.edu>, 2008
+ * Copyirght 2016 Russ Allbery <eagle@eyrie.org>
* Copyright 2008 Andrew Mortensen <admorten@umich.edu>
* Copyright 2008, 2011, 2012, 2014
* The Board of Trustees of the Leland Stanford Junior University
@@ -65,7 +66,7 @@ ZEND_GET_MODULE(remctl)
* Destructor for a remctl object. Close the underlying connection.
*/
static void
-php_remctl_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+php_remctl_dtor(zend_resource *rsrc TSRMLS_DC)
{
struct remctl *r = (struct remctl *) rsrc->ptr;
@@ -93,14 +94,13 @@ PHP_MINIT_FUNCTION(remctl)
*/
ZEND_FUNCTION(remctl)
{
- zval *cmd_array, **data;
- void **data_ref;
+ zval *cmd_array, *data;
HashTable *hash;
- HashPosition pos;
char *host, *principal = NULL;
const char **command = NULL;
long port;
- int hlen, plen, count, i, status;
+ size_t hlen, plen;
+ int count, i, status;
int success = 0;
struct remctl_result *result = NULL;
@@ -139,10 +139,8 @@ ZEND_FUNCTION(remctl)
RETURN_NULL();
}
i = 0;
- zend_hash_internal_pointer_reset_ex(hash, &pos);
- data_ref = (void **) &data;
- while (zend_hash_get_current_data_ex(hash, data_ref, &pos) == SUCCESS) {
- if (Z_TYPE_PP(data) != IS_STRING) {
+ ZEND_HASH_FOREACH_VAL(hash, data) {
+ if (Z_TYPE_P(data) != IS_STRING) {
zend_error(E_WARNING, "remctl: command contains non-string\n");
goto cleanup;
}
@@ -150,15 +148,14 @@ ZEND_FUNCTION(remctl)
zend_error(E_WARNING, "remctl: internal error: incorrect count\n");
goto cleanup;
}
- command[i] = estrndup(Z_STRVAL_PP(data), Z_STRLEN_PP(data));
+ command[i] = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
if (command[i] == NULL) {
zend_error(E_WARNING, "remctl: estrndup failed\n");
count = i;
goto cleanup;
}
i++;
- zend_hash_move_forward_ex(hash, &pos);
- }
+ } ZEND_HASH_FOREACH_END();
command[count] = NULL;
/* Run the actual remctl call. */
@@ -177,14 +174,14 @@ ZEND_FUNCTION(remctl)
goto cleanup;
}
if (result->error == NULL)
- add_property_string(return_value, "error", "", 1);
+ add_property_string(return_value, "error", "");
else
- add_property_string(return_value, "error", result->error, 1);
+ add_property_string(return_value, "error", result->error);
add_property_stringl(return_value, "stdout", result->stdout_buf,
- result->stdout_len, 1);
+ result->stdout_len);
add_property_long(return_value, "stdout_len", result->stdout_len);
add_property_stringl(return_value, "stderr", result->stderr_buf,
- result->stderr_len, 1);
+ result->stderr_len);
add_property_long(return_value, "stderr_len", result->stderr_len);
add_property_long(return_value, "status", result->status);
success = 1;
@@ -214,7 +211,7 @@ ZEND_FUNCTION(remctl_new)
zend_error(E_WARNING, "remctl_new: %s", strerror(errno));
RETURN_NULL();
}
- ZEND_REGISTER_RESOURCE(return_value, r, le_remctl_internal);
+ RETURN_RES(zend_register_resource(r, le_remctl_internal));
}
@@ -226,7 +223,8 @@ ZEND_FUNCTION(remctl_set_ccache)
struct remctl *r;
zval *zrem;
char *ccache;
- int clen, status;
+ size_t clen;
+ int status;
status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zrem,
&ccache, &clen);
@@ -234,8 +232,8 @@ ZEND_FUNCTION(remctl_set_ccache)
zend_error(E_WARNING, "remctl_set_ccache: invalid parameters\n");
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
if (!remctl_set_ccache(r, ccache))
RETURN_FALSE;
RETURN_TRUE;
@@ -250,7 +248,8 @@ ZEND_FUNCTION(remctl_set_source_ip)
struct remctl *r;
zval *zrem;
char *source;
- int slen, status;
+ size_t slen;
+ int status;
status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zrem,
&source, &slen);
@@ -258,8 +257,8 @@ ZEND_FUNCTION(remctl_set_source_ip)
zend_error(E_WARNING, "remctl_set_source_ip: invalid parameters\n");
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
if (!remctl_set_source_ip(r, source))
RETURN_FALSE;
RETURN_TRUE;
@@ -273,7 +272,7 @@ ZEND_FUNCTION(remctl_set_timeout)
{
struct remctl *r;
zval *zrem;
- long timeout;
+ zend_long timeout;
int status;
status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zrem,
@@ -282,8 +281,8 @@ ZEND_FUNCTION(remctl_set_timeout)
zend_error(E_WARNING, "remctl_set_timeout: invalid parameters\n");
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
if (!remctl_set_timeout(r, timeout))
RETURN_FALSE;
RETURN_TRUE;
@@ -301,8 +300,9 @@ ZEND_FUNCTION(remctl_open)
zval *zrem;
char *host;
char *principal = NULL;
- long port = 0;
- int hlen, plen, status;
+ zend_long port = 0;
+ size_t hlen, plen;
+ int status;
/* Parse and verify arguments. */
status = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|ls", &zrem,
@@ -313,8 +313,8 @@ ZEND_FUNCTION(remctl_open)
}
if (plen == 0)
principal = NULL;
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
/* Now we have all the arguments and can do the real work. */
if (!remctl_open(r, host, port, principal))
@@ -329,10 +329,8 @@ ZEND_FUNCTION(remctl_open)
ZEND_FUNCTION(remctl_command)
{
struct remctl *r;
- zval *zrem, *cmd_array, **data;
- void **data_ref;
+ zval *zrem, *cmd_array, *data;
HashTable *hash;
- HashPosition pos;
struct iovec *cmd_vec = NULL;
int i, count, status;
int success = 0;
@@ -344,8 +342,8 @@ ZEND_FUNCTION(remctl_command)
zend_error(E_WARNING, "remctl_command: invalid parameters\n");
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
hash = Z_ARRVAL_P(cmd_array);
count = zend_hash_num_elements(hash);
if (count < 1) {
@@ -364,10 +362,8 @@ ZEND_FUNCTION(remctl_command)
RETURN_FALSE;
}
i = 0;
- zend_hash_internal_pointer_reset_ex(hash, &pos);
- data_ref = (void **) &data;
- while (zend_hash_get_current_data_ex(hash, data_ref, &pos) == SUCCESS) {
- if (Z_TYPE_PP(data) != IS_STRING) {
+ ZEND_HASH_FOREACH_VAL(hash, data) {
+ if (Z_TYPE_P(data) != IS_STRING) {
zend_error(E_WARNING,
"remctl_command: command contains non-string\n");
goto cleanup;
@@ -377,17 +373,16 @@ ZEND_FUNCTION(remctl_command)
"remctl_command: internal error: incorrect count\n");
goto cleanup;
}
- cmd_vec[i].iov_base = emalloc(Z_STRLEN_PP(data) + 1);
+ cmd_vec[i].iov_base = emalloc(Z_STRLEN_P(data) + 1);
if (cmd_vec[i].iov_base == NULL) {
zend_error(E_WARNING, "remctl_command: emalloc failed\n");
count = i;
goto cleanup;
}
- cmd_vec[i].iov_len = Z_STRLEN_PP(data);
- memcpy(cmd_vec[i].iov_base, Z_STRVAL_PP(data), cmd_vec[i].iov_len);
+ cmd_vec[i].iov_len = Z_STRLEN_P(data);
+ memcpy(cmd_vec[i].iov_base, Z_STRVAL_P(data), cmd_vec[i].iov_len);
i++;
- zend_hash_move_forward_ex(hash, &pos);
- }
+ } ZEND_HASH_FOREACH_END();
/* Finally, we can do the work. */
if (!remctl_commandv(r, cmd_vec, count))
@@ -422,8 +417,8 @@ ZEND_FUNCTION(remctl_output)
zend_error(E_WARNING, "remctl_output: invalid parameters\n");
RETURN_NULL();
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
/* Get the output token. */
output = remctl_output(r);
@@ -440,23 +435,23 @@ ZEND_FUNCTION(remctl_output)
}
switch (output->type) {
case REMCTL_OUT_OUTPUT:
- add_property_string(return_value, "type", "output", 1);
+ add_property_string(return_value, "type", "output");
add_property_stringl(return_value, "data", output->data,
- output->length, 1);
+ output->length);
add_property_long(return_value, "stream", output->stream);
break;
case REMCTL_OUT_ERROR:
- add_property_string(return_value, "type", "error", 1);
+ add_property_string(return_value, "type", "error");
add_property_stringl(return_value, "data", output->data,
- output->length, 1);
+ output->length);
add_property_long(return_value, "error", output->error);
break;
case REMCTL_OUT_STATUS:
- add_property_string(return_value, "type", "status", 1);
+ add_property_string(return_value, "type", "status");
add_property_long(return_value, "status", output->status);
break;
case REMCTL_OUT_DONE:
- add_property_string(return_value, "type", "done", 1);
+ add_property_string(return_value, "type", "done");
break;
}
}
@@ -476,8 +471,8 @@ ZEND_FUNCTION(remctl_noop)
zend_error(E_WARNING, "remctl_noop: invalid parameters\n");
RETURN_FALSE;
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
if (!remctl_noop(r))
RETURN_FALSE;
RETURN_TRUE;
@@ -500,12 +495,12 @@ ZEND_FUNCTION(remctl_error)
zend_error(E_WARNING, "remctl_error: invalid parameters\n");
RETURN_NULL();
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
+ r = zend_fetch_resource(Z_RES_P(zrem), PHP_REMCTL_RES_NAME,
+ le_remctl_internal);
/* Do the work. */
error = remctl_error(r);
- RETURN_STRING((char *) error, 1);
+ RETURN_STRING((char *) error);
}
@@ -515,7 +510,6 @@ ZEND_FUNCTION(remctl_error)
*/
ZEND_FUNCTION(remctl_close)
{
- struct remctl *r;
zval *zrem;
int status;
@@ -525,10 +519,8 @@ ZEND_FUNCTION(remctl_close)
zend_error(E_WARNING, "remctl_error: invalid parameters\n");
RETURN_NULL();
}
- ZEND_FETCH_RESOURCE(r, struct remctl *, &zrem, -1, PHP_REMCTL_RES_NAME,
- le_remctl_internal);
/* This delete invokes php_remctl_dtor, which calls remctl_close. */
- zend_list_delete(Z_LVAL_P(zrem));
+ zend_list_delete(Z_RES_P(zrem));
RETURN_TRUE;
}