// 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 <regexp.h>

#include <properties.h>
#include <config.h>
#include <language.h>

#define NEED_PROTOTYPES
#include "channel.h"

#define CHANNEL_SAVE  "/p/daemon/save/channeld"
#define MEMORY        "/secure/memory"
#define MAX_HIST_SIZE 200
#define MAX_CHANNELS  90
// Default-Zeit (in Sekunden), die eine Ebene und ihr History inaktiv sein darf,
// bevor sie expired wird. Das reduziert sich jedoch, falls es zuviele
// inaktive Ebenen gibt. Entspricht 30 Tagen.
#define INACTIVE_EXPIRE 2592000
// Aber eine Ebene darf min. solange inaktiv sein, bevor sie geloescht wird
#define MIN_INACTIVE_LIFETIME 3600
// max. Anzahl der inaktiven Ebenen. Wenn die Haelfte davon ueberschritten
// wird, wird mit zunehmend kleinerem CHANNEL_EXPIRE gearbeitet.
#define MAX_INACTIVE_CHANNELS 500
#define CMDS          ({C_FIND, C_LIST, C_JOIN, C_LEAVE, C_SEND, C_NEW})


// Datenstrukturen fuer die Ebenen.
// Basisdaten, welche auch inaktive Ebenen in channelC haben
struct channel_base_s {
  string          name;    // readable channelname, case-sensitive
  string|closure  desc;    // stat. oder dyn. Beschreibung
  string          creator; // Ersteller der Ebene (Objektname), Besitzer
  int             flags;   // Flags, die bestimmtes Verhalten steuern.
};

// Basisdaten + die von aktiven Ebenen
struct channel_s (channel_base_s) {
  object  supervisor;      // aktueller Supervisor der Ebene
  closure access_cl;       // Closure fuer Zugriffsrechtepruefung
  object  *members;        // Zuhoerer der Ebene
};

/* Ebenenliste und die zugehoerigen Daten in struct (<channel>).
   channels = ([string channelname : (<channel_s>) ])
// HINWEIS: Bitte beachten, dass channels immer nur so manipuliert werden
// darf, dass keine Kopie erstellt wird, weder direkt noch implizit. Die
// History wird via Referenz in /secure/memory hinterlegt, damit sie einen
// Reload des Channeld ueberlebt. Das funktioniert aber nur, wenn die Mapping-
// Referenz in Memory und Channeld dieselbe ist.
 */
private nosave mapping channels;

/* Ebenenhistory
   mapping channelH = ([ string channelname : ({ ({string channelname,
                                                   string sender,
                                                   string msg,
                                                   int msg_type}) }) ]) */
// channelH wird in create() geeignet initialisiert
// HINWEIS: Bitte beachten, dass channelH immer nur so manipuliert werden
// darf, dass keine Kopie erstellt wird, weder direkt noch implizit. Die
// History wird via Referenz in /secure/memory hinterlegt, damit sie einen
// Reload des Channeld ueberlebt. Das funktioniert aber nur, wenn die Mapping-
// Referenz in Memory und Channeld dieselbe ist.
private nosave mapping channelH;

/* Ebenen-Cache, enthaelt Daten zu inaktiven Ebenen.
   mapping channelC = ([ string channelname : (<channel_base_s>);
                                              int time() ])
   Der Zeitstempel ist die letzte Aenderung, d.h. in der Regel des Ablegens in
   channelC.
 */
private mapping channelC = ([:2]);

/* Liste von Spielern, fuer die ein Bann besteht, mit den verbotenen Kommandos
   mapping channelB = ([ string playername : string* banned_command ]) */
private mapping channelB = ([]);

/* Timeout-Liste der Datenabfrage-Kommandos; die Timestamps werden verwendet,
   um sicherzustellen, dass jedes Kommando max. 1x pro Minute benutzt werden
   kann.

   mapping Tcmd = ([ "lag": int timestamp,
                     "uptime":  int timestamp,
                     "statistik":  int timestamp]) */
private mapping Tcmd = ([]);

/* Globale channeld-Stats (Startzeit, geladen von, Anzahl erstellte und
   zerstoerte Ebenen.
   mapping stats = ([ "time" : int object_time(),
                      "boot" : string getuid(previous_object()),
                      "new"  : int total_channels_created,
                      "disposed" : int total_channels_removed ]) */
// stats wird in create() geeignet initialisiert
private nosave mapping stats;

/* Flag, das anzeigt, dass Daten veraendert wurden und beim naechsten
   Speicherevent das Savefile geschrieben werden soll.
   Wird auf 0 oder 1 gesetzt. */
private nosave int save_me_soon;

// Private Prototypen
public int join(string chname, object joining);
private int assert_supervisor(struct channel_s ch);

/* CountUsers() zaehlt die Anzahl Abonnenten aller Ebenen. */
// TODO: Mapping- und Arrayvarianten bzgl. der Effizienz vergleichen
private int CountUsers()
{
  object* userlist = ({});
  foreach(string ch_name, struct channel_s ch : channels)
  {
    userlist += ch.members;
  }
  // Das Mapping dient dazu, dass jeder Eintrag nur einmal vorkommt.
  return sizeof(mkmapping(userlist));
}

// Ist das Objekt <sender> Abonnent der Ebene <ch>?
private int IsChannelMember(struct channel_s ch, object sender)
{
  return (member(ch.members, sender) != -1);
}

// Besteht fuer das Objekt <ob> ein Bann fuer die Ebenenfunktion <command>?
private int IsBanned(string|object ob, string command)
{
  if (objectp(ob))
    ob = getuid(ob);
  return(pointerp(channelB[ob]) &&
         member(channelB[ob], command) != -1);
}

private void banned(string plname, string* cmds, string res)
{
  res += sprintf("%s [%s], ", capitalize(plname), implode(cmds, ","));
}

#define TIMEOUT       (time() - 60)

// IsNotBlocked(): prueft fuer die Liste der uebergebenen Kommandos, ob
// die Zeitsperre fuer alle abgelaufen ist und sie ausgefuehrt werden duerfen.
// Dabei gilt jedes Kommando, dessen letzte Nutzung laenger als 60 s
// zurueckliegt, als "nicht gesperrt".
private int IsNotBlocked(string* cmd)
{
  string* res = filter(cmd, function int (string str) {
                    return (Tcmd[str] < TIMEOUT);
                  });
  // Wenn das Ergebnis-Array genauso gross ist wie das Eingabe-Array, dann
  // sind alle Kommandos frei. Sie werden direkt gesperrt; return 1
  // signalisiert dem Aufrufer, dass das Kommando ausgefuehrt werden darf.
  if (sizeof(res) == sizeof(cmd)) {
    foreach(string str : cmd) {
      Tcmd[str] = time();
    }
    return 1;
  }
  return 0;
}

// Prueft, ob der gesendete Befehl <cmd> als gueltiges Kommando <check>
// zugelassen wird. Anforderungen:
// 1) <cmd> muss Teilstring von <check> sein
// 2) <cmd> muss am Anfang von <check> stehen
// 3) <cmd> darf nicht laenger sein als <check>
// 4) die Nutzung von <cmd> darf nur einmal pro Minute erfolgen
// Beispiel: check = "statistik", cmd = "stat" ist gueltig, nicht aber
// cmd = "statistiker" oder cmd = "tist"
// Wenn die Syntax zugelassen wird, wird anschliessend geprueft
private int IsValidChannelCommand(string cmd, string check) {
  // Syntaxcheck (prueft Bedingungen 1 bis 3).
  if ( strstr(check, cmd)==0 && sizeof(cmd) <= sizeof(check) ) {
    string* cmd_to_check;
    // Beim Kombi-Kommando "lust" muessen alle 3 Befehle gecheckt werden.
    // Der Einfachheit halber werden auch Einzelkommandos als Array ueber-
    // geben.
    if ( cmd == "lust" )
      cmd_to_check = ({"lag", "statistik", "uptime"});
    else
      cmd_to_check = ({cmd});
    // Prueft die Zeitsperre (Bedingung 4).
    return (IsNotBlocked(cmd_to_check));
  }
  return 0;
}

#define CH_NAME   0
#define CH_SENDER 1
#define CH_MSG    2
#define CH_MSG_TYPE 3
// Gibt die Channelmeldungen fuer die Kommandos up, stat, lag und bann des
// <MasteR>-Channels aus. Auszugebende Informationen werden in <ret> gesammelt
// und dieses per Callout an send() uebergeben.
// Argument: ({channel.name, object pl, string msg, int type})
// Funktion muss public sein, auch wenn der erste Check im Code das Gegenteil
// nahezulegen scheint, weil sie von send() per call_other() gerufen wird,
// was aber bei einer private oder protected Funktion nicht moeglich waere.
public void ChannelMessage(<string|object|int>* msg)
{
  // Wir reagieren nur auf Meldungen, die wir uns selbst geschickt haben,
  // aber nur dann, wenn sie auf der Ebene <MasteR> eingegangen sind.
  if (msg[CH_SENDER] == this_object() || !stringp(msg[CH_MSG]) ||
      msg[CH_NAME] != CMNAME || previous_object() != this_object())
    return;

  float* lag;
  int max, rekord;
  string ret;
  string mesg = msg[CH_MSG];

  if (IsValidChannelCommand(mesg, "hilfe"))
  {
    ret = "Folgende Kommandos gibt es: hilfe, lag, uptime, statistik, lust, "
      "bann. Die Kommandos koennen abgekuerzt werden.";
  }
  else if (IsValidChannelCommand(mesg, "lag"))
  {
    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]);
    // Erster Callout wird hier schon abgesetzt, um sicherzustellen, dass
    // die Meldung in zwei Zeilen auf der Ebene erscheint.
    call_out(#'send, 2, CMNAME, this_object(), ret);
    ret = query_load_average();
  }
  else if (IsValidChannelCommand(mesg, "uptime"))
  {
    if (file_size("/etc/maxusers") > 0 && file_size("/etc/maxusers.ever"))
    {
      sscanf(read_file("/etc/maxusers"), "%d %~s", max);
      sscanf(read_file("/etc/maxusers.ever"), "%d %~s", rekord);
      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
    {
      ret = "Diese Information liegt nicht vor.";
    }
  }
  else if (IsValidChannelCommand(mesg, "statistik"))
  {
    ret = sprintf(
        "Im Moment sind insgesamt %d Ebenen mit %d Teilnehmern aktiv. "
        "Der %s wurde das letzte mal am %s von %s neu gestartet. "
        "Seitdem wurden %d Ebenen neu erzeugt und %d zerstoert.",
        sizeof(channels), CountUsers(), CMNAME,
        dtime(stats["time"]), stats["boot"], stats["new"], stats["dispose"]);
  }
  // Ebenenaktion beginnt mit "bann"?
  else if (strstr(mesg, "bann")==0)
  {
    string pl, cmd;

    if (mesg == "bann")
    {
      if (sizeof(channelB))
      {
        ret = "Fuer folgende Spieler besteht ein Bann: ";
        // Zwischenspeicher fuer die Einzeleintraege, um diese spaeter mit
        // CountUp() in eine saubere Aufzaehlung umwandeln zu koennen.
        string* banlist = ({});
        foreach(string plname, string* banned_cmds : channelB) {
          banlist += ({ sprintf("%s [%s]",
            capitalize(plname), implode(banned_cmds, ", "))});
        }
        ret = CountUp(banlist);
      }
      else
      {
        ret = "Zur Zeit ist kein Bann aktiv.";
      }
    }
    else
    {
      if (sscanf(mesg, "bann %s %s", pl, cmd) == 2 &&
          IS_DEPUTY(msg[CH_SENDER]))
      {
        pl = lower_case(pl);
        cmd = lower_case(cmd);

        if (member(CMDS, cmd) != -1)
        {
          // Kein Eintrag fuer <pl> in der Bannliste vorhanden, dann anlegen;
          // ist der Eintrag kein Array, ist ohnehin was faul, dann wird
          // ueberschrieben.
          if (!pointerp(channelB[pl]))
            m_add(channelB, pl, ({}));

          if (IsBanned(pl, cmd))
            channelB[pl] -= ({ cmd });
          else
            channelB[pl] += ({ cmd });

          ret = "Fuer '" + capitalize(pl) + "' besteht " +
                (sizeof(channelB[pl])
                  ? "folgender Bann: " + CountUp(channelB[pl]) + "."
                  : "kein Bann mehr.");

          // Liste der gebannten Kommandos leer? Dann <pl> komplett austragen.
          if (!sizeof(channelB[pl]))
            m_delete(channelB, pl);

          save_me_soon = 1;
        }
        else
        {
          ret = "Das Kommando '" + cmd + "' ist unbekannt. "
                "Erlaubte Kommandos: "+ CountUp(CMDS);
        }
      }
      else
      {
        if (IS_ARCH(msg[CH_SENDER]))
          ret = "Syntax: bann <name> <kommando>";
      }
    }
  }
  else if (IsValidChannelCommand(mesg, "lust"))
  {
    lag = "/p/daemon/lag-o-daemon"->read_lag_data();
    if (file_size("/etc/maxusers") > 0 && file_size("/etc/maxusers.ever"))
    {
      sscanf(read_file("/etc/maxusers"), "%d %~2s", max);
      sscanf(read_file("/etc/maxusers.ever"), "%d %~s", rekord);
    }

    int t = time() - last_reboot_time();

    // TODO: fuer solche Anwendungen ein separates Inheritfile bauen, da
    // die Funktionalitaet oefter benoetigt wird als nur hier.
    string up = "";
    if (t >= 86400)
      up += sprintf("%dT", t / 86400);

    t %= 86400;
    if (t >= 3600)
      up += sprintf("%dh", t / 3600);

    t %= 3600;
    if (t > 60)
      up += sprintf("%dm", t / 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), CountUsers());
  }
  else
  {
    return;
  }

  // Nur die Ausgabe starten, wenn ein Ausgabestring vorliegt. Es kann
  // vorkommen, dass weiter oben keiner zugewiesen wird, weil die Bedingungen
  // nicht erfuellt sind.
  if (stringp(ret) && sizeof(ret))
    call_out(#'send, 2, CMNAME, this_object(), ret);
}

// setup() -- set up a channel and register it
//            arguments are stored in the following order:
//            string* chinfo = ({ channel_name, receive_level, send_level,
//                                adminflags, channelflags, description,supervisor })
private void setup(string* chinfo)
{
  string desc = "- Keine Beschreibung -";
  object supervisor;
  int chflags;

  if (sizeof(chinfo) && sizeof(chinfo[0]) > 1 && chinfo[0][0] == '\\')
    chinfo[0] = chinfo[0][1..];

  // Wenn der channeld nur neugeladen wurde, aber das Mud nicht neugestartet,
  // sind alle Ebenen noch da, weil sie im MEMORY liegen. D.h. ist die Ebene
  // noch bekannt, muss nichts gemacht werden.
  if (member(channels, lower_case(chinfo[0])))
    return;

  // Nur die Angabe des SV (Index 6) im initfile ist optional, alle Elemente
  // davor muessen da sein.
  if (sizeof(chinfo) < 6)
    return;
  // Bei genug Elementen schauen, ob der SV ladbar ist.
  if (sizeof(chinfo) >= 7)
  {
    if (stringp(chinfo[6]) && sizeof(chinfo[6]))
      catch(supervisor = load_object(chinfo[6]); publish);
  }
  // Aber falls kein SV angegeben wird oder das Objekt nicht ladbar war, wird
  // ein Default-SV genutzt.
  if (!supervisor)
    supervisor = load_object(DEFAULTSV);

  desc = chinfo[5];
  chflags = to_int(chinfo[4]);

  if (new(chinfo[0], supervisor, desc, chflags) == E_ACCESS_DENIED)
  {
    log_file("CHANNEL", sprintf("[%s] %s: %O: error, access denied\n",
      dtime(time()), chinfo[0], supervisor));
  }
  return;
}

private void create_default_channels()
{
  string ch_list;
#if !defined(__TESTMUD__) && MUDNAME=="MorgenGrauen"
  ch_list = read_file(object_name(this_object()) + ".init");
#else
  ch_list = read_file(object_name(this_object()) + ".init.testmud");
#endif

  if (!stringp(ch_list))
    return;

  // Channeldatensaetze erzeugen, dazu zuerst Datenfile in Zeilen zerlegen
  // "Allgemein:   0: 0: 0:Allgemeine Unterhaltungsebene"
  // Danach drueberlaufen und in Einzelfelder splitten, dabei gleich die
  // Trennzeichen (Doppelpunkt, Tab und Space) rausfiltern.
  foreach(string ch : old_explode(ch_list, "\n"))
  {
    if (ch[0]=='#')
      continue;
    setup( regexplode(ch, ":[ \t]*", RE_OMIT_DELIM) );
  }
}

// BEGIN OF THE CHANNEL MASTER IMPLEMENTATION
protected void create()
{
  int do_complete_init;

  seteuid(getuid());
  restore_object(CHANNEL_SAVE);

  // Altes channelC aus Savefiles konvertieren...
  if (widthof(channelC) == 1)
  {
    mapping new = m_allocate(sizeof(channelC), 2);
    foreach(string chname, mixed arr: channelC)
    {
      struct channel_base_s ch = (<channel_base_s> name: arr[0],
          desc: arr[1]);
      // die anderen beiden Werte bleiben 0
      m_add(new, chname, ch, arr[2]);
    }
    channelC = new;
  }

  /* Die aktiven Ebenen und 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 auf die alten Mappings aus dem
     Memory zu holen. Falls das nicht moeglich ist, wird ein neuer erzeugt und
     gegebenenfalls fuer spaeter im Memory abgelegt. */
  // Hab ich die noetigen Rechte im Memory?
  if (MEMORY->HaveRights())
  {
    // channelH und channels laden
    channels = ({mapping}) MEMORY->Load("Channels");
    // Wenns nich geklappt hat, hat der Memory noch keinen Zeiger
    if (!mappingp(channels))
    {
      // Mapping erzeugen
      channels = ([]);
      // und Zeiger auf das Mapping in den Memory schreiben
      MEMORY->Save("Channels", channels);
      do_complete_init = 1;
    }
    // Und das gleiche fuer die History
    channelH = ({mapping}) MEMORY->Load("History");
    // Wenns nich geklappt hat, hat der Memory noch keinen Zeiger
    if (!mappingp(channelH))
    {
      // Mapping erzeugen
      channelH = ([]);
      // und Zeiger auf das Mapping in den Memory schreiben
      MEMORY->Save("History", channelH);
      // In diesem Fall muessen die Ebenenhistories auch erzeugt werden, falls
      // es aktive Ebenen gibt.
      foreach(string chname: channels)
        channelH[chname] = ({});
    }
  }
  else
  {
    // Keine Rechte im Memory, dann liegt das nur lokal und ist bei
    // remove/destruct weg.
    channelH = ([]);
    channels = ([]);
    do_complete_init = 1;
  }

  stats = (["time": time(),
            "boot": capitalize(getuid(previous_object()) || "<Unbekannt>")]);

  // Das muss auch laufen, wenn wir die alten Ebenen aus dem MEMORY bekommen
  // haben, weil es ja neue Ebenen geben koennte, die dann erstellt werden
  // muessen (verschwundete werden aber nicht aufgeraeumt!)
  create_default_channels();
  // Es muss fuer alle existierenden Ebenen die access_cl neu erstellt
  // werden, die durch Neuladen des channeld verloren gingen, auch wenn die
  // Ebenen im MEMORY lagen.
  foreach(string chname, struct channel_s ch : channels)
  {
    if (ch.access_cl || !assert_supervisor(ch))
      continue;
    ch.access_cl = symbol_function("ch_check_access", ch.supervisor);
  }

  // <MasteR>-Ebene betreten, damit der channeld auf seine Kommandos auf
  // dieser Ebene reagieren kann.
  this_object()->join(CMNAME, this_object());

  // Wenn wir die alten Ebenen nicht aus MEMORY hatten, gibts noch Dinge zu
  // erledigen.
  if (do_complete_init)
  {
    // Spieler muessen die Ebenen abonnieren. NPC und andere Objekte haben
    // leider Pech gehabt, falls das nicht das erste Laden nach Reboot war.
    users()->RegisterChannels();
    // Die Zugriffskontrolle auf die Ebenen wird von der Funktion access()
    // erledigt. Weil sowohl externe Aufrufe aus dem Spielerobjekt, als auch
    // interne Aufrufe aus diesem Objekt vorkommen koennen, wird hier ein
    // explizites call_other() auf this_object() gemacht, damit der
    // Caller-Stack bei dem internen Aufruf denselben Aufbau hat wie bei
    // einem externen.
    this_object()->send(CMNAME, this_object(),
      sprintf("%d Ebenen mit %d Teilnehmern initialisiert.",
        sizeof(channels),
        CountUsers()));
  }
  else
  {
    this_object()->send(CMNAME, this_object(),
      sprintf(CMNAME " neugeladen. %d Ebenen mit %d Teilnehmern sind aktiv.",
        sizeof(channels),
        CountUsers()));
  }
}

varargs void reset()
{
  // Im Durchschnitt 1 Tag: 21.6h + random(4.8h), d.h. naechster reset ist
  // zwischen 21.6h und 26.4h von jetzt.
  set_next_reset(77760 + random(17280));

  // inaktive Ebenen bereinigen 
  int timeout = INACTIVE_EXPIRE;
  // Wir behalten immer ungefaehr die Haelfte von MAX_INACTIVE_CHANNELS
  // inaktive Ebenen. In  jeder Iteration wird das erlaubte Timeout reduziert,
  // bis genug inaktive Ebenen weg sind, aber MIN_INACTIVE_LIFETIME bleiben
  // Ebenen min. inaktiv bestehen.
  while (sizeof(channelC) > MAX_INACTIVE_CHANNELS/2
         && timeout > MIN_INACTIVE_LIFETIME)
  {
    channelC = filter(channelC,
      function int (string ch_name, mixed values)
      {
        int ts = values[1];
        if (ts + timeout > time())
          return 1;
        // Ebenendaten koennen weg, inkl. History, die also auch loeschen
        m_delete(channelH, ch_name);
        return 0;
      });
    // timeout halbieren und neu versuchen wenn noetig.
    timeout /= 2;
  }
  // achja, speichern sollten wir uns ggf. auch noch.
  if (save_me_soon)
  {
    save_me_soon = 0;
    save_object(CHANNEL_SAVE);
  }
}

varargs int remove(int silent)
{
  if (save_me_soon)
  {
    save_me_soon = 0;
    save_object(CHANNEL_SAVE);
  }
  log_file("CHANNEL", sprintf("[%s] remove() durch %O gerufen. Speichern und "
           "Ende.\n", dtime(time()),
            this_interactive()||this_player()||previous_object()));
  destruct(this_object());
  return 1;
}

// name() - define the name of this object.
public varargs string name(int casus,int demon)
{
  return CMNAME;
}

public varargs string Name(int casus, int demon)
{
  return capitalize(CMNAME);
}

// Low-level function for adding members without access checks
// return values < 0 are errors, success is 1.
private int add_member(struct channel_s ch, object m)
{
  if (IsChannelMember(ch, m))
    return E_ALREADY_JOINED;

  ch.members += ({ m });
  return 1;
}

private void remove_all_members(struct channel_s ch)
{
  // Einer geloeschten/inaktiven Ebene kann man nicht zuhoeren: Ebenenname
  // aus der Ebenenliste aller Mitglieder austragen. Dabei werden sowohl ein-,
  // als auch temporaer ausgeschaltete Ebenen beruecksichtigt.
  string chname = lower_case(ch.name);
  foreach(object listener : ch.members)
  {
    string* pl_chans = listener->QueryProp(P_CHANNELS);
    if (pointerp(pl_chans))
    {
      listener->SetProp(P_CHANNELS, pl_chans-({chname}));
    }
    pl_chans = listener->QueryProp(P_SWAP_CHANNELS);
    if (pointerp(pl_chans))
    {
      listener->SetProp(P_SWAP_CHANNELS, pl_chans-({chname}));
    }
  }
}

private void delete_channel(string chname, int force);

// Deaktiviert eine Ebene, behaelt aber einige Stammdaten in channelC und die
// History, so dass sie spaeter reaktiviert werden kann.
// Wenn <force>, dann wird wie Ebene sogar deaktiviert, wenn noch Zuhoerer
// anwesend sind.
private void deactivate_channel(string chname, int force)
{
  // Wenn zuviele inaktive Ebenen, wird sie geloescht statt deaktiviert.
  if (sizeof(channelC) > MAX_INACTIVE_CHANNELS)
  {
    log_file("CHANNEL",
        sprintf("[%s] Zuviele inaktive Ebenen. Channel %s geloescht statt "
                "deaktiviert.\n", dtime(time()), chname));
    this_object()->send(CMNAME, this_object(),
        sprintf("Zuviele inaktive Ebenen. Ebene %s geloescht statt "
                "deaktiviert.\n", chname));
    delete_channel(chname, force);
    return;
  }
  chname = lower_case(chname);
  struct channel_s ch = channels[chname];
  // Deaktivieren kann man nur aktive Ebenen.
  if (!structp(ch))
    return;
  // Falls sie noch Zuhoerer hat, muss man sich erstmal um die kuemmern.
  if (sizeof(ch.members))
  {
    // ohne <force> nur Ebenen ohne Zuhoerer deaktivieren.
    if (!force)
    {
      raise_error(
          sprintf("Attempt to deactivate channel %s with listeners.\n",
                  ch.name));
    }
    else
    {
      remove_all_members(ch);
    }
  }
  // Einige Daten merken, damit sie reaktiviert werden kann, wenn jemand
  // einloggt, der die Ebene abonniert hat.
#if __VERSION_MINOR__ == 6 && __VERSION_MICRO__ < 4
  // Workaround fuer Bug in to_struct: erst in array wandeln, dann in die
  // richtige struct.
  m_add(channelC, chname, to_struct(to_array(channels[chname])[0..3],
                                    (<channel_base_s>)),
        time());
#else
  m_add(channelC, chname, to_struct(channels[chname], (<channel_base_s>)),
        time());
#endif
  // aktive Ebene loeschen bzw. deaktivieren.
  m_delete(channels, chname);
  // History wird nicht geloescht, damit sie noch verfuegbar ist, wenn die
  // Ebene spaeter nochmal neu erstellt wird. Sie wird dann bereinigt, wenn
  // channelC bereinigt wird.

  stats["dispose"]++;
  save_me_soon = 1;
}

// Loescht eine Ebene vollstaendig inkl. Stammdaten und History.
// Wenn <force>, dann wird wie Ebene sogar deaktiviert, wenn noch Zuhoerer
// anwesend sind.
private void delete_channel(string chname, int force)
{
  chname = lower_case(chname);
  struct channel_s ch = channels[chname];
  // Ist die Ebene noch aktiv?
  if (ch)
  {
    // Und hat sie Zuhoerer?
    if (sizeof(ch.members))
    {
      // ohne <force> nur Ebenen ohne Zuhoerer loeschen.
      if (!force)
      {
        raise_error(
            sprintf("Attempt to delete channel %s with listeners.\n",
                    ch.name));
      }
      else
      {
        remove_all_members(ch);
      }
    }
    stats["dispose"]++;
    m_delete(channels, chname);
  }
  // Ab hier das gleiche fuer aktive und inaktive Ebenen.
  m_delete(channelC, chname);
  m_delete(channelH, chname);
  save_me_soon = 1;
}

// Aendert das Supervisor-Objekt einer Ebene, ggf. mit Meldung.
// Wenn kein neuer SV angegeben, wird der aelteste Zuhoerer gewaehlt.
private int change_sv_object(struct channel_s ch, object new_sv)
{
  if (!new_sv)
  {
    ch.members -= ({0});
    if (sizeof(ch.members))
      new_sv = ch.members[0];
    else
      return 0; // kein neuer SV moeglich.
  }
  // evtl. darf der supervisor aber nicht zu was anderes als dem creator
  // wechseln. Ausserdem darf niemand supervisor werden, der nicht auf der
  // Ebene ist.
  if ( ((ch.flags & CHF_FIXED_SUPERVISOR)
         && new_sv != find_object(ch.creator))
      || !IsChannelMember(ch, new_sv)
      )
    return 0;

  object old_sv = ch.supervisor;

  ch.supervisor = new_sv;
  ch.access_cl = symbol_function("ch_check_access", new_sv);

  if (old_sv && new_sv
      && !old_sv->QueryProp(P_INVIS)
      && !new_sv->QueryProp(P_INVIS))
  {
    // Die Zugriffskontrolle auf die Ebenen wird von der Funktion access()
    // erledigt. Weil sowohl externe Aufrufe aus dem Spielerobjekt, als auch
    // interne Aufrufe aus diesem Objekt vorkommen koennen, wird hier ein
    // explizites call_other() auf this_object() gemacht, damit der
    // Caller-Stack bei dem internen Aufruf denselben Aufbau hat wie bei
    // einem externen.
    this_object()->send(ch.name, old_sv,
        sprintf("uebergibt die Ebene an %s.",new_sv->name(WEN)),
        MSG_EMOTE);
  }
  else if (old_sv && !old_sv->QueryProp(P_INVIS))
  {
    this_object()->send(ch.name, old_sv,
        "uebergibt die Ebene an jemand anderen.", MSG_EMOTE);
  }
  else if (new_sv && !new_sv->QueryProp(P_INVIS))
  {
    this_object()->send(ch.name, new_sv,
        "uebernimmt die Ebene von jemand anderem.", MSG_EMOTE);
  }
  return 1;
}

// Stellt sicher, dass einen Ebenen-Supervisor gibt. Wenn dies nicht moeglich
// ist (z.b. leere Ebene), dann wird die Ebene geloescht und 0
// zurueckgegeben. Allerdings kann nach dieser Funktion sehr wohl die
// access_cl 0 sein, wenn der SV keine oeffentliche definiert! In diesem Fall
// wird access() den Zugriff immer erlauben.
private int assert_supervisor(struct channel_s ch)
{
  // Wenn der supervisor nicht mehr existiert, muss ein neuer gesucht werden.
  if (!ch.supervisor)
  {
    // Wenn der Wechsel des SV verboten ist, wird versucht, den
    // urspruenglichen Ersteller neuzuladen und zum neuen, alten Supervisor zu
    // machen.
    if (ch.flags & CHF_FIXED_SUPERVISOR)
    {
      object sv;
      string err=catch(sv=load_object(ch.creator);publish);
      if (!err)
      {
        // Juchu, die richtige SV ist wieder da. Sie muss noch auf die Ebene
        // und kann dann wieder SV werden.
        add_member(ch, sv);
        if (!change_sv_object(ch, sv))
        {
          // ich wuesste nicht, was in change_sv_object in diesem Fall
          // schiefgehen kann, daher einfach ein raise_error.
          raise_error(sprintf("Supervisor von Channel %s konnte nicht "
                "reaktiviert werden: %O\n",ch.name,sv));
        }
      }
      // wenns nicht geklappt hat, wird die Ebene deaktiviert.
      else
      {
        // Die inaktive Ebene kann wegen CHF_FIXED_SUPERVISOR nur vom
        // urspruenglichen Ersteller reaktiviert/neu erstellt werden. Und
        // solange der das nicht tut, ist weder die History zugaenglich, noch
        // kann jemand sonst was damit machen. Wenn die inaktive Ebene
        // irgendwann inkl. History  expired wird, kann jemand anderes dann
        // den Namen wieder verwenden und ein komplett neue Ebene erstellen.
        deactivate_channel(lower_case(ch.name), 1);
        log_file("CHANNEL",
            sprintf("[%s] Channel %s deaktiviert. SV-Fehler: %O -> %O\n",
                  dtime(time()), ch.name, ch.supervisor, err));
        return 0;
      }
    }
    // Der normalfall ist aber, dass wir einfach einen supervisor aus dem
    // Kreise der Zuhoerer bestimmen und zwar den aeltesten. Das macht
    // change_sv_object().
    else
    {
      if (!change_sv_object(ch, 0))
      {
        // wenn das nicht klappt, Ebene deaktivieren, vermutlich hat sie keine
        // Zuhoerer.
        deactivate_channel(lower_case(ch.name), 1);
        log_file("CHANNEL",
            sprintf("[%s] Kein SV, deaktiviere channel %s.\n",
                  dtime(time()), ch.name));
        return 0;
      }
    }
  }
  return 1;
}

// access() - check access by looking for the right argument types and
//            calling access closures respectively
// SEE: new, join, leave, send, list, users
// Wertebereich: 0 fuer Zugriff verweigert, 1 fuer Zugriff erlaubt, 2 fuer
// Zugriff erlaubt fuer privilegierte Objekte, die senden duerfen ohne
// Zuhoerer zu sein. (Die Aufrufer akzeptieren aber auch alle negativen Werte
// als Erfolg und alles ueber >2 als privilegiert.)
varargs private int access(struct channel_s ch, object user, string cmd,
                           string txt)
{
  if (!ch || !user)
    return 0;

  // Dieses Objekt und Root-Objekte duerfen auf der Ebene senden, ohne
  // Mitglied zu sein. Das ist die Folge der zurueckgegebenen 2.
  // Ausserdem duerfen sie auch alles andere machen unter Umgehung aller
  // Supervisoren. (z.B. kann dieses Objekt sogar Meldungen im Namen anderer
  // Objekte faken)
  // Die Pruefung erfolgt absichtlich vor assert_supervisor(), damit der
  // CHANNELD auch in temporaeren SV-losen Zustaenden was machen kann.
  if ( !previous_object(1) || previous_object(1) == this_object() ||
       getuid(previous_object(1)) == ROOTID)
    return 2;

  // Objekte duerfen keine Meldungen im Namen anderer Objekte faken, d.h. der
  // vermeintliche <user> muss auch der Aufrufer sein. Ausser darf auch sonst
  // kein Objekt was fuer ein anderes Objekt duerfen, sonst kann jemand z.B.
  // eine History abfragen indem einfach ein anderes Objekt uebergeben wird.
  if (previous_object(1) != user)
  {
    // Kurzfristiger Workaround: Whitelist fuer bestimmte Objekte, die im
    // Namen von Spielern senden mit dem Spieler als Absender, z.B. die Leiche
    // beim verspotten.
    switch(object_name(previous_object(1)))
    {
      case "/std/corpse":
        break;
      default:
        return 0;
    }
  }
  if (IsBanned(user, cmd))
    return 0;

  // Wenn kein SV-Objekt mehr existiert und kein neues bestimmt werden konnte,
  // wurde die Ebene ausfgeloest. In diesem Fall auch den Zugriff verweigern.
  if (!assert_supervisor(ch))
    return 0;
  // Wenn closure jetzt dennoch 0, wird der Zugriff erlaubt.
  if (!ch.access_cl)
    return 1;

  // Das SV-Objekt wird gefragt, ob der Zugriff erlaubt ist. Dieses erfolgt
  // fuer EM+ aber nur, wenn es das Default-SV-Objekt ist, damit
  // nicht beliebige SV-Objekt EMs den Zugriff verweigern koennen. Ebenen mit
  // Default-SV koennen aber auch EM+ Zugriff verweigern.
  if (IS_ARCH(previous_object(1))
      && ch.supervisor != find_object(DEFAULTSV))
    return 1;

  return funcall(ch.access_cl, lower_case(ch.name), user, cmd, txt);
}

// Neue Ebene <ch> erstellen mit <owner> als Ebenenbesitzer.
// <desc> kann die statische Beschreibung der Ebene sein oder eine Closure,
// die dynamisch aktualisierte Infos ausgibt.
// Das Objekt <owner> sollte eine Funktion ch_check_access() definieren, die
// gerufen wird, wenn eine Ebenenaktion vom Typ join/leave/send/list/users
// eingeht.
#define IGNORE  "^/xx"
public varargs int new(string ch_name, object owner, string|closure desc,
                       int channel_flags)
{
  // Kein Channelmaster angegeben, oder wir sind es selbst, aber der Aufruf
  // kam von ausserhalb. (Nur der channeld selbst darf sich als Channelmaster
  // fuer eine neue Ebene eintragen.)
  if (!objectp(owner) || (owner == this_object() && extern_call()) )
    return E_ACCESS_DENIED;

  // Kein gescheiter Channelname angegeben.
  if (!stringp(ch_name) || !sizeof(ch_name))
    return E_ACCESS_DENIED;

  // Channel schon vorhanden oder schon alle Channel-Slots belegt.
  if (channels[lower_case(ch_name)] || sizeof(channels) >= MAX_CHANNELS)
    return E_ACCESS_DENIED;

  // Der angegebene Ebenenbesitzer darf keine Ebenen erstellen, wenn fuer ihn
  // ein Bann auf die Aktion C_NEW besteht, oder das Ignore-Pattern auf
  // seinen Objektnamen matcht.
  if (IsBanned(owner,C_NEW) || regmatch(object_name(owner), IGNORE))
    return E_ACCESS_DENIED;

  // Zunaechst pruefen, ob eine alte, inaktive Ebene mit dem Namen noch
  // existiert.
  struct channel_base_s cbase = channelC[lower_case(ch_name)];
  struct channel_s ch;
  if (cbase)
  {
    // Wenn bei Reaktivierung von Ebenen (auch mit neuer Beschreibung *g*) der
    // neue owner != dem urspruenglichen Ersteller der Ebene ist und das Flag
    // CHF_FIXED_SUPERVISOR gesetzt ist, wird die Reaktivierung abgebrochen,
    // damit niemand inaktive Ebenen und deren History auf diesem Wege
    // uebernehmen kann, d.h. den Supervisor ersetzen kann.
    if ((cbase.flags & CHF_FIXED_SUPERVISOR)
        && object_name(owner) != cbase.creator)
      return E_ACCESS_DENIED;
    // Alte Daten der Ebene uebernehmen
#if __VERSION_MINOR__ == 6 && __VERSION_MICRO__ < 4
    // Workaround fuer Bug in to_struct: erst in array wandeln, dann in die
    // richtige struct.
    ch = to_struct(to_array(cbase), (<channel_s>));
#else
    ch = to_struct(cbase, (<channel_s>));
#endif
    // Wenn eine Beschreibung uebergeben, dann ersetzt sie jetzt die alte
    if (desc)
      ch.desc = desc;
    // creator bleibt natuerlich bestehen. Die Flags auch. Wir behalten auch
    // die Schreibweise (Gross-/Kleinschreibung) des Namens aus
    // Konsistenzgruenden bei.
  }
  else
  {
    // Wenn keine Beschreibung und keine inaktive Ebene da ist, wirds nen
    // Fehler...
    if (!desc)
      return E_ACCESS_DENIED;
    // prima, alles da. Dann wird ein ganz frische neue Ebenenstruktur
    // erzeugt.
    ch = (<channel_s> name: ch_name, desc: desc, creator: object_name(owner),
          flags: channel_flags);
  }

  ch_name = lower_case(ch_name);

  ch.members = ({ owner });
  ch.supervisor = owner;
  // ch_check_access() dient der Zugriffskontrolle und entscheidet, ob die
  // Nachricht gesendet werden darf oder nicht.
  ch.access_cl = symbol_function("ch_check_access", owner);

  m_add(channels, ch_name, ch);

  // History fuer eine Ebene nur dann initialisieren, wenn es sie noch
  // nicht gibt.
  if (!pointerp(channelH[ch_name]))
    channelH[ch_name] = ({});

  // Datenstruktur einer ggf. inaktiven Ebene mit dem Namen in channelC kann
  // jetzt auch weg.
  if (cbase)
    m_delete(channelC, ch_name);

  // Erstellen neuer Ebenen loggen, wenn wir nicht selbst der Ersteller sind.
  if (owner != this_object())
    log_file("CHANNEL.new", sprintf("[%s] Neue Ebene %s: %O %O\n",
        dtime(time()), ch.name, owner, desc));

  // Erfolgsmeldung ausgeben, ausser bei unsichtbarem Ebenenbesitzer.
  if (!owner->QueryProp(P_INVIS))
  {
    // Die Zugriffskontrolle auf die Ebenen wird von der Funktion access()
    // erledigt. Weil sowohl externe Aufrufe aus dem Spielerobjekt, als auch
    // interne Aufrufe aus diesem Objekt vorkommen koennen, wird hier ein
    // explizites call_other() auf this_object() gemacht, damit der
    // Caller-Stack bei dem internen Aufruf denselben Aufbau hat wie bei
    // einem externen.
    this_object()->send(CMNAME, owner,
      "laesst die Ebene '" + ch.name + "' entstehen.", MSG_EMOTE);
  }

  stats["new"]++;
  return (0);
}

// Objekt <pl> betritt Ebene <ch>. Dies wird zugelassen, wenn <pl> die
// Berechtigung hat und noch nicht Mitglied ist. (Man kann einer Ebene nicht
// zweimal beitreten.)
public int join(string chname, object joining)
{
  struct channel_s ch = channels[lower_case(chname)];
  /* funcall() auf Closure-Operator, um einen neuen Eintrag im Caller Stack
     zu erzeugen, weil access() mit extern_call() und previous_object()
     arbeitet und sichergestellt sein muss, dass das in jedem Fall das
     richtige ist. */
  if (!funcall(#'access, ch, joining, C_JOIN))
    return E_ACCESS_DENIED;
  //TODO: Sollte der creator das Recht auf join haben, auch wenn der aktuelle
  //SV es verweigert? (s.u.)
  int res = add_member(ch, joining);
  if (res != 1)
    return res;

  // Wenn <joining> der urspruengliche Ersteller der Ebene und kein
  // Spieler ist, wird es automatisch wieder zum Supervisor.
  if (!query_once_interactive(joining)
      && object_name(joining) == ch.creator)
    change_sv_object(ch, joining);

  return 0;
}

// Objekt <pl> verlaesst Ebene <ch>.
// Zugriffsrechte werden nur der Vollstaendigkeit halber geprueft; es duerfte
// normalerweise keinen Grund geben, das Verlassen einer Ebene zu verbieten.
// Dies ist in ch_check_access() so geregelt, allerdings koennte dem Objekt
// <pl> das Verlassen auf Grund eines Banns verboten sein.
// Wenn kein Zuhoerer mehr auf der Ebene ist, loest sie sich auf.
public int leave(string chname, object leaving)
{
  struct channel_s ch = channels[lower_case(chname)];
  // Nicht-existierenden Ebenen soll das Spielerobjekt austragen, also tun wir
  // so, als sei das erfolgreich gewesen.
  if (!ch)
    return 0;

  ch.members -= ({0}); // kaputte Objekte erstmal raus

  if (!IsChannelMember(ch, leaving))
    return E_NOT_MEMBER;

  /* funcall() auf Closure-Operator, um einen neuen Eintrag im Caller Stack
     zu erzeugen, weil access() mit extern_call() und previous_object()
     arbeitet und sichergestellt sein muss, dass das in jedem Fall das
     richtige ist. */
  if (!funcall(#'access, ch, leaving, C_LEAVE))
    return E_ACCESS_DENIED;

  // Dann mal den Zuhoerer raus.
  ch.members -= ({leaving});

  // Wenn auf der Ebene jetzt noch Objekte zuhoeren, muss ggf. der SV
  // wechseln.
  if (sizeof(ch.members))
  {
    // Kontrolle an jemand anderen uebergeben, wenn der Ebenensupervisor
    // diese verlassen hat. change_sv_object() waehlt per Default den
    // aeltesten Zuhoerer.
    if (leaving == ch.supervisor)
    {
      change_sv_object(ch, 0);
    }
  }
  // ansonsten Ebene loeschen, wenn keiner zuhoert.
  // Kommentar: Supervisoren sind auch Zuhoerer auf der Ebene. Wenn keine
  // Zuhoerer mehr, folglich auch kein Supervisor mehr da.
  else
  {
    // Der Letzte macht das Licht aus, aber nur, wenn er nicht unsichtbar ist.
    // Wenn Spieler, NPC, Clone oder Channeld als letztes die Ebene verlassen,
    // wird diese zerstoert, mit Meldung.
    if (!leaving->QueryProp(P_INVIS))
    {
      // Die Zugriffskontrolle auf die Ebenen wird von der Funktion access()
      // erledigt. Weil sowohl externe Aufrufe aus dem Spielerobjekt, als auch
      // interne Aufrufe aus diesem Objekt vorkommen koennen, wird hier ein
      // explizites call_other() auf this_object() gemacht, damit der
      // Caller-Stack bei dem internen Aufruf denselben Aufbau hat wie bei
      // einem externen.
      this_object()->send(CMNAME, leaving,
        "verlaesst als "+
        (leaving->QueryProp(P_GENDER) == 1 ? "Letzter" : "Letzte")+
        " die Ebene '" + ch.name + "', worauf diese sich in "
        "einem Blitz oktarinen Lichts aufloest.", MSG_EMOTE);
    }
    deactivate_channel(lower_case(ch.name),0);
  }
  return (0);
}

// Nachricht <msg> vom Typ <type> mit Absender <pl> auf der Ebene <ch> posten,
// sofern <pl> dort senden darf.
public varargs int send(string chname, object sender, string msg, int type)
{
  chname = lower_case(chname);
  struct channel_s ch = channels[chname];
  /* funcall() auf Closure-Operator, um einen neuen Eintrag im Caller Stack
     zu erzeugen, weil access() mit extern_call() und previous_object()
     arbeitet und sichergestellt sein muss, dass das in jedem Fall das
     richtige ist. */
  int a = funcall(#'access, ch, sender, C_SEND, msg);
  if (!a)
    return E_ACCESS_DENIED;

  // a<2 bedeutet effektiv a==1 (weil a==0 oben rausfaellt), was dem
  // Rueckgabewert von ch_check_access() entspricht, wenn die Aktion zugelassen
  // wird. access() liefert allerdings 2 fuer "privilegierte" Objekte (z.B.
  // ROOT-Objekte oder den channeld selber). Der Effekt ist, dass diese
  // Objekte auf Ebenen senden duerfen, auf denen sie nicht zuhoeren.
  if (a < 2 && !IsChannelMember(ch, sender))
    return E_NOT_MEMBER;

  if (!msg || !stringp(msg) || !sizeof(msg))
    return E_EMPTY_MESSAGE;

  // Jedem Mitglied der Ebene wird die Nachricht ueber die Funktion
  // ChannelMessage() zugestellt. Der Channeld selbst hat ebenfalls eine
  // Funktion dieses Namens, so dass er, falls er Mitglied der Ebene ist, die
  // Nachricht ebenfalls erhaelt.
  // Um die Kommandos der Ebene <MasteR> verarbeiten zu koennen, muss er
  // demzufolge Mitglied dieser Ebene sein. Da Ebenenbesitzer automatisch
  // auch Mitglied sind, wird die Ebene <MasteR> im create() mittels new()
  // erzeugt und der Channeld als Besitzer angegeben.
  // Die Aufrufkette ist dann wie folgt:
  // Eingabe "-< xyz" => pl::ChannelParser() => send() => ChannelMessage()
  (ch.members)->ChannelMessage(
                            ({ ch.name, sender, msg, type}));

  if (sizeof(channelH[chname]) > MAX_HIST_SIZE)
    channelH[chname] = channelH[chname][1..];

  channelH[chname] +=
    ({ ({ ch.name,
          (sender->QueryProp(P_INVIS)
                    ? "/(" + capitalize(getuid(sender)) + ")$"
                    : "")
                  + (sender->Name(WER, 2) || "<Unbekannt>"),
          msg + " <" + strftime("%a, %H:%M:%S") + ">\n",
          type }) });
  return (0);
}

// Gibt ein Mapping mit allen Ebenen aus, die das Objekt <pl> lesen kann,
// oder einen Integer-Fehlercode
public int|mapping list(object pl)
{
  mapping chs = ([]);
  foreach(string chname, struct channel_s ch : channels)
  {
    /* funcall() auf Closure-Operator, um einen neuen Eintrag im Caller Stack
       zu erzeugen, weil access() mit extern_call() und previous_object()
       arbeitet und sichergestellt sein muss, dass das in jedem Fall das
       richtige ist. */
    if(funcall(#'access, ch, pl, C_LIST))
    {
      ch.members = filter(ch.members, #'objectp);
      m_add(chs, chname, ({ch.members, ch.access_cl, ch.desc,
                           ch.supervisor, ch.name }) );
    }
  }

  if (!sizeof(chs))
    return E_ACCESS_DENIED;
  return (chs);
}

// Ebene suchen, deren Name <ch> enthaelt, und auf der Objekt <pl> senden darf
// Rueckgabewerte:
// - den gefundenen Namen als String
// - String-Array, wenn es mehrere Treffer gibt
// - 0, wenn es keinen Treffer gibt
public string|string* find(string chname, object pl)
{
  chname = lower_case(chname);

  // Suchstring <ch> muss Formatanforderung erfuellen;
  // TODO: soll das ein Check auf gueltigen Ebenennamen als Input sein?
  // Wenn ja, muesste laut Manpage mehr geprueft werden:
  // "Gueltige Namen setzen sich zusammen aus den Buchstaben a-z, A-Z sowie
  // #$%&@<>-." Es wuerden also $%&@ fehlen.
  if (!regmatch(chname, "^[<>a-z0-9#-]+$"))
    return 0;

  // Der Anfang des Ebenennamens muss dem Suchstring entsprechen und das
  // Objekt <pl> muss auf dieser Ebene senden duerfen, damit der Ebenenname
  // in das Suchergebnis aufgenommen wird.
  string* chs = filter(m_indices(channels), function int (string ch_n) {
                 /* Normalerweise benoetigen wir ein funcall() auf 
                    Closure-Operator, um einen neuen Eintrag im Caller Stack
                    zu erzeugen, weil access() mit extern_call() und
                    previous_object() arbeitet und sichergestellt sein muss,
                    dass das in jedem Fall das richtige ist.
                    In diesem Fall gibt es schon durch filter() einen neuen
                    Eintrag, daher muss access() direkt gerufen werden, sonst
                    ist previous_object(1) == this_object(). */
                  return ( stringp(regmatch(ch_n, "^"+chname)) &&
                           access(channels[ch_n], pl, C_FIND) );
                });

  int num_channels = sizeof(chs);
  if (num_channels > 1)
    return chs;
  else if (num_channels == 1)
    return chs[0];
  else
    return 0;
}

// Ebenen-History abfragen.
public int|<int|string>** history(string chname, object pl)
{
  struct channel_s ch = channels[lower_case(chname)];
  /* funcall() auf Closure-Operator, um einen neuen Eintrag im Caller Stack
     zu erzeugen, weil access() mit extern_call() und previous_object()
     arbeitet und sichergestellt sein muss, dass das in jedem Fall das
     richtige ist. */
  if (!funcall(#'access, ch, pl, C_JOIN))
    return E_ACCESS_DENIED;
  else
    return channelH[chname];
}

// Wird aus der Shell gerufen, fuer das Erzmagier-Kommando "kill".
public int remove_channel(string chname, object pl)
{
  if (!member(channels, chname))
    return E_ACCESS_DENIED;
  //TODO: integrieren in access()?
  if (previous_object() != this_object())
  {
    if (!stringp(chname) ||
        pl != this_player() || this_player() != this_interactive() ||
        this_interactive() != previous_object() ||
        !IS_ARCH(this_interactive()))
      return E_ACCESS_DENIED;
  }

  delete_channel(lower_case(chname), 1);

  return (0);
}

// Wird aus der Shell aufgerufen, fuer das Erzmagier-Kommando "clear".
public int clear_history(string chname)
{
  if (!member(channelH, chname))
    return E_ACCESS_DENIED;
  //TODO: mit access() vereinigen?
  // Sicherheitsabfragen
  if (previous_object() != this_object())
  {
    if (!stringp(chname) ||
        this_player() != this_interactive() ||
        this_interactive() != previous_object() ||
        !IS_ARCH(this_interactive()))
      return E_ACCESS_DENIED;
  }
  chname=lower_case(chname);
  // History des Channels loeschen (ohne die ebene als ganzes, daher Key nicht
  // aus dem mapping loeschen.)
  if (pointerp(channelH[chname]))
    channelH[chname] = ({});

  return 0;
}

// Aendert den Ersteller/Besitzer der Ebene.
// Achtung: das ist nicht das gleiche wie der aktuelle Supervisor!
public int transfer_ownership(string chname, object new_owner)
{
  struct channel_s ch = channels[lower_case(chname)];
  if (!ch)
    return E_ACCESS_DENIED;
  // Nur der aktuelle Besitzer oder EM+ darf die Ebene verschenken
  if (ch.creator != object_name(previous_object())
      && !IS_ARCH(previous_object()))
    return E_ACCESS_DENIED;

  ch.creator = object_name(new_owner);
  return 1;
}

// Aendert den Flags der Ebene.
public int change_channel_flags(string chname, int newflags)
{
  struct channel_s ch = channels[lower_case(chname)];
  if (!ch)
    return E_ACCESS_DENIED;
  // Nur der aktuelle Besitzer, Supervisor oder EM+ darf die Flags aendern.
  if (ch.supervisor != previous_object()
      && ch.creator != object_name(previous_object())
      && !IS_ARCH(previous_object()))
    return E_ACCESS_DENIED;

  ch.flags = newflags;
  return 1;
}

