Browse Source

Telnet callbacks implemented, now work on timers.

Beoran 9 năm trước cách đây
mục cha
commit
21c54b422d
10 tập tin đã thay đổi với 475 bổ sung193 xóa
  1. 1 0
      Tupfile
  2. 0 0
      data/script/action.rb
  3. 74 0
      data/script/client.rb
  4. 12 0
      data/script/log.rb
  5. 81 57
      data/script/main.rb
  6. 39 0
      include/timer.h
  7. 3 91
      include/tr_macro.h
  8. 14 14
      src/client.c
  9. 112 0
      src/timer.c
  10. 139 31
      src/toruby.c

+ 1 - 0
Tupfile

@@ -12,6 +12,7 @@ endif
 SRC_FILES   = src/libtelnet.c
 SRC_FILES  += src/config.c
 SRC_FILES  += src/esh.c
+SRC_FILES  += src/timer.c
 SRC_FILES  += src/client.c
 SRC_FILES  += src/mem.c
 SRC_FILES  += src/every.c

+ 0 - 0
data/script/action.rb


+ 74 - 0
data/script/client.rb

@@ -0,0 +1,74 @@
+
+# Model and handle the clients of the server
+class Client 
+  attr_reader :id
+  attr_reader :buffer
+  attr_reader :in_lines
+  
+  def initialize(id)
+    @id       = id
+    @buffer   = ""
+    @in_lines = []
+  end
+  
+  def self.add(client_id)
+    @clients ||= {}
+    @clients[client_id] = Client.new(client_id)
+  end
+  
+  def self.get(client_id)
+    @clients ||= {}
+    return @clients[client_id]
+  end
+  
+  def self.remove(client_id)    
+    @clients[client_id] = nil
+  end
+  
+  def send(text) 
+    log "Client #{@id}, send #{text}"
+    Woe::Server.send_to_client(@id, text)
+  end
+  
+  def puts(text) 
+    log "Client #{@id}, puts #{text}"
+    Woe::Server.puts(@id, text)
+  end
+  
+  def printf(fmt, *args)
+    text = fmt.format(*args) 
+    puts(text)
+  end
+
+  def raw_puts(text) 
+    log "Client #{@id}, puts #{text}"
+    Woe::Server.raw_puts(@id, text)
+  end
+  
+  def raw_printf(fmt, *args)
+    text = fmt.format(*args) 
+    puts(text)
+  end
+  
+  
+  def on_input(str)
+    @buffer ||= ""
+    @buffer << str
+    if @buffer["\r\n"]
+      command, rest = @buffer.split("\r\n", 1)
+      log "Client #{@id}, command #{command}"
+      if (command.strip == "quit") 
+        self.send("Bye bye!")
+        Woe::Server.disconnect(@id)
+        Client.remove(@id)
+        return nil
+      else 
+        self.send("I don't know how to #{command}")
+      end
+      @buffer = rest
+    end    
+  end  
+end
+
+log "Mruby client script loaded OK."
+

+ 12 - 0
data/script/log.rb

@@ -0,0 +1,12 @@
+
+# log function, with formatting support and auto newline.
+def log(fmt, *args)
+  if fmt && !(args.empty?) 
+    woe_log(fmt.format(*args)) 
+  else
+    woe_log(fmt.to_s) 
+  end
+end
+
+log("log.rb script loaded")
+

+ 81 - 57
data/script/main.rb

@@ -1,60 +1,26 @@
 
-p "Hi from main.rb"
-p global_variables
-# p :$--TEST--
-# p $"--TEST
-log "hello to log"
-
-class Client 
-  attr_reader :id
-  attr_reader :buffer
-  attr_reader :in_lines
-  
-  def initialize(id)
-    @id       = id
-    @buffer   = ""
-    @in_lines = []
-  end
-  
-  def self.add(client_id)
-    @clients2 ||= {}
-    @clients[client_id] = Client.new(client_id)
-  end
-  
-  def self.get(client_id)
-    @clients ||= {}
-    return @clients[client_id]
-  end
-  
-  def self.remove(client_id)    
-    @clients[client_id] = nil
-  end
-  
-  def send(text) 
-  log "Client #{@id}, send #{text}"
-    Woe::Server.send_to_client(@id, text)
+script "log.rb"
+
+log "Main mruby script loaded OK."
+p Signal.constants
+
+script "client.rb"
+
+# Return an array of symbols of constants of klass that match value
+def const_syms(klass, value)
+  res = []
+  klass.constants.each do |c|
+     cv = klass.const_get(c)
+     res << c if cv == value
   end
-  
-  def on_input(str)
-    @buffer ||= ""
-    @buffer << str
-    if @buffer["\r\n"]
-      command, rest = @buffer.split("\r\n", 1)
-      log "Client #{@id}, command #{command}"
-      if (command.strip == "quit") 
-        self.send("Bye bye!")
-        Woe::Server.disconnect(@id)
-        Client.remove(@id)
-        return nil
-      else 
-        self.send("I don't know how to #{command}")
-      end
-      @buffer = rest
-    end    
-  end  
+  return res
 end
 
 
+def signal_syms(value)
+  return const_syms(Signal, value) 
+end
+
 
 def woe_on_connect(client_id)
   p "Client #{client_id} connected"
@@ -79,17 +45,75 @@ def woe_on_input(client_id, buf)
 end
 
 def woe_on_negotiate(client_id, how, option) 
-  p "Client #{client} #{client.id} negotiating."
+  p "Client #{client_id} negotiating."
 end
 
 def woe_on_subnegotiate(client_id, option, buffer) 
-  p "Client #{client} #{client.id} negotiating."
+  p "Client #{client_id} subnegotiating."
+end
+
+def woe_on_iac(client_id, option, command) 
+  p "Client #{client_id} iac #{command}."
+end
+
+
+def woe_on_ttype(client_id, cmd, name) 
+  p "Client #{client_id} ttype #{cmd} #{name}."
+end
+
+def woe_on_error(client_id, code, message) 
+end
+
+def woe_on_warning(client_id, code, message) 
+end
+
+
+def woe_begin_compress(client_id, state) 
+end
+
+
+def woe_begin_zmp(client_id, size) 
+end
+
+def woe_zmp_arg(client_id, index, value)  
+end
+
+def woe_finish_zmp(client_id, size) 
 end
 
 
+def woe_begin_environ(client_id, size) 
+end
+
+def woe_environ_arg(client_id, index, type, key, value)  
+end
+
+def woe_finish_environ(client_id, size) 
+end
+
+
+def woe_begin_mssp(client_id, size) 
+end
+
+def woe_mssp_arg(client_id, index, type, key, value)  
+end
+
+def woe_finish_mssp(client_id, size) 
+end
+
+
+
 def woe_on_signal(signal)
-  log "Received signal in script #{signal}"
-  if signal !=28 
-    Woe::Server.quit 
+  log "Received signal #{signal} #{signal_syms(signal)} in script"
+  case signal 
+    when 10 # SIGUSR1
+      log "Reloading main script."
+      script "main.rb"
+    when 28 
+      # ignore this signal
+    else
+      Woe::Server.quit 
   end
 end
+
+

+ 39 - 0
include/timer.h

@@ -0,0 +1,39 @@
+#ifndef WOE_TIMER_H
+#define WOE_TIMER_H
+
+#if !defined(_POSIX_C_SOURCE)
+#define _POSIX_C_SOURCE 200801L
+#endif
+
+#if !defined(_POSIX_SOURCE)
+#define _POSIX_SOURCE
+#endif
+#if !defined(_BSD_SOURCE)
+#define _BSD_SOURCE
+#endif
+
+#include <signal.h>
+#include <time.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+
+struct woe_server;
+
+struct woe_timer {  
+  struct woe_server * server;
+  int                 index;
+  timer_t             timer;
+};
+
+
+struct woe_timer * woe_timer_new(struct woe_server * srv,  int index);
+struct woe_timer * woe_timer_free(struct woe_timer * tim);
+
+
+
+#endif

+ 3 - 91
include/tr_macro.h

@@ -29,71 +29,6 @@ mrb_obj_value(Data_Wrap_Struct(RUBY,                        \
   return mrb_float_value(mrb, TOCALL());                                       \
 }
 
-#define SCEGRA_ICALLER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index;                                                                   \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "i", &index);                                              \
-  return mrb_fixnum_value(TOCALL(index));                                      \
-}
-
-#define SCEGRA_BCALLER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index;                                                                   \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "i", &index);                                              \
-  return rh_bool_value(TOCALL(index));                                         \
-}
-
-
-#define SCEGRA_FCALLER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  mrb_int index;                                                               \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "i", &index);                                              \
-  return mrb_float_value(mrb, TOCALL(index));                                  \
-  }
-
-#define SCEGRA_ISETTER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index, value;                                                            \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "ii", &index, &value);                                     \
-  return mrb_fixnum_value(TOCALL(index, value));                               \
-}
-
-#define SCEGRA_BSETTER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index; mrb_value value;                                                  \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "io", &index, &value);                                     \
-  return mrb_fixnum_value(TOCALL(index, rh_tobool(value)));                    \
-}
-  
-#define SCEGRA_PSETTER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index, x, y;                                                             \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "iii", &index, &x, &y);                                    \
-  return mrb_fixnum_value(TOCALL(index, x, y));                                \
-}
-
-#define SCEGRA_CSETTER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index, r, g, b, a;                                                       \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "iiiii", &index, &r, &g, &b, &a);                          \
-  return mrb_fixnum_value(TOCALL(index, r, g, b, a));                          \
-}
-
-#define SCEGRA_FSETTER(NAME, TOCALL)                                           \
-  static mrb_value NAME(mrb_state * mrb, mrb_value self) {                     \
-  int index; mrb_float value;                                                  \
-  (void) self;                                                                 \
-  mrb_get_args(mrb, "if", &index, &value);                                     \
-  return mrb_fixnum_value(TOCALL(index, value));                               \
-}
-
 #define TR_WRAP_NOARG_BOOL(NAME, TOCALL)                                       \
 static mrb_value NAME(mrb_state * mrb, mrb_value self) {                       \
   (void) self; (void) mrb;                                                     \
@@ -176,32 +111,6 @@ static mrb_value NAME(mrb_state * mrb, mrb_value self) {                       \
 }
 
 
-#define TR_SPRITE_GET(SPRITE, STATE, SPRITEID)                                 \
-  SPRITE = state_sprite(STATE, SPRITEID);                                      \
-  if (!SPRITE) {                                                               \
-    return mrb_nil_value();                                                    \
-  }                                                                            
-
-#define TR_SPRITE_FUNC_INIT(SPRITE, STATE, SPRITEID)                           \
-  mrb_int SPRITEID = -1;                                                       \
-  State * STATE    = state_get();                                              \
-  Sprite * sprite  = NULL;                                                     \
-  (void) self;                                                                 
-
-
-#define TR_SPRITE_II_INT(NAME, TOCALL)                                         \
-static mrb_value NAME(mrb_state * mrb, mrb_value self) {                       \
-  TR_SPRITE_FUNC_INIT(sprite, state, index)                                    \
-  mrb_int result;                                                              \
-  mrb_int i1, i2;                                                              \
-  mrb_get_args(mrb, "iii", &index, &i1, &i2);                                  \
-  TR_SPRITE_GET(sprite, state, index);                                         \
-  result = TOCALL(sprite, i1, i2);                                             \
-  return mrb_fixnum_value(result);                                             \
-}
-
-
-
 
 #define TR_METHOD(MRB, CLASS, NAME, IMPL, FLAGS)                               \
         mrb_define_method((MRB), (CLASS), (NAME), (IMPL), (FLAGS))
@@ -235,5 +144,8 @@ mrb_define_class_method((MRB), (CLASS), (NAME), (IMPL), ARGS_REQ(ARGC) | ARGS_OP
 #define TR_CONST_INT_EASY(MRB, CLASS, PREFIX, NAME) \
         TR_CONST_INT(MRB, CLASS, #NAME, PREFIX##NAME)
 
+#define TR_CONST_INT_VALUE(MRB, CLASS, VALUE) \
+        TR_CONST_INT(MRB, CLASS, #VALUE, VALUE)
+
 
 #endif // TR_H_INCLUDED

+ 14 - 14
src/client.c

@@ -113,7 +113,7 @@ int woe_client_send(struct woe_client * client, const char *buffer, unsigned int
 
 int woe_client_input(struct woe_client * cli, const char *buffer, size_t size) {
   mrb_state * mrb;
-  LOG_NOTE("Received input for client %d", cli->index);
+  LOG_NOTE("Received input for client %d\n", cli->index);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_input", "is", cli->index, buffer, size);
@@ -124,7 +124,7 @@ int woe_client_input(struct woe_client * cli, const char *buffer, size_t size) {
 int woe_client_zmp(struct woe_client * cli, int argc, const char *argv[]) {
   unsigned int i;
   mrb_state * mrb;
-  LOG_NOTE("Received ZMP reply for client %d", cli->index);
+  LOG_NOTE("Received ZMP reply for client %d\n", cli->index);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_begin_zmp", "ii", cli->index, argc);
@@ -138,7 +138,7 @@ int woe_client_zmp(struct woe_client * cli, int argc, const char *argv[]) {
 
 int woe_client_iac(struct woe_client * cli, int cmd) {
   mrb_state * mrb;
-  LOG_NOTE("Received iac for client %d %d", cli->index, cmd);
+  LOG_NOTE("Received iac for client %d %d\n", cli->index, cmd);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_iac", "i", cli->index, cmd);
@@ -149,7 +149,7 @@ int woe_client_iac(struct woe_client * cli, int cmd) {
 
 int woe_client_negotiate(struct woe_client * cli, int how, int option) {
   mrb_state * mrb;
-  LOG_NOTE("Received negotiate for client %d %d %d", cli->index, how, option);
+  LOG_NOTE("Received negotiate for client %d %d %d\n", cli->index, how, option);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_negotiate", "iii", cli->index, how, option);
@@ -159,7 +159,7 @@ int woe_client_negotiate(struct woe_client * cli, int how, int option) {
 
 int woe_client_subnegotiate(struct woe_client * cli, const char * buf, int len, int telopt) {
   mrb_state * mrb;
-  LOG_NOTE("Received subnegotiate for client %d", cli->index);
+  LOG_NOTE("Received subnegotiate for client %d\n", cli->index);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_subnegotiate", "iis", cli->index, telopt, buf, len);
@@ -169,7 +169,7 @@ int woe_client_subnegotiate(struct woe_client * cli, const char * buf, int len,
 
 int woe_client_ttype(struct woe_client * cli, int cmd, const char * name) {
   mrb_state * mrb;
-  LOG_NOTE("Received ttype for client %d %d %s", cli->index, cmd, name);
+  LOG_NOTE("Received ttype for client %d %d %s\n", cli->index, cmd, name);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_ttype", "iz", cli->index, cmd, name);
@@ -180,10 +180,10 @@ int woe_client_ttype(struct woe_client * cli, int cmd, const char * name) {
 
 int woe_client_error(struct woe_client * cli, int code, const char * msg) {
   mrb_state * mrb;
-  LOG_NOTE("Received error for client %d %d %s", cli->index, code, msg);
+  LOG_NOTE("Received error for client %d %d %s\n", cli->index, code, msg);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
-    rh_run_toplevel(mrb, "woe_on_error", "iz", cli->index, code, msg);
+    rh_run_toplevel(mrb, "woe_on_error", "iz\n", cli->index, code, msg);
   }
   return 0;
 }
@@ -191,7 +191,7 @@ int woe_client_error(struct woe_client * cli, int code, const char * msg) {
 
 int woe_client_warning(struct woe_client * cli, int code, const char * msg) {
   mrb_state * mrb;
-  LOG_NOTE("Received warning for client %d %d %s", cli->index, code, msg);
+  LOG_NOTE("Received warning for client %d %d %s\n", cli->index, code, msg);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_warning", "iz", cli->index, code, msg);
@@ -202,7 +202,7 @@ int woe_client_warning(struct woe_client * cli, int code, const char * msg) {
 
 int woe_client_compress(struct woe_client * cli, int state) {
   mrb_state * mrb;
-  LOG_NOTE("Received compress for client %d %d", cli->index, state);
+  LOG_NOTE("Received compress for client %d %d\n", cli->index, state);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_on_compress", "ii", cli->index, state);
@@ -213,14 +213,14 @@ int woe_client_compress(struct woe_client * cli, int state) {
 int woe_client_environ(struct woe_client * cli, int cmd, const struct telnet_environ_t *values, size_t size) {
   int i;
   mrb_state * mrb;
-  LOG_NOTE("Received environ for client %d %d", cli->index, cmd);
+  LOG_NOTE("Received environ for client %d %d\n", cli->index, cmd);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_begin_environ", "iii", cli->index, cmd, size);
     for (i=0; i < size; i++) {
       rh_run_toplevel(mrb, "woe_environ_arg", "iiizz", cli->index, i, values[i].type, values[i].var, values[i].value);
     }  
-   rh_run_toplevel(mrb, "woe_end_environ", "iii", cli->index, cmd, size);
+   rh_run_toplevel(mrb, "woe_finish_environ", "iii", cli->index, cmd, size);
   }
   return 0;
 }
@@ -228,14 +228,14 @@ int woe_client_environ(struct woe_client * cli, int cmd, const struct telnet_env
 int woe_client_mssp(struct woe_client * cli, const struct telnet_environ_t *values, size_t size) {
   int i;
   mrb_state * mrb;
-  LOG_NOTE("Received mssp for client %d", cli->index);
+  LOG_NOTE("Received mssp for client %d\n", cli->index);
   mrb = woe_server_get_mrb(cli->server);  
   if (mrb) {  
     rh_run_toplevel(mrb, "woe_begin_mssp", "ii", cli->index, size);
     for (i=0; i < size; i++) {
       rh_run_toplevel(mrb, "woe_mssp_arg", "iiizz", cli->index, i, values[i].type, values[i].var, values[i].value);
     }  
-   rh_run_toplevel(mrb, "woe_end_mssp", "iii", cli->index, size);
+   rh_run_toplevel(mrb, "woe_finish_mssp", "iii", cli->index, size);
   }
   return 0;
 }

+ 112 - 0
src/timer.c

@@ -0,0 +1,112 @@
+/**
+ * This file client.c, handles clients of the WOE server.
+ */
+
+#if !defined(_WIN32)
+# if !defined(_POSIX_SOURCE)
+#   define _POSIX_SOURCE
+# endif
+# if !defined(_BSD_SOURCE)
+#   define _BSD_SOURCE
+# endif
+
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# include <poll.h>
+# include <unistd.h>
+#else
+# include <winsock2.h>
+# include <ws2tcpip.h>
+
+# define snprintf _snprintf
+# define poll WSAPoll
+# define close closesocket
+# define strdup _strdup
+# define ECONNRESET WSAECONNRESET
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "libtelnet.h"
+#include "monolog.h"
+#include "rh.h"
+#include "timer.h"
+#include "server.h"
+
+
+
+struct woe_timer * woe_timer_alloc() {
+  return calloc(sizeof(struct woe_timer), 1);
+}
+
+struct woe_client * woe_timer_init(struct woe_timer * me,
+  struct woe_server * server, int index) {
+  sigevent_t sev;
+  if (!me) return NULL;
+  me->server  = server;
+  me->index   = index;
+  sev.sigev_notify= SIGEV_NONE;
+  if (timer_create(CLOCK_MONOTONIC, &sev, &me->timer) < 0) { 
+    LOG_ERROR("Could not create timer %d.", index)
+    return NULL;
+  }
+  LOG_NOTE("Timer %d initialized: %d.\n", client->index, client->timer);
+
+  return me;
+}
+
+struct woe_timer * woe_timer_new(struct woe_server * server, int index) {
+  struct woe_timer * me = woe_timer_alloc();
+  if (!me) return NULL;  
+  if (!woe_timer_init(me, index)) { 
+    free(me);
+    return NULL;
+  }
+  return me;
+}
+
+struct woe_timer * woe_timer_done(struct woe_timer * me) {
+  if (!me) return NULL;
+  if (me->timer > -1)  timer_delete(me->timer);
+  me->timer     = -1;
+  LOG_NOTE("Timer %d destroyed.\n", client->index);
+  me->index     = -1;
+  return me;
+}
+
+struct woe_timer * woe_timer_free(struct woe_timer * me) {
+  woe_client_done(client);
+  free(client);  
+  return NULL;
+}
+
+struct timespec * timespec_init(struct timespec * tv, double sec) {
+  if !tv) return NULL;
+  if (sec <= 0.0) {
+    tv->tv_sec  = 0;
+    tv->tv_nsec = 0;
+  } else {
+    tv->tv_sec  = floor(sec);
+    tv->tv_nsec = (sec - floor(sec)) * 1000000000;
+  }
+  return tv;
+} 
+
+int woe_timer_set(struct woe_timer * me, double value, double interval) {
+  if (!me) return -1;
+  itimerspec nv, ov;
+  timespec_init(&nv.it_value, value);
+  timespec_init(&nv.it_interval, interval);
+  return timer_settime(me->timer, 0, &nv, &ov);
+}
+
+
+
+

+ 139 - 31
src/toruby.c

@@ -10,7 +10,9 @@
 #include "rh.h"
 #include "state.h"
 #include "server.h"
+#include "libtelnet.h"
 
+#include <signal.h>
 #include <mruby/hash.h>
 #include <mruby/class.h>
 #include <mruby/data.h>
@@ -285,39 +287,23 @@ int tr_init(mrb_state * mrb) {
   struct RClass *woe;
   struct RClass *srv;
   struct RClass *krn;
+  struct RClass *tel;
+  struct RClass *sig;
+  
  
   woe = mrb_define_module(mrb, "Woe");
   srv = mrb_define_module_under(mrb, woe, "Server"); 
+  tel = mrb_define_module(mrb, "Telnet");
+  sig = mrb_define_module(mrb, "Signal");
+  krn = mrb_module_get(mrb, "Kernel");
+  if(!krn) return -1;
+  
   TR_CLASS_METHOD_NOARG(mrb, woe, "quit"  , tr_server_done);
   TR_CLASS_METHOD_NOARG(mrb, srv, "quit"  , tr_server_done);
   TR_CLASS_METHOD_ARGC(mrb, srv, "send_to_client"  , tr_send_to_client, 2);
   TR_CLASS_METHOD_NOARG(mrb, srv, "disconnect"  , tr_disconnect_client);
-
-int woe_server_iac(struct woe_server * srv, int client, int command);
-int woe_server_negotiate(struct woe_server * srv, int client, int how, int option);
-int woe_server_begin_sb(struct woe_server * srv, int client, int telopt);
-int woe_server_finish_sb(struct woe_server * srv, int client);
-int woe_server_subnegotiation(struct woe_server * srv, int client, int telopt, char * buffer, int size);
-int woe_server_begin_compress2(struct woe_server * srv, int client);
-int woe_server_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va);
-int woe_server_printf(struct woe_server * srv, int client, const char *fmt, ...);
-int woe_server_raw_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va);
-int woe_server_raw_printf(struct woe_server * srv, int client, const char *fmt, ...);
-int woe_server_begin_newenviron(struct woe_server * srv, int client, int type);
-int woe_server_newenviron_value(struct woe_server * srv, int client, int type, char * value);
-int woe_server_finish_newenviron(struct woe_server * srv, int client);
-int woe_server_ttype_send(struct woe_server * srv, int client);
-int woe_server_ttype_is(struct woe_server * srv, int client, char * ttype);
-int woe_server_send_zmp(struct woe_server * srv, int client, int argc, const char ** argv);
-int woe_server_send_vzmpv(struct woe_server * srv, int client, va_list va);
-int woe_server_send_zmpv(struct woe_server * srv, int client, ...);
-int woe_server_begin_zmp(struct woe_server * srv, int client, const char * cmd);
-int woe_server_zmp_arg(struct woe_server * srv, int client, const char * arg);
-int woe_server_finish_zmp(struct woe_server * srv, int client, const char * cmd);
-
-
+  
   TR_CLASS_METHOD_ARGC(mrb, srv, "iac"  , tr_server_iac, 2);
-
   TR_CLASS_METHOD_ARGC(mrb, srv, "negotiate"      , tr_server_negotiate     , 3);
   TR_CLASS_METHOD_ARGC(mrb, srv, "begin_sb"       , tr_server_begin_sb      , 2);
   TR_CLASS_METHOD_ARGC(mrb, srv, "finish_sb"      , tr_server_finish_sb     , 1);
@@ -334,14 +320,136 @@ int woe_server_finish_zmp(struct woe_server * srv, int client, const char * cmd)
   TR_CLASS_METHOD_ARGC(mrb, srv, "zmp_arg"  , tr_server_finish_zmp, 2);
   TR_CLASS_METHOD_ARGC(mrb, srv, "finish_zmp"  , tr_server_finish_zmp, 2);
 
+  /* Telnet constants, commands, etc. */
+  
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_IAC);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_DONT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_DO);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_WILL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_WONT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_SB);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_GA);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EC);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_AYT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_AO);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_IP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_BREAK);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_DM);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_NOP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_SE);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EOR);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ABORT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_SUSP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EOF);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_BINARY);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_ECHO);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_RCP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_SGA);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAMS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_STATUS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_TM);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_RCTE);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOCRD);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOHTS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOHTD);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOFFD);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOVTS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOVTD);
+  
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAOLFD);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_XASCII);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_LOGOUT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_BM);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_DET);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_SUPDUP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_SUPDUPOUTPUT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_SNDLOC);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_TTYPE);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_EOR);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_3270REGIME);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_X3PAD);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NAWS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_TSPEED);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_LFLOW);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_LINEMODE);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_XDISPLOC);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_ENVIRON);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_AUTHENTICATION);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_ENCRYPT);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_NEW_ENVIRON);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_MSSP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_COMPRESS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_COMPRESS2);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_ZMP);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_EXOPL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TELOPT_MCCP2);
+
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TTYPE_IS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_TTYPE_SEND);
+
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_IS);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_SEND);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_INFO);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_VAR);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_VALUE);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_ESC);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENVIRON_USERVAR);
+
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_MSSP_VAL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_MSSP_VAR);
+
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EOK);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EBADVAL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ENOMEM);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EOVERFLOW);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_EPROTOCOL);
+  TR_CONST_INT_VALUE(mrb, tel, TELNET_ECOMPRESS);
+
+  TR_CONST_INT_VALUE(mrb, sig, SIGHUP);
+  TR_CONST_INT_VALUE(mrb, sig, SIGINT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGQUIT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGILL);
+  TR_CONST_INT_VALUE(mrb, sig, SIGABRT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGFPE);
+  TR_CONST_INT_VALUE(mrb, sig, SIGKILL);
+  TR_CONST_INT_VALUE(mrb, sig, SIGSEGV);
+  TR_CONST_INT_VALUE(mrb, sig, SIGPIPE);
+  TR_CONST_INT_VALUE(mrb, sig, SIGALRM);
+  TR_CONST_INT_VALUE(mrb, sig, SIGTERM);
+  TR_CONST_INT_VALUE(mrb, sig, SIGUSR1);
+  TR_CONST_INT_VALUE(mrb, sig, SIGUSR2);
+  TR_CONST_INT_VALUE(mrb, sig, SIGCHLD);
+  TR_CONST_INT_VALUE(mrb, sig, SIGCONT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGSTOP);
+  TR_CONST_INT_VALUE(mrb, sig, SIGTSTP);
+  TR_CONST_INT_VALUE(mrb, sig, SIGTTIN);
+  TR_CONST_INT_VALUE(mrb, sig, SIGTTOU);
+  TR_CONST_INT_VALUE(mrb, sig, SIGBUS);
+  TR_CONST_INT_VALUE(mrb, sig, SIGPOLL);
+  TR_CONST_INT_VALUE(mrb, sig, SIGPROF);
+  TR_CONST_INT_VALUE(mrb, sig, SIGSYS);
+  TR_CONST_INT_VALUE(mrb, sig, SIGTRAP);
+  TR_CONST_INT_VALUE(mrb, sig, SIGURG);
+  TR_CONST_INT_VALUE(mrb, sig, SIGVTALRM);
+  TR_CONST_INT_VALUE(mrb, sig, SIGXCPU);  
+  TR_CONST_INT_VALUE(mrb, sig, SIGXFSZ);
+  TR_CONST_INT_VALUE(mrb, sig, SIGIOT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGSTKFLT);
+  TR_CONST_INT_VALUE(mrb, sig, SIGIO);
+  TR_CONST_INT_VALUE(mrb, sig, SIGCLD);
+  TR_CONST_INT_VALUE(mrb, sig, SIGPWR);
+  TR_CONST_INT_VALUE(mrb, sig, SIGWINCH);
+  TR_CONST_INT_VALUE(mrb, sig, SIGUNUSED);
+
   
-  krn = mrb_module_get(mrb, "Kernel");
-  if(!krn) return -1;
   
-  TR_METHOD_ARGC(mrb, krn, "warn"         , tr_warn   , 1);
-  TR_METHOD_ARGC(mrb, krn, "warning"      , tr_warn   , 1);
-  TR_METHOD_ARGC(mrb, krn, "log"          , tr_log    , 1);
-  TR_METHOD_ARGC(mrb, krn, "log_to"       , tr_log_to , 2);
+  TR_METHOD_ARGC(mrb, krn, "woe_warn"     , tr_warn   , 1);
+  TR_METHOD_ARGC(mrb, krn, "woe_warning"  , tr_warn   , 1);
+  TR_METHOD_ARGC(mrb, krn, "woe_log"      , tr_log    , 1);
+  TR_METHOD_ARGC(mrb, krn, "woe_log_to"   , tr_log_to , 2);
   TR_METHOD_ARGC(mrb, krn, "log_enable"   , tr_log_disable , 1);
   TR_METHOD_ARGC(mrb, krn, "log_disable"  , tr_log_enable  , 1);
   TR_METHOD_ARGC(mrb, krn, "script"       , tr_script , 1);