cvs: php4 /ext/ircg ircg.c
| From: | Sascha Schumann | 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;
}