cvs: php4 /ext/ircg ircg.c php_ircg.h

From: Date: Sun, 29 Jul 2001 19:02:50 +0000
Subject: cvs: php4 /ext/ircg ircg.c php_ircg.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-6392@lists.php.net to get a copy of this message
sas Sun Jul 29 15:02:50 2001 EDT Modified files: /php4/ext/ircg ircg.c php_ircg.h Log: Add a simple mechanism which enables IRCG users to retrieve the error message which caused the irc connection to be killed. We maintain a separate list for this purpose which performs automatic gc. Index: php4/ext/ircg/ircg.c diff -u php4/ext/ircg/ircg.c:1.87 php4/ext/ircg/ircg.c:1.88 --- php4/ext/ircg/ircg.c:1.87 Sat Jul 28 21:59:49 2001 +++ php4/ext/ircg/ircg.c Sun Jul 29 15:02:50 2001 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ircg.c,v 1.87 2001/07/29 01:59:49 sas Exp $ */ +/* $Id: ircg.c,v 1.88 2001/07/29 19:02:50 sas Exp $ */ #include <time.h> @@ -42,8 +42,7 @@ static HashTable h_fmt_msgs; /* Integer IDs to php_fmt_msgs_t * */ static int irconn_id = 1; -static unsigned long irc_connects, irc_set_currents, irc_quit_handlers, - irc_hash_hits, irc_hash_misses; +static unsigned long irc_connects, irc_set_currents, irc_quit_handlers; /* {{{ Format string numbers */ enum { @@ -94,8 +93,9 @@ PHP_FE(ircg_nickname_escape, NULL) PHP_FE(ircg_nickname_unescape, NULL) PHP_FE(ircg_ignore_add, NULL) - PHP_FE(ircg_ignore_del, NULL) PHP_FE(ircg_disconnect, NULL) + PHP_FE(ircg_fetch_error_msg, NULL) + PHP_FE(ircg_ignore_del, NULL) PHP_FE(ircg_is_conn_alive, NULL) PHP_FE(ircg_lookup_format_messages, NULL) PHP_FE(ircg_register_format_messages, NULL) @@ -713,6 +713,105 @@ msg_send(conn, &m); } +/* + * This is an internal API which serves the purpose to store the reason + * for terminating a connection. The termination will cause the + * connection id to become invalid. A script can then use a + * function to retrieve the last error message which was received + * from the IRC server, and will usually present a nicely formatted + * error message to the end-user. + * + * We automatically garbage-collect every n-th login, so there is + * no need for a separate gc thread. + */ + +struct errormsg { + smart_str msg; + int msgid; + int id; + struct errormsg *next; +}; + +static struct errormsg *errormsgs; + +static void error_msg_dtor(struct errormsg *m) +{ + smart_str_free_ex(&m->msg, 1); + free(m); +} + +static void error_msg_gc(void) +{ + struct errormsg *m, *prev = NULL, *next; + int lim; + + lim = irconn_id - 1000; + + for (m = errormsgs; m; prev = m, m = m->next) { + if (m->id < lim) { + struct errormsg *to; + /* Check whether we have subsequent outdated records */ + + for (to = m->next; to; to = next) { + next = to->next; + if (m->id >= lim) break; + error_msg_dtor(to); + } + + error_msg_dtor(m); + + if (prev) + prev->next = to; + else + errormsgs = to; + + if (!to) break; + m = to; + } + } +} + +static void add_error_msg(smart_str *msg, int msgid, php_irconn_t *conn) +{ + struct errormsg *m; + + for (m = errormsgs; m; m = m->next) { + if (m->id == conn->irconn_id) break; + } + + if (!m) { + m = malloc(sizeof(*m)); + m->msg.c = 0; + m->id = conn->irconn_id; + } + + smart_str_append_ex(&m->msg, msg, 1); + m->msgid = msgid; + m->next = errormsgs; + errormsgs = m; + + printf("stored msgid %d for %d at %p\n", msgid, conn->irconn_id, m); +} + +static struct errormsg *lookup_and_remove_error_msg(int id) +{ + struct errormsg *m, *prev = NULL; + + printf("looking up msg for %d\n", id); + for (m = errormsgs; m; prev = m, m = m->next) { + if (m->id == id) { + if (prev) + prev->next = m->next; + else + errormsgs = m->next; + + printf("found it at %p\n", m); + return m; + } + } + printf("nope\n"); + return NULL; +} static void error_handler(irconn_t *ircc, int id, int fatal, smart_str *msg, void *conn_data) { @@ -720,11 +819,15 @@ smart_str m = {0}; smart_str s_username; smart_str tmp; - + smart_str_setl(&tmp, "IRC SERVER", sizeof("IRC SERVER") - 1); smart_str_setl(&s_username, ircc->username, ircc->username_len); format_msg(MSG(conn, fatal ? FMT_MSG_FATAL_ERROR : FMT_MSG_ERROR), NULL, &s_username, &tmp, msg, &m); + + if (fatal) { + add_error_msg(msg, id, conn); + } msg_send(conn, &m); } @@ -1021,6 +1124,29 @@ } /* }}} */ +/* {{{ PHP_FUNCTION(ircg_fetch_error_msg) + */ +PHP_FUNCTION(ircg_fetch_error_msg) +{ + zval **args[2]; + struct errormsg *m; + + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) == FAILURE) + WRONG_PARAM_COUNT; + + convert_to_long_ex(args[0]); + + m = lookup_and_remove_error_msg(Z_LVAL_PP(args[0])); + + if (!m) RETURN_FALSE; + + array_init(return_value); + add_index_long(return_value, 0, m->msgid); + add_index_stringl(return_value, 1, m->msg.c, m->msg.len, 1); + error_msg_dtor(m); +} +/* }}} */ + /* {{{ PHP_FUNCTION(ircg_ignore_del) */ PHP_FUNCTION(ircg_ignore_del) @@ -1338,7 +1464,7 @@ { /* This should become an array very soon */ zval **p1, **p2, **p3, **p4 = NULL, **p5 = NULL, **p6; - const char *username; + const char *username = 0; const char *server = "0"; int port = 6667; php_fmt_msgs_t *fmt_msgs = NULL; @@ -1407,6 +1533,8 @@ } conn->password = conn->ident = NULL; irconn_id++; + if ((irconn_id % 1000) == 0) + error_msg_gc(); conn->irconn_id = irconn_id; zend_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL); conn->buffer.c = NULL; Index: php4/ext/ircg/php_ircg.h diff -u php4/ext/ircg/php_ircg.h:1.13 php4/ext/ircg/php_ircg.h:1.14 --- php4/ext/ircg/php_ircg.h:1.13 Sat Jul 28 07:35:57 2001 +++ php4/ext/ircg/php_ircg.h Sun Jul 29 15:02:50 2001 @@ -42,6 +42,7 @@ PHP_FUNCTION(ircg_ignore_add); PHP_FUNCTION(ircg_ignore_del); PHP_FUNCTION(ircg_kick); +PHP_FUNCTION(ircg_fetch_error_msg); PHP_FUNCTION(ircg_topic); PHP_FUNCTION(ircg_channel_mode); PHP_FUNCTION(ircg_disconnect);

« previous php.cvs (#6392) next »