MudOSa4DGD/
MudOSa4DGD/bin/
MudOSa4DGD/data/
MudOSa4DGD/doc/
MudOSa4DGD/doc/driver/
MudOSa4DGD/doc/efun/bitstrings/
MudOSa4DGD/doc/efun/command/
MudOSa4DGD/doc/efun/communication/
MudOSa4DGD/doc/efun/heart_beat/
MudOSa4DGD/doc/efun/interactive/
MudOSa4DGD/doc/efun/inventory/
MudOSa4DGD/doc/efun/living/
MudOSa4DGD/doc/efun/mappings/
MudOSa4DGD/doc/efun/strings/
MudOSa4DGD/doc/efun/uid/
MudOSa4DGD/doc/funs/
MudOSa4DGD/doc/language/
MudOSa4DGD/mudlib/dgd/doc/
MudOSa4DGD/mudlib/dgd/lib/include/dgd/
MudOSa4DGD/mudlib/dgd/lib/std/
MudOSa4DGD/mudlib/dgd/lib/sys/
MudOSa4DGD/mudlib/dgd/log/
MudOSa4DGD/mudlib/log/
MudOSa4DGD/mudlib/std/include/
MudOSa4DGD/mudlib/std/obj/
/*
 * auto.c
 *
 * The so called auto object, automatically inherited everywhere
 *
 * (C) Frank Schmidt, Jesus@NorseMUD
 *
 */

#define __AUTO
#include <driver.h>

/* include prototypes from auto object */
#if 1
# include "auto.h"
#endif

/* include prototypes from simul_efun object */
#if 1
# include "../../simul_efun.h"
#endif



/* kfun/s are used to override original DGD functions (Kernel FUNctions)
   efun/s are used to emulate MudOS behaviour (External FUNctions) */
#define _INCLUDED_KFUNS
#define _INCLUDED_EFUNS
#include "efun/template.c"
#include "efun/copy.c"
#include "efun/functions.c"
#include "efun/big_explode.c"
#include "efun/string.c"
#include "kfun/call_other.c"
#ifdef MUDOS_FUNCTIONP
# include "efun/fp.c"
#endif
#include "efun/array.c"
#include "kfun/sizeof.c"
#include "kfun/allocate.c"
#include "kfun/crypt.c"
#include "efun/mapping.c"
#ifdef MUDOS_BITSTRING
# include "efun/bitstring.c"
#endif
#include "efun/file_name.c"
#ifdef MUDOS_USER_ID
# include "efun/uid.c"
#endif
#include "kfun/this_user.c"
#include "efun/this_player.c"
#include "efun/interactive.c"
#if defined(MUDOS_LIVING)
#include "efun/living.c"
#endif
#if defined(MUDOS_INVENTORY)
# include "efun/inventory.c"
# include "efun/present.c"
#endif
#include "efun/comm.c"
#ifdef MUDOS_SPRINTF
# include "efun/printf.c"
#endif
#include "kfun/dgd_funcs.c"
#include "kfun/swapdump.c"
#include "kfun/find_object.c"
#include "kfun/compile_object.c"
#include "kfun/clone_object.c"
#include "kfun/call_out.c"
#ifdef MUDOS_VERSION
# include "efun/version.c"
#endif
#include "efun/time.c"
#ifdef MUDOS_HEART_BEAT
# include "efun/heart_beat.c"
#endif
#include "efun/math.c"
#ifdef MUDOS_NOTIFY_FAIL
# include "efun/notify_fail.c"
#endif
#include "efun/objects.c"
#if defined(MUDOS_COMMAND)
#include "efun/verb.c"
#endif
#if defined(MUDOS_TRIGGER)
# include "efun/trigger.c"
#endif
#include "efun/command.c"
#include "kfun/file.c"
#include "kfun/error.c"
#include "kfun/destruct.c"
#ifdef MUDOS_ORIGIN
# include "efun/origin.c"
#endif
#ifdef MUDOS_CHILDREN
# include "efun/children.c"
#endif


/* include our "quasi"-simul_efun object */
#if 1
#define _INCLUDED_SIMUL_EFUN
#include "../../simul_efun.c"
#endif



/* are we in driver object now? (this file included) */
#ifndef __DRIVER



#if 1

/* create() */
void __CREATE_DEF() {}


/* reset(int flag) */
#ifdef MUDOS_RESET
varargs void __RESET_DEF(int flag) {}
#endif


/* init() */
#ifdef MUDOS_LIVING
# ifdef MUDOS_INVENTORY
void __INIT_DEF() {}
# endif
#endif


/* heart_beat() */
#ifdef MUDOS_HEART_BEAT
void __HEART_BEAT_DEF() {}
#endif


/* prevent cloning of this_object? default: no */
int __QUERY_PREVENT_CLONE_DEF() {}

#endif /* 1 */


/* destroy() */
void __DESTROY_DEF() {
  destruct_object(this_object());
}



/* need to check if we are already loaded, and without uid, we need a flag */
#ifndef MUDOS_USER_ID
private static int _loaded;
#endif


/* set up security before create() */
nomask void __DGD_CREATE_DEF() {
  string file;
  object po;
  int is_valid;

#ifdef MUDOS_USER_ID
  if (uid) {
    /* Already loaded! */
    illegal();
    return;
  }
#else
  if (_loaded) {
    /* Already loaded! */
    illegal();
    return;
  }
  _loaded = 1;
#endif


  file = object_name(this_object());
  if (catch(is_valid=__QUERY_PREVENT_CLONE_DEF()) ||
      (is_valid && strsrch(file, "#") >= 0)) {
    illegal("Illegal object to clone.");
    ::destruct_object(this_object());
    return;
  }


#ifdef MUDOS_USER_ID
  if ((po=previous_object()) && !(geteuid(po))) {
    /* cloned by an object without euid */
    error("Cannot load objects without effective user id.");
    ::destruct_object(this_object());
    return;
  }
#endif


  /* check wether we're dealing with a DriverLib objects */
  if (strcocmp(_DGD_DIR, file)) {
#ifdef MUDOS_USER_ID
    /* set UID and EUID of DriverLib objects */
    switch (file) {
    case DRIVER:
    case GLOBAL:
      /* DGD files has driver uid & euid */
      uid = DRIVER_UID;
#ifdef AUTO_SETEUID
      euid = DRIVER_UID;
#endif
      break;
    case MASTER:
    case SIMUL_EFUN:
      /* Master and simul_efun has root user id */
      uid = ROOT_UID;
#ifdef AUTO_SETEUID
      euid = ROOT_UID;
#endif
      break;
    default:
      if (strcocmp(USER, file) || strcocmp(EDITOR, file)) {
	/* User- and editor objects got driver id/euid */
	uid = DRIVER_UID;
#ifdef AUTO_SETEUID
	euid = DRIVER_UID;
#endif
      }
      else {
	/* others have noname access */
	uid = NONAME_UID;
#ifdef AUTO_SETEUID
	euid = NONAME_UID;
#endif
      }
    }
#endif /* MUDOS_USER_ID */
  }
  else {
    /* set uid/euid on mudlib objects */
#ifdef MUDOS_USER_ID
#ifdef AUTO_TRUST_BACKBONE
    /* AUTO_TRUST_BACKBONE, euid is set to uid of cloner if backbone */
    string puid;
    if ((puid=getuid(po)) == BACKBONE_UID) {
      euid = puid;
    }
#endif
    /* get creator of this_object() from Master object */
    catch(uid = call_other(master(), __CREATOR_FILE_FUNC, file));
    
#ifndef AUTO_TRUST_BACKBONE
# ifdef AUTO_SETEUID
    /* AUTO_SETEUID, euid is set to uid */
    seteuid(uid);
# endif
#endif
    
    /* uid must be a string */
    if (!stringp(uid)) {
      illegal("Illegal object to load: return value of "+
	      "master::creator_file() was not a string.");
      ::destruct_object(this_object());
      return;
    }
#endif /* MUDOS_USER_ID */
      

#ifdef MASTER_VALID_OBJECT
    /* check with master() if this_object() is valid or not */
    if (catch(is_valid=call_other(master(), __VALID_OBJECT_FUNC, 
				  this_object())) || !is_valid) {
      /* if NO: dest us! */
      illegal("Illegal object to load: "+
	      "master::valid_object() returned 0.");
      ::destruct_object(this_object());
      return;
    }
#endif

    /* update global objects() with this new mudlib object */
    if (catch(GLOBAL->add_object(this_object()))) {
      ::destruct_object(this_object());
      error("Too many objects loaded.");
      return;
    }
  }


  /* call local create() function */
  catch(__CREATE_DEF());


#ifdef MUDOS_RESET
  /* first reset() (with argument 0) */
  catch(__RESET_DEF(0));
#endif
}



/* prevent recompilation this_object() if it is out of date and inherited? */
#ifndef AUTO_RECOMPILE_OBJECTS
int __QUERY_PREVENT_RECOMPILE_DEF() {
  return 1;
}
#endif



#endif /* __DRIVER */