sas Sat Nov 30 22:47:50 2002 EDT
Added files:
/php4/ext/ircg ircg_common.c php_ircg_alloc.h php_ircg_hash.h
php_ircg_lock.h
Removed files:
/php4/ext/ircg ircg_dummy.c
Modified files:
/php4/ext/ircg config.m4 ircg.c ircg_thttpd.c php_ircg.h
Log:
Initial work on porting extension to IRCG 4.
Index: php4/ext/ircg/config.m4
diff -u php4/ext/ircg/config.m4:1.15 php4/ext/ircg/config.m4:1.16
--- php4/ext/ircg/config.m4:1.15 Wed Nov 13 20:09:45 2002
+++ php4/ext/ircg/config.m4 Sat Nov 30 22:47:49 2002
@@ -1,5 +1,5 @@
dnl
-dnl $Id: config.m4,v 1.15 2002/11/14 01:09:45 sas Exp $
+dnl $Id: config.m4,v 1.16 2002/12/01 03:47:49 sas Exp $
dnl
PHP_ARG_WITH(ircg, for IRCG support,
@@ -29,9 +29,9 @@
PHP_NEW_EXTENSION(ircg, ircg.c ircg_scanner.c, $ext_shared)
if test "$PHP_SAPI" = "thttpd"; then
PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_thttpd.c,[],sapi)
- PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_dummy.c,[],cli)
+ PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_common.c,[],cli)
else
- PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_dummy.c)
+ PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_common.c)
fi
AC_DEFINE(HAVE_IRCG, 1, [Whether you want IRCG support])
PHP_ADD_MAKEFILE_FRAGMENT
Index: php4/ext/ircg/ircg.c
diff -u php4/ext/ircg/ircg.c:1.143 php4/ext/ircg/ircg.c:1.144
--- php4/ext/ircg/ircg.c:1.143 Sun Nov 17 00:29:17 2002
+++ php4/ext/ircg/ircg.c Sat Nov 30 22:47:49 2002
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: ircg.c,v 1.143 2002/11/17 05:29:17 sas Exp $ */
+/* $Id: ircg.c,v 1.144 2002/12/01 03:47:49 sas Exp $ */
/* {{{ includes */
@@ -28,13 +28,17 @@
#include "config.h"
#endif
+/* for smart_strs */
+#define realloc(a,b) IRCG_SHARED_REALLOC(a,b)
+#define free(a) IRCG_SHARED_FREE(a)
+
#include "php.h"
#include "php_ini.h"
#include "php_ircg.h"
#include "ext/standard/html.h"
#include "ext/standard/php_lcg.h"
-#include "ext/standard/php_smart_str.h"
+
#include "ext/standard/info.h"
#include "ext/standard/basic_functions.h"
@@ -61,15 +65,48 @@
/* {{{ Definitions */
-/* This module is not intended for thread-safe use */
-
-static HashTable h_fd2irconn; /* fd's to Integer IDs */
+#if IRCG_API_VERSION < 20021127
+#define USE_IRCONN_MANAGEMENT
static HashTable h_irconn; /* Integer IDs to php_irconn_t * */
-static HashTable h_fmt_msgs; /* Integer IDs to php_fmt_msgs_t * */
static int irconn_id;
-static unsigned long irc_connects, irc_set_currents, irc_quit_handlers,
- exec_fmt_msgs, exec_token_compiler;
+#define USE_FD2IRCONN
+static HashTable h_fd2irconn; /* fd's to Integer IDs */
+
+
+/* provide dummy definitions */
+#include "php_ircg_hash.h"
+#include "php_ircg_alloc.h"
+#include "php_ircg_lock.h"
+
+#else
+#include <ircg_resource.h>
+#include <ircg_alloc.h>
+#include <ircg_hash.h>
+#include <ircg_lock.h>
+#endif
+
+#include "ext/standard/php_smart_str.h"
+
+static struct {
+ ircg_hash_table h_fmt_msgs;
+
+#define h_fmt_msgs php_ircg->h_fmt_msgs
+
+ /* these just serve statistical/entertainment purposes */
+ unsigned long irc_connects, irc_set_currents, irc_quit_handlers,
+ exec_fmt_msgs, exec_token_compiler;
+
+#define irc_connects php_ircg->irc_connects
+#define irc_set_currents php_ircg->irc_set_currents
+#define irc_quit_handlers php_ircg->irc_quit_handlers
+#define exec_fmt_msgs php_ircg->exec_fmt_msgs
+#define exec_token_compiler php_ircg->exec_token_compiler
+
+
+ IRCG_LOCK(fmt_msgs_lock);
+#define fmt_msgs_lock php_ircg->fmt_msgs_lock
+} *php_ircg;
/* }}} */
@@ -195,7 +232,7 @@
#endif
php_fmt_msgs_t *fmt_msgs;
irc_write_buf wb;
- HashTable ctcp_msgs;
+ ircg_hash_table ctcp_msgs;
#ifdef IRCG_PENDING_URL
char *od_data; /* On_Die */
@@ -243,8 +280,6 @@
static void msg_send(php_irconn_t *conn, smart_str *msg);
-static php_irconn_t *flush_data;
-
/* }}} */
/* {{{ Default format messages */
@@ -263,9 +298,9 @@
"",
"%f changes nick to %t<br />",
"%f quits (%m)<br />",
- "Welcome to channel %c:",
+ "Users in channel %c:",
" %f",
- " in this very fine channel %c",
+ " in the channel %c<br />",
"%f: user(%t) host(%c) real name(%m)<br />",
"%f: server(%c) server info(%m)<br />",
"%f has been idle for %m seconds<br />",
@@ -284,6 +319,8 @@
"%f is inviting %t to %c<br />",
};
+ZEND_DECLARE_MODULE_GLOBALS(ircg)
+
/* }}} */
/* {{{ Format-message accessor macros */
@@ -307,16 +344,29 @@
{
php_irconn_t **ret;
- if (zend_hash_index_find(&h_irconn, id, (void **) &ret) == FAILURE)
+#ifdef USE_IRCONN_MANAGEMENT
+ if (ircg_hash_index_find(&h_irconn, id, (void **) &ret) == FAILURE)
return NULL;
return *ret;
+#else
+ return ircg_resource_get(id);
+#endif
}
+#ifdef USE_IRCONN_MANAGEMENT
+#define put_irconn(a) do {} while(0)
+#else
+static void put_irconn(php_irconn_t *c)
+{
+ ircg_resource_put(c->irconn_id);
+}
+#endif
+
static php_fmt_msgs_t *lookup_fmt_msgs(zval **id)
{
php_fmt_msgs_t *ret;
- if (zend_hash_find(&h_fmt_msgs, Z_STRVAL_PP(id), Z_STRLEN_PP(id), (void **)
&ret) == FAILURE)
+ if (ircg_hash_find(&h_fmt_msgs, Z_STRVAL_PP(id), Z_STRLEN_PP(id), (void **)
+&ret) == FAILURE)
return NULL;
return ret;
}
@@ -336,13 +386,13 @@
switch (f->t[i].code) {
case C_STRING:
smart_str_free_ex(f->t[i].para.ptr, 1);
- free(f->t[i].para.ptr);
+ IRCG_SHARED_FREE(f->t[i].para.ptr);
break;
}
i++;
}
- free(f->t);
+ IRCG_SHARED_FREE(f->t);
}
static void fmt_msgs_dtor(void *dummy)
@@ -387,11 +437,13 @@
irc_quit_handlers++;
if (conn->fd > -1) {
- zend_hash_index_del(&h_fd2irconn, conn->fd);
- if (conn->file_fd == -1)
- irc_write_buf_del(&conn->wb);
+#ifdef USE_FD2IRCONN
+ ircg_hash_index_del(&h_fd2irconn, conn->fd);
if (is_my_conn(conn))
shutdown(conn->fd, 2);
+#endif
+ if (conn->file_fd == -1)
+ irc_write_buf_del(&conn->wb);
}
if (conn->file_fd != -1) {
smart_str m = {0};
@@ -405,19 +457,22 @@
}
conn->fd = -2;
- zend_hash_index_del(&h_irconn, conn->irconn_id);
- zend_hash_destroy(&conn->ctcp_msgs);
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_index_del(&h_irconn, conn->irconn_id);
+#endif
+
+ ircg_hash_destroy(&conn->ctcp_msgs);
smart_str_free_ex(&conn->buffer, 1);
#ifdef IRCG_PENDING_URL
if (conn->od_port) {
irc_add_pending_url(conn->od_ip, conn->od_port, conn->od_data,
conn->od_len);
- free(conn->od_data);
+ IRCG_SHARED_FREE(conn->od_data);
}
#endif
- free(conn);
+ IRCG_SHARED_FREE(conn);
}
/* }}} */
@@ -559,7 +614,7 @@
/* {{{ token_compiler */
-#define NEW_TOKEN(a, b) t = realloc(t, sizeof(token_t) * (++n)); t[n-1].code=a;
t[n-1].para.b
+#define NEW_TOKEN(a, b) t = IRCG_SHARED_REALLOC(t, sizeof(token_t) * (++n));
+t[n-1].code=a; t[n-1].para.b
static void token_compiler(const char *fmt, format_msg_t *f)
{
@@ -587,7 +642,7 @@
q = p;
while (*q != '%')
if (++q >= pe) {
- s = malloc(sizeof *s);
+ s = IRCG_SHARED_ALLOC(sizeof *s);
s->c = 0;
smart_str_appendl_ex(s, p, pe - p, 1);
NEW_TOKEN(C_STRING, ptr) = s;
@@ -596,7 +651,7 @@
len = q - p;
if (len > 0) {
- s = malloc(sizeof *s);
+ s = IRCG_SHARED_ALLOC(sizeof *s);
s->c = 0;
smart_str_appendl_ex(s, p, len, 1);
NEW_TOKEN(C_STRING, ptr) = s;
@@ -733,31 +788,34 @@
#define ADD_HEADER(a) sapi_add_header(a, sizeof(a) - 1, 1)
+#ifdef USE_FD2IRCONN
static void http_closed_connection(int fd)
{
int *id, stored_id;
- if (zend_hash_index_find(&h_fd2irconn, fd, (void **) &id) == FAILURE)
+ if (ircg_hash_index_find(&h_fd2irconn, fd, (void **) &id) == FAILURE)
return;
stored_id = *id;
- zend_hash_index_del(&h_fd2irconn, fd);
- zend_hash_index_del(&h_irconn, stored_id);
+ ircg_hash_index_del(&h_fd2irconn, fd);
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_index_del(&h_irconn, stored_id);
+#endif
}
+#endif
/* }}} */
-static time_t ircg_now(void)
+static time_t php_ircg_now(void)
{
struct timeval now;
#if IRCG_API_VERSION >= 20010601
- if (ircg_now_time_t != (time_t) 0)
- return ircg_now_time_t;
- else
+ now.tv_sec = ircg_now_time_t;
+ if (now.tv_sec == (time_t) 0)
#endif
- gettimeofday(&now, NULL);
+ gettimeofday(&now, NULL);
return now.tv_sec;
}
@@ -783,7 +841,7 @@
case -2: /* Connection was finished */
goto done;
case -1: /* No message window yet. Buffer */
- if ((ircg_now() - conn->login) > WINDOW_TIMEOUT) {
+ if ((php_ircg_now() - conn->login) > WINDOW_TIMEOUT) {
irc_disconnect(&conn->conn, timeout_message);
goto done;
}
@@ -871,7 +929,7 @@
*real_msg_end = '\0';
*token_end = '\0';
- if (zend_hash_find(&conn->ctcp_msgs, msg->c + 1, token_end -
msg->c - 1, (void **) &fmt_msg) != SUCCESS) {
+ if (ircg_hash_find(&conn->ctcp_msgs, msg->c + 1, token_end -
+msg->c - 1, (void **) &fmt_msg) != SUCCESS) {
return;
}
@@ -1094,7 +1152,7 @@
static void error_msg_dtor(struct errormsg *m)
{
smart_str_free_ex(&m->msg, 1);
- free(m);
+ IRCG_SHARED_FREE(m);
}
static void error_msg_gc(time_t now)
@@ -1138,12 +1196,12 @@
}
if (!m) {
- m = malloc(sizeof(*m));
+ m = IRCG_SHARED_ALLOC(sizeof(*m));
m->msg.c = 0;
m->id = conn->irconn_id;
}
- m->when = ircg_now();
+ m->when = php_ircg_now();
m->msg.len = 0;
smart_str_append_ex(&m->msg, msg, 1);
m->msgid = msgid;
@@ -1318,13 +1376,19 @@
{
php_irconn_t *conn = dummy;
- if (conn->fd >= 0)
- send(conn->fd, " ", 2, 0);
- else if (conn->file_fd < 0 && (ircg_now() - conn->login) > WINDOW_TIMEOUT) {
+
+ if (conn->fd >= 0) {
+ smart_str tmp = {0};
+
+ smart_str_setl(&tmp, " ", 2);
+ irc_write_buf_append_ex(&conn->wb, &tmp, 1);
+ } else if (conn->file_fd < 0
+ && (php_ircg_now() - conn->login) > WINDOW_TIMEOUT) {
char buf[1024];
- sprintf(buf, "timeout after %d seconds (%d, %d)",
ircg_now()-conn->login,
- ircg_now(), conn->login);
+ sprintf(buf, "timeout after %d seconds (%d, %d)",
+ php_ircg_now()-conn->login,
+ php_ircg_now(), conn->login);
irc_disconnect(ircc, buf);
}
}
@@ -1389,15 +1453,17 @@
convert_to_long_ex(p3);
convert_to_string_ex(p4);
- if (inet_aton(Z_STRVAL_PP(p2), &conn->od_ip) == 0)
- RETURN_FALSE;
-
- conn->od_port = Z_LVAL_PP(p3);
- conn->od_data = malloc(Z_STRLEN_PP(p4));
- memcpy(conn->od_data, Z_STRVAL_PP(p4), Z_STRLEN_PP(p4));
- conn->od_len = Z_STRLEN_PP(p4);
-
- RETURN_TRUE;
+ if (inet_aton(Z_STRVAL_PP(p2), &conn->od_ip) != 0) {
+ conn->od_port = Z_LVAL_PP(p3);
+ conn->od_data = IRCG_SHARED_ALLOC(Z_STRLEN_PP(p4));
+ memcpy(conn->od_data, Z_STRVAL_PP(p4), Z_STRLEN_PP(p4));
+ conn->od_len = Z_STRLEN_PP(p4);
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+
+ put_irconn(conn);
}
#endif
/* }}} */
@@ -1419,6 +1485,8 @@
if (!conn) RETURN_FALSE;
RETVAL_STRINGL((char *) conn->conn.username, conn->conn.username_len, 1);
+
+ put_irconn(conn);
}
/* }}} */
@@ -1441,28 +1509,29 @@
if (conn->fd != -1) {
php_error(E_WARNING, "%s(): Called after a call to ircg_set_current().
You must set the output filename before opening the persistent HTTP connection which
is kept alive.", get_active_function_name(TSRMLS_C));
- RETURN_FALSE;
- }
+ RETVAL_FALSE;
+ } else {
+ if (conn->file_fd != -1)
+ close(conn->file_fd);
- if (conn->file_fd != -1)
- close(conn->file_fd);
-
- conn->file_fd = open(Z_STRVAL_PP(p2), O_WRONLY | O_CREAT | O_TRUNC | O_APPEND,
0644);
- if (conn->file_fd == -1) {
- RETURN_FALSE;
- }
-
+ conn->file_fd = open(Z_STRVAL_PP(p2), O_WRONLY | O_CREAT | O_TRUNC |
+O_APPEND, 0644);
+ if (conn->file_fd == -1) {
+ RETVAL_FALSE;
+ } else {
#ifdef F_SETFD
- if (fcntl(conn->file_fd, F_SETFD, 1)) {
- close(conn->file_fd);
- conn->file_fd = -1;
- RETURN_FALSE;
- }
+ if (fcntl(conn->file_fd, F_SETFD, 1)) {
+ close(conn->file_fd);
+ conn->file_fd = -1;
+ RETVAL_FALSE;
+ } else
#endif
-
- msg_replay_buffer(conn);
-
- RETURN_TRUE;
+ {
+ msg_replay_buffer(conn);
+ RETVAL_TRUE;
+ }
+ }
+ }
+ put_irconn(conn);
}
/* }}} */
@@ -1472,9 +1541,6 @@
{
zval **p1;
php_irconn_t *conn;
-#if 0
- socklen_t len = sizeof(struct sockaddr_in);
-#endif
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &p1) == FAILURE)
WRONG_PARAM_COUNT;
@@ -1486,36 +1552,38 @@
if (!conn) RETURN_FALSE;
if (conn->fd >= 0) {
+#ifdef USE_FD2IRCONN
/* There is a HTTP connection alive, kill it */
- zend_hash_index_del(&h_fd2irconn, conn->fd);
+ ircg_hash_index_del(&h_fd2irconn, conn->fd);
+#endif
if (conn->file_fd == -1)
irc_write_buf_del(&conn->wb);
- if (is_my_conn(conn))
- shutdown(conn->fd, 2);
+ conn->fd = -1;
}
-#if 0
- /* store peer information for safe shutdown */
- if (getpeername(conn->fd, &conn->sin, &len) == -1) {
- php_error(E_WARNING, "getpeername failed: %d (%s)", errno,
strerror(errno));
- }
-#endif
-
irc_set_currents++;
-
- if (php_ircg_register_with_sapi(&conn->fd, http_closed_connection)
+
+ if (php_ircg_register_with_sapi(&conn->fd TSRMLS_CC)
+#ifdef USE_FD2IRCONN
+ || php_ircg_register_closed_connection(http_closed_connection)
+#endif
|| fcntl(conn->fd, F_GETFL) == -1) {
- zend_hash_index_del(&h_irconn, Z_LVAL_PP(p1));
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_index_del(&h_irconn, Z_LVAL_PP(p1));
+#endif
php_error(E_WARNING, "current fd is not valid");
- RETURN_FALSE;
- }
- zend_hash_index_update(&h_fd2irconn, conn->fd, &Z_LVAL_PP(p1), sizeof(int),
NULL);
- if (conn->file_fd == -1) {
- flush_data = conn;
- irc_write_buf_add(&conn->wb, conn->fd);
+ RETVAL_FALSE;
+ } else {
+#ifdef USE_FD2IRCONN
+ ircg_hash_index_update(&h_fd2irconn, conn->fd, &Z_LVAL_PP(p1),
+ sizeof(int), NULL);
+#endif
+ if (conn->file_fd == -1 && conn->fd >= 0) {
+ IRCGG(flush_data) = conn;
+ }
+ RETVAL_TRUE;
}
-
- RETURN_TRUE;
+ put_irconn(conn);
}
/* }}} */
@@ -1593,6 +1661,8 @@
irc_join(&conn->conn, Z_STRVAL_PP(p2), key, conn);
+ put_irconn(conn);
+
RETVAL_TRUE;
}
/* }}} */
@@ -1616,6 +1686,8 @@
if (!conn) RETURN_FALSE;
irc_handle_command(&conn->conn, "WHOIS", 1, Z_STRVAL_PP(p2));
+
+ put_irconn(conn);
RETVAL_TRUE;
}
#endif
@@ -1642,6 +1714,8 @@
smart_str_setl(&s, Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]));
if (irc_ignore_check(&conn->conn, &s) == 0)
irc_ignore_add(&conn->conn, &s, 1);
+
+ put_irconn(conn);
}
#endif
/* }}} */
@@ -1688,9 +1762,12 @@
if (!conn) RETURN_FALSE;
smart_str_setl(&s, Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]));
- if (irc_ignore_del(&conn->conn, &s))
- RETURN_FALSE;
- RETURN_TRUE;
+ if (irc_ignore_del(&conn->conn, &s)) {
+ RETVAL_FALSE;
+ } else {
+ RETVAL_TRUE;
+ }
+ put_irconn(conn);
}
#endif
/* }}} */
@@ -1716,6 +1793,7 @@
irc_handle_command(&conn->conn, "MODE", 3, Z_STRVAL_PP(args[1]),
Z_STRVAL_PP(args[2]), Z_STRVAL_PP(args[3]));
+ put_irconn(conn);
RETVAL_TRUE;
}
#endif
@@ -1741,6 +1819,7 @@
if (!conn) RETURN_FALSE;
irc_handle_command(&conn->conn, "TOPIC", 2, Z_STRVAL_PP(p2), Z_STRVAL_PP(p3));
+ put_irconn(conn);
RETVAL_TRUE;
}
#endif
@@ -1804,6 +1883,8 @@
if (!conn) RETURN_FALSE;
irc_handle_command(&conn->conn, "WHO", ops ? 2 : 1, Z_STRVAL_PP(p2), "o");
+
+ put_irconn(conn);
RETVAL_TRUE;
}
@@ -1832,6 +1913,7 @@
irc_handle_command(&conn->conn, "INVITE", 2, Z_STRVAL_PP(p3),
Z_STRVAL_PP(p2));
+ put_irconn(conn);
RETVAL_TRUE;
}
@@ -1859,6 +1941,7 @@
if (!conn) RETURN_FALSE;
irc_handle_command(&conn->conn, "KICK", 3, Z_STRVAL_PP(p2), Z_STRVAL_PP(p3),
Z_STRVAL_PP(p4));
+ put_irconn(conn);
RETVAL_TRUE;
}
#endif
@@ -1882,6 +1965,7 @@
if (!conn) RETURN_FALSE;
irc_part(&conn->conn, Z_STRVAL_PP(p2));
+ put_irconn(conn);
RETVAL_TRUE;
}
/* }}} */
@@ -1891,15 +1975,17 @@
PHP_FUNCTION(ircg_is_conn_alive)
{
zval **p1;
-
+ php_irconn_t *conn;
+
if (ZEND_NUM_ARGS() != 1
|| zend_get_parameters_ex(1, &p1) == FAILURE)
WRONG_PARAM_COUNT;
convert_to_long_ex(p1);
- if (lookup_irconn(Z_LVAL_PP(p1)))
+ if ((conn = lookup_irconn(Z_LVAL_PP(p1))))
RETURN_TRUE;
+ put_irconn(conn);
RETURN_FALSE;
}
/* }}} */
@@ -1953,10 +2039,12 @@
token_compiler("", &fmt_msgs.fmt_msgs[i]);
}
-
- zend_hash_update(&h_fmt_msgs, Z_STRVAL_PP(p1), Z_STRLEN_PP(p1),
+ IRCG_LOCK_GET(fmt_msgs_lock);
+ ircg_hash_update(&h_fmt_msgs, Z_STRVAL_PP(p1), Z_STRLEN_PP(p1),
&fmt_msgs, sizeof(fmt_msgs), NULL);
+ IRCG_LOCK_PUT(fmt_msgs_lock);
+
RETVAL_TRUE;
}
/* }}} */
@@ -2069,7 +2157,7 @@
zend_hash_get_current_data_ex(Z_ARRVAL_PP(array), (void **) &val,
&pos);
convert_to_string_ex(val);
token_compiler(Z_STRVAL_PP(val), &fmt);
- zend_hash_add(&conn->ctcp_msgs, str, str_len - 1, &fmt,
+ ircg_hash_add(&conn->ctcp_msgs, str, str_len - 1, &fmt,
sizeof(fmt), NULL);
zend_hash_move_forward_ex(Z_ARRVAL_PP(array), &pos);
@@ -2123,7 +2211,7 @@
* conn must be able to live longer than the hash entry in h_irconn,
* so we have to allocate it ourselves.
*/
- conn = malloc(sizeof(*conn));
+ conn = IRCG_SHARED_ALLOC(sizeof(*conn));
conn->fd = conn->file_fd = -1;
conn->ident = conn->password = conn->realname = NULL;
if (ZEND_NUM_ARGS() > 5 && Z_TYPE_PP(p6) == IS_ARRAY) {
@@ -2154,34 +2242,40 @@
conn->fmt_msgs = fmt_msgs;
if (irc_connect(username, register_hooks,
conn, server, port, &conn->conn)) {
- free(conn);
+ IRCG_SHARED_FREE(conn);
RETURN_FALSE;
}
irc_connects++;
- zend_hash_init(&conn->ctcp_msgs, 10, NULL, (dtor_func_t) ctcp_msgs_dtor, 1);
+ ircg_hash_init(&conn->ctcp_msgs, 10, NULL, (dtor_func_t) ctcp_msgs_dtor, 1);
if (p5 && Z_TYPE_PP(p5) == IS_ARRAY) {
ircg_copy_ctcp_msgs(p5, conn);
}
conn->password = conn->ident = NULL;
+
+#ifdef USE_IRCONN_MANAGEMENT
if (irconn_id == 0)
irconn_id = 10000.0 * php_combined_lcg(TSRMLS_C);
else
irconn_id += 20.0 * (1.0 + php_combined_lcg(TSRMLS_C));
- while (zend_hash_index_exists(&h_irconn, irconn_id)) {
+ while (ircg_hash_index_exists(&h_irconn, irconn_id)) {
irconn_id++;
}
conn->irconn_id = irconn_id;
- zend_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL);
+ ircg_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL);
+#else
+ conn->irconn_id = conn->conn.resid;
+#endif
+
conn->buffer.c = NULL;
- conn->login = ircg_now();
+ conn->login = php_ircg_now();
if (conn->login >= next_gc)
error_msg_gc(conn->login);
- RETVAL_LONG(irconn_id);
+ RETVAL_LONG(conn->irconn_id);
}
/* }}} */
@@ -2197,7 +2291,9 @@
convert_to_long_ex(id);
convert_to_string_ex(reason);
- zend_hash_index_del(&h_irconn, Z_LVAL_PP(id));
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_index_del(&h_irconn, Z_LVAL_PP(id));
+#endif
RETURN_TRUE;
}
@@ -2221,6 +2317,7 @@
if (!conn) RETURN_FALSE;
irc_nick(&conn->conn, Z_STRVAL_PP(newnick));
+ put_irconn(conn);
RETURN_TRUE;
}
@@ -2245,6 +2342,7 @@
if (!conn) RETURN_FALSE;
irc_handle_command(&conn->conn, "NOTICE", 2, Z_STRVAL_PP(recipient),
Z_STRVAL_PP(msg));
+ put_irconn(conn);
RETURN_TRUE;
}
/* }}} */
@@ -2418,21 +2516,47 @@
msg_send(conn, &m);
}
+ put_irconn(conn);
RETURN_TRUE;
}
/* }}} */
+PHP_RINIT_FUNCTION(ircg)
+{
+ IRCGG(flush_data) = 0;
+}
+
/* {{{ PHP_RSHUTDOWN
*/
PHP_RSHUTDOWN_FUNCTION(ircg)
{
- if (flush_data) {
- php_irconn_t *conn = flush_data;
+ if (IRCGG(flush_data)) {
+ php_irconn_t *conn = IRCGG(flush_data);
+
+ irc_write_buf_add(&conn->wb, conn->fd);
+
+#if IRCG_API_VERSION >= 20021127
+
+ /*
+ * In a multi-process environment, IRCG will use sendmsg(2)
+ * to send the socket to the control process. After that
+ * system call, we can close the socket without any problem.
+ *
+ * Some web servers (e.g. Apache) will call shutdown(2) on
+ * the socket, so that the control process could not send
+ * any more data. This must be prevented, so we
+ * relinquish this process's control of the socket.
+ */
+
+ if (irc_write_buf_close_conn()) {
+ sapi_send_headers();
+ sapi_flush();
+ close(conn->fd);
+ }
+#endif
msg_replay_buffer(conn);
irc_write_buf_flush(&conn->wb);
-
- flush_data = NULL;
}
return SUCCESS;
@@ -2446,7 +2570,7 @@
ircg_functions,
PHP_MINIT(ircg),
PHP_MSHUTDOWN(ircg),
- NULL,
+ PHP_RINIT(ircg),
PHP_RSHUTDOWN(ircg),
PHP_MINFO(ircg),
NO_VERSION_YET,
@@ -2458,12 +2582,26 @@
#endif
/* }}} */
+static void setup(int stage)
+{
+ if (stage == 0) {
+ int i;
+
+ php_ircg = IRCG_SHARED_ALLOC(sizeof *php_ircg);
+ memset(php_ircg, 0, sizeof *php_ircg);
+
+ IRCG_LOCK_INIT(fmt_msgs_lock);
+
+ for (i = 0; i < NO_FMTS; i++) {
+ token_compiler(fmt_msgs_default[i],
+&fmt_msgs_default_compiled.fmt_msgs[i]);
+ }
+ }
+}
+
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(ircg)
{
- int i;
-
#if IRCG_API_VERSION >= 20010307
if (irc_sizeof_irconn() != sizeof(irconn_t)) {
printf("FATAL: The size of the irconn_t structure has changed "
@@ -2480,13 +2618,20 @@
}
#endif
- for (i = 0; i < NO_FMTS; i++) {
- token_compiler(fmt_msgs_default[i],
&fmt_msgs_default_compiled.fmt_msgs[i]);
- }
-
- zend_hash_init(&h_fmt_msgs, 0, NULL, fmt_msgs_dtor, 1);
- zend_hash_init(&h_fd2irconn, 0, NULL, NULL, 1);
- zend_hash_init(&h_irconn, 0, NULL, irconn_dtor, 1);
+#if IRCG_API_VERSION >= 20021127
+ ircg_setup_global("/tmp/ircg.lock", 0, setup);
+#else
+ setup(0);
+ setup(1);
+#endif
+
+ ircg_hash_init(&h_fmt_msgs, 0, NULL, fmt_msgs_dtor, 1);
+#ifdef USE_FD2IRCONN
+ ircg_hash_init(&h_fd2irconn, 0, NULL, NULL, 1);
+#endif
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_init(&h_irconn, 0, NULL, irconn_dtor, 1);
+#endif
return SUCCESS;
}
/* }}} */
@@ -2495,9 +2640,18 @@
*/
PHP_MSHUTDOWN_FUNCTION(ircg)
{
- zend_hash_destroy(&h_fmt_msgs);
- zend_hash_destroy(&h_irconn);
- zend_hash_destroy(&h_fd2irconn);
+ ircg_hash_destroy(&h_fmt_msgs);
+#ifdef USE_IRCONN_MANAGEMENT
+ ircg_hash_destroy(&h_irconn);
+#endif
+#ifdef USE_FD2IRCONN
+ ircg_hash_destroy(&h_fd2irconn);
+#endif
+
+ IRCG_LOCK_DESTROY(fmt_msgs_lock);
+
+ ircg_shutdown_global();
+
return SUCCESS;
}
/* }}} */
Index: php4/ext/ircg/ircg_thttpd.c
diff -u php4/ext/ircg/ircg_thttpd.c:1.1 php4/ext/ircg/ircg_thttpd.c:1.2
--- php4/ext/ircg/ircg_thttpd.c:1.1 Wed Nov 13 20:09:46 2002
+++ php4/ext/ircg/ircg_thttpd.c Sat Nov 30 22:47:49 2002
@@ -16,14 +16,16 @@
+----------------------------------------------------------------------+
*/
-/* $Id: ircg_thttpd.c,v 1.1 2002/11/14 01:09:46 sas Exp $ */
+/* $Id: ircg_thttpd.c,v 1.2 2002/12/01 03:47:49 sas Exp $ */
-
-int php_ircg_register_with_sapi(int *fd, void (*http_closed_connection)(int))
+int php_ircg_register_closed_connection(void (*http_closed_connection)(int))
{
thttpd_register_on_close(http_closed_connection);
thttpd_set_dont_close();
- *fd = thttpd_get_fd();
-
return 0;
+}
+
+int php_ircg_register_with_sapi(int *fd TSRMLS_DC)
+{
+ return sapi_get_fd(fd TSRMLS_CC);
}
Index: php4/ext/ircg/php_ircg.h
diff -u php4/ext/ircg/php_ircg.h:1.22 php4/ext/ircg/php_ircg.h:1.23
--- php4/ext/ircg/php_ircg.h:1.22 Sun Nov 17 00:29:17 2002
+++ php4/ext/ircg/php_ircg.h Sat Nov 30 22:47:49 2002
@@ -65,14 +65,9 @@
PHP_FUNCTION(confirm_ircg_compiled); /* For testing, remove later. */
-/*
- Declare any global variables you may need between the BEGIN
- and END macros here:
-
ZEND_BEGIN_MODULE_GLOBALS(ircg)
- int global_variable;
+ void *flush_data;
ZEND_END_MODULE_GLOBALS(ircg)
-*/
/* In every function that needs to use variables in php_ircg_globals,
do call IRCGLS_FETCH(); after declaring other variables used by
Index: php4/ext/ircg/ircg_common.c
+++ php4/ext/ircg/ircg_common.c
/*
+----------------------------------------------------------------------+
| PHP Version 4 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2002 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.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 |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Sascha Schumann <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
/* $Id: ircg_common.c,v 1.1 2002/12/01 03:47:49 sas Exp $ */
#include "php.h"
int php_ircg_register_closed_connection(void (*http_closed_connection)(int))
{
return -1;
}
int php_ircg_register_with_sapi(int *fd TSRMLS_DC)
{
sapi_force_http_10(TSRMLS_C);
return sapi_get_fd(fd TSRMLS_CC);
}
Index: php4/ext/ircg/php_ircg_alloc.h
+++ php4/ext/ircg/php_ircg_alloc.h
#define IRCG_SHARED_ALLOC(a) malloc((a))
#define IRCG_SHARED_REALLOC(a,b) realloc((a),(b))
#define IRCG_SHARED_FREE(a) free((a))
Index: php4/ext/ircg/php_ircg_hash.h
+++ php4/ext/ircg/php_ircg_hash.h
typedef HashTable ircg_hash_table;
#define ircg_hash_index_find zend_hash_index_find
#define ircg_hash_find zend_hash_find
#define ircg_hash_index_del zend_hash_index_del
#define ircg_hash_update zend_hash_update
#define ircg_hash_internal_pointer_reset_ex zend_hash_internal_pointer_reset_ex
#define ircg_hash_get_current_key_ex zend_hash_get_current_key_ex
#define ircg_hash_get_current_data_ex zend_hash_get_current_data_ex
#define ircg_hash_add zend_hash_add
#define ircg_hash_move_forward_ex zend_hash_move_forward_ex
#define ircg_hash_init zend_hash_init
#define ircg_hash_destroy zend_hash_destroy
#define ircg_hash_index_update zend_hash_index_update
#define ircg_hash_index_exists zend_hash_index_exists
Index: php4/ext/ircg/php_ircg_lock.h
+++ php4/ext/ircg/php_ircg_lock.h
#define IRCG_LOCK(name) char dummy_ ## name
#define IRCG_LOCK_INIT(name) do {} while (0)
#define IRCG_LOCK_GET(name) do {} while (0)
#define IRCG_LOCK_PUT(name) do {} while (0)
#define IRCG_LOCK_DESTROY(name) do {} while (0)
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php