Bläddra i källkod

Working with files and directories now seems OK.

Beoran 9 år sedan
förälder
incheckning
5941d0ae38

+ 1 - 0
Tupfile

@@ -19,6 +19,7 @@ SRC_FILES  += src/every.c
 SRC_FILES  += src/dynar.c
 SRC_FILES  += src/monolog.c
 SRC_FILES  += src/server.c
+SRC_FILES  += src/tr_file.c
 SRC_FILES  += src/rh.c
 SRC_FILES  += src/toruby.c
 

+ 59 - 3
data/script/main.rb

@@ -5,6 +5,7 @@ log "Main mruby script loaded OK."
 p Signal.constants
 
 script "client.rb"
+script "timer.rb"
 
 # Return an array of symbols of constants of klass that match value
 def const_syms(klass, value)
@@ -21,6 +22,24 @@ def signal_syms(value)
   return const_syms(Signal, value) 
 end
 
+def woe_on_healing_tick
+  # p "healing"
+end
+
+def woe_on_motion_tick
+  # p "motion"
+end
+
+def woe_on_battle_tick
+  # p "battle"
+end
+
+def woe_on_weather_tick
+ # p "weather"
+end
+
+
+
 
 def start_timers
   @started_timers ||= false
@@ -28,8 +47,13 @@ def start_timers
     log "Timers already started."
   else
     log "Staring timer(s)..."
-    @timer_id = Woe::Server.new_timer()
-    Woe::Server.set_timer(@timer_id, 1.0, 1.0);
+    Timer.add("healing" , 30.0, 30.0) { woe_on_healing_tick }
+    Timer.add("motion"  ,  5.0,  5.0) { woe_on_motion_tick }
+    Timer.add("battle"  ,  1.0,  1.0) { woe_on_battle_tick }
+    Timer.add("weather" , 90.0, 90.0) { woe_on_weather_tick }
+    
+    #@timer_id = Woe::Server.new_timer()
+    #Woe::Server.set_timer(@timer_id, 1.0, 1.0);
   end
   @started_timers = true
 end
@@ -130,10 +154,42 @@ end
 
 
 def woe_on_timer(timer, value, interval)
-  log "Timer #{timer} #{value} #{interval} passed."
+  # log "Timer #{timer} #{value} #{interval} passed."
+  Timer.on_timer(timer)
 end
 
 
 start_timers
 
 
+f = File.open("/account/B/Beoran/Beoran.account", "r");
+if f
+  while (!f.eof?)
+    lin = f.gets(255)
+    log "Read line #{lin}"
+  end
+  f.close
+end
+
+Dir.mkdir("/account/C")
+Dir.mkdir("/account/C/Celia")
+
+
+
+f = File.open("/account/C/Celia/Celia.account", "w");
+if f
+  f.puts("name=Celia\n")
+  f.puts("algo=plain\n")
+  f.puts("pass=hello1woe\n")
+  f.close
+end
+
+f = File.open("/account/C/Celia/Celia.account", "r");
+if f
+  while (!f.eof?)
+    lin = f.gets(255)
+    log "Read line #{lin}"
+  end
+  f.close
+end
+

+ 59 - 0
data/script/timer.rb

@@ -0,0 +1,59 @@
+
+# Model and handle the clients of the server
+class Timer 
+  
+  
+  attr_reader :id
+  attr_reader :name
+  
+  def initialize(name, &block)
+    @name     = name
+    @id       = nil
+    @block    = block
+  end
+  
+  def set(value = 1.0, interval = 1.0)
+     Woe::Server.set_timer(@id, value, interval);
+  end
+  
+  def start(value = 1.0, interval = 1.0)
+    @id = Woe::Server.new_timer()
+    return @id if (@id < 0)
+    self.set(value, interval);
+    return @id
+  end
+  
+  def self.add(name, value, interval, &block)
+    timer = Timer.new(name, &block)
+    return nil if timer.start(value, interval) < 0 
+    @timers ||= {}
+    @timers[timer.id] = timer
+  end
+  
+  def self.get(id)
+    @timers ||= {}
+    @timers[id]  
+  end
+  
+  def self.get_by_name(name) 
+    @timers ||= {}
+    @timers.select { |t| t.name == name }.first 
+  end
+  
+  def self.remove(id)    
+    @timers[id] = nil
+  end
+  
+  def on_timer()
+    @block.call
+  end
+  
+  def self.on_timer(id) 
+    timer = self.get(id)
+    timer.on_timer if timer
+  end
+  
+end
+
+log "Mruby timer script loaded OK."
+

+ 3 - 0
data/var/account/B/Beoran/Beoran.account

@@ -0,0 +1,3 @@
+name=Beoran
+algo=clear
+pass=memuma,27

+ 3 - 0
data/var/account/C/Celia/Celia.account

@@ -0,0 +1,3 @@
+name=Celia
+algo=plain
+pass=hello1woe

+ 30 - 0
include/tr_file.h

@@ -0,0 +1,30 @@
+#ifndef FILE_H_INCLUDED
+#define FILE_H_INCLUDED
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "config.h"
+
+struct woe_file;
+typedef struct woe_file woe_file;
+
+woe_file * woe_file_open(struct woe_config * cfg, char * filename, char * mode);
+void woe_file_close(woe_file * file);
+
+size_t woe_file_write(woe_file * file, void * buf, size_t size);
+size_t woe_file_read(woe_file * file, void * buf, size_t size);
+
+int woe_file_puts(woe_file * file, char * buf);
+int woe_file_gets(woe_file * file, char * buf, int size);
+
+int woe_file_putc(woe_file * file, char c);
+int woe_file_getc(woe_file * file, char c);
+
+int woe_mkdir(struct woe_config * cfg, char * filename);
+
+int woe_file_eof(woe_file * file);
+
+int tr_init_file(mrb_state * mrb);
+
+#endif

+ 3 - 0
src/toruby.c

@@ -11,6 +11,7 @@
 #include "state.h"
 #include "server.h"
 #include "libtelnet.h"
+#include "tr_file.h"
 
 #include <signal.h>
 #include <mruby/hash.h>
@@ -327,7 +328,9 @@ int tr_init(mrb_state * mrb) {
   struct RClass *krn;
   struct RClass *tel;
   struct RClass *sig;
+  struct RClass *fil;
   
+  tr_init_file(mrb);
  
   woe = mrb_define_module(mrb, "Woe");
   srv = mrb_define_module_under(mrb, woe, "Server"); 

+ 330 - 0
src/tr_file.c

@@ -0,0 +1,330 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+
+#include "esh.h"
+#include "toruby.h"
+#include "tr_macro.h"
+#include "monolog.h"
+#include "rh.h"
+#include "state.h"
+#include "server.h"
+#include "tr_file.h"
+
+
+struct tr_file {
+  FILE              * file;
+  struct woe_config * cfg;
+};
+
+typedef struct tr_file tr_file;
+
+static void file_close(tr_file * file) {
+  if (!file) return;
+  if (!file->file) return;
+  fclose(file->file);
+  file->file = NULL;
+}
+
+static void tr_file_free(mrb_state *mrb, void *ptr) {
+  struct tr_file * file = ptr;
+  file_close(file);
+  mrb_free(mrb, file);
+}
+
+static tr_file * file_open(mrb_state * mrb, char * filename, char * mode) 
+{
+  struct woe_config * cfg;
+  struct woesb buf = { 0 };
+  tr_file * me = NULL;
+  if (!mrb) return NULL;
+  cfg = MRB_WOE_CONFIG(mrb);
+  if (!cfg) return NULL;
+  
+  me  = mrb_malloc(mrb, sizeof(struct tr_file));
+  if (!me) return NULL;
+  if (!woesb_new_join(&buf, cfg->data_dir, "/var/", filename, NULL)) {
+    LOG_ERROR("Cannot allocate space for file name.\n");
+    mrb_free(mrb, me);
+    return NULL;
+  }
+  
+  if (strstr(buf.text, "..")) {
+    mrb_free(mrb, me);
+    woesb_free(&buf);
+    LOG_ERROR("Path may not contain '..' \n");
+    return NULL;
+  }
+
+  me->file = fopen(buf.text, mode);
+  if (!me->file) {
+    LOG_ERROR("Cannot open file %s.\n", filename);
+    mrb_free(mrb, me);
+    woesb_free(&buf);
+    return NULL;
+  }
+  me->cfg = cfg; 
+  woesb_free(&buf);
+  return me;
+}
+
+int woe_mkdir(struct woe_config * cfg, char * filename) {
+  int res;
+  DIR * dir;
+  
+  struct woesb buf = { 0 };
+  if (!cfg) return -3;
+ 
+  if (!woesb_new_join(&buf, cfg->data_dir, "/var/", filename, NULL)) {
+    LOG_ERROR("Cannot allocate space for file name.\n");
+    return -1;
+  }
+  
+  if (strstr(buf.text, "..")) {
+    woesb_free(&buf);
+    LOG_ERROR("Path may not contain '..' \n");
+    return -2;
+  }
+  
+  dir = opendir(buf.text);
+  if (dir) {
+    LOG_DEBUG("Dir %s already exists\n");
+    /* Directory already exists */
+    closedir(dir);
+    woesb_free(&buf);
+    return 0; 
+  }
+  
+  errno = 0;
+  res = mkdir(buf.text , 0770);
+
+  if (res < 0) {
+    LOG_ERROR("Cannot make dir %s.\n", filename);
+    woesb_free(&buf);
+    return errno;
+  }
+  
+  woesb_free(&buf);
+  return 0;
+}
+
+int woe_link(struct woe_config * cfg, char * old_filename, char * new_filename) {
+  int res;
+  
+  struct woesb old_buf = { 0 };
+  struct woesb new_buf = { 0 };
+
+  if (!cfg) return -3;
+ 
+  if (!woesb_new_join(&old_buf, cfg->data_dir, "/var/", old_filename, NULL)) {
+    LOG_ERROR("Cannot allocate space for file name.\n");
+    return -1;
+  }
+
+  if (!woesb_new_join(&new_buf, cfg->data_dir, "/var/", new_filename, NULL)) {
+    woesb_free(&old_buf);
+    LOG_ERROR("Cannot allocate space for file name.\n");
+    return -1;
+  }
+
+  
+  if (strstr(old_buf.text, "..") || strstr(new_buf.text, "..")) {
+    woesb_free(&new_buf);
+    woesb_free(&old_buf);    
+    LOG_ERROR("Path may not contain '..' \n");
+    return -2;
+  }
+  
+  errno = 0;
+  res = link(old_buf.text, new_buf.text);
+
+  if (res < 0) {
+    LOG_ERROR("Cannot link %s to %s.\n", old_filename, new_filename);
+    woesb_free(&new_buf);
+    woesb_free(&old_buf);
+    return errno;
+  }
+  
+  woesb_free(&new_buf);
+  woesb_free(&old_buf);
+  return 0;
+}
+
+
+struct mrb_data_type tr_file_type = { "File", tr_file_free };
+
+static mrb_value tr_file_wrap(mrb_state *mrb, struct RClass *tc, tr_file * file) {
+  return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &tr_file_type, file));
+}
+
+tr_file * tr_file_unwrap(mrb_state *mrb, mrb_value val) {
+  return DATA_CHECK_GET_PTR(mrb, val, &tr_file_type, tr_file);
+}
+
+static mrb_value tr_file_open(mrb_state * mrb, mrb_value self) {
+  int res; 
+  char * name, * mode;
+  tr_file * file; 
+  
+  mrb_get_args(mrb, "zz", &name, &mode);
+  file = file_open(mrb, name, mode);
+  
+  if (!file) return mrb_nil_value();
+  
+  return tr_file_wrap(mrb, mrb_class_get(mrb, "File"), file);
+     
+}    
+  
+static mrb_value tr_file_close(mrb_state * mrb, mrb_value self) {
+  file_close(tr_file_unwrap(mrb, self));
+  return mrb_nil_value();
+}
+
+static mrb_value tr_file_write(mrb_state * mrb, mrb_value self) { 
+  mrb_int res, size;
+  tr_file * file; 
+  char * buf;
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "s", &buf, &size);
+  res = fwrite(buf, size, 1, file->file);
+  return mrb_fixnum_value(res);
+}
+
+static mrb_value tr_file_read(mrb_state * mrb, mrb_value self) {
+  mrb_int res, size;
+  tr_file * file; 
+  mrb_value buf;
+  
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "i", &size);
+  buf = mrb_str_buf_new(mrb, size);
+ 
+  res = fread(RSTRING(buf), size, 1, file->file);
+  if (res > 0) {
+    mrb_str_resize(mrb, buf, res); 
+    return buf;
+  } 
+  
+  if (res == 0) {
+    return mrb_nil_value();
+  }
+  
+  // if (res < 0)
+  LOG_ERROR("Failed to read from file.\n");
+  return mrb_nil_value();
+}   
+ 
+
+static mrb_value tr_file_puts(mrb_state * mrb, mrb_value self) { 
+  mrb_int res, size;
+  tr_file * file; 
+  char * buf;
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "z", &buf);
+  res = fputs(buf, file->file);
+  return mrb_fixnum_value(res);
+}
+
+
+static mrb_value tr_file_gets(mrb_state * mrb, mrb_value self) {
+  mrb_int size;
+  tr_file * file; 
+  char * buf;
+  char * check;
+  mrb_value res;
+  
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "i", &size);
+  buf = calloc(size, 1);
+  if (!buf) {
+    return mrb_nil_value();
+  }
+  
+  check = fgets(buf, size, file->file);
+  if (check) {
+    res = mrb_str_new_cstr(mrb, buf);
+    free(buf); 
+    return res;
+  } 
+  
+  free(buf);
+  return mrb_nil_value();
+}
+
+
+static mrb_value tr_file_putc(mrb_state * mrb, mrb_value self) { 
+  mrb_int res, chara = 0;
+  tr_file * file; 
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "i", &chara);
+  res = fputc(chara, file->file);
+  return mrb_fixnum_value(res);
+}
+
+
+static mrb_value tr_file_getc(mrb_state * mrb, mrb_value self) {
+  mrb_int res;
+  tr_file * file; 
+  file = tr_file_unwrap(mrb, self);
+  res = fgetc(file->file);
+  return mrb_fixnum_value(res);
+} 
+ 
+static mrb_value tr_file_eof(mrb_state * mrb, mrb_value self) {
+  tr_file * file; 
+  file = tr_file_unwrap(mrb, self);  
+  return rh_bool_value(feof(file->file));
+}
+
+static mrb_value tr_dir_mkdir(mrb_state * mrb, mrb_value self) {
+  tr_file * file; 
+  char * name;
+  struct woe_config * cfg;
+  cfg = MRB_WOE_CONFIG(mrb);
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "z", &name);
+  return mrb_fixnum_value(woe_mkdir(cfg, name));
+}
+
+static mrb_value tr_file_link(mrb_state * mrb, mrb_value self) {
+  tr_file * file; 
+  char * old_name, * new_name;
+  struct woe_config * cfg;
+  cfg = MRB_WOE_CONFIG(mrb);
+  file = tr_file_unwrap(mrb, self);
+  mrb_get_args(mrb, "zz", &old_name, &new_name);
+  return mrb_fixnum_value(woe_link(cfg, old_name, new_name));
+}
+
+
+int tr_init_file(mrb_state * mrb) {
+  struct RClass *krn;
+  struct RClass *dir;
+  struct RClass *fil;
+  
+  fil = mrb_define_class(mrb, "File"    , mrb_class_get(mrb, "Object"));
+  dir = mrb_define_class(mrb, "Dir"     , mrb_class_get(mrb, "Object"));
+
+  TR_CLASS_METHOD_ARGC(mrb, fil, "open" , tr_file_open, 2);
+  TR_CLASS_METHOD_ARGC(mrb, fil, "link" , tr_file_link, 2);
+  TR_CLASS_METHOD_ARGC(mrb, dir, "mkdir", tr_dir_mkdir, 1);
+
+
+  TR_METHOD_NOARG(mrb, fil, "close"     , tr_file_close);
+  TR_METHOD_NOARG(mrb, fil, "eof?"       , tr_file_eof);
+  TR_METHOD_ARGC(mrb, fil, "read"       , tr_file_read, 1);
+  TR_METHOD_ARGC(mrb, fil, "write"      , tr_file_read, 2);
+  TR_METHOD_ARGC(mrb, fil, "gets"       , tr_file_gets, 1);
+  TR_METHOD_ARGC(mrb, fil, "puts"       , tr_file_puts, 1);
+  TR_METHOD_ARGC(mrb, fil, "putc"       , tr_file_putc, 1);
+  TR_METHOD_ARGC(mrb, fil, "getc"       , tr_file_getc, 1);
+  
+  return 0;
+}