X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=php_ircclient.c;h=06d3cc14240783467873658808fad47d48b83e07;hb=4972a9a46a1ffa16bc29787ca5ec94e4f69b015f;hp=5b3d4ae25ba614de8e21fe9b9b40f424d01c4e9b;hpb=9679c73d557c8d4462a2867d97ae07aa72bd9dc3;p=m6w6%2Fext-ircclient diff --git a/php_ircclient.c b/php_ircclient.c index 5b3d4ae..06d3cc1 100644 --- a/php_ircclient.c +++ b/php_ircclient.c @@ -1,38 +1,38 @@ /* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2011 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: | - +----------------------------------------------------------------------+ + +--------------------------------------------------------------------+ + | PECL :: ircclient | + +--------------------------------------------------------------------+ + | Redistribution and use in source and binary forms, with or without | + | modification, are permitted provided that the conditions mentioned | + | in the accompanying LICENSE file are met. | + +--------------------------------------------------------------------+ + | Copyright (c) 2011, Michael Wallner | + +--------------------------------------------------------------------+ */ -/* $Id: header 310447 2011-04-23 21:14:10Z bjori $ */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/php_string.h" -#include "ext/standard/info.h" +#include
+#include
+#include
+#include +#include -#include "zend_interfaces.h" +#include +#include +#include + +#ifdef ZTS +#include +#endif #include "php_ircclient.h" +#include #include -#include +#include PHP_FUNCTION(parse_origin) { @@ -77,19 +77,22 @@ done: const zend_function_entry php_ircclient_function_entry[] = { ZEND_NS_FENTRY("irc\\client", parse_origin, ZEND_FN(parse_origin), NULL, 0) - PHP_FE_END + {0} }; +PHP_MINIT_FUNCTION(ircclient); +PHP_MINFO_FUNCTION(ircclient); + zend_module_entry ircclient_module_entry = { STANDARD_MODULE_HEADER, "ircclient", php_ircclient_function_entry, PHP_MINIT(ircclient), - PHP_MSHUTDOWN(ircclient), - PHP_RINIT(ircclient), - PHP_RSHUTDOWN(ircclient), + NULL, + NULL, + NULL, PHP_MINFO(ircclient), - "0.1.0", + PHP_IRCCLIENT_VERSION, STANDARD_MODULE_PROPERTIES }; @@ -116,7 +119,9 @@ static irc_callbacks_t php_ircclient_callbacks = { .event_channel = php_ircclient_event_callback, .event_privmsg = php_ircclient_event_callback, .event_notice = php_ircclient_event_callback, - /* .event_channel_notice = php_ircclient_event_callback, */ +#if PHP_IRCCLIENT_HAVE_EVENT_CHANNEL_NOTICE + .event_channel_notice = php_ircclient_event_callback, +#endif .event_invite = php_ircclient_event_callback, .event_ctcp_req = php_ircclient_event_callback, .event_ctcp_rep = php_ircclient_event_callback, @@ -127,10 +132,18 @@ static irc_callbacks_t php_ircclient_callbacks = { .event_dcc_send_req = php_ircclient_event_dcc_send_callback }; +typedef struct php_ircclient_session_callback { + zval *zfn; + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} php_ircclient_session_callback_t; + typedef struct php_ircclient_session_object { zend_object zo; zend_object_value ov; irc_session_t *sess; + unsigned opts; + HashTable cbc; #ifdef ZTS void ***ts; #endif @@ -146,20 +159,37 @@ void php_ircclient_session_object_free(void *object TSRMLS_DC) irc_destroy_session(o->sess); o->sess = NULL; } + zend_hash_destroy(&o->cbc); zend_object_std_dtor((zend_object *) o TSRMLS_CC); efree(o); } +static void php_ircclient_session_callback_dtor(void *ptr) +{ + php_ircclient_session_callback_t *cb = (php_ircclient_session_callback_t *) ptr; + + zend_fcall_info_args_clear(&cb->fci, 1); + zval_ptr_dtor(&cb->zfn); +} + zend_object_value php_ircclient_session_object_create(zend_class_entry *ce TSRMLS_DC) { php_ircclient_session_object_t *obj; obj = ecalloc(1, sizeof(*obj)); +#if PHP_VERSION_ID >= 50399 zend_object_std_init((zend_object *) obj, ce TSRMLS_CC); object_properties_init((zend_object *) obj, ce); +#else + obj->zo.ce = ce; + ALLOC_HASHTABLE(obj->zo.properties); + zend_hash_init(obj->zo.properties, zend_hash_num_elements(&ce->default_properties), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(obj->zo.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); +#endif obj->sess = irc_create_session(&php_ircclient_callbacks); irc_set_ctx(obj->sess, obj); + zend_hash_init(&obj->cbc, 10, NULL, php_ircclient_session_callback_dtor, 0); TSRMLS_SET_CTX(obj->ts); obj->ov.handle = zend_objects_store_put(obj, NULL, php_ircclient_session_object_free, NULL TSRMLS_CC); @@ -168,11 +198,47 @@ zend_object_value php_ircclient_session_object_create(zend_class_entry *ce TSRML return obj->ov; } +static php_ircclient_session_callback_t *php_ircclient_session_get_callback(php_ircclient_session_object_t *obj, const char *fn_str, size_t fn_len) +{ + zval *zo, *zm; + php_ircclient_session_callback_t cb, *cbp = NULL; + TSRMLS_FETCH_FROM_CTX(obj->ts); + + if (SUCCESS == zend_hash_find(&obj->cbc, fn_str, fn_len + 1, (void *) &cbp)) { + return cbp; + } + + MAKE_STD_ZVAL(zo); + Z_TYPE_P(zo) = IS_OBJECT; + zo->value.obj = obj->ov; + zend_objects_store_add_ref(zo TSRMLS_CC); + + MAKE_STD_ZVAL(zm); + ZVAL_STRINGL(zm, estrndup(fn_str, fn_len), fn_len, 0); + + MAKE_STD_ZVAL(cb.zfn); + array_init_size(cb.zfn, 2); + add_next_index_zval(cb.zfn, zo); + add_next_index_zval(cb.zfn, zm); + + if (SUCCESS != zend_fcall_info_init(cb.zfn, IS_CALLABLE_STRICT, &cb.fci, &cb.fcc, NULL, NULL TSRMLS_CC)) { + zval_ptr_dtor(&cb.zfn); + return NULL; + } + + if (SUCCESS != zend_hash_add(&obj->cbc, fn_str, fn_len + 1, &cb, sizeof(cb), (void *) &cbp)) { + zval_ptr_dtor(&cb.zfn); + return NULL; + } + + return cbp; +} + static void php_ircclient_event_callback(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) { char *fn_str; - int i, fn_len; - zval *zo, *zr, *za; + int fn_len; + php_ircclient_session_callback_t *cb; php_ircclient_session_object_t *obj = irc_get_ctx(session); TSRMLS_FETCH_FROM_CTX(obj->ts); @@ -186,120 +252,135 @@ static void php_ircclient_event_callback(irc_session_t *session, const char *eve } } while (*event++); - MAKE_STD_ZVAL(zo); - Z_TYPE_P(zo) = IS_OBJECT; - zo->value.obj = obj->ov; - zend_objects_store_add_ref(zo TSRMLS_CC); + if ((cb = php_ircclient_session_get_callback(obj, fn_str, fn_len -1))) { + int i; + zval *zo, *zp; - MAKE_STD_ZVAL(zr); - if (origin) { - ZVAL_STRING(zr, estrdup(origin), 0); - } else { - ZVAL_NULL(zr); - } + MAKE_STD_ZVAL(zo); + if (origin) { + ZVAL_STRING(zo, estrdup(origin), 0); + } else { + ZVAL_NULL(zo); + } - MAKE_STD_ZVAL(za); - array_init(za); - for (i = 0; i < count; ++i) { - add_next_index_string(za, estrdup(params[i]), 0); - } + MAKE_STD_ZVAL(zp); + array_init(zp); + for (i = 0; i < count; ++i) { + add_next_index_string(zp, estrdup(params[i]), 0); + } - zend_call_method(&zo, NULL, NULL, fn_str, fn_len - 1, NULL, 2, zr, za TSRMLS_CC); + if (SUCCESS == zend_fcall_info_argn(&cb->fci TSRMLS_CC, 2, &zo, &zp)) { + zend_fcall_info_call(&cb->fci, &cb->fcc, NULL, NULL TSRMLS_CC); + } - zval_ptr_dtor(&za); - zval_ptr_dtor(&zr); - zval_ptr_dtor(&zo); + zval_ptr_dtor(&zo); + zval_ptr_dtor(&zp); + } efree(fn_str); } static void php_ircclient_event_code_callback(irc_session_t *session, unsigned int event, const char *origin, const char **params, unsigned int count) { - int i; - zval *zo, *zr, *zp, *za; + php_ircclient_session_callback_t *cb; php_ircclient_session_object_t *obj = irc_get_ctx(session); TSRMLS_FETCH_FROM_CTX(obj->ts); - MAKE_STD_ZVAL(zo); - Z_TYPE_P(zo) = IS_OBJECT; - zo->value.obj = obj->ov; - zend_objects_store_add_ref(zo TSRMLS_CC); - MAKE_STD_ZVAL(zr); - if (origin) { - ZVAL_STRING(zr, estrdup(origin), 0); - } else { - ZVAL_NULL(zr); - } + if ((cb = php_ircclient_session_get_callback(obj, ZEND_STRL("onNumeric")))) { + int i; + zval *zo, *ze, *zp; - MAKE_STD_ZVAL(za); - array_init(za); - add_assoc_long_ex(za, ZEND_STRS("event"), event); + MAKE_STD_ZVAL(zo); + if (origin) { + ZVAL_STRING(zo, estrdup(origin), 0); + } else { + ZVAL_NULL(zo); + } - MAKE_STD_ZVAL(zp); - array_init(zp); - for (i = 0; i < count; ++i) { - add_next_index_string(zp, estrdup(params[i]), 0); - } - add_assoc_zval_ex(za, ZEND_STRS("params"), zp); + MAKE_STD_ZVAL(ze); + ZVAL_LONG(ze, event); - zend_call_method(&zo, NULL, NULL, ZEND_STRL("onnumeric"), NULL, 2, zr, za TSRMLS_CC); + MAKE_STD_ZVAL(zp); + array_init(zp); + for (i = 0; i < count; ++i) { + add_next_index_string(zp, estrdup(params[i]), 0); + } - zval_ptr_dtor(&zp); - zval_ptr_dtor(&za); - zval_ptr_dtor(&zr); - zval_ptr_dtor(&zo); + if (SUCCESS == zend_fcall_info_argn(&cb->fci TSRMLS_CC, 3, &zo, &ze, &zp)) { + zend_fcall_info_call(&cb->fci, &cb->fcc, NULL, NULL TSRMLS_CC); + } + zval_ptr_dtor(&zp); + zval_ptr_dtor(&ze); + zval_ptr_dtor(&zo); + } } static void php_ircclient_event_dcc_chat_callback(irc_session_t *session, const char *nick, const char *addr, irc_dcc_t dccid) { - zval *zo, *zp; + php_ircclient_session_callback_t *cb; php_ircclient_session_object_t *obj = irc_get_ctx(session); TSRMLS_FETCH_FROM_CTX(obj->ts); - MAKE_STD_ZVAL(zo); - Z_TYPE_P(zo) = IS_OBJECT; - zo->value.obj = obj->ov; - zend_objects_store_add_ref(zo TSRMLS_CC); + if ((cb = php_ircclient_session_get_callback(obj, ZEND_STRL("onDccChatReq")))) { + zval *zn, *za, *zd; - MAKE_STD_ZVAL(zp); - array_init(zp); - add_assoc_string_ex(zp, ZEND_STRS("nick"), estrdup(nick), 0); - add_assoc_string_ex(zp, ZEND_STRS("remote_addr"), estrdup(addr), 0); - add_assoc_long_ex(zp, ZEND_STRS("dccid"), dccid); + MAKE_STD_ZVAL(zn); + ZVAL_STRING(zn, estrdup(nick), 0); + MAKE_STD_ZVAL(za); + ZVAL_STRING(za, estrdup(addr), 0); + MAKE_STD_ZVAL(zd); + ZVAL_LONG(zd, dccid); - zend_call_method(&zo, NULL, NULL, ZEND_STRS("ondccchatreq"), NULL, 1, zp, NULL TSRMLS_CC); + if (SUCCESS == zend_fcall_info_argn(&cb->fci TSRMLS_CC, 3, &zn, &za, &zd)) { + zend_fcall_info_call(&cb->fci, &cb->fcc, NULL, NULL TSRMLS_CC); + } - zval_ptr_dtor(&zp); - zval_ptr_dtor(&zo); + zval_ptr_dtor(&zd); + zval_ptr_dtor(&za); + zval_ptr_dtor(&zn); + } } static void php_ircclient_event_dcc_send_callback(irc_session_t *session, const char *nick, const char *addr, const char *filename, unsigned long size, irc_dcc_t dccid) { - zval *zo, *zp; + php_ircclient_session_callback_t *cb; php_ircclient_session_object_t *obj = irc_get_ctx(session); TSRMLS_FETCH_FROM_CTX(obj->ts); - MAKE_STD_ZVAL(zo); - Z_TYPE_P(zo) = IS_OBJECT; - zo->value.obj = obj->ov; - zend_objects_store_add_ref(zo TSRMLS_CC); - - MAKE_STD_ZVAL(zp); - array_init(zp); - add_assoc_string_ex(zp, ZEND_STRS("nick"), estrdup(nick), 0); - add_assoc_string_ex(zp, ZEND_STRS("remote_addr"), estrdup(addr), 0); - add_assoc_string_ex(zp, ZEND_STRS("filename"), estrdup(filename), 0); - add_assoc_long_ex(zp, ZEND_STRS("filesize"), size); - add_assoc_long_ex(zp, ZEND_STRS("dccid"), dccid); - - zend_call_method(&zo, NULL, NULL, ZEND_STRL("ondccsendreq"), NULL, 1, zp, NULL TSRMLS_CC); + if ((cb = php_ircclient_session_get_callback(obj, ZEND_STRL("onDccChatReq")))) { + zval *zn, *za, *zf, *zs, *zd; + + MAKE_STD_ZVAL(zn); + ZVAL_STRING(zn, estrdup(nick), 0); + MAKE_STD_ZVAL(za); + ZVAL_STRING(za, estrdup(addr), 0); + MAKE_STD_ZVAL(zf); + ZVAL_STRING(zf, estrdup(filename), 0); + MAKE_STD_ZVAL(zs); + ZVAL_LONG(zs, size); + MAKE_STD_ZVAL(zd); + ZVAL_LONG(zd, dccid); + + if (SUCCESS == zend_fcall_info_argn(&cb->fci TSRMLS_CC, 5, &zn, &za, &zf, &zs, &zd)) { + zend_fcall_info_call(&cb->fci, &cb->fcc, NULL, NULL TSRMLS_CC); + } - zval_ptr_dtor(&zp); - zval_ptr_dtor(&zo); + zval_ptr_dtor(&zd); + zval_ptr_dtor(&zs); + zval_ptr_dtor(&zf); + zval_ptr_dtor(&za); + zval_ptr_dtor(&zn); + } } +ZEND_BEGIN_ARG_INFO_EX(ai_Session___construct, 0, 0, 0) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, user) + ZEND_ARG_INFO(0, real) +ZEND_END_ARG_INFO() +/* {{{ proto void Session::__construct([string nick[, string user[, string real]]]) */ PHP_METHOD(Session, __construct) { char *nick_str = NULL, *user_str = NULL, *real_str = NULL; @@ -317,7 +398,16 @@ PHP_METHOD(Session, __construct) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doConnect, 0, 0, 2) + ZEND_ARG_INFO(0, ip6) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doConnect(bool ip6, string host[, int port[, string password]]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doConnect) { char *server_str, *passwd_str = NULL; @@ -328,7 +418,7 @@ PHP_METHOD(Session, doConnect) if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "bs|ls!", &ip6, &server_str, &server_len, &port, &passwd_str, &passwd_len)) { php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); char *nick = NULL, *user = NULL, *real = NULL; - zval *znick, *zuser, *zreal, *tmp; + zval *znick, *zuser, *zreal; znick = zend_read_property(php_ircclient_session_class_entry, getThis(), ZEND_STRL("nick"), 0 TSRMLS_CC); SEPARATE_ARG_IF_REF(znick); @@ -366,7 +456,9 @@ PHP_METHOD(Session, doConnect) zval_ptr_dtor(&zreal); } } +/* }}} */ +/* {{{ proto bool Session::isConnected() */ PHP_METHOD(Session, isConnected) { if (SUCCESS == zend_parse_parameters_none()) { @@ -375,7 +467,9 @@ PHP_METHOD(Session, isConnected) RETURN_BOOL(irc_is_connected(obj->sess)); } } +/* }}} */ +/* {{{ proto void Session::disconnect() */ PHP_METHOD(Session, disconnect) { if (SUCCESS == zend_parse_parameters_none()) { @@ -384,22 +478,187 @@ PHP_METHOD(Session, disconnect) irc_disconnect(obj->sess); } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_run, 0, 0, 0) + ZEND_ARG_INFO(0, read_fd_array_for_select) + ZEND_ARG_INFO(0, write_fd_array_for_select) + ZEND_ARG_INFO(0, timeout_seconds) +ZEND_END_ARG_INFO() +/* {{{ proto array Session::run([array read_fds_for_select[, array write_fds_for_select[, double timeout = null]]]) + Returns array(array of readable fds, array of writeable fds) or false on error. */ PHP_METHOD(Session, run) { - if (SUCCESS == zend_parse_parameters_none()) { + HashTable *ifds = NULL, *ofds = NULL; + double to = php_get_inf(); + int connected; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H!H!d", &ifds, &ofds, &to)) { php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (0 != irc_run(obj->sess)) { - int err = irc_errno(obj->sess); + if (ifds || ofds) { + struct timeval t, *tp = NULL; + fd_set i, o; + int m = 0; + zval **zfd, *zr, *zw; + + FD_ZERO(&i); + FD_ZERO(&o); + + if ((connected = irc_is_connected(obj->sess))) { + if (0 != irc_add_select_descriptors(obj->sess, &i, &o, &m)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_add_select_descriptors: %s", irc_strerror(irc_errno(obj->sess))); + RETURN_FALSE; + } + } + if (ifds) { + for ( zend_hash_internal_pointer_reset(ifds); + SUCCESS == zend_hash_get_current_data(ifds, (void *) &zfd); + zend_hash_move_forward(ifds) + ) { + if (Z_TYPE_PP(zfd) == IS_RESOURCE) { + php_stream *s = NULL; + int fd = -1; + + php_stream_from_zval_no_verify(s, zfd); + + if (!s || SUCCESS != php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT, (void *) &fd, 1) || fd == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid resource"); + } else { + PHP_SAFE_FD_SET(fd, &i); + if (m < fd) { + m = fd; + } + } + } + } + } + if (ofds) { + for ( zend_hash_internal_pointer_reset(ofds); + SUCCESS == zend_hash_get_current_data(ofds, (void *) &zfd); + zend_hash_move_forward(ofds) + ) { + if (Z_TYPE_PP(zfd) == IS_RESOURCE) { + php_stream *s = NULL; + int fd = -1; + + php_stream_from_zval_no_verify(s, zfd); + + if (!s || SUCCESS != php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT|PHP_STREAM_CAST_INTERNAL, (void *) &fd, 1) || fd == -1) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid resource"); + } else { + PHP_SAFE_FD_SET(fd, &o); + if (m < fd) { + m = fd; + } + } + } + } + } + + PHP_SAFE_MAX_FD(m, m); + array_init(return_value); + + if (to != php_get_inf()) { + t.tv_sec = (time_t) to; + t.tv_usec = (suseconds_t) ((to - t.tv_sec) * 1000000.0); + tp = &t; + } + + if (0 > select(m + 1, &i, &o, NULL, tp)) { + if (errno == EINTR) { + /* interrupt; let userland be able to handle signals etc. */ + return; + } + + php_error_docref(NULL TSRMLS_CC, E_WARNING, "select() error: %s", strerror(errno)); + RETURN_FALSE; + } + + if (connected) { + if (0 != irc_process_select_descriptors(obj->sess, &i, &o)) { + int err = irc_errno(obj->sess); + + if (err) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_process: %s", irc_strerror(err)); + RETURN_FALSE; + } + } + } + + + MAKE_STD_ZVAL(zr); + array_init(zr); + MAKE_STD_ZVAL(zw); + array_init(zw); + + if (ifds) { + for ( zend_hash_internal_pointer_reset(ifds); + SUCCESS == zend_hash_get_current_data(ifds, (void *) &zfd); + zend_hash_move_forward(ifds) + ) { + if (Z_TYPE_PP(zfd) == IS_RESOURCE) { + php_stream *s = NULL; + int fd = -1; + + php_stream_from_zval_no_verify(s, zfd); + + if (s && SUCCESS == php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT|PHP_STREAM_CAST_INTERNAL, (void *) &fd, 1) && fd != -1) { + if (PHP_SAFE_FD_ISSET(fd, &i)) { + Z_ADDREF_PP(zfd); + add_next_index_zval(zr, *zfd); + } + } + } + } + } + if (ofds) { + for ( zend_hash_internal_pointer_reset(ofds); + SUCCESS == zend_hash_get_current_data(ofds, (void *) &zfd); + zend_hash_move_forward(ofds) + ) { + if (Z_TYPE_PP(zfd) == IS_RESOURCE) { + php_stream *s = NULL; + int fd = -1; + + php_stream_from_zval_no_verify(s, zfd); + + if (s && SUCCESS == php_stream_cast(s, PHP_STREAM_AS_FD_FOR_SELECT|PHP_STREAM_CAST_INTERNAL, (void *) &fd, 1) && fd != -1) { + if (PHP_SAFE_FD_ISSET(fd, &o)) { + Z_ADDREF_PP(zfd); + add_next_index_zval(zw, *zfd); + } + } + } + } + } + + add_next_index_zval(return_value, zr); + add_next_index_zval(return_value, zw); + + return; - if (err) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(err)); + } else { + if (0 != irc_run(obj->sess)) { + int err = irc_errno(obj->sess); + + if (err) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "irc_run: %s", irc_strerror(err)); + RETURN_FALSE; + } } } + + RETURN_TRUE; } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_setOption, 0, 0, 1) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, enable) +ZEND_END_ARG_INFO() +/* {{{ proto void Session::setOption(int option[, bool enable = true]) */ PHP_METHOD(Session, setOption) { long opt; @@ -409,13 +668,22 @@ PHP_METHOD(Session, setOption) php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); if (onoff) { + obj->opts |= opt; irc_option_set(obj->sess, opt); } else { + obj->opts ^= opt; irc_option_reset(obj->sess, opt); } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doJoin, 0, 0, 1) + ZEND_ARG_INFO(0, channel) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doJoin(string channel[, string password]) + Returns TRUE when the command was successfully sent. */ PHP_METHOD(Session, doJoin) { char *chan_str, *key_str = NULL; @@ -432,7 +700,13 @@ PHP_METHOD(Session, doJoin) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doPart, 0, 0, 1) + ZEND_ARG_INFO(0, channel) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doPart(string channel) + Returns TRUE when the command was successfully sent. */ PHP_METHOD(Session, doPart) { char *chan_str; @@ -449,7 +723,14 @@ PHP_METHOD(Session, doPart) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doInvite, 0, 0, 2) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, channel) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doInvite(string nick, string channel) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doInvite) { char *chan_str, *nick_str; @@ -466,7 +747,13 @@ PHP_METHOD(Session, doInvite) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doNames, 0, 0, 1) + ZEND_ARG_INFO(0, channel) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doNames(string channel) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doNames) { char *chan_str; @@ -483,7 +770,13 @@ PHP_METHOD(Session, doNames) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doList, 0, 0, 1) + ZEND_ARG_INFO(0, channel) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doList(string channel) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doList) { char *chan_str; @@ -500,7 +793,14 @@ PHP_METHOD(Session, doList) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doTopic, 0, 0, 1) + ZEND_ARG_INFO(0, channel) + ZEND_ARG_INFO(0, topic) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doTopic(string channel[, string topic]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doTopic) { char *chan_str, *topic_str = NULL; @@ -517,7 +817,14 @@ PHP_METHOD(Session, doTopic) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doChannelMode, 0, 0, 1) + ZEND_ARG_INFO(0, channel) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doChannelMode(string channel[, string mode]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doChannelMode) { char *chan_str, *mode_str = NULL; @@ -526,7 +833,7 @@ PHP_METHOD(Session, doChannelMode) if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!", &chan_str, &chan_len, &mode_str, &mode_len)) { php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (0 != irc_cmd_topic(obj->sess, chan_str, mode_str)) { + if (0 != irc_cmd_channel_mode(obj->sess, chan_str, mode_str)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(irc_errno(obj->sess))); RETVAL_FALSE; } else { @@ -534,7 +841,15 @@ PHP_METHOD(Session, doChannelMode) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doKick, 0, 0, 2) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, channel) + ZEND_ARG_INFO(0, reason) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doKick(string nick, string channel[, string reason]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doKick) { char *chan_str, *nick_str, *reason_str = NULL; @@ -551,7 +866,14 @@ PHP_METHOD(Session, doKick) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doMsg, 0, 0, 2) + ZEND_ARG_INFO(0, destination) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doMsg(string destination, string message) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doMsg) { char *dest_str, *msg_str; @@ -568,7 +890,14 @@ PHP_METHOD(Session, doMsg) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doMe, 0, 0, 2) + ZEND_ARG_INFO(0, destination) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doMe(string destination, string message) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doMe) { char *dest_str, *msg_str; @@ -585,7 +914,14 @@ PHP_METHOD(Session, doMe) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doNotice, 0, 0, 2) + ZEND_ARG_INFO(0, destination) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doNotice(string destination, string message) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doNotice) { char *dest_str, *msg_str; @@ -602,7 +938,13 @@ PHP_METHOD(Session, doNotice) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doQuit, 0, 0, 0) + ZEND_ARG_INFO(0, reason) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doQuit([string reason]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doQuit) { char *reason_str = NULL; @@ -619,7 +961,13 @@ PHP_METHOD(Session, doQuit) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doUserMode, 0, 0, 0) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doUserMode([string mode]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doUserMode) { char *mode_str = NULL; @@ -636,7 +984,13 @@ PHP_METHOD(Session, doUserMode) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doNick, 0, 0, 1) + ZEND_ARG_INFO(0, nick) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doNick(string nick) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doNick) { char *nick_str; @@ -653,7 +1007,13 @@ PHP_METHOD(Session, doNick) } } } +/* }}} */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doWhois, 0, 0, 0) + ZEND_ARG_INFO(0, nick) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doWhois([string nick]) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doWhois) { char *nick_str = NULL; @@ -670,7 +1030,14 @@ PHP_METHOD(Session, doWhois) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doCtcpReply, 0, 0, 2) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, reply) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doCtcpReply(string nick, string reply) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doCtcpReply) { char *nick_str, *reply_str; @@ -687,7 +1054,14 @@ PHP_METHOD(Session, doCtcpReply) } } } - +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doCtcpRequest, 0, 0, 2) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, request) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doCtcpRequest(string nick, string request) + Returns TRUE when the command was sent successfully. */ PHP_METHOD(Session, doCtcpRequest) { char *nick_str, *request_str; @@ -704,84 +1078,164 @@ PHP_METHOD(Session, doCtcpRequest) } } } +/* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(ai_Session_doRaw, 0, 0, 1) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() +/* {{{ proto bool Session::doRaw(string message) + Returns TRUE when the command was sent successfully. */ +PHP_METHOD(Session, doRaw) +{ + char *msg_str; + int msg_len; + + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msg_str, &msg_len)) { + php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + + if (0 != irc_send_raw(obj->sess, "%.*s", msg_len, msg_str)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", irc_strerror(irc_errno(obj->sess))); + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + } +} +/* }}} */ + +/* {{{ event_callbacks */ +ZEND_BEGIN_ARG_INFO_EX(ai_Session_event, 0, 0, 2) + ZEND_ARG_INFO(0, origin) + ZEND_ARG_ARRAY_INFO(0, args, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ai_Session_event_code, 0, 0, 3) + ZEND_ARG_INFO(0, origin) + ZEND_ARG_INFO(0, event) + ZEND_ARG_ARRAY_INFO(0, args, 0) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ai_Session_event_dcc_chat, 0, 0, 3) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, remote_addr) + ZEND_ARG_INFO(0, dccid) +ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(ai_Session_event_dcc_send, 0, 0, 5) + ZEND_ARG_INFO(0, nick) + ZEND_ARG_INFO(0, remote_addr) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, dccid) +ZEND_END_ARG_INFO() + +static void call_closure(INTERNAL_FUNCTION_PARAMETERS, /* stupid non-const API */ char *prop_str, size_t prop_len) +{ + zval **params = ecalloc(ZEND_NUM_ARGS(), sizeof(zval *)); + php_ircclient_session_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (obj->opts & LIBIRC_OPTION_DEBUG) { + zval za; + INIT_PZVAL(&za); + array_init(&za); -PHP_METHOD(Session, onConnect) {} -PHP_METHOD(Session, onNick) {} -PHP_METHOD(Session, onQuit) {} -PHP_METHOD(Session, onJoin) {} -PHP_METHOD(Session, onPart) {} -PHP_METHOD(Session, onMode) {} -PHP_METHOD(Session, onUmode) {} -PHP_METHOD(Session, onTopic) {} -PHP_METHOD(Session, onKick) {} -PHP_METHOD(Session, onChannel) {} -PHP_METHOD(Session, onPrivmsg) {} -PHP_METHOD(Session, onNOTICE) {} -PHP_METHOD(Session, onChannelNotice) {} -PHP_METHOD(Session, onInvite) {} -PHP_METHOD(Session, onCtcpReq) {} -PHP_METHOD(Session, onCtcpRep) {} -PHP_METHOD(Session, onCtcpAction) {} -PHP_METHOD(Session, onUnknown) {} -PHP_METHOD(Session, onNumeric) {} -PHP_METHOD(Session, onDccChatReq) {} -PHP_METHOD(Session, onDccSendReq) {} + if (SUCCESS == zend_copy_parameters_array(ZEND_NUM_ARGS(), &za)) { + php_printf("ircclient: %s - ", prop_str); + zend_print_flat_zval_r(&za TSRMLS_CC); + php_printf("\n"); + } + zval_dtor(&za); + } -#define ME(m) PHP_ME(Session, m, NULL, ZEND_ACC_PUBLIC) + if (SUCCESS == zend_get_parameters_array(ZEND_NUM_ARGS(), ZEND_NUM_ARGS(), params)) { + zval *prop = zend_read_property(Z_OBJCE_P(getThis()), getThis(), prop_str, prop_len, 0 TSRMLS_CC); + + if (Z_TYPE_P(prop) != IS_NULL) { + call_user_function(NULL, NULL, prop, return_value, ZEND_NUM_ARGS(), params TSRMLS_CC); + } + } + + efree(params); +} + +PHP_METHOD(Session, onConnect) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onConnect")); } +PHP_METHOD(Session, onNick) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onNick")); } +PHP_METHOD(Session, onQuit) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onQuit")); } +PHP_METHOD(Session, onJoin) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onJoin")); } +PHP_METHOD(Session, onPart) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onPart")); } +PHP_METHOD(Session, onMode) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onMode")); } +PHP_METHOD(Session, onUmode) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onUmode")); } +PHP_METHOD(Session, onTopic) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onTopic")); } +PHP_METHOD(Session, onKick) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onKick")); } +PHP_METHOD(Session, onChannel) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onChannel")); } +PHP_METHOD(Session, onPrivmsg) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onPrivmsg")); } +PHP_METHOD(Session, onNotice) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onNotice")); } +PHP_METHOD(Session, onChannelNotice) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onChannelNotice")); } +PHP_METHOD(Session, onInvite) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onInvite")); } +PHP_METHOD(Session, onCtcpReq) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onCtcpReq")); } +PHP_METHOD(Session, onCtcpRep) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onCtcpRep")); } +PHP_METHOD(Session, onAction) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onAction")); } +PHP_METHOD(Session, onUnknown) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onUnknown")); } +PHP_METHOD(Session, onNumeric) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onNumeric")); } +PHP_METHOD(Session, onDccChatReq) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onDccChatReq")); } +PHP_METHOD(Session, onDccSendReq) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onDccSendReq")); } +PHP_METHOD(Session, onError) { call_closure(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_STRL("onError")); } +/* }}} */ + +#define ME(m, ai) PHP_ME(Session, m, ai, ZEND_ACC_PUBLIC) zend_function_entry php_ircclient_session_method_entry[] = { - ME(__construct) - ME(doConnect) - ME(isConnected) - ME(disconnect) - ME(run) - ME(setOption) - - ME(doJoin) - ME(doPart) - ME(doInvite) - ME(doNames) - ME(doList) - ME(doTopic) - ME(doChannelMode) - ME(doKick) - - ME(doMsg) - ME(doMe) - ME(doNotice) - - ME(doQuit) - ME(doUserMode) - ME(doNick) - ME(doWhois) - - ME(doCtcpReply) - ME(doCtcpRequest) - - ME(onConnect) - ME(onNick) - ME(onQuit) - ME(onJoin) - ME(onPart) - ME(onMode) - ME(onUmode) - ME(onTopic) - ME(onKick) - ME(onChannel) - ME(onPrivmsg) - ME(onNOTICE) - ME(onChannelNotice) - ME(onInvite) - ME(onCtcpReq) - ME(onCtcpRep) - ME(onCtcpAction) - ME(onUnknown) - ME(onNumeric) - ME(onDccChatReq) - ME(onDccSendReq) - PHP_FE_END + ME(__construct, ai_Session___construct) + ME(doConnect, ai_Session_doConnect) + ME(isConnected, NULL) + ME(disconnect, NULL) + ME(run, ai_Session_run) + ME(setOption, ai_Session_setOption) + + ME(doJoin, ai_Session_doJoin) + ME(doPart, ai_Session_doPart) + ME(doInvite, ai_Session_doInvite) + ME(doNames, ai_Session_doNames) + ME(doList, ai_Session_doList) + ME(doTopic, ai_Session_doTopic) + ME(doChannelMode, ai_Session_doChannelMode) + ME(doKick, ai_Session_doKick) + + ME(doMsg, ai_Session_doMsg) + ME(doMe, ai_Session_doMe) + ME(doNotice, ai_Session_doNotice) + + ME(doQuit, ai_Session_doQuit) + ME(doUserMode, ai_Session_doUserMode) + ME(doNick, ai_Session_doNick) + ME(doWhois, ai_Session_doWhois) + + ME(doCtcpReply, ai_Session_doCtcpReply) + ME(doCtcpRequest, ai_Session_doCtcpRequest) + + ME(doRaw, ai_Session_doRaw) + + ME(onConnect, ai_Session_event) + ME(onNick, ai_Session_event) + ME(onQuit, ai_Session_event) + ME(onJoin, ai_Session_event) + ME(onPart, ai_Session_event) + ME(onMode, ai_Session_event) + ME(onUmode, ai_Session_event) + ME(onTopic, ai_Session_event) + ME(onKick, ai_Session_event) + ME(onChannel, ai_Session_event) + ME(onPrivmsg, ai_Session_event) + ME(onNotice, ai_Session_event) + ME(onChannelNotice, ai_Session_event) + ME(onInvite, ai_Session_event) + ME(onCtcpReq, ai_Session_event) + ME(onCtcpRep, ai_Session_event) + ME(onAction, ai_Session_event) + ME(onUnknown, ai_Session_event) + ME(onNumeric, ai_Session_event_code) + ME(onDccChatReq, ai_Session_event_dcc_chat) + ME(onDccSendReq, ai_Session_event_dcc_send) + ME(onError, ai_Session_event) + {0} }; PHP_MINIT_FUNCTION(ircclient) @@ -797,36 +1251,197 @@ PHP_MINIT_FUNCTION(ircclient) zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC); zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("real"), ZEND_ACC_PUBLIC TSRMLS_CC); - return SUCCESS; -} - - -PHP_MSHUTDOWN_FUNCTION(ircclient) -{ - return SUCCESS; -} - - + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onNick"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onQuit"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onJoin"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onPart"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onMode"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onUmode"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onTopic"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onKick"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onChannel"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onPrivmsg"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onNotice"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onChannelNotice"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onInvite"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onCtcpReq"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onCtcpRep"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onAction"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onUnknown"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onNumeric"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onDccChatReq"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onDccSendReq"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(php_ircclient_session_class_entry, ZEND_STRL("onError"), ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WELCOME", 001, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_YOURHOST", 002, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_CREATED", 003, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_MYINFO", 004, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_BOUNCE", 005, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_USERHOST", 302, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ISON", 303, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_AWAY", 301, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_UNAWAY", 305, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_NOWAWAY", 306, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOISUSER", 311, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOISSERVER", 312, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOISOPERATOR", 313, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOISIDLE", 317, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFWHOIS", 318, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOISCHANNELS", 319, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOWASUSER", 314, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFWHOWAS", 369, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LIST", 322, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LISTEND", 323, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_UNIQOPIS", 325, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_CHANNELMODEIS", 324, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_NOTOPIC", 331, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TOPIC", 332, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_INVITING", 341, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_SUMMONING", 342, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_INVITELIST", 346, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFINVITELIST", 347, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_EXCEPTLIST", 348, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFEXCEPTLIST", 349, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_VERSION", 351, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_WHOREPLY", 352, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFWHO", 315, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_NAMREPLY", 353, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFNAMES", 366, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LINKS", 364, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFLINKS", 365, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_BANLIST", 367, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFBANLIST", 368, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_INFO", 371, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFINFO", 374, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_MOTDSTART", 375, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_MOTD", 372, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFMOTD", 376, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_YOUREOPER", 381, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_REHASHING", 382, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_YOURESERVICE", 383, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TIME", 391, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_USERSSTART", 392, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_USERS", 393, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFUSERS", 394, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_NOUSERS", 395, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACELINK", 200, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACECONNECTING", 201, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACEHANDSHAKE", 202, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACEUNKNOWN", 203, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACEOPERATOR", 204, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACEUSER", 205, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACESERVER", 206, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACESERVICE", 207, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACENEWTYPE", 208, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACECLASS", 209, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACELOG", 261, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRACEEND", 262, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_STATSLINKINFO", 211, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_STATSCOMMANDS", 212, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ENDOFSTATS", 219, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_STATSUPTIME", 242, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_STATSOLINE", 243, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_UMODEIS", 221, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_SERVLIST", 234, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_SERVLISTEND", 235, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LUSERCLIENT", 251, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LUSEROP", 252, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LUSERUNKNOWN", 253, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LUSERCHANNELS", 254, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_LUSERME", 255, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ADMINME", 256, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ADMINLOC1", 257, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ADMINLOC2", 258, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_ADMINEMAIL", 259, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "RPL_TRYAGAIN", 263, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOSUCHNICK", 401, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOSUCHSERVER", 402, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOSUCHCHANNEL", 403, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_CANNOTSENDTOCHAN", 404, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_TOOMANYCHANNELS", 405, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_WASNOSUCHNICK", 406, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_TOOMANYTARGETS", 407, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOSUCHSERVICE", 408, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOORIGIN", 409, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NORECIPIENT", 411, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOTEXTTOSEND", 412, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOTOPLEVEL", 413, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_WILDTOPLEVEL", 414, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_BADMASK", 415, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_UNKNOWNCOMMAND", 421, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOMOTD", 422, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOADMININFO", 423, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_FILEERROR", 424, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NONICKNAMEGIVEN", 431, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_ERRONEUSNICKNAME", 432, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NICKNAMEINUSE", 433, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NICKCOLLISION", 436, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_UNAVAILRESOURCE", 437, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_USERNOTINCHANNEL", 441, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOTONCHANNEL", 442, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_USERONCHANNEL", 443, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOLOGIN", 444, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_SUMMONDISABLED", 445, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_USERSDISABLED", 446, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOTREGISTERED", 451, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NEEDMOREPARAMS", 461, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_ALREADYREGISTRED", 462, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOPERMFORHOST", 463, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_PASSWDMISMATCH", 464, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_YOUREBANNEDCREEP", 465, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_YOUWILLBEBANNED", 466, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_KEYSET", 467, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_CHANNELISFULL", 471, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_UNKNOWNMODE", 472, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_INVITEONLYCHAN", 473, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_BANNEDFROMCHAN", 474, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_BADCHANNELKEY", 475, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_BADCHANMASK", 476, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOCHANMODES", 477, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_BANLISTFULL", 478, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOPRIVILEGES", 481, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_CHANOPRIVSNEEDED", 482, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_CANTKILLSERVER", 483, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_RESTRICTED", 484, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_UNIQOPPRIVSNEEDED", 485, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_NOOPERHOST", 491, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_UMODEUNKNOWNFLAG", 501, CONST_CS|CONST_PERSISTENT); + REGISTER_NS_LONG_CONSTANT("irc\\client", "ERR_USERSDONTMATCH", 502, CONST_CS|CONST_PERSISTENT); -PHP_RINIT_FUNCTION(ircclient) -{ return SUCCESS; } - - -PHP_RSHUTDOWN_FUNCTION(ircclient) -{ - return SUCCESS; -} - - PHP_MINFO_FUNCTION(ircclient) { + unsigned int high, low; + char *version[2]; + + irc_get_version(&high, &low); + spprintf(&version[1], 0, "%u.%u", high, low); +#if PHP_IPHP_IRCCLIENT_LIBIRCCLIENT_VERSION_HIGH + spprintf(&version[0], 0, "%u.%u", PHP_IRCCLIENT_LIBIRCCLIENT_VERSION_HIGH, PHP_IRCCLIENT_LIBIRCCLIENT_VERSION_LOW); +#else + /* version <= 1.6 doesn't exposed its version */ + spprintf(&version[0], 0, "-"); +#endif + php_info_print_table_start(); + php_info_print_table_header(2, "IRC client support", "enabled"); + php_info_print_table_row(2, "Version", PHP_IRCCLIENT_VERSION); + php_info_print_table_end(); + php_info_print_table_start(); - php_info_print_table_header(2, "ircclient support", "enabled"); + php_info_print_table_header(3, "Used Library", "compiled", "linked"); + php_info_print_table_row(3, + "libircclient", + version[0], + version[1] + ); php_info_print_table_end(); + efree(version[0]); + efree(version[1]); }