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;
+}
