// MorgenGrauen MUDlib
//
// thing/properties.c -- most general class (property handling)
//
// $Id: properties.c 6951 2008-08-09 23:08:31Z Zesstra $

// Properties.c -- Propertyverwaltung
// (c) 1993 Hate@MorgenGrauen, Mateese@NightFall
//          Idea and Code      Flames and Destructions
// -> *grin* thats the point actually :) 
//
// Ueberarbeitet von Jof       am 12.06.1994
// Ueberarbeitet von Mandragon am 11.05.2003

#pragma strict_types
#pragma save_types
#pragma range_check
#pragma no_clone

#include <driver_info.h>

#define NEED_PROTOTYPES

#include "/sys/thing/properties.h"
#include "/secure/wizlevels.h"

// the mapping where the actual properties are stored. Direct initialization.
// Indexed with F_VALUE, F_MODE, F_SET_METHOD, F_QUERY_METHOD, F_VALIDATOR
// F_MODE, F_SET_METHOD, F_QUERY_METHOD and F_VALIDATOR are usually 'sparse'
// (i.e. there is no entry for most properties), therefore it is more
// memory-efficient to store them like this than in one mapping, although it
// requires more mapping lookups.
private nosave mapping *prop = allocate(F_PROP_ENTRIES, ([]));

// the mapping that is used for saving. During save_object/restore_object it
// contains the properties with SAVE flag. 
// This is empty outside of a save_object() or restore_object() call!
private mapping properties;

// security-flag: wenn gesetzt und es gleich der aktuellen DI_EVAL_NUMBER ist,
// ist dieser Ausfuehrungsthread in einer Auswertung von F_QUERY/SET_METHOD
// (ggf. rekursiv) und es wird jeder Aufruf als extern gewertet bzgl.
// PROTECTED/SECURED.
private nosave int closure_call;


// Z.Zt. nur Abschalten des Resets noetig.
protected void create() {
  // Blueprints in /std benoetigenkeinen Reset ....
  if (object_name()=="/std/thing/properties")
    set_next_reset(-1);
}

protected void create_super() {
  set_next_reset(-1);
}

// Prueft, ob ein Zugriff auf eine Property erlaubt ist.
// Properties, die SECURED oder PROTECTED sind, duerfen nur vom Objekt
// selber, EM+ oder ROOT veraendert werden.
#define SAVE_OBJECT      1
#define PROP_SET         2
#define PROTECTED_SET    3
#define PROTECTED_DELETE 4
#define SECURED_SET      5
#define SECURED_DELETE   6
nomask private int prop_check_privilege(int drop_priv, int mode,
          int op=PROP_SET)
{
  // Wenn closure_call in diesem Ausfuehrungsthread (Top-Level-Call) gesetzt
  // wurde, zaehlt der Aufruf immer als drop_priv, auch wenn drop_priv 0 sein
  // sollte.
  drop_priv ||= (closure_call == driver_info(DI_EVAL_NUMBER));

  // Interne Calls oder eigenes Objekt (als letzter 'externer' Aufrufer via
  // Callother) darf alles
  if (!drop_priv || previous_object() == this_object())
    return 1;

  // Ab hier nur noch fremde Objekte
  switch(op)
  {
    case SAVE_OBJECT:
      // Eigentlich nur vom jeweils aktiven simul_efun-Objekt gerufen, aber
      // der einfacheit halber sind alle ROOT-Objekte erlaubt. Aber nur
      // direkten Caller pruefen, *nicht* ROOT_SECURITY!
      if (get_euid(previous_object()) == ROOTID)
        return 1;

    case SECURED_DELETE:
      // Das SECURED-Flag darf bei Properties nicht mehr geloescht werden
      return 0;

    case SECURED_SET:
      if (geteuid(previous_object()) == ROOTID || ARCH_SECURITY)
        return 1;

    case PROTECTED_DELETE:
    case PROTECTED_SET:
    case PROP_SET:
      // Properties, die schon SECURED oder PROTECTED sind, duerfen
      // nur vom Objekt selber manipuliert werden
      if (!(mode & (PROTECTED|SECURED)) // nicht geschuetzt
          || (geteuid(previous_object()) == ROOTID || ARCH_SECURITY))
        return 1;
  }
  return 0;
}

// Set() -- provides direct access to a property, no filters
// Type=F_VALUE und drop_priv=extern_call() by default
public mixed Set(string name, mixed Value, int Type, int drop_priv)
{
  int mode = prop[F_MODE][name];
  // Es ist verfuehrerisch, das 'drop_priv||extern_call()' durch 'drop_priv' zu
  // ersetzen, weil extern_call() das default-argument fuer <drop_priv> ist.
  // Das ist keine gute Idee, weil <drop_priv> unter der Kontrolle des Aufrufers
  // ist und dieser 0 uebergeben kann. Sprich: wenn es 0 ist, muessen wir
  // dennoch selber pruefen. Wir glauben aber immer, wenn es 1 ist, der
  // Aufrufer hat nichts davon und das eigene Objekt darf Privilegien abgeben.
  drop_priv = drop_priv||extern_call();

  // Erstmal pruefen, ob Aenderung der Prop erlaubt ist.
  if (!prop_check_privilege(drop_priv, mode, PROP_SET))
    return -1;
  // Bemerkung: aktuell koennen alle Objekte PROTECTED setzen. Loeschen
  // koennen es ROOT, EM+ und ME ueber den Check oben.

  // Soll SECURED geloescht werden und ist das erlaubt?
  if ((Type==F_MODE||Type==F_MODE_AD) && (Value & SECURED)
      && !prop_check_privilege(drop_priv, mode, SECURED_DELETE))
    return -2;

  // Soll SECURED gesetzt werden und ist das erlaubt?
  if ((Type==F_MODE||Type==F_MODE_AS) && (Value&SECURED)
      && !prop_check_privilege(drop_priv, mode, SECURED_SET) )
    return -3;

  switch(Type)
  {
    // Je nach Modus Flags veraendern
    case F_MODE_AS:  prop[F_MODE][name]|= Value;
                     return prop[F_MODE][name];
    case F_MODE_AD:  prop[F_MODE][name]&= ~Value;
                     if (!prop[F_MODE][name]) prop[F_MODE]-=([name]);
                     return prop[F_MODE][name];
    case F_MODE:     prop[F_MODE][name]^= Value;
                     if (!prop[F_MODE][name]) prop[F_MODE]-=([name]);
                     return prop[F_MODE][name];

    // Query- und Setmethoden laufen ab hier durch.
    case F_SET_METHOD:
    case F_SET_MAPPER:
      // SETMAPPED passend setzen
      if (Type==F_SET_METHOD)
        prop[F_MODE][name] &= ~SETMAPPED;
      else
        prop[F_MODE][name] |= SETMAPPED;
      // Ab hier alles gleich
      // -1 als Setz-Methode: Nosetmethod setzen
      if (Value == -1)
      {
        prop[F_SET_METHOD]-=([name]);
        prop[F_MODE][name] |= NOSETMETHOD;
        return 0;
      }
      // Kein break! Rest wie Querymethod
    case F_QUERY_METHOD:
      // Ungebundene Lambda_Closure? Heutzutage ein Fehler.
      if (closurep(Value) && !query_closure_object(Value))
      {
        raise_error("Ungebundene Lambdas sind als Querymethoden "
                    "nicht mehr unterstuetzt.\n");
      }
      // Kein break!
    default:
      if (!Value) prop[Type]-=([name]);
      else prop[Type][name] = Value;
  }

  // Gesamtwert zurueckgeben
  return prop[Type][name];
}


// Direktes Auslesen der Property ohne Filter ...
// Type = F_VALUE by default
public mixed Query( string name, int Type )
{
    if (pointerp(prop)) return prop[Type][name];
    return 0;
}

// Property setzen unter Verwendung evtl. vorhandener Zugriffsfunktionen
public mixed SetProp( string name, mixed Value, int drop_priv)
{
  mixed result;

  int mode = prop[F_MODE][name];
  // NOSETMETHOD: Darf nicht gesetzt werden
  if (mode & NOSETMETHOD ) return -1;

  // Set-Method abfragen, so vorhanden
  // TODO: nachdem alle moeglichen Werte als Set-Methode illegal sind, auf
  // closure aendern.
  mixed func = prop[F_SET_METHOD][name];
  if (func)
  {
    // Wert als Set-Method? gleich zurueckgeben
    if (!closurep(func)) return func;

    // An dieser Stelle muss func eine Closure sein. Da Set() ungebundene
    // Lambdas bindet, kann es auch nur eine gebundene Closure sein und das
    // Objekt existiert auch noch (sonst waere func == 0).

    // closure_call setzen, falls noch nicht gesetzt
    int set_closure_call = closure_call != driver_info(DI_EVAL_NUMBER);
    if (set_closure_call)
      closure_call = driver_info(DI_EVAL_NUMBER);

    // Dann mal die Closure aufrufen. Bei Fehler selbige loeschen
    if (catch(result=funcall(func, Value, name);publish))
    {
      prop[F_SET_METHOD]-=([name]);
    }
    else // Erfolgreicher call
    {
      if (mode & SETMAPPED) // SM hat noch nicht selber gesetzt
        result = Set( name, result, F_VALUE, drop_priv||extern_call() );
    }

    // Wenn dieser Aufruf closure_call gesetzt hat, wieder loeschen.
    // Da 0 ein gueltiger Wert ist, wird um eins dekrementiert, damit das Flag
    // fuer diese Top-Level-Ausfuehrung wieder freigegeben.
    if (set_closure_call) --closure_call;

    // Und zurueckgeben
    return result;
  }

  // _set_*-Methode vorhanden? falls ja, aufrufen.
  if (call_resolved(&result,this_object(),"_set_"+name,Value ))
        return result;

  // Letzte Moeglichkeit: Muss eine 'normale' Property sein
  // Es ist verfuehrerisch, das 'drop_priv||extern_call()' durch 'drop_priv'
  // zu ersetzen, weil extern_call() das default-argument fuer <drop_priv>
  // ist. Das ist keine gute Idee, weil <drop_priv> unter der Kontrolle des
  // Aufrufers ist und dieser 0 uebergeben kann. Sprich: wenn es 0 ist,
  // muessen wir dennoch selber pruefen. Wir glauben aber immer, wenn es 1
  // ist und der Aufrufer Privilegien abgeben will.
  return Set( name, Value, F_VALUE, drop_priv||extern_call() );
}


// Property auslesen unter Verwendung evtl. vorhandener Zugriffsfunktionen
public mixed QueryProp( string name )
{
  mixed result;
  // Query-Methode vorhanden?
  mixed func = prop[F_QUERY_METHOD][name];
  if (func)
  {
    // Wert als Query-Method? Gleich zurueckgeben ...
    if (!closurep(func)) return func;
 
    // An dieser Stelle muss func eine Closure sein. Da Set() ungebundene
    // Lambdas bindet, kann es auch nur eine gebundene Closure sein und das
    // Objekt existiert auch noch (sonst waere func == 0).
   
    // closure_call setzen, falls noch nicht gesetzt
    int set_closure_call = closure_call != driver_info(DI_EVAL_NUMBER);
    if (set_closure_call)
      closure_call = driver_info(DI_EVAL_NUMBER);

    // Dann Mal die Closure aufrufen. Bei Fehler selbige loeschen
    if (catch(result=funcall(func, prop[F_VALUE][name]);publish))
    {
      prop[F_QUERY_METHOD]-=([name]);
    }
    // Wenn dieser Aufruf closure_call gesetzt hat, wieder loeschen.
    // Da 0 ein gueltiger Wert ist, wird um eins dekrementiert, damit das Flag
    // fuer diese Top-Level-Ausfuehrung wieder freigegeben.
    if (set_closure_call) --closure_call;
    
    // Und zurueckgeben
    return result;
  }
  // _query_*-Methode vorhanden? falls ja, aufrufen.
  else if (call_resolved(&result,this_object(),"_query_"+name))
    return result;

  // Hilft alles nichts. Es ist eine 'normale' Property ...
  return prop[F_VALUE][name];
}

// Addiert einen Wert zu einer Prop. Eigentlich ist es nur ein Short-Cut fuer
// QueryProp und += und SetProp. Dementsprechend gehen auch hier nur
// Typ-Kombinationen, die += auch kann.
public mixed AddToProp(string pname,
                       <int|float|string|mixed*|mapping|bytes> add_value)
{
  mixed value = QueryProp(pname);
  string err = catch(value += add_value; nolog);
  if (err)
    raise_error(sprintf("Nicht unterstuetzter Typ des Summanden: %s\n",
                        err[strstr(err,":")+2..]));

  return SetProp(pname, value, extern_call());
}

// "subtrahiert" einen Wert von einer Prop. Eigentlich ist es nur ein
// Short-Cut fuer QueryProp und -= und SetProp. Dementsprechend gehen auch
// hier nur Typ-Kombinationen, die -= auch kann.
public mixed SubFromProp(string pname,
                       <int|float|string|mixed*|mapping|bytes> sub_value)
{
  mixed value = QueryProp(pname);
  string err = catch(value -= sub_value; nolog);
  if (err)
    raise_error(sprintf("Nicht unterstuetzter Typ des Subtrahenden: %s\n",
                        err[strstr(err,":")+2..]));

  return SetProp(pname, value, extern_call());
}

// Viele Properties auf einen Schlag setzen.
// genutzt von simul_efun zum Setzen aller Properties, welche im
// restore_object() eingelesen wurden.
// Andere objekt-externe Nutzung ausdruecklich **NICHT** supportet!
public void SetProperties( mapping props )
{
  int i, j;

  // Kein Mapping? Schlecht ...
  if(!mappingp(props)) return;

  string *names = m_indices(props);

  // Das SECURED-Flag darf nur durch das Objekt selber gesetzt werden:
  // mode ist hier egal. Antwort cachen fuer den Loop
  int no_secure = !prop_check_privilege(extern_call(), 0, SECURED_SET);

  j=sizeof(names);
  while(j--)
  {
    if (prop_check_privilege(extern_call(), prop[F_MODE][names[j]],
                             PROP_SET))
    {
      // Prop-Setzen erlaubt, aber ggf. SECURED flag loeschen, wenn nicht
      // das nicht erlaubt ist (s.o.).
      if (no_secure)
        props[names[j], F_MODE] &= ~SECURED;
      // jetzt die einzelnen Teile der Prop seztzen.
      i=F_PROP_ENTRIES;
      while(i--)
      {
        if(props[names[j],i])
          prop[i][names[j]] = props[names[j], i];
        else
          prop[i]-=([names[j]]);
      }
    }
  }
  return;
}


// Ein Mapping mit allen Properties zurueckgeben
// genutzt von simul_efun im save_object() zur Abfrage aller Properties, um
// hieraus die gespeicherten zu bestimmen.
// Andere objekt-externe Nutzung ausdruecklich **NICHT** supportet!
// TODO fuer zukuenftige Features (wie private Properties) auf die simul_efun
// beschraenken.
public mapping QueryProperties()
{
  mapping props;
  int i, j;
  string *names;

  props = m_allocate( sizeof(prop[F_VALUE]), F_PROP_ENTRIES );

  if (pointerp(prop))
  {
    i=F_PROP_ENTRIES;
    while(i--)
    {
      names = m_indices(prop[i]);
      j=sizeof(names);
      while(j--) props[names[j], i] = prop[i][names[j]];
    }
  }
  return props;
}

// Die Properties als urspruengliches Array zurueckgeben
public mixed *__query_properties()
{
  if ( pointerp(prop) )
    return(deep_copy(prop));
  else
    return allocate(F_PROP_ENTRIES, ([]));
}


// mapping Properties setzen zum Speichern (per save_object())
// Aufruf nur aus simul_efun heraus (sinnvoll). Diese fragt alle Properties
// via QueryProperties() ab, filtert alle nicht-gespeicherten Properties aus
// und setzt ueber diese Funktion die gespeicherten in der tatsaechlich von
// save_object() gespeicherten Variable <properties>.
public void  _set_save_data(mixed data) { properties = data; }

// mapping Properties zum Restoren zurueckgeben
// Aufruf nur aus simul_efun heraus (sinnvoll). Diese ruft nach dem
// restore_object die restaurierten Properties hiermit ab und schreibt sie
// nach Konditionierung via SetProperties() zurueck, damit die Daten (wieder)
// in <prop> zur Verfuegung steheh.
public mixed _get_save_data()           { return properties; }

