gnome-mud r668 - in trunk: . src
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r668 - in trunk: . src
- Date: Sun, 22 Jun 2008 05:23:14 +0000 (UTC)
Author: lharris
Date: Sun Jun 22 05:23:14 2008
New Revision: 668
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=668&view=rev
Log:
Removed gnomevfs, added mud-telnet.[ch].
Added:
trunk/src/mud-telnet.c
trunk/src/mud-telnet.h
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/src/Makefile.am
trunk/src/utils.c
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Sun Jun 22 05:23:14 2008
@@ -53,14 +53,12 @@
GMODULE_REQUIRED=2.0.0
GTK_REQUIRED=2.10.0
LIBGLADE_REQUIRED=2.0.1
-dnl LIBGNETWORK_REQUIRED=0.0.6
LIBGNET_REQUIRED=0.22
VTE_REQUIRED=0.11.00
PCRE_REQUIRED=6.0.0
GCONF_REQUIRED=0.20
-GNOMEVFS_REQUIRED=0.16
-PKG_CHECK_MODULES(GMUD, gtk+-2.0 >= $GTK_REQUIRED vte >= $VTE_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED libpcre >= $PCRE_REQUIRED gmodule-2.0 >= $GMODULE_REQUIRED gnet-2.0 >= $LIBGNET_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gnome-vfs-2.0 >= $GNOMEVFS_REQUIRED)
+PKG_CHECK_MODULES(GMUD, gtk+-2.0 >= $GTK_REQUIRED vte >= $VTE_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED libpcre >= $PCRE_REQUIRED gmodule-2.0 >= $GMODULE_REQUIRED gnet-2.0 >= $LIBGNET_REQUIRED gconf-2.0 >= $GCONF_REQUIRED)
AC_SUBST(GMUD_CFLAGS)
AC_SUBST(GMUD_LIBS)
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Sun Jun 22 05:23:14 2008
@@ -45,8 +45,8 @@
mud-profile.h \
mud-regex.c \
mud-regex.h \
- mud-telnet.c \
- mud-telnet.h \
+ mud-telnet.c \
+ mud-telnet.h \
mud-tray.c \
mud-tray.h \
mud-window.c \
Added: trunk/src/mud-telnet.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet.c Sun Jun 22 05:23:14 2008
@@ -0,0 +1,638 @@
+/* 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 <stdarg.h>
+#include <string.h> // memset
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+
+#define TELNET_TRACE_MASK _("telnet")
+
+struct _MudTelnetPrivate
+{
+
+};
+
+GType mud_telnet_get_type (void);
+static void mud_telnet_init (MudTelnet *pt);
+static void mud_telnet_class_init (MudTelnetClass *klass);
+static void mud_telnet_finalize (GObject *object);
+
+static void mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2);
+static void mud_telnet_on_handle_subnego(MudTelnet *telnet);
+static void mud_telnet_on_enable_opt(MudTelnet *telnet,
+ const guchar opt_no, gint him);
+static void mud_telnet_on_disable_opt(MudTelnet *telnet,
+ const guchar opt_no, gint him);
+static guchar mud_telnet_get_telopt_state(guchar *storage, const guint bitshift);
+static gint mud_telnet_get_telopt_queue(guchar *storage, const guint bitshift);
+static void mud_telnet_set_telopt_state(guchar *storage,
+ const enum TelnetOptionState state, const guint bitshift);
+static void mud_telnet_set_telopt_queue(guchar *storage,
+ gint bit_on, const guint bitshift);
+static gint mud_telnet_handle_positive_nego(MudTelnet *telnet,
+ const guchar opt_no,
+ const guchar affirmative,
+ const guchar negative,
+ gint him);
+static gint
+mud_telnet_handle_negative_nego(MudTelnet *telnet,
+ const guchar opt_no,
+ const guchar affirmative,
+ const guchar negative,
+ gint him);
+
+// MudTelnet class functions
+GType
+mud_telnet_get_type (void)
+{
+ static GType object_type = 0;
+
+ g_type_init();
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (MudTelnetClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) mud_telnet_class_init,
+ NULL,
+ NULL,
+ sizeof (MudTelnet),
+ 0,
+ (GInstanceInitFunc) mud_telnet_init,
+ };
+
+ object_type = g_type_register_static(G_TYPE_OBJECT, "MudTelnet", &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+mud_telnet_init (MudTelnet *telnet)
+{
+ telnet->priv = g_new0(MudTelnetPrivate, 1);
+
+}
+
+static void
+mud_telnet_class_init (MudTelnetClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->finalize = mud_telnet_finalize;
+}
+
+static void
+mud_telnet_finalize (GObject *object)
+{
+ MudTelnet *telnet;
+ GObjectClass *parent_class;
+
+ telnet = MUD_TELNET(object);
+
+ g_free(telnet->priv);
+
+ parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+ parent_class->finalize(object);
+}
+
+/*** Public Methods ***/
+
+// Instantiate MudTelnet
+MudTelnet*
+mud_telnet_new(MudConnectionView *parent, GConn *connection)
+{
+ MudTelnet *telnet;
+
+ telnet = g_object_new(MUD_TYPE_TELNET, NULL);
+
+ telnet->parent = parent;
+ telnet->conn = connection;
+ // FIXME
+
+ memset(telnet->telopt_states, 0, sizeof(telnet->telopt_states));
+/* memset(m_handlers, 0, sizeof(m_handlers));
+ */
+
+ return telnet;
+}
+
+gint
+mud_telnet_register_handler(MudTelnet *telnet, guint8 option_number, const gchar *classname)
+{
+
+ // FIXME
+ /*
+ TeloptHandlersMap::const_iterator iter = telopt_handler_names.find(option_number);
+ if (iter == telopt_handler_names.end())
+ {
+ // FIXME: Leaks?
+ telopt_handler_names[option_number] = wxString(classname);
+ //wxPrintf(wxT("class '%s' registered as handling option %u\n"), classname, option_number);
+ return TRUE;
+ }
+ else
+ // Already registered.
+ // FIXME: Should we consider re-registering and handling properly the already existing
+ // FIXME: handler instances in m_handlers[option_number]?
+ return FALSE;
+ */
+
+ return FALSE;
+}
+
+gint
+mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him)
+{
+ // FIXME!!
+ /*TeloptHandlersMap::const_iterator iter = telopt_handler_names.find(option_number);
+
+ if (iter != telopt_handler_names.end() && (*iter).second)
+ {
+ if (!m_handlers[option_number])
+ m_handlers[option_number] = (TelnetHandler*)wxCreateDynamicObject((*iter).second);
+
+ return m_handlers[option_number]->IsEnabled();
+ }
+ else
+ return FALSE;*/
+
+ return FALSE;
+}
+
+MudTelnetBuffer
+mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count)
+{
+ guchar processed[32768];
+ size_t pos = 0;
+ guint32 i;
+ MudTelnetBuffer ret;
+ g_assert(telnet != NULL);
+
+ for (i = 0;i < count;++i)
+ {
+ switch (telnet->tel_state)
+ {
+ case TEL_STATE_TEXT:
+ g_message("Text state\n");
+ if (buf[i] == (guchar)TEL_IAC)
+ telnet->tel_state = TEL_STATE_IAC;
+ else
+ processed[pos++] = buf[i];
+ break;
+
+ case TEL_STATE_IAC:
+ g_message("IAC\n");
+ switch (buf[i])
+ {
+ case (guchar)TEL_IAC:
+ g_message("\tIAC\n");
+ processed[pos++] = buf[i];
+ telnet->tel_state = TEL_STATE_TEXT;
+ break;
+
+ case (guchar)TEL_DO:
+ g_message("\tDO\n");
+ telnet->tel_state = TEL_STATE_DO;
+ break;
+
+ case (guchar)TEL_DONT:
+ g_message("\tDONT\n");
+ telnet->tel_state = TEL_STATE_DONT;
+ break;
+
+ case (guchar)TEL_WILL:
+ g_message("\tWILL\n");
+ telnet->tel_state = TEL_STATE_WILL;
+ break;
+
+ case (guchar)TEL_WONT:
+ g_message("\tWONT\n");
+ telnet->tel_state = TEL_STATE_WONT;
+ break;
+
+ case (guchar)TEL_SB:
+ g_message("Receiving subrequest\n");
+ telnet->tel_state = TEL_STATE_SB;
+ telnet->subreq_pos = 0;
+ break;
+
+ default:
+ g_warning("Illegal IAC command %d received\n", buf[i]);
+ telnet->tel_state = TEL_STATE_TEXT;
+ break;
+ }
+ break;
+
+ case TEL_STATE_DO:
+ g_message("STATE_DO\n");
+ 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\n");
+ 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\n");
+ 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\n");
+ 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\n");
+ 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\n", buf[i]);
+
+ // FIXME: Handle overflow
+ if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
+ {
+ g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.\n");
+ telnet->subreq_pos = 0;
+ telnet->tel_state = TEL_STATE_TEXT;
+ }
+ else
+ telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
+ }
+ break;
+
+ case TEL_STATE_SB_IAC:
+ g_message("STATE_SB_IAC\n");
+ if (buf[i] == (guchar)TEL_IAC)
+ {
+ if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
+ {
+ g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.\n");
+ telnet->subreq_pos = 0;
+ telnet->tel_state = TEL_STATE_TEXT;
+ }
+ else
+ telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
+
+ telnet->tel_state = TEL_STATE_SB;
+ }
+ else if (buf[i] == (guchar)TEL_SE)
+ {
+ g_message("STATE_TEL_SE\n");
+ g_message("Subrequest for option %d succesfully received with length %d\n",
+ telnet->subreq_buffer[0], telnet->subreq_pos-1);
+ g_message("Subreq buffer content: %d %d %d %d\n",
+ telnet->subreq_buffer[0], telnet->subreq_buffer[1],
+ telnet->subreq_buffer[2], telnet->subreq_buffer[3]);
+
+ mud_telnet_on_handle_subnego(telnet);
+ telnet->tel_state = TEL_STATE_TEXT;
+ } else {
+ g_warning("Erronous byte %d after an IAC inside a subrequest\n", buf[i]);
+ telnet->subreq_pos = 0;
+ telnet->tel_state = TEL_STATE_TEXT;
+ }
+ break;
+ }
+ }
+
+ ret.buffer = processed;
+ ret.len = pos;
+
+ return ret;
+}
+
+gchar*
+mud_telnet_get_telnet_string(guchar ch)
+{
+ GString *string = g_string_new(NULL);
+ gchar *ret = string->str;
+
+ switch (ch)
+ {
+ case TEL_WILL:
+ g_string_append(string, "WILL");
+ case TEL_WONT:
+ g_string_append(string, "WONT");
+ case TEL_DO:
+ g_string_append(string, "DO");
+ case TEL_DONT:
+ g_string_append(string, "DONT");
+ case TEL_IAC:
+ g_string_append(string, "IAC");
+ default:
+ g_string_append_c(string,ch);
+ }
+
+ g_string_free(string, FALSE);
+
+ return ret;
+}
+
+gchar*
+mud_telnet_get_telopt_string(guchar ch)
+{
+ GString *string = g_string_new(NULL);
+ gchar *ret = string->str;
+
+ switch (ch)
+ {
+ case TELOPT_ECHO:
+ g_string_append(string, "ECHO");
+ case TELOPT_TTYPE:
+ g_string_append(string, "TTYPE");
+ case TELOPT_EOR:
+ g_string_append(string, "END-OF-RECORD");
+ case TELOPT_NAWS:
+ g_string_append(string, "NAWS");
+ case TELOPT_CHARSET:
+ g_string_append(string, "CHARSET");
+ case TELOPT_MCCP:
+ g_string_append(string, "MCCP");
+ case TELOPT_MCCP2:
+ g_string_append(string, "MCCPv2");
+ case TELOPT_CLIENT:
+ g_string_append(string, "CLIENT");
+ case TELOPT_CLIENTVER:
+ g_string_append(string, "CLIENTVER");
+ case TELOPT_MSP:
+ g_string_append(string, "MSP");
+ case TELOPT_MXP:
+ g_string_append(string, "MXP");
+ case TELOPT_ZMP:
+ g_string_append(string, "ZMP");
+ default:
+ g_string_append_c(string, ch);
+ }
+
+ g_string_free(string, FALSE);
+
+ return ret;
+}
+
+void
+mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...)
+{
+ guchar byte;
+ guint32 i;
+ va_list va;
+ va_start(va, count);
+
+ byte = (guchar)TEL_IAC;
+
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+ byte = (guchar)TEL_SB;
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+
+ for (i = 0; i < count; ++i)
+ {
+ byte = (guchar)va_arg(va, gint);
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+
+ if (byte == (guchar)TEL_IAC)
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 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);
+}
+
+/*** Private Methods ***/
+static void
+mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2)
+{
+ guchar buf[3];
+ buf[0] = (guchar)TEL_IAC;
+ buf[1] = ch1;
+ buf[2] = ch2;
+
+ // Replace with gnet equivalent
+ gnet_conn_write(telnet->conn, (gchar *)buf, 3);
+}
+
+static void
+mud_telnet_on_handle_subnego(MudTelnet *telnet)
+{
+ if (telnet->subreq_pos < 1)
+ return;
+
+ /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
+ m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
+ */
+}
+
+static void
+mud_telnet_on_enable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
+{
+ if (telnet->subreq_pos < 1)
+ return;
+
+ /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
+ m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
+ */
+}
+
+static void
+mud_telnet_on_disable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
+{
+ if (telnet->subreq_pos < 1)
+ return;
+
+ /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
+ m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
+ */
+}
+
+static guchar
+mud_telnet_get_telopt_state(guint8 *storage, const guint bitshift)
+{
+ return (*storage >> bitshift) & 0x03u;
+}
+
+static gint
+mud_telnet_get_telopt_queue(guchar *storage, const guint bitshift)
+{
+ return !!((*storage >> bitshift) & 0x04u);
+}
+
+static void
+mud_telnet_set_telopt_state(guchar *storage, const enum TelnetOptionState state,
+ const guint bitshift)
+{
+ *storage = (*storage & ~(0x03u << bitshift)) | (state << bitshift);
+}
+
+static void
+mud_telnet_set_telopt_queue(guchar *storage, gint bit_on, const guint bitshift)
+{
+ *storage = bit_on ? (*storage | (0x04u << bitshift)) : (*storage & ~(0x04u << bitshift));
+}
+
+// Otherwise handlers called on state changes could see the wrong options
+// (I think theoretically they should not care at all, but in practice...)
+static gint
+mud_telnet_handle_positive_nego(MudTelnet *telnet,
+ const guchar opt_no,
+ const guchar affirmative,
+ const guchar negative,
+ gint him)
+{
+ const guint bitshift = him ? 4 : 0;
+ guchar * opt = &(telnet->telopt_states[opt_no]);
+
+ switch (mud_telnet_get_telopt_state(opt, bitshift))
+ {
+ case TELOPT_STATE_NO:
+ // If we agree that server should enable telopt, set
+ // his state to YES and send DO; otherwise send DONT
+ // FIXME-US/HIM
+ // FIXME: What to do in the opposite "him" gint value case?
+ if (mud_telnet_isenabled(telnet, opt_no, him))
+ {
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+ mud_telnet_send_iac(telnet, affirmative, opt_no);
+ 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;
+ }
+
+ case TELOPT_STATE_YES:
+ // Ignore, he already supposedly has it enabled. Includes the case where
+ // DONT was answered by WILL with himq = OPPOSITE to prevent loop.
+ return FALSE;
+
+ case TELOPT_STATE_WANTNO:
+ if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+ {
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+ g_message("TELNET NEGOTIATION: DONT answered by WILL; ill-behaved server. Ignoring IAC WILL %d. him = NO\n", opt_no);
+ return FALSE;
+ } else { // The opposite is queued
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+ mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+ g_message("TELNET NEGOTIATION: DONT answered by WILL; ill-behaved server. Ignoring IAC WILL %d. him = YES, himq = EMPTY\n", opt_no);
+ return FALSE;
+ }
+ break;
+
+ case TELOPT_STATE_WANTYES:
+ if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+ {
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+ mud_telnet_on_enable_opt(telnet, opt_no, him);
+ return TRUE;
+ } else { // The opposite is queued
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTNO, bitshift);
+ mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+ //printf("Server, you should make up your mind. Fine DONT do %d then.\n", opt_no);
+ mud_telnet_send_iac(telnet, negative, opt_no);
+ return FALSE;
+ }
+ default:
+ g_warning("Something went really wrong\n");
+ return FALSE;
+ }
+}
+
+static gint
+mud_telnet_handle_negative_nego(MudTelnet *telnet,
+ const guchar opt_no,
+ const guchar affirmative,
+ const guchar negative,
+ gint him)
+{
+ const guint bitshift = him ? 4 : 0;
+ guchar * opt = &(telnet->telopt_states[opt_no]);
+
+ switch (mud_telnet_get_telopt_state(opt, bitshift))
+ {
+ case TELOPT_STATE_NO:
+ // Ignore, he already supposedly has it disabled
+ return FALSE;
+
+ case TELOPT_STATE_YES:
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+ //printf("Ok, server, I ACK that you DONT do %d\n", opt_no);
+ mud_telnet_send_iac(telnet, negative, opt_no);
+ mud_telnet_on_disable_opt(telnet, opt_no, him);
+ return TRUE;
+
+ case TELOPT_STATE_WANTNO:
+ if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+ {
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+ return FALSE;
+ } else { // but the opposite is queued...
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTYES, bitshift);
+ mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+ //printf("Ok, server, you are making me angry. DO %d", opt_no);
+ mud_telnet_send_iac(telnet, affirmative, opt_no);
+ mud_telnet_on_enable_opt(telnet, opt_no, him); // FIXME: Is this correct?
+ return TRUE;
+ }
+
+ case TELOPT_STATE_WANTYES:
+ if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+ {
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+ return FALSE;
+ } else { // The opposite is queued
+ mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+ mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+ return FALSE;
+ }
+ default:
+ g_warning("TELNET NEGOTIATION: Something went really wrong\n");
+ return FALSE;
+ }
+}
+
Added: trunk/src/mud-telnet.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet.h Sun Jun 22 05:23:14 2008
@@ -0,0 +1,138 @@
+/* GNOME-Mud - A simple Mud CLient
+ * Copyright (C) 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
+ */
+
+#ifndef MUD_TELNET_H
+#define MUD_TELNET_H
+
+G_BEGIN_DECLS
+
+#define MUD_TYPE_TELNET (mud_telnet_get_type ())
+#define MUD_TELNET(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET, MudTelnet))
+#define MUD_TELNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET, MudTelnetClass))
+#define MUD_IS_TELNET(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET))
+#define MUD_IS_TELNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET))
+#define MUD_TELNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET, MudTelnetClass))
+
+#define TEL_SE 240 // End of subnegotiation parameters
+//#define TEL_NOP 241 // No operation - not yet supported
+#define TEL_GA 249 // Go ahead
+#define TEL_SB 250 // Indicates that what follows is subnegotiation of the indicated option
+#define TEL_WILL 251 // I will use option
+#define TEL_WONT 252 // I won't use option
+#define TEL_DO 253 // Please, you use this option
+#define TEL_DONT 254 // You are not to use this option
+#define TEL_IAC 255 // Interpret as command escape sequence - prefix to all telnet commands
+ // Two IAC's in a row means Data Byte 255
+
+#define TELOPT_ECHO 1 // Echo - RFC 857
+#define TELOPT_TTYPE 24 // Terminal type - RFC 1091
+# define TEL_TTYPE_IS 0 // Terminal type IS ...
+# define TEL_TTYPE_SEND 1 // SEND me terminal type
+#define TELOPT_EOR 25 // End of record - RFC 885
+#define TELOPT_NAWS 31 // Window size - RFC 1073
+#define TELOPT_CHARSET 42 // Charset - RFC 2066
+#define TELOPT_MCCP 85 // MCCP
+#define TELOPT_MCCP2 86 // MCCP2
+#define TELOPT_CLIENT 88 // Client name - from Clandestine MUD protocol
+#define TELOPT_CLIENTVER 89 // Client version - from Clandestine MUD protocol
+#define TELOPT_MSP 90 // MSP - http://www.zuggsoft.com/zmud/msp.htm
+#define TELOPT_MXP 91 // MXP - http://www.zuggsoft.com/zmud/mxp.htm
+#define TELOPT_ZMP 93 // ZMP - http://www.awemud.net/zmp/draft.php
+
+// FIXME: What size should we use?
+#define TEL_SUBREQ_BUFFER_SIZE 256
+#define TELOPT_STATE_QUEUE_EMPTY FALSE
+#define TELOPT_STATE_QUEUE_OPPOSITE TRUE
+
+typedef struct _MudTelnet MudTelnet;
+typedef struct _MudTelnetClass MudTelnetClass;
+typedef struct _MudTelnetPrivate MudTelnetPrivate;
+typedef struct _MudTelnetBuffer MudTelnetBuffer;
+
+enum TelnetState
+{
+ TEL_STATE_TEXT,
+ TEL_STATE_IAC,
+ TEL_STATE_WILL,
+ TEL_STATE_WONT,
+ TEL_STATE_DO,
+ TEL_STATE_DONT,
+ TEL_STATE_SB,
+ TEL_STATE_SB_IAC
+};
+
+enum TelnetOptionState
+{
+ TELOPT_STATE_NO = 0, // bits 00
+ TELOPT_STATE_WANTNO = 1, // bits 01
+ TELOPT_STATE_WANTYES = 2, // bits 10
+ TELOPT_STATE_YES = 3, // bits 11
+};
+
+struct _MudTelnetClass
+{
+ GObjectClass parent_class;
+};
+
+struct _MudTelnetBuffer
+{
+ guchar *buffer;
+ size_t len;
+};
+
+#include <gnet.h>
+#include <mud-connection-view.h>
+struct _MudTelnet
+{
+ GObject parent_instance;
+
+ MudTelnetPrivate *priv;
+
+ enum TelnetState tel_state;
+ guchar subreq_buffer[TEL_SUBREQ_BUFFER_SIZE];
+ guint32 subreq_pos;
+
+ guchar telopt_states[256];
+
+ GConn *conn;
+ MudConnectionView *parent;
+
+ /**
+ Pointers to option handler instances. NULL if none is created yet.
+ */
+ //TelnetHandler * m_handlers[256];
+};
+
+GType mud_telnet_get_type (void) G_GNUC_CONST;
+
+MudTelnet *mud_telnet_new(MudConnectionView *parent, GConn *connection);
+
+gint mud_telnet_register_handler(MudTelnet *telnet,
+ guint8 option_number, const gchar *classname);
+gint mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him);
+MudTelnetBuffer mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count);
+void mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_H
Modified: trunk/src/utils.c
==============================================================================
--- trunk/src/utils.c (original)
+++ trunk/src/utils.c Sun Jun 22 05:23:14 2008
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <gtk/gtkaboutdialog.h>
-#include <libgnomevfs/gnome-vfs.h>
gchar *
remove_whitespace(gchar *string)
@@ -74,6 +73,6 @@
void
utils_activate_url(GtkAboutDialog *about, const gchar *url, gpointer data)
{
- gnome_vfs_url_show(url);
+ // use gtk_show_uri when available.
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]