cvs: php4 /ext/ircg ircg.c

From: Date: Tue, 14 Nov 2000 15:40:14 +0000
Subject: cvs: php4 /ext/ircg ircg.c
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-2603@lists.php.net to get a copy of this message
sas Tue Nov 14 07:40:14 2000 EDT Modified files: /php4/ext/ircg ircg.c Log: Allow customization of format strings. By using Javascript in these format strings, you can have various customized front-ends to the same back-end. Index: php4/ext/ircg/ircg.c diff -u php4/ext/ircg/ircg.c:1.1 php4/ext/ircg/ircg.c:1.2 --- php4/ext/ircg/ircg.c:1.1 Mon Nov 13 06:51:09 2000 +++ php4/ext/ircg/ircg.c Tue Nov 14 07:40:14 2000 @@ -20,16 +20,30 @@ #include "php_ini.h" #include "php_ircg.h" +#include "ext/standard/php_smart_str.h" #include "ext/standard/info.h" /* If you declare any globals in php_ircg.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(ircg) */ +/* This module is not intended for thread-safe use */ + static HashTable h_fd2irconn; static HashTable h_irconn; static int irconn_id; +/* Format string numbers */ +enum { + FMT_MSG_CHAN, + FMT_MSG_PRIV_TO_ME, + FMT_MSG_PRIV_FROM_ME, + FMT_MSG_LEAVE, + FMT_MSG_JOIN, + FMT_MSG_KICK, + NO_FMTS +}; + /* Every user visible function must have an entry in ircg_functions[]. */ function_entry ircg_functions[] = { @@ -50,8 +64,21 @@ const char *channel; zend_llist buffer; int fd; + char *fmt_msgs[NO_FMTS]; } php_irconn_t; +static char *fmt_msgs_default[] = { + "%f@%c: %m<br>\n", + "%f: %m<br>\n", + "To %t: %m<br>\n", + "%f leaves %c<br>\n", + "%f joins %c<br>\n", + "%t was kicked by %f from %c (%m)<br>\n" +}; + +#define MSG(conn, type) \ + conn->fmt_msgs[type]?conn->fmt_msgs[type]:fmt_msgs_default[type] + php_irconn_t *lookup_irconn(int id) { php_irconn_t **ret = NULL; @@ -64,7 +91,12 @@ static void irconn_dtor(void *dummy) { php_irconn_t **conn = dummy; + int i; + for (i = 0; i < NO_FMTS; i++) { + if ((*conn)->fmt_msgs[i]) free((*conn)->fmt_msgs[i]); + } + irc_disconnect(&(*conn)->conn, "Browser connection closed"); free((char *) (*conn)->username); } @@ -82,6 +114,52 @@ free(conn); } +static void format_msg(const char *fmt, const char *channel, const char *to, const char *from, const char *msg, smart_str *result) +{ + const char *p; + char c; + int mode = 0; + + for (p = fmt; (c = *p); p++) { + switch (mode) { + case 0: + switch (c) { + case '%': + mode = 1; + break; + default: + smart_str_appendc_ex(result, c, 1); + } + break; + case 1: + switch (c) { + case '%': + smart_str_appendc_ex(result, c, 1); + break; + case 'c': + smart_str_appends_ex(result, channel, 1); + break; + case 't': + smart_str_appends_ex(result, to, 1); + break; + case 'f': + smart_str_appends_ex(result, from, 1); + break; + case 'm': + smart_str_appends_ex(result, msg, 1); + break; + default: + smart_str_appendc_ex(result, '%', 1); + smart_str_appendc_ex(result, c, 1); + } + mode = 0; + break; + } + } + + smart_str_0(result); +} + #include "SAPI.h" #define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1) @@ -92,12 +170,14 @@ sapi_flush(); } -static void msg_send(php_irconn_t *conn, const char *msg) +static void msg_send(php_irconn_t *conn, smart_str *msg) { + /* XXX: Currently we don't buffer data. This is quite bad, + but leaves the implementation quite easy for now. */ /* zend_llist_add_element(&conn->buffer, strdup(msg)); */ if (conn->fd != -1) { - send(conn->fd, msg, strlen(msg), 0); + send(conn->fd, msg->c, msg->len, 0); } } @@ -105,13 +185,18 @@ smart_str *msg, void *conn_data, void *chan_data) { php_irconn_t *conn = conn_data; - char buf[2048]; + smart_str m = {0}; + + if (chan) { + format_msg(MSG(conn, FMT_MSG_CHAN), chan, conn->username, from, msg->c, + &m); + } else { + format_msg(MSG(conn, FMT_MSG_PRIV_TO_ME), NULL, conn->username, from, + msg->c, &m); + } - if (chan) - snprintf(buf, sizeof(buf), "%s@%s: %s<br>", from, chan, msg->c); - else - snprintf(buf, sizeof(buf), "%s: %s<br>", from, msg->c); - msg_send(conn, buf); + msg_send(conn, &m); + smart_str_free_ex(&m, 1); } static void user_add(irconn_t *ircc, const char *channel, smart_str *users, @@ -119,21 +204,24 @@ { php_irconn_t *conn = dummy; int i; - char buf[2048]; + smart_str m = {0}; for (i = 0; i < nr; i++) { - snprintf(buf, sizeof(buf), "%s joins %s<br>", users[i].c, channel); - msg_send(conn, buf); + format_msg(MSG(conn, FMT_MSG_JOIN), channel, NULL, users[i].c, + "", &m); + msg_send(conn, &m); } + smart_str_free_ex(&m, 1); } static void user_leave(irconn_t *ircc, const char *channel, smart_str *user, void *dummy) { php_irconn_t *conn = dummy; - char buf[2048]; + smart_str m = {0}; - snprintf(buf, sizeof(buf), "%s leaves %s<br>", user->c, channel); - msg_send(conn, buf); + format_msg(MSG(conn, FMT_MSG_LEAVE), channel, NULL, user->c, "", &m); + msg_send(conn, &m); + smart_str_free_ex(&m, 1); } static void http_closed_connection(int fd) @@ -222,17 +310,22 @@ PHP_FUNCTION(ircg_pconnect) { - zval **p1, **p2, **p3; + zval **p1, **p2, **p3, **p4; const char *username; const char *server = "0"; int port = 6667; php_irconn_t *conn; - if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3 - || zend_get_parameters_ex(ZEND_NUM_ARGS(), &p1, &p2, &p3) == FAILURE) + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 4 + || zend_get_parameters_ex(ZEND_NUM_ARGS(), &p1, &p2, &p3, &p4) == FAILURE) WRONG_PARAM_COUNT; switch (ZEND_NUM_ARGS()) { + case 4: + if (Z_TYPE_PP(p4) != IS_ARRAY) { + php_error(E_WARNING, "Fourth parameter to ircg_pconnect() shall be an array"); + RETURN_FALSE; + } case 3: convert_to_long_ex(p3); port = Z_LVAL_PP(p3); @@ -248,12 +341,27 @@ conn->username = strdup(username); conn->channel = NULL, conn->fd = -1; + if (p4) { + HashTable *h; + int i; + zval **arg; + + h = HASH_OF(*p4); + for (i = 0; i < NO_FMTS; i++) { + if (zend_hash_index_find(h, i, &arg) == SUCCESS + && Z_STRLEN_PP(arg)) { + conn->fmt_msgs[i] = strdup(Z_STRVAL_PP(arg)); + } else + conn->fmt_msgs[i] = NULL; + } + } else { + memset(conn->fmt_msgs, 0, sizeof(conn->fmt_msgs)); + } irconn_id++; zend_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL); zend_llist_init(&conn->buffer, 0, buffer_dtor, 1); irc_connect(username, NULL, msg_handler, quit_handler, conn, server, port, &conn->conn); - st_sleep(0); RETVAL_LONG(irconn_id); } @@ -279,6 +387,7 @@ zval **id, **recipient, **msg; php_irconn_t *conn; smart_str l = {0}; + smart_str m = {0}; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &id, &recipient, &msg) == FAILURE) WRONG_PARAM_COUNT; @@ -293,7 +402,20 @@ irc_msg(&conn->conn, Z_STRVAL_PP(recipient), Z_STRVAL_PP(msg)); smart_str_setl(&l, Z_STRVAL_PP(msg), Z_STRLEN_PP(msg)); - msg_handler(&conn->conn, Z_STRVAL_PP(recipient), conn->username, &l, conn, NULL); + + switch (Z_STRVAL_PP(recipient)[0]) { + case '#': + case '&': + format_msg(MSG(conn, FMT_MSG_CHAN), Z_STRVAL_PP(recipient), + NULL, conn->username, l.c, &m); + break; + default: + format_msg(MSG(conn, FMT_MSG_PRIV_FROM_ME), NULL, + Z_STRVAL_PP(recipient), conn->username, l.c, &m); + } + + msg_send(conn, &m); + smart_str_free_ex(&m, 1); RETURN_TRUE; }

« previous php.cvs (#2603) next »