gnome-mud r673 - in trunk: . src



Author: lharris
Date: Thu Jun 26 10:34:16 2008
New Revision: 673
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=673&view=rev

Log:
Added ZMP support, removed debugging messages.


Added:
   trunk/src/mud-telnet-zmp.c
   trunk/src/mud-telnet-zmp.h
Modified:
   trunk/ChangeLog
   trunk/src/Makefile.am
   trunk/src/mud-connection-view.c
   trunk/src/mud-telnet-handlers.c
   trunk/src/mud-telnet-handlers.h
   trunk/src/mud-telnet.c
   trunk/src/mud-telnet.h

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Thu Jun 26 10:34:16 2008
@@ -49,6 +49,8 @@
 	mud-telnet.h                \
 	mud-telnet-handlers.c		\
 	mud-telnet-handlers.h		\
+	mud-telnet-zmp.c			\
+	mud-telnet-zmp.h			\
 	mud-tray.c					\
 	mud-tray.h					\
 	mud-window.c				\

Modified: trunk/src/mud-connection-view.c
==============================================================================
--- trunk/src/mud-connection-view.c	(original)
+++ trunk/src/mud-connection-view.c	Thu Jun 26 10:34:16 2008
@@ -38,6 +38,7 @@
 #include "mud-log.h"
 #include "mud-parse-base.h"
 #include "mud-telnet.h"
+#include "mud-telnet-zmp.h"
 
 /* Hack, will refactor with plugin rewrite -lh */
 extern gboolean PluginGag;
@@ -373,6 +374,8 @@
     if(connection_view->priv->history)
         g_queue_free(connection_view->priv->history);
     
+    mud_zmp_finalize(connection_view->priv->telnet);
+    
     gnet_conn_disconnect(connection_view->connection);
     gnet_conn_unref(connection_view->connection);
 	

Modified: trunk/src/mud-telnet-handlers.c
==============================================================================
--- trunk/src/mud-telnet-handlers.c	(original)
+++ trunk/src/mud-telnet-handlers.c	Thu Jun 26 10:34:16 2008
@@ -32,6 +32,7 @@
 #include "gnome-mud.h"
 #include "mud-telnet.h"
 #include "mud-telnet-handlers.h"
+#include "mud-telnet-zmp.h"
 
 /* TTYPE */
 
@@ -52,7 +53,6 @@
 MudHandler_TType_HandleSubNeg(MudTelnet *telnet, guchar *buf,
                               guint len, MudTelnetHandler *handler)
 {
-	if (len == 1 && buf[0] == TEL_TTYPE_SEND)
 	    switch(telnet->ttype_iteration)
 	    {
 	        case 0:
@@ -94,7 +94,7 @@
 	                                 'U','N','K','N','O','W','N');
 	            telnet->ttype_iteration = 0;
 	        break;
-	    }
+	       }
 }
 
 /* NAWS */
@@ -233,3 +233,67 @@
         break;
     }
 }
+
+/* ZMP */
+void 
+MudHandler_ZMP_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+    handler->enabled = TRUE;
+    mud_zmp_init(telnet);
+}
+
+void 
+MudHandler_ZMP_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+	/* Cannot disable ZMP once enabled per specification */
+    return;
+}
+
+void 
+MudHandler_ZMP_HandleSubNeg(MudTelnet *telnet, guchar *buf, 
+    guint len, MudTelnetHandler *handler)
+{
+	gchar command_buf[1024];
+	gint count = 0;
+	gint index = 0;
+	GString *args = g_string_new(NULL);
+	gchar **argv;
+	gint argc;
+	MudZMPFunction zmp_handler = NULL;
+	
+	while(buf[count] != '\0' && count < len)
+		command_buf[index++] = buf[count++];
+	command_buf[index] = '\0';
+	
+	while(count < len - 1)
+	{
+		if(buf[count] == '\0')
+		{
+			g_string_append(args,"|gmud_sep|");
+			count++;
+			continue;
+		}
+		
+		g_string_append_c(args, buf[count++]);
+	}
+	
+	g_string_prepend(args, command_buf);
+	
+	argv = g_strsplit(args->str, "|gmud_sep|", -1);
+	argc = g_strv_length(argv);
+	
+	if(mud_zmp_has_command(telnet, command_buf))
+	{
+		zmp_handler = mud_zmp_get_function(telnet, command_buf);
+		
+		if(zmp_handler)
+			zmp_handler(telnet, argc, argv);
+		else
+			g_warning("NULL ZMP functioned returned.");
+	}
+	
+	g_strfreev(argv);
+	g_string_free(args, TRUE);
+	
+}
+

Modified: trunk/src/mud-telnet-handlers.h
==============================================================================
--- trunk/src/mud-telnet-handlers.h	(original)
+++ trunk/src/mud-telnet-handlers.h	Thu Jun 26 10:34:16 2008
@@ -55,6 +55,12 @@
 void MudHandler_CHARSET_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
 void MudHandler_CHARSET_HandleSubNeg(MudTelnet *telnet, guchar *buf, 
     guint len, MudTelnetHandler *handler);
+
+/* ZMP */
+void MudHandler_ZMP_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_ZMP_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_ZMP_HandleSubNeg(MudTelnet *telnet, guchar *buf, 
+    guint len, MudTelnetHandler *handler);
     
 #endif // MUD_TELNET_HANDLERS_H
 

Added: trunk/src/mud-telnet-zmp.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-zmp.c	Thu Jun 26 10:34:16 2008
@@ -0,0 +1,258 @@
+/* GNOME-Mud - A simple Mud CLient
+ * Copyright (C) 1998-2006 Robin Ericsson <lobbin localhost nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Code originally from wxMUD. Converted to a GObject by Les Harris.
+ * wxMUD - an open source cross-platform MUD client.
+ * Copyright (C) 2003-2008 Mart Raudsepp and Gabriel Levin
+ */
+ 
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <gnet.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-zmp.h"
+
+static void mud_zmp_register_core_functions(MudTelnet *telnet);
+static void mud_zmp_send_command(MudTelnet *telnet, guint32 count, ...);
+static void mud_zmp_destroy_key(gpointer k);
+static void mud_zmp_destroy_command(gpointer c);
+
+/* Core ZMP Functions */
+static void ZMP_ident(MudTelnet *telnet, gint argc, gchar **argv);
+static void ZMP_ping_and_time(MudTelnet *telnet, gint argc, gchar **argv);
+static void ZMP_check(MudTelnet *telnet, gint argc, gchar **argv);
+
+/* Public Interface */
+void 
+mud_zmp_init(MudTelnet *telnet)
+{
+	telnet->zmp_commands = g_hash_table_new_full(g_str_hash, g_str_equal,
+		mud_zmp_destroy_key, mud_zmp_destroy_command);
+
+	mud_zmp_register_core_functions(telnet);
+}
+
+void 
+mud_zmp_finalize(MudTelnet *telnet)
+{
+	if(telnet->zmp_commands)
+		g_hash_table_destroy(telnet->zmp_commands);
+}
+
+void
+mud_zmp_register(MudTelnet *telnet, MudZMPCommand *command)
+{		
+	if(command && mud_zmp_has_command(telnet, command->name))
+		return; // Function already registered.
+	
+	g_hash_table_insert(telnet->zmp_commands, g_strdup(command->name), command);
+}
+
+gboolean
+mud_zmp_has_command(MudTelnet *telnet, gchar *name)
+{
+	return !(g_hash_table_lookup(telnet->zmp_commands, name) == NULL);
+}
+
+gboolean
+mud_zmp_has_package(MudTelnet *telnet, gchar *package)
+{
+	GList *keys = g_hash_table_get_keys(telnet->zmp_commands);
+	GList *iter;
+	
+	for(iter = g_list_first(keys); iter != NULL; iter = g_list_next(iter))
+	{
+		MudZMPCommand *command = 
+			(MudZMPCommand *)g_hash_table_lookup(telnet->zmp_commands, 
+			(gchar *)iter->data);
+		
+		if(strcmp(command->package, package) == 0)
+		{
+			g_list_free(keys);
+			return TRUE;
+		}
+	}
+	
+	g_list_free(keys);
+	
+	return FALSE;
+}
+
+MudZMPFunction
+mud_zmp_get_function(MudTelnet *telnet, gchar *name)
+{
+	MudZMPFunction ret = NULL;
+	MudZMPCommand *val;
+	
+	if(!mud_zmp_has_command(telnet, name))
+		return NULL;
+	
+	val = (MudZMPCommand *)g_hash_table_lookup(telnet->zmp_commands, name);
+	
+	if(val)
+		ret = (MudZMPFunction)val->execute;
+	
+	return ret;
+}
+
+/* Private Methods */
+static void
+mud_zmp_send_command(MudTelnet *telnet, guint32 count, ...)
+{
+    guchar byte;
+    guint32 i;
+    guint32 j;
+	guchar null = '\0';
+	byte = (guchar)TEL_IAC;
+	va_list va;
+	va_start(va, count);
+	gchar *arg;
+	
+	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+	byte = (guchar)TEL_SB;
+	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    byte = (guchar)TELOPT_ZMP;
+    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    
+    for (i = 0; i < count; ++i)
+	{
+		arg = (gchar *)va_arg(va, gchar *);
+		
+		for(j = 0; j < strlen(arg); ++j)
+		{
+			byte = (guchar)arg[j];
+			
+			gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+			
+			if (byte == (guchar)TEL_IAC)
+				gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+		}
+		
+		gnet_conn_write(telnet->conn, (gchar *)&null, 1);
+	}
+
+	va_end(va);
+	
+	byte = (guchar)TEL_IAC;
+	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+	byte = (guchar)TEL_SE;
+	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+}
+
+static void
+mud_zmp_register_core_functions(MudTelnet *telnet)
+{
+	gint count = 4;
+	gint i;
+	
+	telnet->commands[0].name = g_strdup("zmp.ident");
+	telnet->commands[0].package = g_strdup("zmp.");
+	telnet->commands[0].execute = ZMP_ident;
+	
+	telnet->commands[1].name = g_strdup("zmp.ping");
+	telnet->commands[1].package = g_strdup("zmp.");
+	telnet->commands[1].execute = ZMP_ping_and_time;
+	
+	telnet->commands[2].name = g_strdup("zmp.time");
+	telnet->commands[2].package = g_strdup("zmp.");
+	telnet->commands[2].execute = ZMP_ping_and_time;
+	
+	telnet->commands[3].name = g_strdup("zmp.check");
+	telnet->commands[3].package = g_strdup("zmp.");
+	telnet->commands[3].execute = ZMP_check;
+	
+	for(i = 0; i < count; ++i)
+		mud_zmp_register(telnet, &telnet->commands[i]);
+}
+
+static void 
+mud_zmp_destroy_key(gpointer k)
+{
+	gchar *key = (gchar *)k;
+	
+	if(key)
+		g_free(key);
+}
+
+static void 
+mud_zmp_destroy_command(gpointer c)
+{
+	MudZMPCommand *command = (MudZMPCommand *)c;
+	
+	if(command)
+	{
+		if(command->name)
+			g_free(command->name);
+			
+		if(command->package)
+			g_free(command->package);
+	}
+}
+
+/* Core ZMP Functions */
+static void
+ZMP_ident(MudTelnet *telnet, gint argc, gchar **argv)
+{
+	mud_zmp_send_command(telnet, 4, 
+		"zmp.ident", "gnome-mud", "0.11", 
+		"A mud client written for the GNOME environment.");
+}
+
+static void 
+ZMP_ping_and_time(MudTelnet *telnet, gint argc, gchar **argv)
+{
+	time_t t;
+	time(&t);
+	gchar time_buffer[128];
+	
+	strftime(time_buffer, sizeof(time_buffer), 
+		"%Y-%m-%d %H:%M:%S", gmtime(&t));
+
+	mud_zmp_send_command(telnet, 2, "zmp.time", time_buffer);
+}
+
+static void
+ZMP_check(MudTelnet *telnet, gint argc, gchar **argv)
+{
+	gchar *item = argv[1];
+	
+	if(item[strlen(item) - 1] == '.') // Check for package.
+	{
+		if(mud_zmp_has_package(telnet, item))
+			mud_zmp_send_command(telnet, 2, "zmp.support", item);
+		else
+			mud_zmp_send_command(telnet, 2, "zmp.no-support", item);
+	}
+	else // otherwise command
+	{
+		if(mud_zmp_has_command(telnet, item))
+			mud_zmp_send_command(telnet, 2, "zmp.support", item);
+		else
+			mud_zmp_send_command(telnet, 2, "zmp.no-support", item);
+	}	
+}
+

Added: trunk/src/mud-telnet-zmp.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-zmp.h	Thu Jun 26 10:34:16 2008
@@ -0,0 +1,41 @@
+/* GNOME-Mud - A simple Mud CLient
+ * Copyright (C) 1998-2006 Robin Ericsson <lobbin localhost nu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_ZMP_H
+#define MUD_TELNET_ZMP_H
+
+#include <glib.h>
+#include "mud-telnet.h"
+
+typedef void(*MudZMPFunction)(MudTelnet *telnet, gint argc, gchar **argv);
+
+typedef struct MudZMPCommand
+{
+	gchar *package;
+	gchar *name;
+	MudZMPFunction execute;
+} MudZMPCommand;
+
+void mud_zmp_init(MudTelnet *telnet);
+void mud_zmp_finalize(MudTelnet *telnet);
+void mud_zmp_register(MudTelnet *telnet, MudZMPCommand *command);
+gboolean mud_zmp_has_command(MudTelnet *telnet, gchar *name);
+MudZMPFunction mud_zmp_get_function(MudTelnet *telnet, gchar *name);
+
+#endif // MUD_TELNET_ZMP_H
+

Modified: trunk/src/mud-telnet.c
==============================================================================
--- trunk/src/mud-telnet.c	(original)
+++ trunk/src/mud-telnet.c	Thu Jun 26 10:34:16 2008
@@ -33,6 +33,7 @@
 #include "gnome-mud.h"
 #include "mud-telnet.h"
 #include "mud-telnet-handlers.h"
+#include "mud-telnet-zmp.h"
 
 #define TELNET_TRACE_MASK _("telnet")
 
@@ -208,6 +209,14 @@
     telnet->handlers[4].disable = MudHandler_CHARSET_Disable;
     telnet->handlers[4].handle_sub_neg = MudHandler_CHARSET_HandleSubNeg;
     
+    /* ZMP */
+    telnet->handlers[5].type = HANDLER_ZMP;
+    telnet->handlers[5].option_number = (guchar)TELOPT_ZMP;
+    telnet->handlers[5].enabled = TRUE;
+    telnet->handlers[5].enable = MudHandler_ZMP_Enable;
+    telnet->handlers[5].disable = MudHandler_ZMP_Disable;
+    telnet->handlers[5].handle_sub_neg = MudHandler_ZMP_HandleSubNeg;
+    
 }
 
 gint
@@ -287,52 +296,42 @@
 				break;
 
 			case TEL_STATE_IAC:
-			    g_message("IAC");
 				switch (buf[i])
 				{
 					case (guchar)TEL_IAC:
-					    g_message("\tIAC");
 						processed[pos++] = buf[i];
 						telnet->tel_state = TEL_STATE_TEXT;
 						break;
 
 					case (guchar)TEL_DO:
-					    g_message("\tDO");
 						telnet->tel_state = TEL_STATE_DO;
 						break;
 
 					case (guchar)TEL_DONT:
-					    g_message("\tDONT");
 						telnet->tel_state = TEL_STATE_DONT;
 						break;
 
 					case (guchar)TEL_WILL:
-					    g_message("\tWILL");
 						telnet->tel_state = TEL_STATE_WILL;
 						break;
 						
 					case (guchar)TEL_NOP:
-					    g_message("\tNOP");
 					    telnet->tel_state = TEL_STATE_TEXT;
 					    break;
 
                     case (guchar)TEL_GA:
-                        g_message("\tGA");
                         telnet->tel_state = TEL_STATE_TEXT;
                         break;
                         
                     case (guchar)TEL_EOR_BYTE:
-                        g_message("\tEOR");
                         telnet->tel_state = TEL_STATE_TEXT;
                         break;
 
 					case (guchar)TEL_WONT:
-					    g_message("\tWONT");
 						telnet->tel_state = TEL_STATE_WONT;
 						break;
 
 					case (guchar)TEL_SB:
-						g_message("Receiving subrequest");
 						telnet->tel_state = TEL_STATE_SB;
 						telnet->subreq_pos = 0;
 						break;
@@ -345,41 +344,33 @@
 				break;
 
 			case TEL_STATE_DO:
-			    g_message("STATE_DO");
 				mud_telnet_handle_positive_nego(telnet, buf[i], 
 				    (guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
 				telnet->tel_state = TEL_STATE_TEXT;
 
 			case TEL_STATE_WILL:
-			    g_message("STATE_WILL");
 				mud_telnet_handle_positive_nego(telnet, buf[i], 
 				    (guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
 				telnet->tel_state = TEL_STATE_TEXT;
 				break;
 
 			case TEL_STATE_DONT:
-			    g_message("STATE_DONT");
 				mud_telnet_handle_negative_nego(telnet, 
 				    buf[i], (guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
 				telnet->tel_state = TEL_STATE_TEXT;
 				break;
 
 			case TEL_STATE_WONT:
-			    g_message("STATE_WONT: Won't do telopt: %d", buf[i]);
 				mud_telnet_handle_negative_nego(telnet, 
 				    buf[i], (guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
 				telnet->tel_state = TEL_STATE_TEXT;
 				break;
 
 			case TEL_STATE_SB:
-			    g_message("STATE_SB");
 				if (buf[i] == (guchar)TEL_IAC)
 					telnet->tel_state = TEL_STATE_SB_IAC;
 				else
 				{
-					if (telnet->subreq_pos == 0)
-						g_message("Subrequest for option %d", buf[i]);
-
 					// FIXME: Handle overflow
 					if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
 					{
@@ -393,7 +384,6 @@
 				break;
 
 			case TEL_STATE_SB_IAC:
-			    g_message("STATE_SB_IAC");
 				if (buf[i] == (guchar)TEL_IAC)
 				{
 					if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
@@ -409,12 +399,7 @@
 				}
 				else if (buf[i] == (guchar)TEL_SE)
 				{
-				    g_message("STATE_TEL_SE");
-				    telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
-				    
-					g_message("Subrequest for option %d succesfully received with length %d %s", 
-					    telnet->subreq_buffer[0], telnet->subreq_pos-1, (telnet->subreq_buffer[telnet->subreq_pos-1] == (guchar)TEL_SE) ? "SE" : "");
-					    
+				    telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];	    
 					mud_telnet_on_handle_subnego(telnet);
 					telnet->tel_state = TEL_STATE_TEXT;
 				} else {
@@ -506,6 +491,9 @@
     guchar byte;
 	guint32 i;
 
+	if(!encoding)
+		return;
+		
     /* Writes IAC SB CHARSET ACCEPTED <charset> IAC SE to server */
 	byte = (guchar)TEL_IAC;
 	
@@ -693,7 +681,6 @@
 				mud_telnet_on_enable_opt(telnet, opt_no, him);
 				return TRUE;
 			} else {
-				//printf("Server, you DONT do %d\n", opt_no);
 				mud_telnet_send_iac(telnet, negative, opt_no);
 				return FALSE;
 			}

Modified: trunk/src/mud-telnet.h
==============================================================================
--- trunk/src/mud-telnet.h	(original)
+++ trunk/src/mud-telnet.h	Thu Jun 26 10:34:16 2008
@@ -111,7 +111,8 @@
     HANDLER_NAWS,
     HANDLER_ECHO,
     HANDLER_EOR,
-    HANDLER_CHARSET
+    HANDLER_CHARSET,
+    HANDLER_ZMP
 };
 
 struct _MudTelnetClass
@@ -141,6 +142,7 @@
 
 #include <gnet.h>
 #include <mud-connection-view.h>
+#include <mud-telnet-zmp.h>
 struct _MudTelnet
 {
 	GObject parent_instance;
@@ -159,6 +161,9 @@
 	MudConnectionView *parent;
 
 	MudTelnetHandler handlers[TEL_HANDLERS_SIZE];
+	
+	GHashTable *zmp_commands;
+	MudZMPCommand commands[2048];
 };
 
 GType mud_telnet_get_type (void) G_GNUC_CONST;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]