]> granicus.if.org Git - php/commitdiff
added SNMPException class, enabling ability to throw exceptions
authorBoris Lytochkin <lytboris@php.net>
Fri, 2 Sep 2011 10:04:19 +0000 (10:04 +0000)
committerBoris Lytochkin <lytboris@php.net>
Fri, 2 Sep 2011 10:04:19 +0000 (10:04 +0000)
when a known SNMP error has occured
FR #55542

ext/snmp/php_snmp.h
ext/snmp/snmp.c
ext/snmp/tests/snmp-object-error.phpt
ext/snmp/tests/snmp-object-properties.phpt

index 500d4f8df8d75be6645ccbb8c21d47733b01721a..46deeff3adfba4bbb8b1a77928a8e320a6b355c5 100644 (file)
@@ -94,6 +94,7 @@ typedef struct _php_snmp_object {
        int oid_output_format;
        int snmp_errno;
        int oid_increasing_check;
+       int exceptions_enabled;
        char snmp_errstr[256];
 } php_snmp_object;
 
index 327b32e4044d62e9da2651041f298fb81273331b..41906f8d552d973bfbcebe8e92cc4a4f18d9bfbb 100644 (file)
 
 #include "zend_exceptions.h"
 
+#if HAVE_SPL
+#include "ext/spl/spl_exceptions.h"
+#endif
+
 #if HAVE_SNMP
 
 #include <sys/types.h>
@@ -113,12 +117,21 @@ typedef struct snmp_session php_snmp_session;
 }
 
 #define PHP_SNMP_ERRNO_NOERROR                 0
-#define PHP_SNMP_ERRNO_GENERIC                 1
-#define PHP_SNMP_ERRNO_TIMEOUT                 2
-#define PHP_SNMP_ERRNO_ERROR_IN_REPLY          3
-#define PHP_SNMP_ERRNO_OID_NOT_INCREASING      4
-#define PHP_SNMP_ERRNO_OID_PARSING_ERROR       5
-#define PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES    6
+#define PHP_SNMP_ERRNO_GENERIC                 (1 << 1)
+#define PHP_SNMP_ERRNO_TIMEOUT                 (1 << 2)
+#define PHP_SNMP_ERRNO_ERROR_IN_REPLY          (1 << 3)
+#define PHP_SNMP_ERRNO_OID_NOT_INCREASING      (1 << 4)
+#define PHP_SNMP_ERRNO_OID_PARSING_ERROR       (1 << 5)
+#define PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES    (1 << 6)
+#define PHP_SNMP_ERRNO_ANY     ( \
+               PHP_SNMP_ERRNO_GENERIC | \
+               PHP_SNMP_ERRNO_TIMEOUT | \
+               PHP_SNMP_ERRNO_ERROR_IN_REPLY | \
+               PHP_SNMP_ERRNO_OID_NOT_INCREASING | \
+               PHP_SNMP_ERRNO_OID_PARSING_ERROR | \
+               PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES | \
+               PHP_SNMP_ERRNO_NOERROR \
+       )
 
 ZEND_DECLARE_MODULE_GLOBALS(snmp)
 static PHP_GINIT_FUNCTION(snmp);
@@ -133,6 +146,7 @@ static zend_object_handlers php_snmp_object_handlers;
 
 /* Class entries */
 zend_class_entry *php_snmp_ce;
+zend_class_entry *php_snmp_exception_ce;
 
 /* Class object properties */
 static HashTable php_snmp_properties;
@@ -533,9 +547,13 @@ static void php_snmp_error(zval *object, const char *docref TSRMLS_DC, int type,
                return;
        }
 
-       va_start(args, format);
-       php_verror(docref, "", E_WARNING, format, args TSRMLS_CC);
-       va_end(args);
+       if (object && (snmp_object->exceptions_enabled & type)) {
+               zend_throw_exception_ex(php_snmp_exception_ce, type, snmp_object->snmp_errstr TSRMLS_CC);
+       } else {
+               va_start(args, format);
+               php_verror(docref, "", E_WARNING, format, args TSRMLS_CC);
+               va_end(args);
+       }
 }
 
 /* }}} */
@@ -1829,6 +1847,7 @@ PHP_METHOD(snmp, __construct)
        snmp_object->oid_output_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
        snmp_object->quick_print = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT);
        snmp_object->oid_increasing_check = TRUE;
+       snmp_object->exceptions_enabled = 0;
 }
 /* }}} */
 
@@ -2204,6 +2223,7 @@ PHP_SNMP_BOOL_PROPERTY_READER_FUNCTION(enum_print)
 
 PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(valueretrieval)
 PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(oid_output_format)
+PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(exceptions_enabled)
 
 /* {{{ */
 static int php_snmp_write_info(php_snmp_object *snmp_object, zval *newval TSRMLS_DC)
@@ -2330,6 +2350,27 @@ static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval *
 }
 /* }}} */
 
+/* {{{ */
+static int php_snmp_write_exceptions_enabled(php_snmp_object *snmp_object, zval *newval TSRMLS_DC)
+{
+       zval ztmp;
+       int ret = SUCCESS;
+       if (Z_TYPE_P(newval) != IS_LONG) {
+               ztmp = *newval;
+               zval_copy_ctor(&ztmp);
+               convert_to_long(&ztmp);
+               newval = &ztmp;
+       }
+
+       snmp_object->exceptions_enabled = Z_LVAL_P(newval);     
+
+       if (newval == &ztmp) {
+               zval_dtor(newval);
+       }
+       return ret;
+}
+/* }}} */
+
 /* {{{ php_snmp_class_methods[] */
 static zend_function_entry php_snmp_class_methods[] = {
        PHP_ME(snmp,     __construct,                   arginfo_snmp_create,            ZEND_ACC_PUBLIC)
@@ -2357,6 +2398,7 @@ const php_snmp_prop_handler php_snmp_property_entries[] = {
        PHP_SNMP_PROPERTY_ENTRY_RECORD(enum_print),
        PHP_SNMP_PROPERTY_ENTRY_RECORD(oid_output_format),
        PHP_SNMP_PROPERTY_ENTRY_RECORD(oid_increasing_check),
+       PHP_SNMP_PROPERTY_ENTRY_RECORD(exceptions_enabled),
        { NULL, 0, NULL, NULL}
 };
 /* }}} */
@@ -2366,7 +2408,7 @@ const php_snmp_prop_handler php_snmp_property_entries[] = {
 PHP_MINIT_FUNCTION(snmp)
 {
        netsnmp_log_handler *logh;
-       zend_class_entry ce;
+       zend_class_entry ce, cex;
 
        le_snmp_session = zend_register_list_destructors_ex(php_snmp_session_destructor, NULL, PHP_SNMP_SESSION_RES_NAME, module_number);
 
@@ -2424,18 +2466,27 @@ PHP_MINIT_FUNCTION(snmp)
        REGISTER_LONG_CONSTANT("SNMP_INTEGER",          ASN_INTEGER,    CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("SNMP_COUNTER64",        ASN_COUNTER64,  CONST_CS | CONST_PERSISTENT);
 
-       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_1",                     (long)SNMP_VERSION_1);
-       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_2c",                    (long)SNMP_VERSION_2c);
-       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_2C",                    (long)SNMP_VERSION_2c);
-       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_3",                     (long)SNMP_VERSION_3);
-
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_NOERROR",                 (long)PHP_SNMP_ERRNO_NOERROR);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_GENERIC",                 (long)PHP_SNMP_ERRNO_GENERIC);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_TIMEOUT",                 (long)PHP_SNMP_ERRNO_TIMEOUT);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_ERROR_IN_REPLY",          (long)PHP_SNMP_ERRNO_ERROR_IN_REPLY);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_OID_NOT_INCREASING",      (long)PHP_SNMP_ERRNO_OID_NOT_INCREASING);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_OID_PARSING_ERROR",       (long)PHP_SNMP_ERRNO_OID_PARSING_ERROR);
-       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_MULTIPLE_SET_QUERIES",    (long)PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES);
+       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_1",                     SNMP_VERSION_1);
+       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_2c",                    SNMP_VERSION_2c);
+       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_2C",                    SNMP_VERSION_2c);
+       REGISTER_SNMP_CLASS_CONST_LONG("VERSION_3",                     SNMP_VERSION_3);
+
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_NOERROR",                 PHP_SNMP_ERRNO_NOERROR);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_ANY",                     PHP_SNMP_ERRNO_ANY);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_GENERIC",                 PHP_SNMP_ERRNO_GENERIC);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_TIMEOUT",                 PHP_SNMP_ERRNO_TIMEOUT);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_ERROR_IN_REPLY",          PHP_SNMP_ERRNO_ERROR_IN_REPLY);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_OID_NOT_INCREASING",      PHP_SNMP_ERRNO_OID_NOT_INCREASING);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_OID_PARSING_ERROR",       PHP_SNMP_ERRNO_OID_PARSING_ERROR);
+       REGISTER_SNMP_CLASS_CONST_LONG("ERRNO_MULTIPLE_SET_QUERIES",    PHP_SNMP_ERRNO_MULTIPLE_SET_QUERIES);
+
+       /* Register SNMPException class */
+       INIT_CLASS_ENTRY(cex, "SNMPException", NULL);
+#ifdef HAVE_SPL
+       php_snmp_exception_ce = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
+#else
+       php_snmp_exception_ce = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
+#endif
 
        return SUCCESS;
 }
@@ -2465,10 +2516,30 @@ PHP_MINFO_FUNCTION(snmp)
 }
 /* }}} */
 
+/* {{{ snmp_module_deps[]
+ */
+#if ZEND_MODULE_API_NO >= 20050922
+static const zend_module_dep snmp_module_deps[] = {
+#ifdef HAVE_SPL
+       ZEND_MOD_REQUIRED("spl")
+#endif
+       ZEND_MOD_END
+};
+#endif
+
+
+/* }}} */
+
 /* {{{ snmp_module_entry
  */
 zend_module_entry snmp_module_entry = {
+#if ZEND_MODULE_API_NO >= 20050922
+       STANDARD_MODULE_HEADER_EX,
+       NULL,
+       snmp_module_deps,
+#else
        STANDARD_MODULE_HEADER,
+#endif
        "snmp",
        snmp_functions,
        PHP_MINIT(snmp),
index 83ba2b72631c6a0389aa26e47b7effd8d173fea9..b2fed9f3734eaa857a9b4c21ecbfa55492b4b7a0 100644 (file)
@@ -17,24 +17,41 @@ snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
 try {
 var_dump(new SNMP(SNMP::VERSION_1, $hostname));
 } catch (Exception $e) {
-    print $e->getMessage() . "\n";
+       print $e->getMessage() . "\n";
 }
 try {
 var_dump(new SNMP(SNMP::VERSION_1, $hostname, $community, ''));
 } catch (Exception $e) {
-    print $e->getMessage() . "\n";
+       print $e->getMessage() . "\n";
 }
 try {
 var_dump(new SNMP(SNMP::VERSION_1, $hostname, $community, $timeout, ''));
 } catch (Exception $e) {
-    print $e->getMessage() . "\n";
+       print $e->getMessage() . "\n";
 }
 try {
 var_dump(new SNMP(7, $hostname, $community));
 } catch (Exception $e) {
-    print $e->getMessage() . "\n";
+       print $e->getMessage() . "\n";
 }
 
+echo "Exception handling\n";
+$session = new SNMP(SNMP::VERSION_3, $hostname, $user_noauth, $timeout, $retries);
+try {
+       var_dump($session->get('.1.3.6.1.2.1.1.1..0'));
+} catch (SNMPException $e) {
+       var_dump($e->getCode());
+       var_dump($e->getMessage());
+}
+$session->exceptions_enabled = SNMP::ERRNO_ANY;
+try {
+       var_dump($session->get('.1.3.6.1.2.1.1.1..0'));
+} catch (SNMPException $e) {
+       var_dump($e->getCode());
+       var_dump($e->getMessage());
+}
+var_dump($session->close());
+
 echo "Open normal session\n";
 $session = new SNMP(SNMP::VERSION_3, $hostname, $user_noauth, $timeout, $retries);
 $session->valueretrieval = 67;
@@ -62,6 +79,13 @@ SNMP::__construct() expects at least 3 parameters, 2 given
 SNMP::__construct() expects parameter 4 to be long, string given
 SNMP::__construct() expects parameter 5 to be long, string given
 Unknown SNMP protocol version
+Exception handling
+
+Warning: SNMP::get(): Invalid object identifier: .1.3.6.1.2.1.1.1..0 in %s on line %d
+bool(false)
+int(32)
+string(46) "Invalid object identifier: .1.3.6.1.2.1.1.1..0"
+bool(true)
 Open normal session
 
 Warning: main(): Unknown SNMP value retrieval method '67' in %s on line %d
index e4c0538a09c51297b38b6ff8e1836db0fbe369e9..40b69683df49e63ed6a0422a1d3914a9697c1827 100644 (file)
@@ -91,6 +91,8 @@ object(SNMP)#%d (%d) {
   int(3)
   ["oid_increasing_check"]=>
   bool(true)
+  ["exceptions_enabled"]=>
+  int(0)
 }
 object(SNMP)#%d (%d) {
   ["info"]=>
@@ -116,6 +118,8 @@ object(SNMP)#%d (%d) {
   int(4)
   ["oid_increasing_check"]=>
   bool(false)
+  ["exceptions_enabled"]=>
+  int(0)
 }
 object(SNMP)#%d (%d) {
   ["info"]=>
@@ -141,6 +145,8 @@ object(SNMP)#%d (%d) {
   int(3)
   ["oid_increasing_check"]=>
   bool(true)
+  ["exceptions_enabled"]=>
+  int(0)
 }
 bool(true)
 bool(true)
@@ -169,6 +175,8 @@ object(SNMP)#%d (%d) {
   int(3)
   ["oid_increasing_check"]=>
   bool(true)
+  ["exceptions_enabled"]=>
+  int(0)
   ["123"]=>
   string(11) "param_value"
 }