diff --git a/secure/master/misc.c b/secure/master/misc.c
new file mode 100644
index 0000000..02b0fcc
--- /dev/null
+++ b/secure/master/misc.c
@@ -0,0 +1,772 @@
+// MorgenGrauen MUDlib
+//
+// master/misc.c -- Diverses: (T)Banish, Projektverwaltung, Levelaufstieg, ...
+//
+// $Id: misc.c 9467 2016-02-19 19:48:24Z Zesstra $
+
+#pragma strict_types,rtt_checks
+
+#include "/sys/functionlist.h"
+#include "/sys/lpctypes.h"
+#include "/sys/object_info.h"
+#include "/sys/interactive_info.h"
+
+#include "/secure/master.h"
+#include "/mail/post.h"
+#include "/sys/thing/language.h"
+#include "/sys/thing/description.h"
+
+// Fuer CIDR-Notatio im sbanish
+#include "/secure/master/cidr.c"
+
+static mixed *banished;
+static mapping tbanished, sbanished;
+static string *deputies;
+
+// TODO: muss ggf. Fakeobjekt erzeugen+uebergeben, wenn sender kein object
+protected void send_channel_msg(string channel,mixed sendername,string msg)
+{
+  object sender;
+  if (objectp(sendername))
+    sender=sendername;
+  else
+  {
+    // wenn kein Objekt uebergeben, erstmal schauen, ob ein Spielerobject
+    // existiert... Wenn ja, das nehmen.
+    sender = call_sefun("find_player", sendername)
+             || call_sefun("find_netdead", sendername);
+    if (!objectp(sender))
+    {
+      // sonst faken wir eins. *seufz*
+      sender=clone_object("/p/daemon/namefake");
+      sender->SetProp(P_NAME, sendername); 
+      sender->SetProp(P_ARTICLE,0);
+      // Dieses Objekt zerstoert sich nach 3s automatisch.
+    }
+  }
+  CHMASTER->send(channel, sender, msg);
+}
+
+static string *explode_files(string file) {
+  string data;
+  mixed *exploded;
+  int i;
+
+  data=read_file(file);
+  if (!data || !stringp(data) || data == "") return ({});
+  exploded = efun::explode(data,"\n");
+  for (i=sizeof(exploded);i--;)
+    if (!stringp(exploded[i]) || exploded[i]=="" || exploded[i][0]=='#')
+      exploded[i]=0;
+  exploded-=({0});
+  printf("%-30s: %3d Objekt%s\n",file,i=sizeof(exploded),(i==1?"":"e"));
+  return exploded;
+}
+
+void UpdateTBanish();
+
+mixed QueryBanished(string str){
+  int i;
+
+  if (!str) return 0;
+  if (!pointerp(banished)) return 0;
+  for (i=sizeof(banished)-1;i>=0;i--)
+    if (sizeof(regexp(({str}),"^"+banished[i][0]+"$")))
+    {
+      if (!banished[i][1] || banished[i][1]=="")
+        return "Dieser Name ist gesperrt.";
+      else
+        return banished[i][1];
+    }
+  return 0;
+}
+
+mixed QueryTBanished(string str) {
+  int i;
+
+  if (!str || !mappingp(tbanished) || !(i=tbanished[str]))
+    return 0;
+
+  if (i == -1 || i > time())
+    return sprintf("Es gibt schon einen Spieler diesen Namens.\n"
+        +"Allerdings kann er/sie erst am %s wieder ins Mud kommen.\n",
+          (i == -1 ? "St. Nimmerleinstag" :
+           call_sefun("dtime",i)[0..16]));
+
+// Ansonsten: die Zeit ist abgelaufen, Spieler darf wieder...
+  m_delete(tbanished, str);
+  UpdateTBanish();
+  return 0;
+}
+
+void ReloadBanishFile(){
+    int i, t;
+    string s1, s2, *s;
+
+    banished = efun::explode( read_file("/secure/BANISH") || "", "\n" );
+    banished = banished - ({""});
+    for ( i = sizeof(banished); i--; ){
+        s = efun::explode( banished[i], " " );
+        s1 = s[0];
+        s2 = implode( s[1..], " " );
+        banished[i] = ({ s1, s2 });
+    }
+
+    if ( !mappingp(tbanished) ){
+        tbanished = ([]);
+
+        s = efun::explode( read_file("/secure/TBANISH") || "", "\n" );
+        s -= ({""});
+
+        for ( i = sizeof(s); i--; ){
+            sscanf( s[i], "%s:%d", s1, t );
+            tbanished += ([ s1 : t ]);
+        }
+    }
+
+    if ( !mappingp(sbanished) ){
+        sbanished = m_allocate(3, 2);
+
+        s = efun::explode( read_file("/secure/SITEBANISH") || "", "\n" );
+        s -= ({""});
+
+        for ( i = sizeof(s); i--; ) {
+            int int_ip;
+            sscanf( s[i], "%s:%d:%s", s1, t, s2 );
+            int_ip = IPv4_addr2int(s1);
+            m_add(sbanished, int_ip, t, s2);
+        }
+    }
+}
+
+int IsDeputy(mixed name)
+{
+    if ( IS_ARCH(name) )
+        return 1;
+
+    if ( objectp(name) )
+        name = getuid(name);
+
+    if ( member( deputies || ({}), name ) >= 0 )
+        return 1;
+
+    return 0;
+}
+
+
+varargs void BanishName( string name, string reason, int force )
+{
+  string *names;
+  int i;
+
+  if ( PO != TO && call_sefun("secure_level") < LORD_LVL
+           && !IsDeputy( call_sefun("secure_euid") ) )
+      return;
+
+  if ( !stringp(name) || !sizeof(name) )
+      return;
+
+  name = lower_case(name);
+
+  if ( !reason || !stringp(reason) )
+      reason = "";
+
+  if ( QueryBanished(name) && lower_case(reason) != "loeschen" ){
+      write("Der Name ist schon gebannt.\n");
+      return;
+  }
+
+  if ( !force && file_size(SAVEPATH+name[0..0]+"/"+name+".o") > 0 ){
+      write("Es existiert bereits ein Spieler dieses Namens.\n");
+      return;
+  }
+
+/*  if (!("/secure/login"->valid_name(name))) return;*/
+  if ( lower_case(reason) != "loeschen" ){
+      names = ({ name + " " + reason });
+
+      for ( i = sizeof(banished); i--; )
+          names += ({ banished[i][0] + " " + banished[i][1] });
+  }
+  else{
+      names = ({});
+
+      for ( i = sizeof(banished); i--; )
+          if ( banished[i][0] != name )
+              names += ({ banished[i][0] + " " + banished[i][1] });
+  }
+
+  names = sort_array( names, #'> );
+  rm("/secure/BANISH");
+  write_file( "/secure/BANISH", implode(names, "\n") );
+  write( "Okay, '"+capitalize(name)+"' ist jetzt "+
+      (lower_case(reason) == "loeschen" ? "nicht mehr " : "")+"gebanisht.\n" );
+  ReloadBanishFile();
+}
+
+void UpdateTBanish()
+{
+  int i;
+  string *names;
+
+  for (i=sizeof(names = sort_array(m_indices(tbanished), #'</*'*/))-1;i>=0;i--)
+    names[i] = sprintf("%s:%d", names[i], tbanished[names[i]]);
+
+  rm("/secure/TBANISH");
+  write_file("/secure/TBANISH", implode(names, "\n"));
+}
+
+void UpdateSBanish()
+{
+    int i;
+    mapping lines = m_allocate(sizeof(sbanished),0);
+
+    foreach(int ip, int tstamp, string user : sbanished) {
+      m_add(lines, sprintf("%s:%d:%s",
+                           IPv4_int2addr(ip), tstamp, user));
+    }
+
+    write_file( "/secure/SITEBANISH", 
+        implode( sort_array (m_indices(lines), #'<), "\n" ), 1);
+}
+
+int TBanishName(string name, int days)
+{
+  int t;
+
+  if ( (getuid(TI) != name) &&
+       !IsDeputy( call_sefun("secure_euid") ) )
+    return 0;
+
+  if (days && QueryTBanished(name)){
+    write("Der Name ist schon gebannt.\n");
+    return 0;
+  }
+
+  if (file_size(SAVEPATH+name[0..0]+"/"+name+".o")<=0){
+    write("Es existiert kein Spieler dieses Namens!\n");
+    return 0;
+  }
+
+  if (!days && member(tbanished, name))
+    m_delete(tbanished, name);
+  else {
+    if (!mappingp(tbanished))
+      tbanished = ([]);
+    if (days <= -1)
+      t = -1;
+    else
+      t = (time()/86400)*86400 + days*86400;
+    tbanished += ([ name : t ]);
+  }
+
+  UpdateTBanish();
+  return 1;
+}
+
+
+mixed QuerySBanished( string ip )
+{
+    int save_me, site;
+    string banished_meldung =
+      "\nSorry, von Deiner Adresse kamen ein paar Idioten, die "
+            "ausschliesslich\nAerger machen wollten. Deshalb haben wir "
+            "die Moeglichkeit,\neinfach neue Charaktere "
+            "anzulegen, kurzzeitig fuer diese Adresse gesperrt.\n\n"
+            "Falls Du bei uns spielen moechtest, schicke bitte eine Email "
+            "an\n\n                         mud@mg.mud.de\n\n"
+            "mit der Bitte, einen Charakter fuer Dich anzulegen.\n" ;
+
+    if ( !ip || !stringp(ip) || !mappingp(sbanished) || !sizeof(sbanished) )
+        return 0;
+
+    foreach(site, int tstamp: sbanished) {
+        if ( tstamp > 0 && tstamp < time() ) {
+            m_delete( sbanished, site );
+            save_me=1;
+        }
+    }
+    if (save_me)
+        UpdateSBanish();
+
+    if ( !sizeof(sbanished) )
+        return 0;
+
+    site = IPv4_addr2int(ip);
+    if (!site)
+        return 0;
+    // direkt drin?
+    if (member(sbanished, site))
+        return banished_meldung;
+    // oder Netz dieser IP gesperrt?
+    foreach(int locked_site : sbanished) {
+        if ((locked_site & site) == locked_site)
+            return banished_meldung;
+    }
+
+    return 0;
+}
+
+
+private int _sbanished_by( int key, string name )
+{
+    return sbanished[key, 1] == name;
+}
+
+
+mixed SiteBanish( string ip, int days )
+{
+    string *s, tmp, euid;
+    int t, level;
+
+    euid = call_sefun("secure_euid");
+    level = call_sefun("secure_level");
+
+    // Unter L26 gibt's gar nix.
+    if ( level <= DOMAINMEMBER_LVL )
+        return -1;
+
+    // Die Liste der gesperrten IPs anschauen darf jeder ab L26.
+    if ( !ip && !days )
+        return copy(sbanished);
+
+
+    if ( !stringp(ip) || !intp(days) )
+        return 0;
+
+    if ( days && QuerySBanished(ip) ){
+        write( "Diese Adresse ist schon gebannt.\n" );
+        return 0;
+    }
+
+    if ( !days ) {
+        int int_ip = IPv4_addr2int(ip);
+
+        if( member(sbanished, int_ip) ){
+            // Fremde Sitebanishs duerfen nur Deputies loeschen.
+            if ( sbanished[int_ip, 1] != euid && !IsDeputy(euid) )
+                return -1;
+
+            call_sefun("log_file", "ARCH/SBANISH",
+                    sprintf( "%s: %s hebt die Sperrung der Adresse %s von %s "
+                             + "auf.\n", 
+                             ctime(time()), capitalize(euid), ip,
+                             capitalize(sbanished[int_ip, 1]) ) );
+
+            m_delete( sbanished, int_ip );
+        }
+        else
+            return 0;
+    }
+    else {
+        // Alles, was nicht Deputy ist, darf nur fuer einen Tag sbanishen.
+        if ( days != 1 && !IsDeputy(euid) )
+            return -1;
+
+        // Nur Deputies duerfen mehr als 10 Sperrungen vornehmen.
+        if ( sizeof(filter_indices(sbanished, #'_sbanished_by, euid)) >= 10
+             && !IsDeputy(euid) )
+            return -2;
+
+        int int_ip = IPv4_addr2int(ip);
+
+        if(!int_ip) {
+            write( "Ungueltige Adresse!\n" );
+            return 0;
+        }
+
+        // L26 duerfen exakt eine IP sperren, RMs ganze Class C-Subnetze
+        // und Deputies auch Class B-Subnetze.
+        int nsize=IPv4_net_size(ip);
+        if ( nsize > 1 && level < LORD_LVL
+             || nsize > 255 && !IsDeputy(euid) )
+            return -1;
+
+        if ( !mappingp(sbanished) )
+            sbanished = m_allocate(1, 2);
+
+        if ( days < 0 )
+            t = -1;
+        else
+            t = (time() / 86400) * 86400 + days * 86400;
+
+        m_add(sbanished, int_ip, t, euid);
+
+        call_sefun("log_file", "ARCH/SBANISH",
+                sprintf( "%s: %s sperrt die Adresse %s %s.\n",
+                         ctime(time()), capitalize(euid),
+                         ip,
+                         days > 0 ? (days > 1 ? "fuer " + days + " Tage"
+                                     : "fuer einen Tag")
+                         : "bis zum St. Nimmerleinstag" ) );
+    }
+
+    UpdateSBanish();
+    return 1;
+}
+
+static void CheckDeputyRights()
+{
+    object ob;
+    mixed *ginfo;
+
+    // Lese- und Schreibberechtigungen fuer die Rubrik 'polizei' setzen
+    call_other( "/secure/news", "???" );
+    ob = find_object("secure/news");
+    ginfo = ((mixed)ob->GetGroup("polizei"))[5..6];
+    ob->RemoveAllowed( "polizei", 0, ginfo[0], ginfo[1] );
+    ob->AddAllowed( "polizei", 0, deputies, deputies );
+    LoadDeputyFileList();
+}
+
+int ReloadDeputyFile()
+{
+    deputies = efun::explode( read_file("/secure/DEPUTIES") || "", "\n" );
+    deputies -= ({""});
+    deputies = map( deputies, #'lower_case/*'*/ );
+    call_out( "CheckDeputyRights", 2 );
+    return(1);
+}
+
+
+static int create_home(string owner, int level)
+{
+  string def_castle;
+  string dest, castle, wizard;
+  object player;
+  string *domains;
+  int i;
+
+  player = call_sefun("find_player",owner);
+  if (!player)
+    return -5;
+  domains=get_domain_homes(owner);
+  if (!sizeof(domains) && level >= DOMAINMEMBER_LVL)
+  {
+    tell_object(player,"Du gehoerst noch keiner Region an !\n");
+    return -6;
+  }
+  tell_object(player,"Du bist Mitarbeiter der folgenden Regionen:\n");
+  for (i=0;i<sizeof(domains);i++)
+  {
+    if (i) tell_object(player,", ");
+    tell_object(player,domains[i]);
+  }
+  tell_object(player,".\n");
+  update_wiz_level(owner, level);
+  wizard = "/players/" + owner;
+  castle = "/players/" + owner + "/workroom.c";
+  if (file_size(wizard) == -1) {
+    tell_object(player, "Verzeichnis " + wizard + " angelegt\n");
+    mkdir(wizard);
+  }
+  dest = object_name(environment(player));
+  def_castle = read_file("/std/def_workroom.c");
+  if (file_size(castle) > 0) {
+    tell_object(player, "Du HATTEST ja schon ein Arbeitszimmer !\n");
+  } else {
+    if (write_file(castle, def_castle))
+    {
+      tell_object(player, "Arbeitszimmer " + castle + " erzeugt.\n");
+      // Arbeitszimmer als Home setzen
+      player->SetProp(P_START_HOME,castle[0..<3]);
+    }
+    else
+      tell_object(player, "Arbeitszimmer konnte nicht erzeugt werden !\n");
+  }
+  return 1;
+}
+
+// Sendet dem befoerderten Magier eine Hilfemail zu.
+protected void SendWizardHelpMail(string name, int level) {
+  
+  object pl=call_sefun("find_player",name);
+  if (!objectp(pl)) return;
+
+  string file=sprintf("%sinfo_ml%d", WIZ_HELP_MAIL_DIR, level);
+  // wenn kein Hilfetext fuer den Level da ist: raus
+  if (file_size(file) <= 0)
+    return;
+
+  string subject = read_file(file,1,1);
+  string text = call_sefun("replace_personal",
+                         read_file(file,2), ({pl}));
+
+  mixed mail = ({"Merlin", "<Master>", name, 0, 0, subject,
+                 call_sefun("dtime",time()),
+                 MUDNAME+time(), text });
+  MAILDEMON->DeliverMail(mail, 0);
+}
+
+int allowed_advance_wizlevel(mixed ob)
+{
+  string what;
+
+  if (objectp(ob) && geteuid(ob)==ROOTID) return 1;
+
+  if (!stringp(ob))
+    what=efun::explode(object_name(ob),"#")[0];
+  else
+    what=ob;
+
+  if (what=="/secure/merlin") return 1;
+
+  return 0;
+}
+
+int advance_wizlevel(string name, int level)
+{
+  int answer;
+  mixed *user;
+
+  if (!allowed_advance_wizlevel(PO))
+    return -1;
+
+  if (level>80) return -2;
+
+  if (!find_userinfo(name)) return -3;
+
+  user=get_full_userinfo(name);
+
+  if (user[USER_LEVEL+1]>level) return -4;
+
+  if (user[USER_LEVEL+1]==level) return 1;
+
+  if (level>=10 && level<20)
+  {
+    update_wiz_level(name, level);
+    SendWizardHelpMail(name, level);
+    return 1;
+  }
+  if (level>=20 && user[USER_LEVEL+1]<21)
+  {
+    answer = create_home(name, level);
+    if ( answer > 0 ) {
+      answer = update_wiz_level(name, level);
+      SendWizardHelpMail(name, level);
+    }
+    return answer;
+  }
+
+  update_wiz_level(name, level);
+  SendWizardHelpMail(name, level);
+
+  return 1;
+}
+
+void restart_heart_beat(object heart_beat)
+{
+  if (heart_beat) heart_beat->_restart_beat();
+}
+
+int renew_player_object(mixed who)
+{
+  object newob;
+  object *obs, *obs2;
+  mixed err;
+  string ob_name;
+  object *armours, weapon;
+  object tp;
+  int i,active,j;
+
+  if (stringp(who))
+  {
+    who=call_sefun("find_player",who);
+    if (!who)
+    {
+      who=call_sefun("find_netdead",who);
+      if (!who)
+        return -1;
+    }
+  }
+  if (!objectp(who))
+    return -2;
+  if (!object_info(who, OI_ONCE_INTERACTIVE))
+    return -3;
+  if (who->QueryGuest())
+  {
+    printf("Can't renew guests!\n");
+    return -6;
+  }
+  active=interactive(who);
+  printf("OK, renewing %O\n",who);
+  seteuid(geteuid(who));
+  err=catch(newob=clone_object(query_player_object(getuid(who))); publish);
+  seteuid(getuid(TO));
+  if (err)
+  {
+    printf("%O\n",err);
+    return -4;
+  }
+  if (!newob)
+    return -5;
+  /* Ok, the object is here now ... lets go for it ... */
+  who->save_me(0);
+  /* SSL ip weiterreichen */
+  if( call_sefun("query_ip_number", who) != efun::interactive_info(who,II_IP_NUMBER) )
+  {
+    newob->set_realip( call_sefun("query_ip_number",who) );
+  }
+  efun::configure_object(previous_object(), OC_COMMANDS_ENABLED, 0);
+  efun::set_this_player(0);
+  armours=(object *)who->QueryProp(P_ARMOURS);
+  weapon=(object)who->QueryProp(P_WEAPON);
+
+  if ( previous_object() && object_name(previous_object()) == "/secure/merlin" )
+      send_channel_msg("Debug",
+                       previous_object(),
+                       sprintf("RENEWING: %O %O\n",newob,who));
+  else
+      send_channel_msg("Entwicklung",
+                       previous_object(),
+                       sprintf("RENEWING: %O %O\n",newob,who));
+
+  ob_name=explode(object_name(newob),"#")[0];
+  if (sizeof(ob_name)>11 && ob_name[0..11]=="/std/shells/")
+    ob_name=ob_name[11..];
+  ob_name=ob_name+":"+getuid((object)who);
+  if (active)
+    exec(newob,who);
+  if (active && (interactive(who)||!interactive(newob)))
+  {
+    send_channel_msg("Debug",previous_object(),
+                     "ERROR: still active !\n");
+    newob->remove();
+    return 0;
+  }
+//   newob->start_player(capitalize(getuid(who)),who->_query_my_ip());
+  funcall(
+          bind_lambda(
+                      unbound_lambda( ({'x, 'y}),
+                                      ({#'call_other/*'*/,
+                                             newob,
+                                             "start_player",
+                                             'x, 'y
+                                             })
+                                      ), who
+                      ),
+          capitalize(getuid(who)), who->_query_my_ip() );
+
+  newob->move(environment(who),M_TPORT|M_NOCHECK|M_NO_SHOW|M_SILENT
+              |M_NO_ATTACK);
+  obs=all_inventory(who);
+  foreach(object tob: all_inventory(who)) {
+    if (!tob->QueryProp(P_AUTOLOADOBJ))
+    {
+      // kein Autoloader...
+      foreach(object ob: deep_inventory(tob))
+      {
+        // aber enthaltene Autoloader entsorgen...
+        if (ob->QueryProp(P_AUTOLOADOBJ))
+        {
+          catch(ob->remove();publish);
+          if (ob) destruct(ob);
+        }
+      }
+      // objekt ohne die AL bewegen.
+      catch(tob->move(newob,M_NOCHECK);publish);
+    }
+    else {
+      // Inhalt von Autoloadern retten.
+      // neue instanz des ALs im neuen Objekt.
+      object new_al_instance = present_clone(tob, newob);
+      foreach(object ob: deep_inventory(tob)) {
+        if (ob->QueryProp(P_AUTOLOADOBJ)) {
+            // autoloader in Autoloadern zerstoeren...
+            catch(ob->remove(1);publish);
+            if (ob) destruct(ob);
+        }
+        // alle nicht autoloader in die AL-Instanz im neuen Objekt oder
+        // notfalls ins Inv.
+        else {
+          if (objectp(new_al_instance))
+            catch(ob->move(new_al_instance, M_NOCHECK);publish);
+          else
+            catch(ob->move(newob, M_NOCHECK);publish);
+        }
+      }
+      // Autoloader zerstoeren. Wird nicht vom Spielerobjekt im remove()
+      // gemacht, wenn nicht NODROP.
+      catch(tob->remove(1);publish);
+      if (tob) destruct(tob);
+    }
+  }
+  who->remove();
+  if ( objectp(who) )
+      destruct(who);
+  rename_object(newob,ob_name);
+  newob->__reload_explore();
+  tp=this_player();
+  efun::set_this_player(newob);
+  if (objectp(weapon))
+    weapon->DoWield();
+  if (pointerp(armours))
+    for (i=sizeof(armours)-1;i>=0;i--)
+      if (objectp(armours[i]))
+        armours[i]->do_wear("alles");
+  efun::set_this_player(tp);
+  //Rueckgabewert noetig, weil Funktion vom Typ 'int'
+  return(1);
+}
+
+mixed __query_variable(object ob, string var)
+{
+  if (!PO || !IS_ARCH(geteuid(PO)) || !this_interactive() ||
+      !IS_ARCH(this_interactive()) || getuid(ob)==ROOTID )
+  {
+    write("Du bist kein EM oder Gott!\n");
+    return 0;
+  }
+  if (efun::object_info(ob, OI_ONCE_INTERACTIVE) && (PO!=ob) &&
+     (var=="history" || var=="hist2"))
+     send_channel_msg("Snoop", previous_object(),
+                      sprintf("%s -> %s (history).",
+                        capitalize(getuid(PO)),capitalize(getuid(ob))));
+
+  call_sefun("log_file", "ARCH/QV",
+                          sprintf("%s: %O inquires var %s in %O\n",
+                                  ctime(time()),this_interactive(),var,ob) );
+  mixed res = variable_list(ob, RETURN_FUNCTION_NAME|RETURN_FUNCTION_FLAGS|
+                                RETURN_FUNCTION_TYPE|RETURN_VARIABLE_VALUE);
+  int index = member(res,var);
+  if (index > -1)
+  {
+    return ({res[index],res[index+1],res[index+2],res[index+3]});
+  }
+  return 0;
+}
+
+void RestartBeats()
+{
+  int i,size,counter;
+  object ob;
+  mixed *list;
+  string file,obname,fun;
+
+  "/secure/simul_efun"->StopCallOut(0);
+  write("CALL_OUT-Restart in progress !\n");
+  filter(users(),#'tell_object,"CALL_OUT-Restart in progress !\n");
+  size=file_size("log/call_out_stop");
+  if (size<=0)
+    return;
+  file="";
+  counter=0;
+  while (counter<size)
+  {
+    file+=read_bytes("log/call_out_stop",counter,
+                     (size-(counter+=40000)>0?counter:size));
+  }
+  list=explode(file,"__(CUT HERE)__\n");
+  list=list[<1..];
+  list=explode(list[0],"\n")-({""});
+  for (i=sizeof(list)-1;i>=0;i--)
+    if (sscanf(list[i],"%s \"%s\"",obname,fun)==2 && ob=find_object(obname))
+    {
+      write(sprintf("%O -> %s\n",ob,fun));
+      catch(ob->__restart(fun);publish);
+    }
+  write("CALL_OUT-Restart completed !\n");
+  filter(users(),#'tell_object,"CALL_OUT-Restart completed !\n");
+  rename("log/call_out_stop","log/call_out_stop.old");
+}
+
