diff --git a/secure/bbmaster.c b/secure/bbmaster.c
new file mode 100644
index 0000000..9677f7f
--- /dev/null
+++ b/secure/bbmaster.c
@@ -0,0 +1,393 @@
+#pragma strict_types
+#pragma no_clone
+#pragma no_shadow
+#pragma no_inherit
+//#pragma pedantic
+//#pragma range_check
+#pragma warn_deprecated
+
+#include <wizlevels.h>
+#include <daemon.h>
+#include <events.h>
+#include <strings.h>
+#include <files.h>
+
+#define FTPSAVE "/secure/ARCH/ftpd"
+
+#define MAXLOGSIZE 2000000
+#define SMALLLOGSIZE 200000
+#define LOGTIME 120
+#define MAXBUFFSIZE 2000
+
+#define DEBUG(x)  if (find_player("zesstra"))\
+            tell_object(find_player("zesstra"),\
+                                      "EDBG: "+x+"\n")
+
+// fuer FTP.
+private mapping monitored;
+
+
+#define D_LOGTIME    0  // Logendezeit, <int>
+#define D_FLAGS      1  // Flags
+#define D_ERSTIE     2  // Name des Ersties.
+#define D_IPSTRING   3
+#define D_INDEX      4  // Index fuer D_LOG, naechster freier index.
+#define D_LOG        5  // Logdaten, <mixed> (Array)
+/* Datenstruktur von D_LOG:
+   ({ ({<zeit>, <kommando>, <environment>}), .... })
+   */
+#define DL_TIME  0  // int
+#define DL_CMD   1  // string
+#define DL_ENV   2  // string
+private nosave mapping ldata = m_allocate(0,D_LOG);
+
+// Flags:
+#define FL_PERMANENT    1 // 'permanent', d.h. nicht nur kurz nach Einloggen
+#define FL_SYNC         2 // nicht puffern, synchron auf Platte schreiben.
+
+// Ja. Macht das bloss nicht nach.
+#define P_SECOND "second"
+
+public int query_bb();
+public void writebb( string msg );
+public varargs void BBWrite(string msg, int catmode);
+
+public int add( string user, int timeout );
+public int sub( string user );
+public void ftpbb( string user, string msg );
+
+private void scan_bb_opfer();
+private void DumpData(string uid, string erstie, string ip, int flags, mixed logdata);
+private void ProcessBuffer(string uid);
+private void RemoveTemporaryPlayer(string uid);
+
+public void create()
+{
+    seteuid( getuid(this_object()) );
+    restore_object( FTPSAVE );
+    scan_bb_opfer();
+    EVENTD->RegisterEvent(EVT_LIB_LOGIN, "Eventhandler", this_object());
+    EVENTD->RegisterEvent(EVT_LIB_LOGOUT, "Eventhandler", this_object());
+    log_file("ARCH/bbmaster.log", strftime("%c: bbmaster wurde geladen.\n"));
+}
+
+// Auf den asynchronen Logout-event zu warten ermoeglicht es theoretisch, 1-2s
+// das Log zu umgehen. Andererseits geht das ohnehin nur dann, wenn die
+// Logzeit eh abgelaufen ist.
+public void Eventhandler(string eid, object trigob, mixed data) {
+  if (previous_object() == find_object(EVENTD)) {
+    string uid;
+    if (objectp(trigob)
+        && strstr(load_name(trigob),"/std/shells/") == 0
+        && !trigob->QueryGuest()) {
+      // Bei Login und Logout den BBMode einschalten (weil der Loginevent ja
+      // erst 1-2s nach Einloggen abgearbeitet wird.
+      trigob->__set_bb(1);
+      uid=getuid(trigob);
+    }
+    else {
+      // kein Objekt mehr da. Vermutlich hat ein Spieler 'ende' gemacht, aber
+      // es koennte auch sein, dass jemand mit nem Selbstzerstoerer den Event
+      // gefakt hat. Aber selbst wenn, viel kann man damit nicht erreichen.
+      uid = data[E_PLNAME];
+      if (!stringp(uid)) return;
+      // Pruefung auf nicht-Anwesenheit von uid waere noch moeglich, hat aber
+      // Probleme, wenn ein Spieler sehr schnell wieder einloggt.
+    }
+
+    if (eid == EVT_LIB_LOGOUT && member(ldata,uid)) {
+      // Wenn Logout und es gibt Daten im Puffer, koennte man die evtl.
+      // wegschreiben oder loeschen.
+      ProcessBuffer(uid);
+      // auf jeden Fall temporaere Spieler entfernen. (Wichtig!)
+      RemoveTemporaryPlayer(uid);
+    }
+  }
+}
+
+// schreibt alle Puffer synchron, ohne Callout... Kann laggen.
+public int ProcessAllBuffers() {
+  
+    if (extern_call() && !ARCH_SECURITY)
+    return -1;
+
+  foreach(string uid, int logtime, int flags, string erstie, string ip,
+          int index, mixed data: ldata) {
+    if (index) {
+      DumpData(uid, erstie, ip, flags, data);
+      ldata[uid,D_LOG]=({});
+      ldata[uid,D_INDEX]=0;
+    }
+  }
+  return 1;
+}
+
+private void ProcessBuffer(string uid) {
+    
+  if (time() <= ldata[uid,D_LOGTIME]
+      && ldata[uid,D_INDEX]) {
+    // Daten wegschreiben, wenn Logzeit nicht abgelaufen. Sonst nicht.
+    call_out(#'DumpData, 2, uid, ldata[uid,D_ERSTIE], ldata[uid,D_IPSTRING],
+	                    ldata[uid,D_FLAGS], ldata[uid,D_LOG]);
+  }
+  ldata[uid,D_LOG] = ({});
+  ldata[uid,D_INDEX] = 0;
+}
+
+private void DumpData(string uid, string erstie, string ip, int flags, mixed logdata) {
+  string res = sprintf("\n%s%s, IP: %s\n", capitalize(uid),
+                      (stringp(erstie) ? " ("+capitalize(erstie)+")" : ""),
+		      (stringp(ip) ? ip : "Unbekannt"));
+  logdata-=({0});
+  foreach(mixed arr : logdata) {
+    res+=sprintf("%O: %O [%s]\n", 
+        strftime("%y%m%d-%H%M%S",arr[DL_TIME]),
+        arr[DL_CMD], arr[DL_ENV] || "<unbekannt>");
+  }
+
+  //DEBUG("DumpData: "+res);
+  if (flags & FL_PERMANENT)
+    catch(log_file("ARCH/bb."+uid, res, MAXLOGSIZE));
+  else if (file_size(LIBLOGDIR"/ARCH/bbmaster") == FSIZE_DIR)
+    catch(log_file("ARCH/bbmaster/"+uid, res, SMALLLOGSIZE));
+  // kein else, in anderen Faellen werden die Daten verworfen.
+}
+
+private void AddTemporaryPlayer(string uid) {
+    // natuerlich nur, wenn noch nix eingetragen.
+    if (!member(ldata, uid)) {
+      object ob = find_player(uid) || find_netdead(uid);
+      
+      mixed erstie;
+      if (ob)
+        erstie = (string)ob->QueryProp(P_SECOND);
+
+      ldata += ([uid: time() + LOGTIME + random(LOGTIME/2); 
+	              0;
+		      (stringp(erstie) ? erstie : 0);
+		      query_ip_number(ob);
+		      0; ({})
+	        ]);
+    }
+}
+
+private void RemoveTemporaryPlayer(string uid) { 
+  if (!(ldata[uid,D_FLAGS] & FL_PERMANENT)) {
+    m_delete(ldata, uid);
+  }
+}
+
+
+// Vom Spielererobjekt bei Erschaffung in InitPlayer() gerufen.
+public int query_bb()
+{
+    
+    if (load_name(previous_object())[0..11] != "/std/shells/")
+        return 0;
+
+    // in jedem Fall wird nun (temporaer) der BB-Modus aktiviert.
+    if (!previous_object()->QueryGuest())
+      previous_object()->__set_bb(1);
+
+    // nur fuer 'permanente' auch 1 zurueckgeben.
+    return ldata[getuid(previous_object()),D_FLAGS] & FL_PERMANENT;
+}
+
+
+
+// neue Funktion. Kriegt nur Kommandosstring uebergegen, werden ggf. gepuffert
+// und dann weggeschrieben.
+public varargs void BBWrite(string msg, int catmode) {
+  
+  if ( !this_interactive() ||
+      (extern_call() && 
+       strstr(load_name(previous_object()), "/std/shells/") != 0 ) )
+    return;
+
+  string uid = getuid(this_interactive());
+
+  if (!member(ldata, uid))
+    AddTemporaryPlayer(uid);  
+  else if (ldata[uid,D_LOGTIME] < time()) {
+    // Logzeit abgelaufen. -> ENDE.
+    if (ldata[uid,D_INDEX]) {
+      this_interactive()->__set_bb(0);
+      // es kann vorkommen, dass hier nen ProcessBuffer mit anderer uid
+      // drinhaengt. Ist aber egal, dann wird der Puffer halt naechstesmal
+      // geschrieben.
+      if (find_call_out(#'ProcessBuffer) == -1)
+          call_out(#'ProcessBuffer, 2, uid);
+    }
+    return;
+  }
+
+  // im synchronen Modus direkt auf Platte schreiben.
+  //DEBUG("BBWrite: Flags von +"+uid+": "+to_string(ldata[uid,D_FLAGS])
+  //    +"\n");
+  if (ldata[uid,D_FLAGS] & FL_SYNC) {
+    //DEBUG("BBWrite: Syncmodus\n");
+    if (!catmode) {
+      msg = sprintf("%s: %s [%O]\n", strftime("%y%m%d-%H%M%S"),
+	  msg, environment(this_interactive()));
+    }
+    else
+      msg = msg + "\n";
+    log_file( "ARCH/bb."+uid, msg, MAXLOGSIZE );
+    return;
+  }
+
+  // alle anderen werden erstmal gepuffert. 
+
+  // wenn catmode und nen Index > 0 wird der Kram an den vorherigen Eintragen
+  // angehaengt.
+  int index = ldata[uid,D_INDEX];
+  if (catmode && index > 0) {
+    --index;
+    ldata[uid,D_LOG][index][DL_CMD] += msg;
+  }
+  else {
+    // Puffer vergroessern?
+    if (index >= sizeof(ldata[uid,D_LOG]))
+      ldata[uid,D_LOG]+=allocate(100);
+    ldata[uid,D_LOG][index] = ({ time(), msg, 
+	                         object_name(environment(this_interactive())) 
+                               });
+    ldata[uid,D_INDEX]++;
+    // es kann vorkommen, dass hier nen ProcessBuffer mit anderer uid
+    // drinhaengt. Ist aber egal, dann wird der Puffer halt naechstesmal
+    // geschrieben.
+    if (index > MAXBUFFSIZE 
+        && find_call_out(#'ProcessBuffer) == -1)
+      call_out(#'ProcessBuffer, 2, uid);
+  }
+}
+
+// Alte Funktion, kriegt Strings, teilweise mit Datum, teilweise ohne,
+// schrieb frueher nur weg. msg faengt entweder mit einem Datum/Zeit-String
+// oder mit einem "->" an.
+public void writebb( string msg )
+{
+  int catmode; 
+ 
+  if ( !this_interactive() ||
+      (extern_call() && 
+       strstr(load_name(previous_object()), "/std/shells/") != 0 ) )
+    return;
+ 
+  // erstmal String bereinigen.
+  msg = trim(msg,TRIM_RIGHT,"\n");
+  if (strstr(msg,"->") == 0) {
+    catmode=1;
+    msg= " -> " + msg[2..];
+  }
+  else {
+    // faengt mit Datumsstring an, erstes Leerzeichen ab dem zehnten Zeichen
+    // suchen und von dort abschneiden.
+    msg = msg[strstr(msg," ",10)+1 ..];
+  }
+
+  // Dann weitergeben
+  BBWrite(msg, catmode);
+}
+
+private void scan_bb_opfer()
+{
+    string* lines;
+    object pl;
+    string uid;
+
+    // diese user werden 'permanent' ueberwacht, nicht nur direkt nach dem
+    // Einloggen.
+    lines = explode( lower_case( read_file("/secure/ARCH/BB_OPFER.dump")
+                                       || "" ), "\n" )[2..];
+    
+    foreach(string line : lines) {
+        if( sizeof(line) && line[0] != '#' ) {
+	    uid=line[0 .. member(line,' ')-1];
+	    AddTemporaryPlayer(uid);
+	    ldata[uid,D_LOGTIME] = __INT_MAX__;
+	    ldata[uid,D_FLAGS] = FL_PERMANENT;
+	    pl = find_player(uid) || find_netdead(uid);
+	    if (pl)
+	      pl->__set_bb(1);
+	}
+    }
+}
+
+// Neuladen ist kein grosses Problem, weil der bbmaster ja automatisch
+// neugeladen wird. Nebeneffekt ist lediglich, dass fuer alle laufenden Logs
+// die Logzeit wieder von vorne anfaengt. Da das Schreiben der Puffer aber Lag
+// verursachen kann, duerfen es nur EM+.
+public varargs int remove(int silent) {
+ 
+  if (!ARCH_SECURITY)
+    return 0;
+
+  log_file("ARCH/bbmaster.log", strftime("%c: remove() called.\n"));
+
+  // alle Puffer leeren...
+  // ProcessAllBuffers() wird hierbei _ohne_ Limits aufgerufen! Kann fieses
+  // Lag erzeugen, aber sonst wurde der Kram evtl. nicht ordentlich
+  // geschrieben.
+  limited(#'ProcessAllBuffers);
+  destruct(this_object());
+  return 1;
+}
+
+
+// Alles ab hier nur zum Ueberwachen von FTP-Aktivitaeten.
+private int player_exists( string user )
+{
+    if ( !stringp( user ) || sizeof( user ) < 2 )
+        return 0;
+    
+  return file_size( "/save/" + user[0..0] + "/" + user + ".o" ) > 0;
+}
+
+public int add( string user, int timeout )
+{
+    if ( !ARCH_SECURITY || process_call() )
+        return -1;
+    
+    if( !stringp(user) || !player_exists(lower_case(user)) || !intp(timeout) ||
+        !timeout )
+        return -2;
+    
+    monitored[lower_case(user)] = timeout;
+    save_object( FTPSAVE );
+    
+    return 1;
+}
+
+
+public int sub( string user )
+{
+    if ( !ARCH_SECURITY || process_call() )
+        return -1;
+    
+    if( !stringp(user) || !member( monitored, lower_case(user) ) )
+        return -2;
+    
+    m_delete( monitored, lower_case(user) );
+    save_object( FTPSAVE );
+    
+    return 1;
+}
+
+
+public void ftpbb( string user, string msg )
+{
+    if( getuid(previous_object()) != ROOTID )
+        return;
+
+    if ( ldata[user,D_FLAGS] & FL_PERMANENT )
+        log_file( "ARCH/bb."+user, msg, 2000000 );
+
+    if ( monitored[user] ){
+        if ( monitored[user] > 0 && monitored[user] < time() )
+            sub( user );
+        else
+            CHMASTER->send( "FTP", capitalize(user), msg );
+    }
+}
+
