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