sefuns read_data und write_data erstellt

Diese entsprechen in der Funktion genau den efuns
read_file() und write_file(), stellen aber sicher,
dass das File immer unterhalb von /data/ liegt,
indem der Pfad ggf. angepasst wird.

Change-Id: Ibbe3cadc8d42ca2e83287d7c4893f5c3e3895837
diff --git a/doc/sefun/read_data b/doc/sefun/read_data
new file mode 100644
index 0000000..b0707ac
--- /dev/null
+++ b/doc/sefun/read_data
@@ -0,0 +1,18 @@
+SYNOPSIS
+        string read_data(string file, int start, int anzahl)
+
+BESCHREIBUNG
+        Diese Funktion macht genau das, was read_file() tut (also siehe dort),
+        allerdings stellt sie sicher, dass <file> immer mit einem /data/
+        beginnt (setzt es also notfalls davor).
+        Es wird also immer irgendwo unterhalb von /data/ gelesen.
+
+BEISPIEL
+        # read_data("/d/ebene/zesstra/blupp");
+        -> liest das File /data/d/ebene/zesstra/blupp.
+        # read_data("/data/d/ebene/zesstra/blupp");
+        -> tut dasselbe.
+
+SIEHE AUCH
+        write_data()
+        read_file(E), write_file(E), read_bytes(E), write_file(E)
diff --git a/doc/sefun/write_data b/doc/sefun/write_data
new file mode 100644
index 0000000..5a205d5
--- /dev/null
+++ b/doc/sefun/write_data
@@ -0,0 +1,23 @@
+SYNOPSIS
+        string write_data(string file, int start, int anzahl)
+
+BESCHREIBUNG
+        Diese Funktion macht genau das, was write_file() tut (also siehe dort),
+        allerdings stellt sie sicher, dass <file> immer mit einem /data/
+        beginnt (setzt es also notfalls davor).
+        Es wird also immer irgendwo unterhalb von /data/ geschrieben.
+
+        Die Benutzung dieser sefun wird dringend empfohlen, falls Daten
+        ausserhalb von Spielerobjekten gepeichert werden, damit Daten und
+        Code getrennt abgelegt sind. Dies vereinfacht z.B. die
+        Datensicherung.
+
+BEISPIEL
+        # write_file("/d/ebene/zesstra/blupp", "Testdaten.\n");
+        -> schreibt in das File /data/d/ebene/zesstra/blupp.
+        # write_file("/data/d/ebene/zesstra/blupp", "Testdaten.\n");
+        -> tut dasselbe.
+
+SIEHE AUCH
+        read_data()
+        read_file(E), write_file(E), read_bytes(E), write_file(E)
diff --git a/secure/simul_efun/files.c b/secure/simul_efun/files.c
new file mode 100644
index 0000000..291bef6
--- /dev/null
+++ b/secure/simul_efun/files.c
@@ -0,0 +1,45 @@
+#include "/sys/files.h"
+
+public varargs string read_data(string file, int start, anzahl)
+{
+    if (!stringp(file))
+      raise_error("Bad arg 1 to read_data(): expected 'string'.\n");
+
+    // Wenn Pfad nicht absolut, ist das nen Fehler, daher wird das nicht
+    // korrigiert.
+
+    // wenn kein /data/ vorn steht, wird es vorangestellt.
+    if (strstr(file,"/"LIBDATADIR"/") != 0)
+    {
+      file = "/"LIBDATADIR + file;
+    }
+    // read_file() nicht direkt rufen, sondern vorher als closure ans
+    // aufrufende Objekt binden. Sonst laeuft die Rechtepruefung in
+    // valid_write() im Master unter der Annahme, dass die simul_efun.c mit
+    // ihrer root id was will.
+    return funcall(bind_lambda(#'efun::read_file, previous_object()),
+                   file, start, anzahl);
+}
+
+public varargs int write_data(string file, string str, int flags)
+{
+    if (!stringp(file))
+      raise_error("Bad arg 1 to write_data(): expected 'string'.\n");
+    if (!stringp(str))
+      raise_error("Bad arg 2 to write_data(): expected 'string'.\n");
+
+    // Wenn Pfad nicht absolut, ist das nen Fehler, daher wird das nicht
+    // korrigiert.
+
+    // wenn kein /data/ vorn steht, wird es vorangestellt.
+    if (strstr(file,"/"LIBDATADIR"/") != 0)
+    {
+      file = "/"LIBDATADIR + file;
+    }
+    // write_file() nicht direkt rufen, sondern vorher als closure ans
+    // aufrufende Objekt binden. Sonst laeuft die Rechtepruefung in
+    // valid_write() im Master unter der Annahme, dass die simul_efun.c mit
+    // ihrer root id was will.
+    return funcall(bind_lambda(#'efun::write_file, previous_object()),
+                   file, str, flags);
+}
diff --git a/secure/simul_efun/simul_efun.c b/secure/simul_efun/simul_efun.c
index 2a89fcf..e36d141 100644
--- a/secure/simul_efun/simul_efun.c
+++ b/secure/simul_efun/simul_efun.c
@@ -86,6 +86,7 @@
 #include __DIR__"shadow.c"
 #include __DIR__"livings.c"
 #include __DIR__"comm.c"
+#include __DIR__"files.c"
 
 #define TO        efun::this_object()
 #define TI        efun::this_interactive()