dmuck0.15-beta/docs/muf/
dmuck0.15-beta/game/
dmuck0.15-beta/game/logs/
dmuck0.15-beta/game/muf/
dmuck0.15-beta/game/muf/text/
#include "prims.h"
/* private globals */
extern inst *p_oper1, *p_oper2, *p_oper3, *p_oper4;
extern char p_buf[BUFFER_LEN];
extern int p_result;
extern int p_nargs;
extern dbref p_ref;
extern dbref_list *p_drl;
extern int shutdown_flag;
extern void fork_and_dump();

void prims_moveto(__P_PROTO)
{
  dbref victim, destination, matchroom;
  CHECKOP(2);
  p_oper1 = POP();
  p_oper2 = POP();
  if ((!valid_object(p_oper1) && !is_home(p_oper1)) || !valid_object(p_oper2))
    abort_interp("Non-object argument.");
   
  victim = p_oper2->data.objref;
  destination = p_oper1->data.objref;
  matchroom = NOTHING;
  if (destination == HOME) destination = DBFETCH(victim)->link;

  if ((Typeof(victim) == TYPE_THING) || (Typeof(victim) == TYPE_PROGRAM))
  {
    if (Typeof(destination) == TYPE_ROOM
      && (DBFETCH(destination)->link != NOTHING)
      && !(FLAGS(destination) & STICKY))
      destination = DBFETCH(destination)->link;
  }
   if(Typeof(victim) == TYPE_ROOM && Typeof(destination) != TYPE_ROOM)
       abort_interp("Permission denied.");

  if (fr->wizard ||
    ((can_link_to(fr->euid, NOTYPE, destination)) ||
    ((FLAGS(destination) & JUMP_OK) &&
    controls(fr->euid, victim))))
    enter_room(victim, destination, DBFETCH(victim)->location);
  else abort_interp("Permission denied.");
}

void prims_contents(__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid argument type.");

  p_ref = DBFETCH(p_oper1->data.objref)->contents;

  CLEAR(p_oper1);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_exits(__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");

  p_ref = p_oper1->data.objref;
  if (!fr->wizard && !permissions(fr->euid, p_ref))
    abort_interp("Permission denied.");
  p_ref = DBFETCH(p_ref)->exits;

  CLEAR(p_oper1);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_next(__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");

  p_ref = DBFETCH(p_oper1->data.objref)->next;

  CLEAR(p_oper1);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_match (__P_PROTO)
{
  match_data md;
  CHECKOP(1);
  p_oper1 = POP();
  if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
  if (!p_oper1->data.string) abort_interp("Empty string argument.");

  init_match(fr->euid, p_oper1->data.string, NOTYPE, &md);
#ifdef PREP
	if (p_oper1->data.string[0] == REGISTERED_TOKEN) {
	    match_registered(&md);
	} else {
#endif
  match_all_exits(&md);
  match_neighbor(&md);
  match_possession(&md);
  match_me(&md);
  match_here(&md);
  match_home(&md);
#ifdef PREP
        }
#endif
  if (fr->wizard)
  {
    match_absolute(&md);
    match_player(&md);
  }
  p_ref = match_result(&md);

  CLEAR(p_oper1);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_rmatch (__P_PROTO)
{
  match_data md;
  CHECKOP(2);
  p_oper1 = POP();
  p_oper2 = POP();
  if (p_oper1->type != PROG_STRING) abort_interp("Invalid argument (2)");
  if (p_oper2->type != PROG_OBJECT
    || Typeof(p_oper2->data.objref) == TYPE_PROGRAM
    || Typeof(p_oper2->data.objref) == TYPE_EXIT)
    abort_interp("Invalid argument (1)");

  init_match(fr->euid, DoNullInd(p_oper1->data.string), TYPE_THING, &md);
  match_rmatch(p_oper2->data.objref, &md);
  p_ref = match_result(&md);

  CLEAR(p_oper1);
  CLEAR(p_oper2);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_owner (__P_PROTO)
{
  frame *fr_tmp;
  CHECKOP(1);
  p_oper1 = POP();
  if (p_oper1->type == PROG_INTEGER)
  {
    p_ref = (fr_tmp = find_frame(p_oper1->data.number)) ?
      fr_tmp->player :
      NOTHING;
  }
  else
  {
    if (!valid_object(p_oper1)) abort_interp("Invalid object.");
    p_ref = OWNER(p_oper1->data.objref);
    CLEAR(p_oper1);
  }
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_location (__P_PROTO)
{
  dbref loc;
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");

  p_ref = p_oper1->data.objref;
#ifdef MUSH
  if(Unfindable(p_ref) && !fr->wizard)
     loc = NOTHING;
  else
#endif
     loc = DBFETCH(p_ref)->location;

  push(arg, top, PROG_OBJECT, MIPSCAST &loc);
}

void prims_getlink (__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if (Typeof(p_oper1->data.objref) == TYPE_PROGRAM)
    abort_interp("Illegal object referenced.");

  switch (Typeof(p_oper1->data.objref))
  {
    case TYPE_EXIT:
      p_ref = (DBFETCH(p_oper1->data.objref)->sp.exit.ndest) ?
      (DBFETCH(p_oper1->data.objref)->sp.exit.dest)[0] : NOTHING;
      break;
    case TYPE_PLAYER:
      p_ref = DBFETCH(p_oper1->data.objref)->link;
      break;
    case TYPE_THING:
      p_ref = DBFETCH(p_oper1->data.objref)->link;
      break;
    case TYPE_ROOM:
      p_ref = DBFETCH(p_oper1->data.objref)->link;
      break;
    default:
      p_ref = NOTHING;
      break;
  }

  CLEAR(p_oper1);
  push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}

void prims_online (__P_PROTO)
{
  descriptor_data *d;

  p_result = 0;
  for(d = descriptor_list; d; d = d->next)
  {
    if((d->connected) && (!(FLAGS(d->player) & DARK) || fr->wizard))
    {
      p_ref = d->player;
      if(*top >= STACK_SIZE) abort_interp("Stack Overflow.");
      push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
      p_result++;
    }
  }
  if(*top >= STACK_SIZE) abort_interp("Stack Overflow.");
  push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}

void prims_db_top (__P_PROTO)
{
  p_result = db_top;
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}

void prims_dbtop (__P_PROTO)
{
  p_result = db_top - 1;
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push(arg, top, PROG_OBJECT, MIPSCAST &p_result);
}

void prims_chown (__P_PROTO)
{
  dbref victim, owner;
  CHECKOP(2);
  p_oper1 = POP();
  p_oper2 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid arguement (2)");
  if (!valid_object(p_oper2)) abort_interp("Invalid arguement (1)");
  victim = p_oper2->data.objref;
  owner = p_oper1->data.objref;

  if (!fr->wizard && !(FLAGS(victim) & CHOWN_OK))
    abort_interp("Permission denied.");
  if (Typeof(victim) == TYPE_PLAYER) abort_interp("Can't chown a player.");
  if (Typeof(owner) != TYPE_PLAYER) abort_interp("Object is not a player.");
  if (!fr->wizard && (owner != player))
    abort_interp("Can't chown to anyone but yourself.");

  remove_ownerlist(victim);
  DBSTORE(victim, owner, owner);
  add_ownerlist(victim);

  CLEAR(p_oper1);
  CLEAR(p_oper2);
}

/* linkcount ( d -- i ) */
void prims_linkcount (__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if ((OWNER(player) != OWNER(p_oper1->data.objref)) && !fr->wizard)
    abort_interp("Permission denied.");

  p_ref = p_oper1->data.objref;
  switch (Typeof(p_ref))
  {
    case TYPE_EXIT:
      p_result = DBFETCH(p_oper1->data.objref)->sp.exit.ndest;
      break;
    case TYPE_ROOM:
      p_result = (DBFETCH(p_ref)->link == NOTHING) ? 0 : 1;
      break;
    case TYPE_THING:
      p_result = (DBFETCH(p_ref)->link == NOTHING) ? 0 : 1;
      break;
    case TYPE_PLAYER:
      p_result = 1;
      break;
    case TYPE_PROGRAM:
      p_result = 0;
  }

  CLEAR(p_oper1);
  push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
}

/* getlinks ( d -- d1 ... dN N ) */
void prims_getlinks (__P_PROTO)
{
  int i;

  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if ((OWNER(player) != OWNER(p_oper1->data.objref)) && !fr->wizard)
    abort_interp ("Permission denied.");

  p_ref = p_oper1->data.objref;
  p_result = 0;
  switch (Typeof(p_ref))
  {
    case TYPE_ROOM:
      if (DBFETCH(p_ref)->link != NOTHING)
      {
        push (arg, top, PROG_OBJECT,
	  MIPSCAST &(DBFETCH(p_ref)->link));
        p_result = 1;
      }
      break;
    case TYPE_THING:
      if (DBFETCH(p_ref)->link != NOTHING)
      {
        push (arg, top, PROG_OBJECT, MIPSCAST &(DBFETCH(p_ref)->link));
        p_result = 1;
      }
      break;
    case TYPE_EXIT:
      p_result = DBFETCH(p_ref)->sp.exit.ndest;
      for (i = 0; i < p_result; i++)
      {
        if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
        push (arg, top, PROG_OBJECT,
          MIPSCAST &((DBFETCH(p_ref)->sp.exit.dest)[i]));
      }
      break;
    case TYPE_PLAYER:
      push (arg, top, PROG_OBJECT, MIPSCAST &(DBFETCH(p_ref)->link));
      p_result = 1;
  }
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_INTEGER, MIPSCAST &p_result);

  CLEAR(p_oper1);
}

/* prog ( -- d ) */
void prims_prog(__P_PROTO)
{
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_OBJECT, MIPSCAST &program);
}

/* callers ( -- d1...dN N ) */
void prims_callers (__P_PROTO)
{
  for (p_drl = fr->caller, p_result = 0; p_drl; p_drl = p_drl->next, p_result++)
  {
    if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
    push (arg, top, PROG_OBJECT, MIPSCAST &p_drl->object);
  }
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_INTEGER, MIPSCAST &p_result);
}

/* caller ( -- d ) */
void prims_caller (__P_PROTO)
{
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_OBJECT, MIPSCAST &(fr->player));
}

/* trig ( -- d ) */
void prims_trig (__P_PROTO)
{
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_OBJECT, MIPSCAST &(fr->trigger));
}

/* backlinks ( d -- d1...dN N ) */
void prims_backlinks (__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if ((OWNER(player) != OWNER(p_oper1->data.objref)) && !fr->wizard)
    abort_interp ("Permission denied.");
  for (p_drl = DBFETCH(p_oper1->data.objref)->backlinks, p_result = 0;
    p_drl; p_drl = p_drl->next, p_result++)
  {
    if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
    push (arg, top, PROG_OBJECT, MIPSCAST &p_drl->object);
  }
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
  push (arg, top, PROG_INTEGER, MIPSCAST &p_result);

  CLEAR(p_oper1);
}

/* backlocks ( d -- d1...dN N ) */
void prims_backlocks (__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if ((OWNER(player) != OWNER(p_oper1->data.objref)) && !fr->wizard)
    abort_interp ("Permission denied.");
  for (p_drl = DBFETCH(p_oper1->data.objref)->backlocks, p_result = 0;
    p_drl; p_drl = p_drl->next, p_result++)
  {
    if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
    push (arg, top, PROG_OBJECT, MIPSCAST &p_drl->object);
  }
  if ((*top) >= STACK_SIZE) abort_interp("Stack overflow.");
    push (arg, top, PROG_INTEGER, MIPSCAST &p_result);
  CLEAR(p_oper1);
}

/* nextowned ( d -- d' ) */
void prims_nextowned(__P_PROTO)
{
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Invalid object.");
  if ((OWNER(player) != OWNER(p_oper1->data.objref)) && !fr->wizard)
    abort_interp ("Permission denied.");
  push (arg, top, PROG_OBJECT,
    MIPSCAST &(DBFETCH(p_oper1->data.objref)->nextowned));
  CLEAR(p_oper1);
}

static boolexp *key;

void prims_lock(__P_PROTO)
{
  dbref thing;
  CHECKOP(2);
  p_oper2 = POP();
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Non-object argument.");
  if (p_oper2->type != PROG_STRING) abort_interp("Non-string argument.");
  if (!fr->wizard && !permissions(fr->euid, p_ref))
    abort_interp("Permission denied.");

  thing = p_oper1->data.objref;
  strncpy(p_buf, p_oper2->data.string, strlen(p_oper2->data.string) + 1);
  key = parse_boolexp(player, p_buf);

  if(key == TRUE_BOOLEXP)
  { 
       abort_interp("Invalid key.");
  }
  else
  {
    /* everything ok, do it   Taken directly from do_lock --Howard */
    remove_backlocks_parse(thing, DBFETCH(thing)->key);
    free_boolexp(DBFETCH(thing)->key);
    DBSTORE(thing, key, key);
    add_backlocks_parse(thing, DBFETCH(thing)->key);
  }

  CLEAR(p_oper1);
  CLEAR(p_oper2);
}

void prims_unlock(__P_PROTO)
{
  dbref thing;
  CHECKOP(1);
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Non-object argument.");
  if (!fr->wizard && !permissions(fr->euid, p_ref))
    abort_interp("Permission denied.");
  thing = p_oper1->data.objref;
  
  remove_backlocks_parse(thing, DBFETCH(thing)->key);
  free_boolexp(DBFETCH(thing)->key);
  DBSTORE(thing, key, TRUE_BOOLEXP);

  CLEAR(p_oper1);
}

void prims_dump(__P_PROTO)
{
  if (!fr->wizard) abort_interp("Permission denied.");

  fork_and_dump();
}

void prims_shutdown(__P_PROTO)
{
  if (!fr->wizard) abort_interp("Permission denied.");

  shutdown_flag = 1;
}

/* toad ( d d -- )
  d - player to toad
  d - recipient of toaded's stuff.
*/
void prims_toad(__P_PROTO)
{
  CHECKOP(2);
  p_oper2 = POP();
  p_oper1 = POP();
  if (!valid_object(p_oper1)) abort_interp("Non-object argument(1).");
  if (!valid_object(p_oper2)) abort_interp("Non-object argument(2).");
  if (Typeof(p_oper1->data.objref) != TYPE_PLAYER)
    abort_interp("Non-player argument(1).");
  if (Typeof(p_oper2->data.objref) != TYPE_PLAYER)
    abort_interp("Non-player argument(2).");

  if (!controls(fr->player, p_oper1->data.objref) ||
    !controls(fr->player, p_oper2->data.objref) ||
    (fr->player == p_oper1->data.objref))
    abort_interp("Permission denied.");
  toad(p_oper1->data.objref, p_oper2->data.objref);
  CLEAR(p_oper1);
  CLEAR(p_oper2);
}

void prims_stats(__P_PROTO)
{
    /* A WhiteFire special. :) */
    CHECKOP(1);
    p_oper1 = POP();

    if (!fr->wizard) abort_interp("Permission denied.");
    if (!valid_player(p_oper1) && (p_oper1->data.objref != NOTHING))
	abort_interp("non-player argument (1)");

    p_ref = p_oper1->data.objref;
    CLEAR(p_oper1);
    {
	dbref   i;
	int     rooms, exits, things, players, programs, garbage;

	/* tmp, ref */
	rooms = exits = things = players = programs = garbage = 0;
	for (i = 0; i < db_top; i++) {
	    if (p_ref == NOTHING || OWNER(i) == p_ref) {
		switch (Typeof(i)) {
		    case TYPE_ROOM:
			rooms++;
			break;
		    case TYPE_EXIT:
			exits++;
			break;
		    case TYPE_THING:
			things++;
			break;
		    case TYPE_PLAYER:
			players++;
			break;
		    case TYPE_PROGRAM:
			programs++;
			break;
		    case TYPE_GARBAGE:
			garbage++;
			break;
		}
	    }
	}
	p_result = rooms + exits + things + players + programs + garbage;
        push(arg, top, PROG_INTEGER, MIPSCAST &p_result);
        push(arg, top, PROG_INTEGER, MIPSCAST &rooms);
        push(arg, top, PROG_INTEGER, MIPSCAST &exits);
        push(arg, top, PROG_INTEGER, MIPSCAST &things);
        push(arg, top, PROG_INTEGER, MIPSCAST &programs);
        push(arg, top, PROG_INTEGER, MIPSCAST &players);
        push(arg, top, PROG_INTEGER, MIPSCAST &garbage);
        if(*top >= STACK_SIZE) abort_interp("Stack Overflow.");
    }
}

void prims_part_pmatch(__P_PROTO)
{
    CHECKOP(1);
    p_oper1 = POP();

    if (p_oper1->type != PROG_STRING) abort_interp("Non-string argument.");
    if (!p_oper1->data.string) abort_interp("Empty string argument.");
    p_ref = partial_pmatch(p_oper1->data.string);
    CLEAR(p_oper1);
    push(arg, top, PROG_OBJECT, MIPSCAST &p_ref);
}