Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/std/util/ex.c b/std/util/ex.c
new file mode 100644
index 0000000..eae9e27
--- /dev/null
+++ b/std/util/ex.c
@@ -0,0 +1,293 @@
+// MorgenGrauen MUDlib
+//
+// util/ex.c -- ex compatible editor
+//
+// $Id: ex.c 9142 2015-02-04 22:17:29Z Zesstra $
+
+#pragma strong_types
+#pragma save_types
+#pragma pedantic
+#pragma range_check
+#pragma no_clone
+
+inherit "/std/util/input";
+
+private nosave mapping ctrl = ([]);
+private nosave mixed buf;
+
+#include <sys_debug.h>
+#undef ARGS
+#include <wizlevels.h>
+#include <player.h>
+
+#define MODE	0
+#  define CMD		0
+#  define INP		1
+#define TEXT	1
+#define LINE	2
+#define FUNC	3
+#define ARGS	4
+#define FLAG	5
+#  define NUM		1
+#define CHG	6
+
+#define YANK	"@YANK"
+
+int evaluate(string in);
+
+varargs int error(string msg, string arg)
+{
+  if(stringp(arg)) write(arg+": "+msg+"\n");
+  else write(msg+"\n");
+}
+
+string substitute(string s, string regex, string n, string extra)
+{
+  mixed del; int i;
+  if((i = sizeof(del = regexplode(s, regex))) < 2) return s;
+  if(member(extra, 'g') == -1) i = 1;
+  else i -= 2;
+  while(i>0) {
+    del[i] = n;
+    i -= 2;
+  }
+  return implode(del, "");
+}
+
+// saveText() -- save edited text
+//
+int saveText()
+{
+  string text;
+  text = implode(ctrl[buf][TEXT][1..], "\n")+"\n";
+  error(sprintf("%O, %d Zeilen, %d Zeichen", 
+	       buf ? buf : "", sizeof(ctrl[buf][TEXT])-1,
+	       sizeof(text)));
+  if(ctrl[buf][FUNC]) apply(ctrl[buf][FUNC], ctrl[buf][ARGS], text);
+  ctrl = m_copy_delete(ctrl, buf);
+  ctrl = m_copy_delete(ctrl, buf+"!");
+  buf = 0;
+  return 1;
+}
+
+// cmdPrompt() -- create command prompt
+//
+string cmdPrompt(int mode, mixed text, int line, int maxl)
+{
+  return ":";
+}
+
+// inputPrompt() -- create input prompt
+//
+string inputPrompt()
+{
+  if(ctrl[buf][FLAG] & NUM) return sprintf("[%02d] ", ctrl[buf][LINE]);
+  return "";
+}
+
+string AddNum(string s)
+{
+  string r;
+  r = inputPrompt()+s;
+  ctrl[buf][LINE]++;
+  return r;
+}
+
+void showLines(int from, int to)
+{
+  write(implode(map(ctrl[buf][TEXT][from..to], #'AddNum), "\n")+"\n");
+  ctrl[buf][LINE] = from;
+}
+
+// commandMode() -- handle commands
+//
+int commandMode(string in)
+{
+  int from, to, swap;
+  string cmd;
+
+  if(!in) return 0;
+  if(in[0..1] == "se") {
+    ctrl[buf][FLAG] ^= NUM;
+    return 0;
+  }
+    
+  if(sscanf(in, "%d,%d%s", from, to, cmd) != 3)
+    if(sscanf(in, "%d%s", from, cmd) != 2)
+      if(!stringp(in)) return error("Kein Editorkommando", in);
+      else { cmd = in; from = to = ctrl[buf][LINE]; }
+    else to = from;
+
+  if(from < 0) from = sizeof(ctrl[buf][TEXT])-1+from;
+  if(to < 1) to = sizeof(ctrl[buf][TEXT])-1+to;
+  if(to && to < from) return error("Erste Adresse groesser als die Zweite");
+  if(from) ctrl[buf][LINE] = from;
+  if(from > sizeof(ctrl[buf][TEXT])-1 ||
+     to > sizeof(ctrl[buf][TEXT])-1) 
+    return error("Nicht so viele Zeilen im Speicher");
+  if(!to) to = from;
+  switch(cmd[0])
+  {
+  case 'h':
+    write("ex: Kommandohilfe\n\n"
+	 "Alle Kommandos funktionieren nach folgendem Prinzip:\n"
+	 "Adresse Kommando Argumente\n"
+	 "Adressen werden gebildet durch: ZeileVon,ZeileBis\n"
+	 "(ZeileBis kann weggelassen werden, samt Komma)\n"
+	 "Kommandos:\n"
+	 "  q,x -- Editor verlassen\n"
+	 "  r   -- Datei einfuegen\n"
+	 "         r<datei>\n"
+	 "  a   -- Text hinter der aktuellen Zeile einfuegen\n"
+	 "  i   -- Text vor der aktuellen Zeile einfuegen\n"
+	 "  d   -- Zeilen loeschen\n"
+	 "  y   -- Zeilen zwischenspeichern\n"
+	 "  pu  -- Zwischengespeicherte Zeilen einfuegen\n"
+	 "  s   -- Substitution von Text in Zeilen\n"
+	 "         s/AlterText/NeuerText/\n"
+          "  p,l -- Zeilen anzeigen\n"
+	 "  z   -- Eine Seite anzeigen\n");
+    break;
+  case 'q':
+    if(ctrl[buf][CHG])
+      if(!(sizeof(cmd) > 1 && cmd[1]=='!'))
+        return error("Datei wurde geaendert! Abbrechen mit q!");
+      else ctrl[buf] = ctrl[buf+"!"];
+  case 'x':
+    if(saveText()) return 1;
+  case 'r':
+    if(!IS_WIZARD(this_player()))
+      return error("Kommando gesperrt", cmd[0..0]);
+    if(file_size(cmd[1..]) < 0) 
+      return error("Datei nicht gefunden", "\""+cmd[1..]+"\"");
+    ctrl[buf][TEXT] = ctrl[buf][TEXT][0..from] 
+		  + explode(read_file(cmd[1..]), "\n")
+	           + ctrl[buf][TEXT][(from == to ? to+1 : to)..];
+    ctrl[buf][CHG] = 1;
+    break;
+  case 'a':
+    ctrl[buf][MODE] = INP;
+    write("Texteingabe: (. beendet zum Kommandomodus, ** beendet ganz)\n");
+    input(#'inputPrompt, 0, #'evaluate); 
+    ctrl[buf][CHG] = 1;
+    return 1;
+  case 'i':
+    ctrl[buf][MODE] = INP;
+    ctrl[buf][LINE]--;
+    write("Texteingabe: (. beendet zum Kommandomodus, ** beendet ganz)\n");
+    input(#'inputPrompt, 0, #'evaluate);
+    ctrl[buf][CHG] = 1;
+    return 1;
+  case 'd':
+    ctrl[buf][TEXT][from..to] = ({});
+    ctrl[buf][CHG] = 1;
+    break;
+  case 'y':
+    ctrl[YANK] = ctrl[buf][TEXT][from..to];
+    if(to - from) error(to-from+1+" Zeilen gespeichert");
+    break;
+  case 's':
+  {
+    mixed reg, new, extra, scmd;
+    if(sizeof(scmd = old_explode(cmd[1..], cmd[1..1])) < 2)
+      return error("Substitution fehlgeschlagen");
+    reg = scmd[0]; new = scmd[1];
+    if(sizeof(scmd) > 2) extra = scmd[2];
+    else extra = "";
+    ctrl[buf][TEXT][from..to] = map(ctrl[buf][TEXT][from..to], 
+				      #'substitute, 
+                                          reg, new, extra);
+    showLines(from, to);
+    ctrl[buf][CHG] = 1;
+    break;
+  }
+  case 'z':
+    showLines(ctrl[buf][LINE], 
+	     ctrl[buf][LINE]+this_player()->QueryProp(P_SCREENSIZE));
+    ctrl[buf][LINE] += this_player()->QueryProp(P_SCREENSIZE);
+    break;
+  case 'p':
+    if(sizeof(cmd) > 1 && cmd[1] == 'u')
+    {
+      if(!pointerp(ctrl[YANK])) return error("Keine Zeilen im Speicher");
+      if(from >= ctrl[buf][LINE]) ctrl[buf][TEXT] += ctrl[YANK];
+      else
+        ctrl[buf][TEXT][0..from] + ctrl[YANK] + ctrl[buf][TEXT][from+1..];
+      ctrl[buf][LINE] += sizeof(ctrl[YANK]);
+      ctrl[YANK] = 0;
+      showLines(ctrl[buf][LINE], ctrl[buf][LINE]);
+      break;
+    }
+  case 'l':
+  default:
+    if(!from) 
+    {
+      error("Kein Editorkommando", sprintf("%c", cmd[0]));
+      return 0;
+    }
+    showLines(from, to);
+  }
+  input(#'cmdPrompt, 0, #'evaluate);
+  return 1;
+}
+
+// inputMode() -- handle input mode commands
+//
+int inputMode(string in)
+{
+  switch(in)
+  {
+  case ".": 
+    ctrl[buf][MODE] = CMD;
+    ctrl[buf][LINE]--;
+    input(#'cmdPrompt, 0, #'evaluate);
+    break;
+  case "**":
+    return saveText();
+  default:
+    if(!in) /* do nothing now */;
+    if(ctrl[buf][LINE] < sizeof(ctrl[buf][TEXT])-1)
+      ctrl[buf][TEXT] = ctrl[buf][TEXT][0..ctrl[buf][LINE]-1] + ({ in }) 
+	        + ctrl[buf][TEXT][ctrl[buf][LINE]..];
+    else ctrl[buf][TEXT] += ({ in });
+    ctrl[buf][LINE]++;
+    input(#'inputPrompt, 0, #'evaluate);
+    break;
+  }
+  return 1;
+}
+
+// evaluate() -- evaluate input (in) in context (ctrl[buf])
+//
+int evaluate(string in)
+{
+  switch(ctrl[buf][MODE])
+  {
+    case INP: return inputMode(in);
+    case CMD: return commandMode(in);
+    default : return 0;
+  }
+}
+
+void StartEX(string in, mixed c)
+{
+  if(!in || in == "j" || in == "J") ctrl[buf] = c;
+  else if(in && (in != "n"  || in != "N"))
+    return 0;
+  ctrl[buf+"!"] = ctrl[buf];
+  input(#'cmdPrompt, 0, #'evaluate);
+}
+
+varargs int ex(mixed text, closure func, mixed fargs, string buffer)
+{
+  int c, l;
+  mixed ct;
+  if(!text) text = "";
+  c = sizeof(text);
+  l = sizeof(text = explode(text, "\n")) - 1;
+  ct = ({ CMD, text, 0, func, fargs, 0, 0});
+  if(!ctrl[buffer]) StartEX(0, ct);
+  else input(sprintf("Es existiert bereits Text! Verwerfen? [j]"),
+	    0, #'StartEX, ct);
+  return 1;
+}