diff --git a/p/daemon/channeld.c b/p/daemon/channeld.c
new file mode 100644
index 0000000..1331d57
--- /dev/null
+++ b/p/daemon/channeld.c
@@ -0,0 +1,647 @@
+// channeld.c
+//
+// $Id: channeld.c 9138 2015-02-03 21:46:56Z Zesstra $
+//
+
+#pragma strong_types
+#pragma no_shadow // keine Shadowing...
+#pragma no_clone
+#pragma no_inherit
+#pragma save_types
+
+#include <sys_debug.h>
+#include <lpctypes.h>
+#include <wizlevels.h>
+
+#include <properties.h>
+#include <config.h>
+#include <language.h>
+
+#define NEED_PROTOTYPES
+#include "channel.h"
+
+#define CMNAME  "<MasteR>"
+#define CHANNEL_SAVE    "/p/daemon/save/channeld"
+
+#define MEMORY "/secure/memory"
+
+// channels - contains the simple channel information
+//            ([ channelname : ({ I_MEMBER, I_ACCESS, I_INFO, I_MASTER })...])
+private nosave mapping lowerch;
+private nosave mapping channels;
+private nosave mapping channelH;
+private nosave mapping stats;
+
+private mapping channelC;
+private mapping channelB;
+
+private int save_me_soon;
+
+// BEGIN OF THE CHANNEL MASTER ADMINISTRATIVE PART
+
+#define RECV    0
+#define SEND    1
+#define FLAG    2
+
+// Channel flags
+// Levelbeschraenkungen gegen Magierlevel (query_wiz_level) pruefen, nicht
+// P_LEVEL.
+#define F_WIZARD 1
+// Keine Gaeste. ;-)
+#define F_NOGUEST 2
+
+private nosave mapping admin = m_allocate(0, 3);
+
+int check(string ch, object pl, string cmd)
+{
+  int level;
+  
+  if((admin[ch, FLAG] & F_NOGUEST) && pl->QueryGuest()) return 0;
+
+  if((admin[ch, FLAG] & F_WIZARD) && query_wiz_level(pl) < SEER_LVL) return 0;
+  level = (admin[ch, FLAG] & F_WIZARD
+           ? query_wiz_level(pl)
+           : pl->QueryProp(P_LEVEL));
+
+  switch(cmd)
+  {
+  case C_FIND:
+  case C_LIST:
+  case C_JOIN:
+    if(admin[ch, RECV] == -1) return 0;
+    if(admin[ch, RECV] <= level) return 1;
+    break;
+  case C_SEND:
+    if(admin[ch, SEND] == -1) return 0;
+    if(admin[ch, SEND] <= level) return 1;
+    break;
+  case C_LEAVE:
+    return 1;
+  default: break;
+  }
+  return(0);
+}
+
+private int CountUser(mapping l)
+{
+  mapping n;
+  n = ([]);
+  walk_mapping(l, lambda(({'i/*'*/, 'a/*'*/, 'n/*'*/}),
+                         ({#'+=/*'*/, 'n/*'*/,
+                              ({#'mkmapping/*'*/,
+                                   ({#'[/*'*/, 'a/*'*/, 0})})})),
+               &n);
+  return sizeof(n);
+}
+
+private void banned(string n, mixed cmds, string res)
+{
+  res += sprintf("%s [%s], ", capitalize(n), implode(cmds, ","));
+}
+
+private mapping Tcmd = ([]);
+#define TIMEOUT (time() - 60)
+
+void ChannelMessage(mixed msg)
+{
+  string ret, mesg;
+  mixed lag;
+  int max, rekord;
+  string tmp;
+  if(msg[1] == this_object() || !stringp(msg[2]) ||
+     msg[0] != CMNAME || previous_object() != this_object()) return;
+
+
+  mesg = lower_case(msg[2]);
+
+  if(!strstr("hilfe", mesg) && sizeof(mesg) <= 5)
+    ret = "Folgende Kommandos gibt es: hilfe, lag, up[time], statistik, bann";
+  else
+  if(!strstr("lag", mesg) && sizeof(mesg) <= 3)
+  {
+    if(Tcmd["lag"] > TIMEOUT) return;
+    Tcmd["lag"] = time();
+    lag = "/p/daemon/lag-o-daemon"->read_ext_lag_data();
+    ret = sprintf("Lag: %.1f%%/60, %.1f%%/15, %.1f%%/5, %.1f%%/1, "
+                       "%.1f%%/20s, %.1f%%/2s",
+                  lag[5], lag[4], lag[3], lag[2], lag[1], lag[0]);
+    call_out(#'send/*'*/, 2, CMNAME, this_object(), ret);
+    ret = query_load_average();
+  } else
+  if(!strstr("uptime", mesg) && sizeof(mesg) <= 6)
+  {
+    if(Tcmd["uptime"] > TIMEOUT) return;
+    Tcmd["uptime"] = time();
+    if(file_size("/etc/maxusers") <= 0) {
+      ret = "Diese Information liegt nicht vor.";
+    } else {
+      sscanf(read_file("/etc/maxusers"), "%d %s", max, tmp);
+      sscanf(read_file("/etc/maxusers.ever"), "%d %s", rekord, tmp);
+      ret = sprintf("Das MUD laeuft jetzt %s. Es sind momentan %d Spieler "
+                  "eingeloggt; das Maximum lag heute bei %d und der Rekord "
+                  "bisher ist %d.", uptime(), sizeof(users()), max, rekord);
+    }
+  } else
+  if(!strstr("statistik", mesg) && sizeof(mesg) <= 9)
+  {
+    if(Tcmd["statistik"] > TIMEOUT) return;
+    Tcmd["statistik"] = time();
+    ret = sprintf(
+    "Im Moment sind insgesamt %d Ebenen mit %d Teilnehmern aktiv.\n"
+    "Der %s wurde das letzte mal am %s von %s neu gestartet.\n"
+    "Seitdem wurden %d Ebenen neu erzeugt und %d zerstoert.\n",
+    sizeof(channels), CountUser(channels), CMNAME,
+    dtime(stats["time"]), stats["boot"], stats["new"], stats["dispose"]);
+  } else
+  if(!strstr(mesg, "bann"))
+  {
+    string pl, cmd;
+    if(mesg == "bann")
+      if(sizeof(channelB))
+      {
+        ret = "";
+        walk_mapping(channelB, #'banned/*'*/, &ret);
+        ret = "Fuer folgende Spieler besteht ein Bann: " + ret;
+      } else ret = "Zur Zeit ist kein Bann aktiv.";
+    else
+    {
+      if(sscanf(mesg, "bann %s %s", pl, cmd) == 2 &&
+         IS_DEPUTY(msg[1]))
+      {
+#     define CMDS ({C_FIND, C_LIST, C_JOIN, C_LEAVE, C_SEND, C_NEW})
+        pl = lower_case(pl); cmd = lower_case(cmd);
+        if(member(CMDS, cmd) != -1)
+        {
+          if(!pointerp(channelB[pl]))
+            channelB[pl] = ({});
+          if(member(channelB[pl], cmd) != -1)
+            channelB[pl] -= ({ cmd });
+          else
+            channelB[pl] += ({ cmd });
+          ret = "Fuer '"+capitalize(pl)+"' besteht "
+            + (sizeof(channelB[pl]) ?
+               "folgender Bann: "+implode(channelB[pl], ", ") :
+               "kein Bann mehr.");
+          if(!sizeof(channelB[pl]))
+            channelB = m_copy_delete(channelB, pl);
+          save_object(CHANNEL_SAVE);
+        }
+        else ret = "Das Kommando '"+cmd+"' ist unbekannt. Erlaubte Kommandos: "
+               + implode(CMDS, ", ");
+      }
+      else
+      {
+        if(!IS_ARCH(msg[1])) return;
+        else ret = "Syntax: bann <name> <kommando>";
+      }
+    }
+  }
+  else if(mesg == "lust")
+  {
+    mixed t, up;
+    if(Tcmd["lag"] > TIMEOUT ||
+       Tcmd["statistik"] > TIMEOUT ||
+       Tcmd["uptime"] > TIMEOUT) return;
+    Tcmd["lag"] = time();
+    Tcmd["statistik"] = time();
+    Tcmd["uptime"] = time();
+    lag = "/p/daemon/lag-o-daemon"->read_lag_data();
+
+    sscanf(read_file("/etc/maxusers"), "%d %s", max, tmp);
+    sscanf(read_file("/etc/maxusers.ever"), "%d %s", rekord, tmp);
+
+    t=time()-last_reboot_time();
+    up="";
+    if(t >= 86400)
+      up += sprintf("%dT", t/86400);
+    if(t >= 3600)
+      up += sprintf("%dh", (t=t%86400)/3600);
+    if(t > 60)
+      up += sprintf("%dm", (t=t%3600)/60);
+    up += sprintf("%ds", t%60);
+
+    ret = sprintf("%.1f%%/15 %.1f%%/1 %s %d:%d:%d E:%d T:%d",
+                  lag[1], lag[2], up, sizeof(users()), max, rekord, 
+                  sizeof(channels), CountUser(channels));
+  } else return;
+
+  call_out(#'send/*'*/, 2, CMNAME, this_object(), ret);
+}
+
+// setup() -- set up a channel and register it
+//            arguments are stored in the following order:
+//            ({ channel name,
+//               receive level, send level,
+//               flags,
+//               description,
+//               master obj
+//            })
+private void setup(mixed c)
+{
+  closure cl;
+  object m;
+  string d;
+  d = "- Keine Beschreibung -";
+  m = this_object();
+  if(sizeof(c) && sizeof(c[0]) > 1 && c[0][0] == '\\')
+    c[0] = c[0][1..];
+
+  switch(sizeof(c))
+  {
+  case 6:
+    if(!stringp(c[5]) || !sizeof(c[5]) 
+        || (catch(m=load_object(c[5]);publish) || !objectp(m) ))
+      m = this_object();
+  case 5: d = stringp(c[4]) || closurep(c[4]) ? c[4] : d;
+  case 4: admin[c[0], FLAG] = to_int(c[3]);
+  case 3: admin[c[0], SEND] = to_int(c[2]);
+  case 2: admin[c[0], RECV] = to_int(c[1]);
+    break;
+  case 0:
+  default:
+    return;
+  }
+  switch(new(c[0], m, d))
+  {
+  case E_ACCESS_DENIED:
+    log_file("CHANNEL", sprintf("[%s] %s: %O: error, access denied\n",
+                           dtime(time()), c[0], m));
+    break;
+  default:
+    break;
+  }
+  return;
+}
+
+void initialize()
+{
+  mixed tmp;
+  tmp = read_file(object_name(this_object())+".init");
+  tmp = regexp(old_explode(tmp, "\n"), "^[^#]");
+  tmp = map(tmp, #'regexplode/*'*/, "[^:][^:]*$|[ \\t]*:[ \\t]*");
+  tmp = map(tmp, #'regexp/*'*/, "^[^: \\t]");
+  map(tmp, #'setup/*'*/);
+}
+
+// BEGIN OF THE CHANNEL MASTER IMPLEMENTATION
+
+void create()
+{
+  seteuid(getuid());
+  restore_object(CHANNEL_SAVE);
+  if(!channelC) channelC = ([]);
+  if(!channelB) channelB = ([]);
+  channels = ([]);
+
+  /* Die Channel-History wird nicht nur lokal sondern auch noch im Memory 
+     gespeichert, dadurch bleibt sie auch ueber ein Reload erhalten. 
+     Der folgende Code versucht, den Zeiger aus dem Memory zu holen. Falls
+     das nicht moeglich ist, wird ein neuer erzeugt und gegebenenfalls im
+     Memory abgelegt. */
+
+  // Hab ich die noetigen Rechte im Memory?
+  if (call_other(MEMORY,"HaveRights")) {
+    // Objektpointer laden
+    channelH = (mixed) call_other(MEMORY,"Load","History");
+
+    // Wenns nich geklappt hat, hat der Memory noch keinen Zeiger, dann
+    if (!mappingp(channelH)){
+      // Zeiger erzeugen
+      channelH = ([]);
+      // und in den Memory schreiben
+      call_other(MEMORY,"Save","History",channelH);
+    }
+  } else {
+    // Keine Rechte im Memory, dann wird mit einem lokalen Zeiger gearbeitet.
+    channelH = ([]);
+  }
+
+  stats = (["time": time(),
+            "boot": capitalize(getuid(previous_object())||"<Unbekannt>")]);
+  new(CMNAME, this_object(), "Zentrale Informationen zu den Ebenen");
+  initialize();
+  map_objects(efun::users(), "RegisterChannels");
+  this_object()->send(CMNAME, this_object(),
+                      sprintf("%d Ebenen mit %d Teilnehmern initialisiert.",
+                              sizeof(channels),
+                              CountUser(channels)));
+}
+
+// reset() and cache_to() - Cache Timeout, remove timed out cached channels
+// SEE: new, send
+private int cache_to(string key, mapping m, int t)
+{
+  if(!pointerp(m[key]) || m[key][2] + 43200 > t) return 1;
+  return(0);
+}
+
+varargs void reset(int nonstd)
+{
+  channelC = filter_indices(channelC, #'cache_to/*'*/, channelC, time());
+  if (save_me_soon)
+  {
+    save_me_soon=0;
+    save_object(CHANNEL_SAVE);
+  }
+}
+
+// name() - define the name of this object.
+string name() { return CMNAME; }
+string Name() { return CMNAME; }
+
+// access() - check access by looking for the right argument types and
+//            calling access closures respectively
+// SEE: new, join, leave, send, list, users
+// Note: <pl> is usually an object, only the master supplies a string during
+//       runtime error handling.
+varargs private int access(mixed ch, mixed pl, string cmd, string txt)
+{
+  mixed co, m;
+
+  if(!stringp(ch) || !sizeof(ch = lower_case(ch)) || !channels[ch])
+    return 0;
+  if(!channels[ch][I_ACCESS]||!previous_object(1)||!extern_call()||
+     previous_object(1)==this_object()||
+     (stringp(channels[ch][I_MASTER])&&
+      previous_object(1)==find_object(channels[ch][I_MASTER]))||
+     getuid(previous_object(1)) == ROOTID)
+    return 2;
+  if(!objectp(pl) || 
+     ((previous_object(1)!=pl) &&(previous_object(1)!=this_object()))) 
+     return 0;
+   if(pointerp(channelB[getuid(pl)]) &&
+     member(channelB[getuid(pl)], cmd) != -1)
+    return 0;
+   if(stringp(channels[ch][I_MASTER]) &&
+     (!(m = find_object(channels[ch][I_MASTER])) ||
+      (!to_object(channels[ch][I_ACCESS]) ||
+       get_type_info(channels[ch][I_ACCESS])[1])))
+  {
+    string err;
+    if(!objectp(m)) err = catch(load_object(channels[ch][I_MASTER]);publish);
+    if(!err &&
+       ((!to_object(channels[ch][I_ACCESS]) ||
+         get_type_info(channels[ch][I_ACCESS])[1]) &&
+        !closurep(channels[ch][I_ACCESS] =
+                  symbol_function("check",
+                                  find_object(channels[ch][I_MASTER])))))
+    {
+      log_file("CHANNEL", sprintf("[%s] %O -> %O\n",
+                                  dtime(time()), channels[ch][I_MASTER],
+                                  err));
+      channels = m_copy_delete(channels, ch);
+      return 0;
+    }
+    this_object()->join(ch, find_object(channels[ch][I_MASTER]));
+  }
+  if(closurep(channels[ch][I_ACCESS]))
+      return funcall(channels[ch][I_ACCESS],
+                     channels[ch][I_NAME], pl, cmd, &txt);
+}
+
+// new() - create a new channel
+//         a channel with name 'ch' is created, the player is the master
+//         info may contain a string which describes the channel or a closure
+//         to display up-to-date information, check may contain a closure
+//         called when a join/leave/send/list/users message is received
+// SEE: access
+
+#define IGNORE  "^/xx"
+
+varargs int new(string ch, object pl, mixed info)
+{
+  mixed pls;
+
+  if(!objectp(pl) || !stringp(ch) || !sizeof(ch) || channels[lower_case(ch)] ||
+     (pl == this_object() && extern_call()) ||
+     sizeof(channels) >= MAX_CHANNELS ||
+     sizeof(regexp(({ object_name(pl) }), IGNORE)) ||
+     (pointerp(channelB[getuid(pl)]) &&
+      member(channelB[getuid(pl)], C_NEW) != -1))
+    return E_ACCESS_DENIED;
+
+  if(!info) {
+    if(channelC[lower_case(ch)]) {
+      ch = channelC[lower_case(ch)][0];
+      info = channelC[lower_case(ch)][1];
+    }
+    else return E_ACCESS_DENIED;
+  }
+  else channelC[lower_case(ch)] = ({ ch, info, time() });
+
+  pls = ({ pl });
+
+  channels[lower_case(ch)] = ({ pls,
+                                symbol_function("check", pl) ||
+                                #'check/*'*/, info,
+                                (!living(pl) &&
+                                 !clonep(pl) &&
+                                 pl != this_object()
+                                 ? object_name(pl)
+                                 : pl),
+                                 ch,
+                             });
+
+  // ChannelH fuer einen Kanal nur dann initialisieren, wenn es sie noch nich gibt.
+  if ( !pointerp(channelH[lower_case(ch)]) )
+         channelH[lower_case(ch)] = ({});
+
+  if(pl != this_object())
+    log_file("CHANNEL.new", sprintf("[%s] %O: %O %O\n",
+                                    dtime(time()), ch, pl, info));
+  if(!pl->QueryProp(P_INVIS))
+    this_object()->send(CMNAME, pl,
+                        "laesst die Ebene '"+ch+"' entstehen.", MSG_EMOTE);
+  stats["new"]++;
+ 
+  save_me_soon=1;
+  return(0);
+}
+
+// join() - join a channel
+//          this function checks whether the player 'pl' is allowed to join
+//          the channel 'ch' and add if successful, one cannot join a channel
+//          twice
+// SEE: leave, access
+int join(string ch, object pl)
+{
+  if(!funcall(#'access,&ch, pl, C_JOIN)) return E_ACCESS_DENIED;
+  if(member(channels[ch][I_MEMBER], pl) != -1) return E_ALREADY_JOINED;
+  channels[ch][I_MEMBER] += ({ pl });
+  return(0);
+}
+
+// leave() - leave a channel
+//           the access check in this function is just there for completeness
+//           one should always be allowed to leave a channel.
+//           if there are no players left on the channel it will vanish, unless
+//           its master is this object.
+// SEE: join, access
+int leave(string ch, object pl)
+{
+  int pos;
+  if(!funcall(#'access,&ch, pl, C_LEAVE)) return E_ACCESS_DENIED;
+  channels[ch][I_MEMBER] -= ({0}); // kaputte Objekte erstmal raus
+  if((pos = member(channels[ch][I_MEMBER], pl)) == -1) return E_NOT_MEMBER;
+  if(pl == channels[ch][I_MASTER] && sizeof(channels[ch][I_MEMBER]) > 1)
+  {
+    channels[ch][I_MASTER] = channels[ch][I_MEMBER][1];
+    if(!pl->QueryProp(P_INVIS))
+      this_object()->send(ch, pl, "uebergibt die Ebene an "
+                          +channels[ch][I_MASTER]->name(WEN)+".", MSG_EMOTE);
+  }
+  channels[ch][I_MEMBER][pos..pos] = ({ });
+
+
+  if(!sizeof(channels[ch][I_MEMBER]) &&
+     !stringp(channels[ch][I_MASTER]))
+  {
+    // delete the channel that has no members
+    if(!pl->QueryProp(P_INVIS))
+      this_object()->send(CMNAME, pl,
+                          "verlaesst als "
+                          +(pl->QueryProp(P_GENDER) == 1 ? "Letzter" :
+                            "Letzte")
+                          +" die Ebene '"
+                          +channels[ch][I_NAME]
+                          +"', worauf diese sich in einem Blitz oktarinen "
+                          +"Lichts aufloest.", MSG_EMOTE);
+    channelC[lower_case(ch)] = ({ channels[ch][I_NAME],
+                                  channels[ch][I_INFO], time() });
+    m_delete(channels, lower_case(ch));
+
+    // Wird ein Channel entfernt, wird auch seine History geloescht
+    channelH = m_copy_delete(channelH, lower_case(ch));
+
+    stats["dispose"]++;
+    save_me_soon=1;
+  }
+  return(0);
+}
+
+// send() - send a message to all recipients of the specified channel 'ch'
+//          checks if 'pl' is allowed to send a message and sends if success-
+//          ful a message with type 'type'
+//          'pl' must be an object, the message is attributed to it. e.g.
+//            ignore checks use it. It can be != previous_object()
+// SEE: access, ch.h
+varargs int send(string ch, object pl, string msg, int type)
+{
+  int a;
+
+  if(!(a = funcall(#'access,&ch, pl, C_SEND, &msg))) return E_ACCESS_DENIED;
+  if(a < 2 && member(channels[ch][I_MEMBER], pl) == -1) return E_NOT_MEMBER;
+  if(!msg || !stringp(msg) || !sizeof(msg)) return E_EMPTY_MESSAGE;
+  map_objects(channels[ch][I_MEMBER],
+              "ChannelMessage", ({ channels[ch][I_NAME], pl, msg, type }));
+  if(sizeof(channelH[ch]) > MAX_HIST_SIZE)
+    channelH[ch] = channelH[ch][1..];
+  channelH[ch] += ({ ({ channels[ch][I_NAME],
+                        (stringp(pl)
+                         ? pl
+                         : (pl->QueryProp(P_INVIS)
+                            ? "/("+capitalize(getuid(pl))+")$" : "")
+                         + (pl->Name(WER, 2) || "<Unbekannt>")),
+                         msg+" <"+strftime("%a, %H:%M:%S")+">\n",
+                         type }) });
+  return(0);
+}
+
+// list() - list all channels, that are at least receivable by 'pl'
+//          returns a mapping,
+// SEE: access, channels
+private void clean(string n, mixed a) { a[0] -= ({ 0 }); }
+mixed list(object pl)
+{
+  mapping chs;
+  
+  chs = filter_indices(channels, #'access/*'*/, pl, C_LIST);
+  walk_mapping(chs, #'clean/*'*/);
+  if(!sizeof(chs)) return E_ACCESS_DENIED;
+  return deep_copy(chs);
+}
+
+// find() - find a channel by its name (may be partial)
+//          returns an array for multiple results and 0 for no matching name
+// SEE: access
+mixed find(string ch, object pl)
+{
+  mixed chs, s;
+  if(stringp(ch)) ch = lower_case(ch);
+  if( !sizeof(regexp(({ch}),"^[<>a-z0-9#-]*$")) ) return 0; // RUM
+  if(!sizeof(chs = regexp(m_indices(channels), "^"+ch+"$")))
+    chs = regexp(m_indices(channels), "^"+ch);
+  if((s = sizeof(chs)) > 1)
+    if(sizeof(chs = filter(chs, #'access/*'*/, pl, C_FIND)) == 1)
+      return channels[chs[0]][I_NAME];
+    else return chs;
+  return ((s && funcall(#'access,chs[0], pl, C_FIND)) ? channels[chs[0]][I_NAME] : 0);
+}
+
+// history() - get the history of a channel
+// SEE: access
+mixed history(string ch, object pl)
+{
+  if(!funcall(#'access,&ch, pl, C_JOIN))
+    return E_ACCESS_DENIED;
+  return deep_copy(channelH[ch]);
+}
+
+// remove - remove a channel (wird aus der Shell aufgerufen)
+// SEE: new
+mixed remove(string ch, object pl)
+{
+  mixed members;
+
+  if(previous_object() != this_object())
+    if(!stringp(ch) ||
+       pl != this_player() || this_player() != this_interactive() ||
+       this_interactive() != previous_object() ||
+       !IS_ARCH(this_interactive()))
+      return E_ACCESS_DENIED;
+
+  if(channels[lower_case(ch)]) {
+    channels[lower_case(ch)][I_MEMBER] =
+        filter_objects(channels[lower_case(ch)][I_MEMBER],
+                       "QueryProp", P_CHANNELS);
+    map(channels[lower_case(ch)][I_MEMBER],
+        lambda(({'u/*'*/}), ({#'call_other/*'*/, 'u, /*'*/
+                                   "SetProp", P_CHANNELS,
+                                   ({#'-/*'*/,
+                                          ({#'call_other/*'*/, 'u, /*'*/
+                                                 "QueryProp", P_CHANNELS}),
+                                          '({ lower_case(ch) })/*'*/,})
+                                   })));
+    channels = m_copy_delete(channels, lower_case(ch));
+
+    // Wird ein Channel entfernt, wird auch seine History geloescht
+    if( pointerp(channelH[lower_case(ch)] ))
+     channelH = m_copy_delete(channelH, lower_case(ch));
+
+    stats["dispose"]++;
+  }
+  if(!channelC[lower_case(ch)])
+    return E_ACCESS_DENIED;
+  channelC = m_copy_delete(channelC, lower_case(ch));
+  save_me_soon=1;
+  return(0);
+}
+
+// Wird aus der Shell aufgerufen 
+mixed clear_history(string ch)
+{
+  mixed members;
+  // Sicherheitsabfragen
+  if(previous_object() != this_object())
+    if(!stringp(ch) ||
+       this_player() != this_interactive() ||
+       this_interactive() != previous_object() ||
+       !IS_ARCH(this_interactive()))
+      return E_ACCESS_DENIED;
+
+  // History des Channels loeschen
+  if( pointerp(channelH[lower_case(ch)] ))
+    channelH[lower_case(ch)]=({});
+
+  return 0;
+}
