irssi-icb patch: misc bugs, version 3

Matt Dunford <[email protected]> Tue, 28 Jun 2005 15:08:59 -0700
Newsgroups gmane.network.irc.irssi.devel
Message-ID <[email protected]>
Hi,

Finally found some time to update my patch of the icb module of irssi.

Changes include:
1) bug: the name of the person beeping you doesn't appear.
2) bug: "/nick newnick" changes your nick, but doesn't update the
   statusbar.  I've also fixed the bug I introduced into this code.
3) bug: "/topic newtopic" changes the topic, but doesn't update the statusbar.
4) added code by Tristan Horn that improves the /w command and adds a
   bunch of others (nobeep, news, cancel, etc).  I haven't tested some
   of these so please send me a bug report if you run into anything.
5) configure script wasn't handling glib correctly.
6) updated README file.

This patch is against the svn irssi-icb module:

Index: configure.in
===================================================================
--- configure.in	(revision 3804)
+++ configure.in	(working copy)
@@ -40,8 +40,108 @@
   AC_ERROR(Not irssi directory: $IRSSI_INCLUDE)
 fi
 
-AM_PATH_GLIB(1.2.0,,, gmodule)
+AC_DEFUN(AC_CHECK_GLIBDIR,[
+  AC_MSG_CHECKING([whether GLib is unpacked to irssi dir])
 
+  GLIB_DIR=`for d in * $IRSSI_INCLUDE/*; do test -f $d/glib.h && echo $d; done`
+  if test -n "$GLIB_DIR"; then
+    dnl * glib in irssi directory, use it
+    AC_MSG_RESULT([yes, using it])
+
+    dnl * we have to do this at this point so we know what libs gmodule needs
+    if test ! -f $GLIB_DIR/.libs/libglib.a; then
+      echo
+      echo "configuring GLib ..."
+      echo
+      cd $GLIB_DIR
+      if test ! -f glib-config; then
+        ./configure
+      fi
+      ${MAKE-make}
+      cd ..
+      echo
+    fi
+
+    GLIB_LDEXTRA=`$GLIB_DIR/glib-config --libs gmodule|$sedpath -e 's/-lglib//' -e 's/-lgmodule//' -e 's,-L/usr/local/lib ,,'|$sedpath 's/ \+/ /g'`
+    full_glib_dir="`pwd`/$GLIB_DIR"
+    GLIB_CFLAGS="-I$full_glib_dir -I$full_glib_dir/gmodule"
+    if test -f $full_glib_dir/.libs/libglib.a; then
+      GLIB_LIBS="$full_glib_dir/.libs/libglib.a $GLIB_LDEXTRA"
+      if test -f $full_glib_dir/gmodule/.libs/libgmodule.a; then
+	GLIB_LIBS="$GLIB_LIBS $full_glib_dir/gmodule/.libs/libgmodule.a"
+        AC_DEFINE(HAVE_GMODULE)
+	have_gmodule=yes
+      fi
+    else
+      GLIB_LIBS="$full_glib_dir/libglib.a $GLIB_LDEXTRA"
+      if test -f $full_glib_dir/gmodule/libgmodule.a; then
+	GLIB_LIBS="$GLIB_LIBS $full_glib_dir/gmodule/libgmodule.a"
+        AC_DEFINE(HAVE_GMODULE)
+	have_gmodule=yes
+      fi
+    fi
+    AC_SUBST(GLIB_CFLAGS)
+    AC_SUBST(GLIB_LIBS)
+  else
+    AC_MSG_RESULT([no])
+  fi
+])
+
+AC_CHECK_GLIBDIR
+
+if test -z "$GLIB_DIR"; then
+  if test "x$with_glib1" = "xyes"; then
+    dnl * check only for glib1
+    checks="1 2"
+  else
+    dnl * check glib2 then glib1
+    checks="3 4 1 2"
+  fi
+
+  for try in $checks; do
+    glib_config_args=
+    if test $try = 1 -o $try = 3; then
+      glib_modules=gmodule
+    else
+      echo "*** trying without -lgmodule"
+      glib_modules=
+    fi
+    if test $try = 1 -o $try = 2; then
+      AM_PATH_GLIB(1.2.0,,, $glib_modules)
+    else
+      AM_PATH_GLIB_2_0(2.0.0,,, $glib_modules)
+    fi
+    if test "$GLIB_LIBS"; then
+      if test $glib_modules = gmodule; then
+        AC_DEFINE(HAVE_GMODULE)
+        have_gmodule=yes
+      fi
+      break
+    fi
+  done
+
+  if test -z "$GLIB_LIBS"; then
+    echo
+    echo "*** If you don't have GLIB, you can get it from ftp://ftp.gtk.org"
+    echo "*** If you can't install GLIB anywhere or if you don't want to,"
+    echo "*** you can just unpack it to Irssi's source directory and"
+    echo "*** Irssi will automatically compile and use it."
+    echo
+
+    dnl * I think it's pretty safe to assume GLib 1.2.9 since the next
+    dnl * will be 2.0 (or 1.4?) and it's not sure if irssi compiles
+    dnl * with it (yea, just a few weeks after I put this text for 1.2.8
+    dnl * the 1.2.9 came :) .. and then .10
+    glib_file=glib-1.2.10.tar.gz
+
+    if test -z "$GLIB_LIBS"; then
+      AC_ERROR([GLIB is required to build irssi.])
+    fi
+  fi
+fi
+
+LIBS="$LIBS $GLIB_LIBS"
+
 # gcc specific options
 if test "x$ac_cv_prog_gcc" = "xyes"; then
   CFLAGS="$CFLAGS -Wall"
Index: src/fe-common/module-formats.c
===================================================================
--- src/fe-common/module-formats.c	(revision 3804)
+++ src/fe-common/module-formats.c	(working copy)
@@ -30,7 +30,9 @@
 	{ "status", "[$0] $1", 2, { 0, 0 } },
 	{ "important", "[$0!] $1", 2, { 0, 0 } },
 	{ "status", "{error [Error]} $0", 1, { 0 } },
-	{ "beep", "[beep] $1 beeps you", 1, { 0 } },
+	{ "beep", "[beep] $0 wants to annoy you.", 1, { 0 } },
+	{ "who_header", " Nickname        Idle Sign-On      Account", 0 },
+	{ "who_list", "$0$[13]1 $[-6]2 $[12]3 $4@$5 $6", 7, { 0, 0, 0, 0, 0, 0, 0 } },
 
 	{ NULL, NULL, 0 }
 };
Index: src/fe-common/module-formats.h
===================================================================
--- src/fe-common/module-formats.h	(revision 3804)
+++ src/fe-common/module-formats.h	(working copy)
@@ -8,7 +8,9 @@
 	ICBTXT_STATUS,
 	ICBTXT_IMPORTANT,
 	ICBTXT_ERROR,
-	ICBTXT_BEEP
+	ICBTXT_BEEP,
+	ICBTXT_WHO_HEADER,
+	ICBTXT_WHO_LIST
 };
 
 extern FORMAT_REC fecommon_icb_formats[];
Index: src/fe-common/fe-icb.c
===================================================================
--- src/fe-common/fe-icb.c	(revision 3804)
+++ src/fe-common/fe-icb.c	(working copy)
@@ -24,6 +24,7 @@
 #include "commands.h"
 #include "servers-setup.h"
 #include "levels.h"
+#include "nicklist.h"
 
 #include "icb.h"
 #include "icb-servers.h"
@@ -36,15 +37,90 @@
 static void event_status(ICB_SERVER_REC *server, const char *data)
 {
 	char **args;
+	int len;
+	char *oldnick, *newnick;
+	char *topic, *setby, *p1, *p2;
 
 	/* FIXME: status messages should probably divided into their own
 	   signals so irssi could track joins, parts, etc. */
 	args = icb_split(data, 2);
 	printformat(server, server->group->name, MSGLEVEL_CRAP,
 		    ICBTXT_STATUS, args[0], args[1]);
+
+	/* sample nick msg: oldnick changed nickname to newnick */
+	len = strlen("Name");
+	if (strncmp(args[0],"Name",len) == 0) {
+
+		oldnick = g_strdup(args[1]);
+		p2 = strchr(oldnick, ' ');
+		if (p2 != NULL)
+		{
+			*p2 = '\0';
+
+			/* make sure it's me changing the nick */
+			if (strcmp(oldnick, server->connrec->nick) == 0)
+			{
+				newnick = strrchr(args[1], ' ');
+				if (newnick != NULL) {
+					newnick++;  /* skip the space */
+
+					server_change_nick(SERVER(server), newnick);
+					nicklist_rename(SERVER(server), server->connrec->nick, newnick);
+					g_free(server->connrec->nick);
+					server->connrec->nick = g_strdup(newnick);
+				}
+			}
+		}
+		g_free(oldnick);
+	}
+
+	/* sample topic msg: nick changed the topic to \"test 1\" */
+	len = strlen("Topic");
+	if (strncmp(args[0],"Topic",len) == 0) {
+		p1 = strchr(args[1], '"');
+		p2 = strrchr(args[1], '"');
+
+		/* make sure there's something between those quotes */
+		if (p1)
+		{
+			p1++;
+			topic = g_strdup(p1);
+			p2 = strrchr(topic, '"');
+			*p2 = '\0';
+
+			setby = g_strdup(args[1]);
+			p2 = strchr(setby, ' ');
+			*p2 = '\0';
+
+			icb_channel_change_topic(server, topic, setby, time(NULL));
+
+			g_free(topic);
+			g_free(setby);
+		}
+	}
+
         icb_split_free(args);
 }
 
+static void icb_channel_change_topic(ICB_SERVER_REC *server, 
+				 const char *topic, const char *setby,
+				 time_t settime)
+{
+	if (topic != NULL) {
+		g_free_not_null(server->group->topic);
+		server->group->topic = g_strdup(topic);
+	}
+
+	if (setby != NULL) {
+		g_free_not_null(server->group->topic_by);
+		server->group->topic_by = g_strdup(setby);
+	}
+	
+	server->group->topic_time = settime;
+
+	signal_emit("channel topic changed", 1, server->group);
+}
+
 static void event_error(ICB_SERVER_REC *server, const char *data)
 {
 	printformat(server, NULL, MSGLEVEL_CRAP, ICBTXT_ERROR, data);
@@ -62,7 +138,7 @@
 
 static void event_beep(ICB_SERVER_REC *server, const char *data)
 {
-	printformat(server, data, MSGLEVEL_CRAP, ICBTXT_BEEP, data);
+	printformat(server, data, MSGLEVEL_MSGS, ICBTXT_BEEP, data);
 }
 
 static void event_open(ICB_SERVER_REC *server, const char *data)
@@ -84,13 +160,51 @@
         icb_split_free(args);
 }
 
+static char *icb_who_idle(char *line)
+{       
+	int	idle = atoi(line);
+	static	char	lbuf[16];
+        
+	if (idle > 99 * 60)
+		g_snprintf(lbuf, sizeof lbuf, "%5dm", idle / 60);
+	else
+	if (idle < 60)
+		g_snprintf(lbuf, sizeof lbuf, "%d sec", idle);
+	else
+		g_snprintf(lbuf, sizeof lbuf, "%d:%02ds", idle / 60, idle % 60);
+	lbuf[6] = 0;    /* XXX see below */
+	return (lbuf);
+}
+       
+static char *icb_who_signon(char *line)
+{       
+	time_t  their_time = (time_t)atoi(line);
+	char	*s = asctime(localtime(&their_time));
+        
+	s[16] = '\0';   /* XXX */
+	/* Tue Mar  2 05:10:10 1999J */
+	/*     <---------->          */
+	return (s + 4);
+}       
+
 static void cmdout_default(ICB_SERVER_REC *server, char **args)
 {
-	char *data;
-
-	data = g_strjoinv(" ", args+1);
-	printtext(server, server->group->name, MSGLEVEL_CRAP, "%s", data);
-        g_free(data);
+	if (args[0][0] == 'w') {
+		if (args[0][1] == 'h')
+			printformat(server, NULL, MSGLEVEL_CRAP, ICBTXT_WHO_HEADER);
+		else if (args[0][1] == 'l') {
+			char *arg1 = args[1][0] == 'm' ? "*" : " ";
+			printformat(server, NULL, MSGLEVEL_CRAP,
+				ICBTXT_WHO_LIST, arg1, args[2],
+				icb_who_idle(args[3]),
+				icb_who_signon(args[5]),
+				args[6], args[7], args[8]);
+		}
+	} else {
+		char *data = g_strjoinv(" ", args+1);
+		printtext(server, server->group->name, MSGLEVEL_CRAP, "%s", data);
+		g_free(data);
+	}
 }
 
 static void sig_server_add_fill(SERVER_SETUP_REC *rec,
Index: src/core/icb-commands.c
===================================================================
--- src/core/icb-commands.c	(revision 3804)
+++ src/core/icb-commands.c	(working copy)
@@ -29,9 +29,10 @@
 	"whois", "p", "delete", "cp", "rname",
 	"phone", "addr", "email", "text", "www",
 	"read", "write", "secure", "nosecure", "info", "?",
-
 	"invite", "v", "echoback", "name", "motd", "topic", "status",
-	"boot", "pass", "drop", "shutdown", "wall",
+	"boot", "pass", "drop", "shutdown", "wall", "away", "noaway",
+	"nobeep", "cancel", "exclude", "news", "notify", "s_help",
+	"shuttime", "whereis", "hush", "talk",
         NULL
 };
 
@@ -114,7 +115,6 @@
 
 	/* adds also some aliases known to IRC users :) */
 	command_bind_icb("quote", NULL, (SIGNAL_FUNC) cmd_quote);
-	command_bind_icb("w", NULL, (SIGNAL_FUNC) cmd_who);
 	command_bind_icb("who", NULL, (SIGNAL_FUNC) cmd_who);
         command_bind_icb("nick", NULL, (SIGNAL_FUNC) cmd_name);
         command_bind_icb("kick", NULL, (SIGNAL_FUNC) cmd_boot);
@@ -133,7 +133,6 @@
 		command_unbind(*cmd, (SIGNAL_FUNC) cmd_self);
 
 	command_unbind("quote", (SIGNAL_FUNC) cmd_quote);
-	command_unbind("w", (SIGNAL_FUNC) cmd_who);
         command_unbind("who", (SIGNAL_FUNC) cmd_who);
         command_unbind("nick", (SIGNAL_FUNC) cmd_name);
         command_unbind("kick", (SIGNAL_FUNC) cmd_boot);
Index: autogen.sh
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-sh
Index: README
===================================================================
--- README	(revision 3804)
+++ README	(working copy)
@@ -14,6 +14,10 @@
 
  icbnet = { type = "ICB"; };
 
+You'll also need to add to your startup file:
+
+ LOAD icb
+
 and then:
 
  /SERVER ADD -auto -icbnet icbnet default.icb.net