Example #1
0
void
do_shutdown(dbref player)
{
	if (Wizard(player)) {
		log_status("SHUTDOWN: by %s", unparse_object(player, player));
		shutdown_flag = 1;
		restart_flag = 0;
	} else {
		notify(player, "Your delusions of grandeur have been duly noted.");
		log_status("ILLEGAL SHUTDOWN: tried by %s", unparse_object(player, player));
	}
}
Example #2
0
void prim_frm(PRIM_PROTOTYPE)
{
  char *filename;
  CHECKOP(1);
  oper1 = POP();
  if (getuid() == 0 )
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");
  if(oper1->type != PROG_STRING) abort_interp("Argument 1 is not a string.");
  if(!oper1->data.string) abort_interp("Argument 1 is a null string.");
  filename = oper1->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif 
  result = unlink(filename);
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s FRM: %s \n", program, unparse_object(player, player), oper1->data.string->data);  
  CLEAR(oper1);
  PushInt(result);
}
Example #3
0
/** Issue a warning about an object.
 * \param player player to receive the warning notification.
 * \param i object the warning is about.
 * \param name name of the warnings.
 * \param desc a formatting string for the warning message.
 */
void
complain(dbref player, dbref i, const char *name, const char *desc, ...)
{
#ifdef HAS_VSNPRINTF
    char buff[BUFFER_LEN];
#else
    char buff[BUFFER_LEN * 3];    /* safety margin */
#endif
    va_list args;

    va_start(args, desc);

#ifdef HAS_VSNPRINTF
    vsnprintf(buff, sizeof buff, desc, args);
#else
    vsprintf(buff, desc, args);
#endif

    buff[BUFFER_LEN - 1] = '\0';
    va_end(args);

    notify_format(player, T("Warning '%s' for %s:"),
                  name, unparse_object(player, i));
    notify(player, buff);
}
Example #4
0
void prim_fsize(PRIM_PROTOTYPE)
{
  FILE *fh;
  char *filename;
  int result; 
  long offset;
  CHECKOP(1);
  oper1 = POP();
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if (oper1->type != PROG_STRING) abort_interp("Arguement 1 is not a string.");
  if (!oper1->data.string) abort_interp("Arguement 1 is a null string.");
  filename = oper1->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif
  fh = fopen(filename, "r");
  if (fh == NULL) { offset = -1; } else {
    fseek(fh, 0, SEEK_END);
    offset = ftell(fh);
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s FSIZE: %s \n", program, unparse_object(player, player), oper1->data.string->data); 
  }
  fclose(fh);
  CLEAR(oper1);
  PushInt(offset);
}
Example #5
0
void
log_program_text(struct line *first, dbref player, dbref i)
{
        FILE *f;
        char fname[BUFFER_LEN];
        time_t lt = time(NULL);

        strcpyn(fname, sizeof(fname), PROGRAM_LOG);
        f = fopen(fname, "ab");
        if (!f) {
                log_status("Couldn't open file %s!", fname);
                return;
        }

        fputs("#######################################", f);
        fputs("#######################################\n", f);
        fprintf(f, "PROGRAM %s, SAVED AT %s BY %s(%d)\n",
                        unparse_object(player, i), ctime(&lt), NAME(player), player);
        fputs("#######################################", f);
        fputs("#######################################\n\n", f);

        while (first) {
                if (!first->this_line)
                        continue;
                fputs(first->this_line, f);
                fputc('\n', f);
                first = first->next;
        }
        fputs("\n\n\n", f);
        fclose(f);
}
Example #6
0
static void 
unparse_boolexp1(dbref player, struct boolexp * b,
		 boolexp_type outer_type, int fullname)
{
    if ((buftop - boolexp_buf) > (BUFFER_LEN / 2))
	return;
    if (b == TRUE_BOOLEXP) {
	strcpy(buftop, "*UNLOCKED*");
	buftop += strlen(buftop);
    } else {
	switch (b->type) {
	    case BOOLEXP_AND:
		if (outer_type == BOOLEXP_NOT) {
		    *buftop++ = '(';
		}
		unparse_boolexp1(player, b->sub1, b->type, fullname);
		*buftop++ = AND_TOKEN;
		unparse_boolexp1(player, b->sub2, b->type, fullname);
		if (outer_type == BOOLEXP_NOT) {
		    *buftop++ = ')';
		}
		break;
	    case BOOLEXP_OR:
		if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
		    *buftop++ = '(';
		}
		unparse_boolexp1(player, b->sub1, b->type, fullname);
		*buftop++ = OR_TOKEN;
		unparse_boolexp1(player, b->sub2, b->type, fullname);
		if (outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
		    *buftop++ = ')';
		}
		break;
	    case BOOLEXP_NOT:
		*buftop++ = '!';
		unparse_boolexp1(player, b->sub1, b->type, fullname);
		break;
	    case BOOLEXP_CONST:
		if (fullname) {
#ifndef SANITY
		    strcpy(buftop, unparse_object(player, b->thing));
#endif
		} else {
		    sprintf(buftop, "#%d", b->thing);
		}
		buftop += strlen(buftop);
		break;
	    case BOOLEXP_PROP:
		strcpy(buftop, PropName(b->prop_check));
		strcat(buftop, ":");
		if (PropType(b->prop_check) == PROP_STRTYP)
		    strcat(buftop, PropDataStr(b->prop_check));
		buftop += strlen(buftop);
		break;
	    default:
		abort();	/* bad type */
		break;
	}
    }
}
Example #7
0
/*
  Use this to create a program.
  First, find a program that matches that name.  If there's one,
  then we put him into edit mode and do it.
  Otherwise, we create a new object for him, and call it a program.
  */
void
do_prog(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;

    if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = match_result(&md)) == NOTHING) {
        i = new_program(OWNER(player), name);
        FLAGS(i) |= INTERNAL;
        DBFETCH(player)->sp.player.curr_prog = i;

        anotify_fmt(player, CSUCC "Program %s created with number %d.", name,
                    i);
        anotify_nolisten2(player, CINFO "Entering editor.");
    } else if (i == AMBIGUOUS) {
        anotify_nolisten2(player, CINFO "I don't know which one you mean!");
        return;
    } else {
        if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) {
            anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
            return;
        } else if (FLAGS(i) & INTERNAL) {
            anotify_nolisten2(player, CFAIL NOEDIT_MESG);
            return;
        }

        DBFETCH(i)->sp.program.first = read_program(i);
        FLAGS(i) |= INTERNAL;
        DBFETCH(player)->sp.player.curr_prog = i;
        anotify_fmt(player, CINFO "Entering editor for %s.",
                    unparse_object(player, i));
        /* list current line */
        do_list(player, i, 0, 0, 0);
        DBDIRTY(i);
    }

    FLAGS(player) |= INTERACTIVE;
    DBDIRTY(player);
}
Example #8
0
void 
do_restart(dbref player, const char *msg)
{
    if (Arch(player)) {
      if( *msg == '\0' || strcmp(msg, tp_muckname))
      {
	notify(player, "Usage: @restart muckname" );
	return;
      }
	log_status("REST: by %s\n", unparse_object(player, player));
	shutdown_flag = 1;
	restart_flag = 1;
    } else {
	anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
	log_status("SHAM: Restart by %s\n", unparse_object(player, player));
    }
}
Example #9
0
void 
check_exit(dbref obj)
{
    int     i, j;

    printf("Dest#: %d\n", j = DBFETCH(obj)->sp.exit.ndest);
    for (i = 0; i < j; i++) {
	printf("Link #%d: %s\n", i + 1, unparse_object(me, DBFETCH(obj)->sp.exit.dest[i]));
    }
}
Example #10
0
static void ShowPsLine(BQUE *tmp)
{
    char *bufp = unparse_object(Show_Player, tmp->executor, false);
    if (tmp->IsTimed && (Good_obj(tmp->sem)))
    {
        CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow;
        notify(Show_Player, tprintf("[#%d/%d]%s:%s", tmp->sem, ltd.ReturnSeconds(), bufp, tmp->comm));
    }
    else if (tmp->IsTimed)
    {
        CLinearTimeDelta ltd = tmp->waittime - Show_lsaNow;
        notify(Show_Player, tprintf("[%d]%s:%s", ltd.ReturnSeconds(), bufp, tmp->comm));
    }
    else if (Good_obj(tmp->sem))
    {
        notify(Show_Player, tprintf("[#%d]%s:%s", tmp->sem, bufp, tmp->comm));
    }
    else
    {
        notify(Show_Player, tprintf("%s:%s", bufp, tmp->comm));
    }
    char *bp = bufp;
    if (Show_Key == PS_LONG)
    {
        for (int i = 0; i < tmp->nargs; i++)
        {
            if (tmp->env[i] != NULL)
            {
                safe_str("; Arg", bufp, &bp);
                safe_chr((char)(i + '0'), bufp, &bp);
                safe_str("='", bufp, &bp);
                safe_str(tmp->env[i], bufp, &bp);
                safe_chr('\'', bufp, &bp);
            }
        }
        *bp = '\0';
        bp = unparse_object(Show_Player, tmp->enactor, false);
        notify(Show_Player, tprintf("   Enactor: %s%s", bp, bufp));
        free_lbuf(bp);
    }
    free_lbuf(bufp);
}
Example #11
0
/*
 * do_attach()
 *
 * This routine attaches a previously existing action to a source object.
 * The action will not do anything unless it is LINKed.
 *
 */
void
do_attach(int descr, dbref player, const char *action_name,
          const char *source_name)
{
    dbref action, source;
    dbref loc;                  /* player's current location */
    struct match_data md;
    char buf[BUFFER_LEN];

    if ((loc = DBFETCH(player)->location) == NOTHING)
        return;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (!*action_name || !*source_name) {
        anotify_nolisten2(player,
                          CINFO
                          "You must specify an action name and a source object.");
        return;
    }
    init_match(descr, player, action_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((action = noisy_match_result(&md)) == NOTHING)
        return;

    if (Typeof(action) != TYPE_EXIT) {
        anotify_nolisten2(player, CINFO "That's not an action.");
        return;
    } else if (!controls(player, action)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    }
    if (((source = parse_source(descr, player, source_name)) == NOTHING)
        || Typeof(source) == TYPE_PROGRAM)
        return;

    if (!unset_source(player, loc, action)) {
        return;
    }
    set_source(player, action, source);
    sprintf(buf, CSUCC "Action %s re-attached to %s.",
            unparse_object(player, action), NAME(source));
    anotify_nolisten2(player, buf);
    if (MLevel(action)) {
        SetMLevel(action, 0);
        anotify_nolisten2(player, CINFO "Action priority Level reset to zero.");
    }
}
Example #12
0
static dbref
parse_linkable_dest(int descr, dbref player, dbref exit, const char *dest_name)
{
    dbref dobj;        /* destination room/player/thing/link */
    char buf[BUFFER_LEN];
    struct match_data md;

    init_match(descr, player, dest_name, NOTYPE, &md);
    match_absolute(&md);
    match_everything(&md);
    match_home(&md);
    match_null(&md);

    if ((dobj = match_result(&md)) == NOTHING || dobj == AMBIGUOUS) {
        sprintf(buf, CINFO "I couldn't find '%s'.", dest_name);
        anotify_nolisten2(player, buf);
        return NOTHING;

    }

    if (!tp_teleport_to_player && Typeof(dobj) == TYPE_PLAYER) {
        sprintf(buf,
                CFAIL "You can't link to players.  Destination %s ignored.",
                unparse_object(player, dobj));
        anotify_nolisten2(player, buf);
        return NOTHING;
    }

    if (!can_link(player, exit)) {
        anotify_nolisten2(player, CFAIL "You can't link that.");
        return NOTHING;
    }

    if (!can_link_to(player, Typeof(exit), dobj)) {
        sprintf(buf, CFAIL "You can't link to %s.",
                unparse_object(player, dobj));
        anotify_nolisten2(player, buf);
        return NOTHING;
    } else
        return dobj;
}
Example #13
0
void prim_curid(PRIM_PROTOTYPE) 
{
  int curuid = getuid(); 
  int curgid = getgid(); 
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if(tp_log_files)
    log2filetime("logs/files", "#%d by %s CURID \n", program, unparse_object(player, player)); 
  PushInt(curgid); 
  PushInt(curuid); 
} 
Example #14
0
void prim_fread(PRIM_PROTOTYPE)
{
  FILE *fh;
  char *filename;
  double offset;
  char tempchr[2];
  int result;
  CHECKOP(2);
  oper1 = POP();
  oper2 = POP();
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if(oper1->type != PROG_INTEGER)
    abort_interp("Arguement 1 is not an integer.");
  if(oper1->data.number < 0 ) abort_interp("Arguement 1 is a negative number.");
  if(oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string.");
  if(!oper2->data.string) abort_interp("Argueemnt 2 is a null string.");
  offset = oper1->data.number;
  filename = oper2->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif
  fh = fopen(filename, "r");
  if (fh == NULL) { result = 0; } else {
    fseek(fh, offset, SEEK_SET);
    tempchr[0] = (char) fgetc(fh);
    tempchr[1] = '\0';
    fclose(fh);
    sprintf(buf, "%s", tempchr);
    result = 1;
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s FREAD: %s \n", program, unparse_object(player, player), oper2->data.string->data); 
   if ( tempchr[0] == EOF )
      result = 0;
  }
  CLEAR(oper1);
  CLEAR(oper2);
  if( result )
     PushString(buf);
  else 
     PushNullStr;
} 
Example #15
0
/** Issue a warning about an object.
 * \param player player to receive the warning notification.
 * \param i object the warning is about.
 * \param name name of the warnings.
 * \param desc a formatting string for the warning message.
 */
void
complain(dbref player, dbref i, const char *name, const char *desc, ...)
{
    char buff[BUFFER_LEN];
    va_list args;

    va_start(args, desc);
    mush_vsnprintf(buff, sizeof buff, desc, args);
    va_end(args);

    notify_format(player, T("Warning '%s' for %s:"),
                  name, unparse_object(player, i));
    notify(player, buff);
}
Example #16
0
void
do_edit(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;

    if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS)
        return;

    if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    } else if (FLAGS(i) & INTERNAL) {
        anotify_nolisten2(player, CFAIL NOEDIT_MESG);
        return;
    }

    FLAGS(i) |= INTERNAL;
    DBFETCH(i)->sp.program.first = read_program(i);
    DBFETCH(player)->sp.player.curr_prog = i;
    anotify_fmt(player, CINFO "Entering editor for %s.",
                unparse_object(player, i));
    /* list current line */
    do_list(player, i, 0, 0, 0);
    FLAGS(player) |= INTERACTIVE;
    DBDIRTY(i);
    DBDIRTY(player);
}
Example #17
0
void prim_bwrite(PRIM_PROTOTYPE)
{
  FILE *fh;
  char *filename;
  int result, tempdat;
  double offset;
  CHECKOP(3);
  oper1 = POP();
  oper2 = POP();
  oper3 = POP();
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if (oper1->type != PROG_INTEGER) abort_interp("Arguement 1 is not an integer.");
  if (oper1->data.number < 0 ) abort_interp("Arguement 1 is a negative number.");
  if (oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string.");
  if (!oper2->data.string) abort_interp("Arguement 2 is a null string.");
  if (oper3->type != PROG_INTEGER) abort_interp("Arguement 3 is not an integer.");
  if (oper3->data.number < 0 ) abort_interp("Arguement 3 is a negative number.");
  offset = oper1->data.number;
  filename = oper2->data.string->data;
  tempdat = (int) oper3->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif
  fh = fopen(filename, "w");
  if (fh == NULL) { result = 0; } else {
    fseek(fh, offset, SEEK_SET);
    fputc(tempdat - 8, fh); 
    fclose(fh);
    result = 1;
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s BWRITE : %s \n", program, unparse_object(player, player), oper2->data.string->data); 
  }
  CLEAR(oper1);
  CLEAR(oper2);
  CLEAR(oper3);
  PushInt(result);
}
Example #18
0
/* quit from edit mode.  Put player back into the regular game mode */
void
do_quit(dbref player, dbref program)
{
	log_status("PROGRAM SAVED: %s by %s(%d)", unparse_object(player, program),
			   NAME(player), player);
	write_program(PROGRAM_FIRST(program), program);

	if (tp_log_programs)
		log_program_text(PROGRAM_FIRST(program), player, program);

	free_prog_text(PROGRAM_FIRST(program));
	PROGRAM_SET_FIRST(program, NULL);
	FLAGS(program) &= ~INTERNAL;
	FLAGS(player) &= ~INTERACTIVE;
	PLAYER_SET_CURR_PROG(player, NOTHING);
	DBDIRTY(player);
	DBDIRTY(program);
}
Example #19
0
void prim_bread(PRIM_PROTOTYPE)
{
  FILE *fh; /* Should return -1 for file open error. */ 
  char *filename; /* -2 for EOF. */ 
  double offset;
  int result;
  CHECKOP(2);
  oper1 = POP();
  oper2 = POP();
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if(oper1->type != PROG_INTEGER)
    abort_interp("Arguement 1 is not an integer.");
  if(oper1->data.number < 0 ) abort_interp("Arguement 1 is a negative number.");
  if(oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string.");
  if(!oper2->data.string) abort_interp("Argueemnt 2 is a null string.");
  offset = oper1->data.number;
  filename = oper2->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif
  fh = fopen(filename, "r");
  if (fh == NULL) { result = -1; } else {
    fseek(fh, offset, SEEK_SET);
    result = fgetc(fh);
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s BREAD: %s \n", program, unparse_object(player, player), oper2->data.string->data); 
    if (result == EOF) { 
      result = -2; 
    } 
    fclose(fh);
  }
  CLEAR(oper1);
  CLEAR(oper2);
  PushInt(result);
} 
Example #20
0
void prim_fren(PRIM_PROTOTYPE)
{
  char *oldname, *newname;
  char tempB[BUFFER_LEN] = "";
  CHECKOP(2);
  oper1 = POP();
  oper2 = POP();
  if (getuid() == 0 )
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if(oper1->type != PROG_STRING) abort_interp("Argument 1 is not a string.");
  if(!oper1->data.string) abort_interp("Argument 1 is a null string.");
  if(oper2->type != PROG_STRING) abort_interp("Argument 2 is not a string.");
  if(!oper2->data.string) abort_interp("Argument 2 is a null string.");
  newname = oper1->data.string->data;
  oldname = oper2->data.string->data; /* ( s<old> s<new> -- i ) */
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name( newname )))
      abort_interp( "Invalid file name. (2)");
  if ( strchr( newname, '$' ) == NULL )
    newname = set_directory(newname);
  else
    newname = parse_token( newname );
  if ( newname == NULL )
    abort_interp( "Invalid shortcut used. (2)" );   
  strcpy( tempB, newname );
  if (!(valid_name(oldname)))
      abort_interp( "Invalid file name. (1)");
  if ( strchr( oldname, '$' ) == NULL )
    oldname = set_directory(oldname);
  else
    oldname = parse_token( oldname );
  if ( oldname == NULL )
    abort_interp( "Invalid shortcut used. (1)" );
  newname = tempB;
#endif
  result = rename(oldname, newname);
  if(tp_log_files)
    log2filetime("logs/files", "#%d by %s FREN: %s -> %s \n", program, unparse_object(player, player), oper2->data.string->data, oper1->data.string->data); 
  CLEAR(oper1);
  CLEAR(oper2);
  PushInt(result);
} 
Example #21
0
void
prim_descr_setuser(PRIM_PROTOTYPE)
{
    char *ptr;

    CHECKOP(3);
    oper3 = POP();
    oper2 = POP();
    oper1 = POP();

    if (mlev < (tp_compatible_muf ? LMAGE : LARCH))
	abort_interp(tp_compatible_muf ? "Mage prim" : "Arch prim");
    if (oper1->type != PROG_INTEGER)
	abort_interp("Integer descriptor number expected (1)");
    if (oper2->type != PROG_OBJECT)
	abort_interp("Player dbref expected (2)");
    ref = oper2->data.objref;
    if (ref != NOTHING && !valid_player(oper2))
	abort_interp("Player dbref expected (2)");
    if (oper3->type != PROG_STRING)
	abort_interp("Password string expected");
    ptr = oper3->data.string? oper3->data.string->data : "";
    if ((ref != NOTHING) && DBFETCH(ref)->sp.player.password &&
	(*DBFETCH(ref)->sp.player.password) &&
	strcmp(ptr, DBFETCH(ref)->sp.player.password)
    )	abort_interp("Incorrect password");

    if (ref != NOTHING) {
	log_status("SUID: %d %s to %s(%d)\n",
		oper1->data.number, unparse_object(MAN, player), NAME(ref), ref);
    }
    tmp = oper1->data.number;

    CLEAR(oper1);
    CLEAR(oper2);
    CLEAR(oper3);

    result = pset_user(tmp, ref);

    PushInt(result);
}
Example #22
0
void prim_fsinfo(PRIM_PROTOTYPE) 
{ 
  struct statfs fs; 
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  /* Returns: */ 
  /* Magic Number, Total Blocks, Free Blocks, Available Blocks, Total Files, */ 
  /* Free Files, Block Size (bytes), and Max Name Length. */ 
  statfs("/", &fs); 
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s FSINFO \n", program, unparse_object(player, player)); 
  PushInt(fs.f_type); 
  PushInt(fs.f_blocks); 
  PushInt(fs.f_bfree); 
  PushInt(fs.f_bavail); 
  PushInt(fs.f_files); 
  PushInt(fs.f_ffree); 
  PushInt(fs.f_bsize); 
  PushInt(fs.f_namelen); 
}
Example #23
0
void prim_fappend(PRIM_PROTOTYPE)
{
  FILE *fh;
  char *filename;
  char *writestring;
  CHECKOP(2);
  oper1 = POP();
  oper2 = POP();
  if (getuid() == 0 ) 
    abort_interp("Muck is running under root privs, file prims disabled.");
  if (mlev < LBOY) abort_interp("BOY primitive only.");  
  if(oper1->type != PROG_STRING) abort_interp("Argument 1 is not a string.");
  if(!oper1->data.string) abort_interp("Argument 1 is a null string.");
  if(oper2->type != PROG_STRING) abort_interp("Arguement 2 is not a string.");
  if(!oper2->data.string) abort_interp("Arguement 2 is a null string.");
  filename = oper1->data.string->data;
  writestring = oper2->data.string->data;
#ifdef SECURE_FILE_PRIMS
  if (!(valid_name(filename)))
      abort_interp( "Invalid file name.");
  if ( strchr( filename, '$' ) == NULL )
    filename = set_directory(filename);
  else
    filename = parse_token( filename );
  if ( filename == NULL )
    abort_interp( "Invalid shortcut used." );
#endif
  fh = fopen(filename, "a");
  if (fh == NULL) { result = 0; } else {
    fputs(writestring, fh);
    fclose(fh);
    result = 1;
    if(tp_log_files)
      log2filetime("logs/files", "#%d by %s FAPPEND: %s \n", program, unparse_object(player, player), oper1->data.string->data); 
  }
  CLEAR(oper1);
  CLEAR(oper2);
  PushInt(result);
}
Example #24
0
/** Unlink an exit or room.
 * \verbatim
 * This is the top-level function for @unlink, which can unlink an exit
 * or remove a drop-to from a room.
 * \endverbatim
 * \param player the enactor.
 * \param name name of the object to unlink.
 */
void
do_unlink(dbref player, const char *name)
{
  dbref exit_l, old_loc;
  long match_flags = MAT_EXIT | MAT_HERE | MAT_ABSOLUTE;

  if (!Wizard(player)) {
    match_flags |= MAT_CONTROL;
  }
  switch (exit_l = match_result(player, name, TYPE_EXIT, match_flags)) {
  case NOTHING:
    notify(player, T("Unlink what?"));
    break;
  case AMBIGUOUS:
    notify(player, T("I don't know which one you mean!"));
    break;
  default:
    if (!controls(player, exit_l)) {
      notify(player, T("Permission denied."));
    } else {
      switch (Typeof(exit_l)) {
      case TYPE_EXIT:
        old_loc = Location(exit_l);
        Location(exit_l) = NOTHING;
        notify_format(player, T("Unlinked exit #%d (Used to lead to %s)."),
                      exit_l, unparse_object(player, old_loc));
        break;
      case TYPE_ROOM:
        Location(exit_l) = NOTHING;
        notify(player, T("Dropto removed."));
        break;
      default:
        notify(player, T("You can't unlink that!"));
        break;
      }
    }
  }
}
Example #25
0
/* do_link
 *
 * Use this to link to a room that you own.  It also sets home for
 * objects and things, and drop-to's for rooms.
 * It seizes ownership of an unlinked exit, and costs 1 penny
 * plus a penny transferred to the exit owner if they aren't you
 *
 * All destinations must either be owned by you, or be LINK_OK.
 */
void
do_link(int descr, dbref player, const char *thing_name, const char *dest_name)
{
    dbref good_dest[MAX_LINKS];
    int ndest, i;
    struct match_data md;
    char buf[BUFFER_LEN];
    dbref thing, dest;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (Guest(player)) {
        anotify_fmt(player, CFAIL "%s", tp_noguest_mesg);
        return;
    }

    init_match(descr, player, thing_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_registered(&md);

    if (Mage(OWNER(player)))
        match_player(&md);

    if ((thing = noisy_match_result(&md)) == NOTHING)
        return;

    switch (Typeof(thing)) {
        case TYPE_EXIT:
            /* we're ok, check the usual stuff */
            if (DBFETCH(thing)->sp.exit.ndest != 0) {
                if (controls(player, thing)) {
                    if ((DBFETCH(thing)->sp.exit.dest)[0] != NIL) {
                        anotify_nolisten2(player,
                                          CINFO "That exit is already linked.");
                        return;
                    }
                } else {
                    anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                    return;
                }
            }

            /* handle costs */
            if (OWNER(thing) == OWNER(player)) {
                if (!payfor(player, tp_link_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                tp_link_cost,
                                (tp_link_cost == 1) ? tp_penny : tp_pennies);
                    return;
                }
            } else {
                if (!payfor(player, tp_link_cost + tp_exit_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                (tp_link_cost + tp_exit_cost),
                                (tp_link_cost + tp_exit_cost ==
                                 1) ? tp_penny : tp_pennies);
                    return;
                } else if (!Builder(player)) {
                    anotify_nolisten2(player, CFAIL NOBBIT_MESG);
                    return;
                } else {
                    /* pay the owner for his loss */
                    dbref owner = OWNER(thing);

                    DBFETCH(owner)->sp.player.pennies += tp_exit_cost;
                    DBDIRTY(owner);
                }
            }

            /* link has been validated and paid for; do it */
            OWNER(thing) = OWNER(player);

            if (!
                (ndest =
                 link_exit(descr, player, thing, (char *) dest_name,
                           good_dest))) {
                anotify_nolisten2(player, CFAIL "No destinations linked.");
                DBFETCH(player)->sp.player.pennies += tp_link_cost; /* Refund! */
                DBDIRTY(player);
                break;
            }

            DBFETCH(thing)->sp.exit.ndest = ndest;
            if (DBFETCH(thing)->sp.exit.dest)
                free(DBFETCH(thing)->sp.exit.dest);

            DBFETCH(thing)->sp.exit.dest =
                (dbref *) malloc(sizeof(dbref) * ndest);
            for (i = 0; i < ndest; i++)
                (DBFETCH(thing)->sp.exit.dest)[i] = good_dest[i];
            break;
        case TYPE_THING:
        case TYPE_PLAYER:
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_absolute(&md);
            match_registered(&md);
            match_me(&md);
            match_here(&md);
            match_null(&md);

            if (Typeof(thing) == TYPE_THING)
                match_possession(&md);
            if ((dest = noisy_match_result(&md)) == NOTHING)
                return;
	    if (Typeof(thing) == TYPE_THING && dest == NIL) {
                anotify_fmt(player, CFAIL "%s", "You cannot HOME a THING to NIL.");
                return;		
	    }
            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                return;
            }
            if (parent_loop_check(thing, dest)) {
                anotify_nolisten2(player,
                                  CFAIL "That would cause a parent paradox.");
                return;
            }
            /* do the link */
            if (Typeof(thing) == TYPE_THING) {
                DBFETCH(thing)->sp.thing.home = dest;
            } else
                DBFETCH(thing)->sp.player.home = dest;
            sprintf(buf, CSUCC "%s's home set to %s.",
                    NAME(thing), unparse_object(player, dest));
            anotify_nolisten2(player, buf);
            break;
        case TYPE_ROOM:        /* room dropto's */
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_possession(&md);
            match_registered(&md);
            match_absolute(&md);
            match_home(&md);
            match_null(&md);

            if ((dest = noisy_match_result(&md)) == NOTHING)
                break;

            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)
                || (thing == dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
            } else {
                DBFETCH(thing)->sp.room.dropto = dest; /* dropto */
                sprintf(buf, CSUCC "%s's dropto set to %s.",
                        NAME(thing), unparse_object(player, dest));
                anotify_nolisten2(player, buf);
            }

            break;
        case TYPE_PROGRAM:
            anotify_nolisten2(player,
                              CFAIL "You can't link programs to things!");
            break;
        default:
            anotify_nolisten2(player, CFAIL "Weird object type.");
            log_status("*BUG: weird object: Typeof(%d) = %d\n",
                       thing, Typeof(thing));
            break;
    }
    DBDIRTY(thing);
    return;
}
Example #26
0
void 
check_room(dbref obj)
{
    printf("Dropto: %s\n", unparse_object(me, DBFETCH(obj)->sp.room.dropto));
    printf("First exit: %s\n", unparse_object(me, DBFETCH(obj)->exits));
}
Example #27
0
/** Link an exit, room, player, or thing.
 * \verbatim
 * This is the top-level function for @link, which is used to link an
 * exit to a destination, set a player or thing's home, or set a
 * drop-to on a room.
 *
 * Linking an exit usually seizes ownership of the exit and costs 1 penny.
 * 1 penny is also transferred to the former owner.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to link.
 * \param room_name the name of the link destination.
 * \param preserve if 1, preserve ownership and zone data on exit relink.
 */
void
do_link(dbref player, const char *name, const char *room_name, int preserve)
{
  /* Use this to link to a room that you own.
   * It usually seizes ownership of the exit and costs 1 penny,
   * plus a penny transferred to the exit owner if they aren't you.
   * You must own the linked-to room AND specify it by room number.
   */

  dbref thing;
  dbref room;

  if (!room_name || !*room_name) {
    do_unlink(player, name);
    return;
  }
  if (!IsRoom(player) && GoodObject(Location(player)) &&
      IsExit(Location(player))) {
    notify(player, T("You somehow wound up in a exit. No biscuit."));
    return;
  }
  if ((thing = noisy_match_result(player, name, TYPE_EXIT, MAT_EVERYTHING))
      != NOTHING) {
    switch (Typeof(thing)) {
    case TYPE_EXIT:
      if ((room = check_var_link(room_name)) == NOTHING)
        room = parse_linkable_room(player, room_name);
      if (room == NOTHING)
        return;
      if (GoodObject(room) && !can_link_to(player, room)) {
        notify(player, T("Permission denied."));
        break;
      }
      /* We may link an exit if it's unlinked and we pass the link-lock
       * or if we control it.
       */
      if (!(controls(player, thing)
            || ((Location(thing) == NOTHING)
                && eval_lock(player, thing, Link_Lock)))) {
        notify(player, T("Permission denied."));
        return;
      }
      if (preserve && !Wizard(player)) {
        notify(player, T("Permission denied."));
        return;
      }
      /* handle costs */
      if (Owner(thing) == Owner(player)) {
        if (!payfor(player, LINK_COST)) {
          notify_format(player, T("It costs %d %s to link this exit."),
                        LINK_COST, ((LINK_COST == 1) ? MONEY : MONIES));
          return;
        }
      } else {
        if (!payfor(player, LINK_COST + EXIT_COST)) {
          int a = LINK_COST + EXIT_COST;
          notify_format(player, T("It costs %d %s to link this exit."), a,
                        ((a == 1) ? MONEY : MONIES));
          return;
        } else if (!preserve) {
          /* pay the owner for his loss */
          giveto(Owner(thing), EXIT_COST);
          chown_object(player, thing, player, 0);
        }
      }

      /* link has been validated and paid for; do it */
      if (!preserve) {
        Owner(thing) = Owner(player);
        Zone(thing) = Zone(player);
      }
      Location(thing) = room;

      /* notify the player */
      notify_format(player, T("Linked exit #%d to %s"), thing,
                    unparse_object(player, room));
      break;
    case TYPE_PLAYER:
    case TYPE_THING:
      if ((room =
           noisy_match_result(player, room_name, NOTYPE,
                              MAT_EVERYTHING)) == NOTHING) {
        notify(player, T("No match."));
        return;
      }
      if (IsExit(room)) {
        notify(player, T("That is an exit."));
        return;
      }
      if (thing == room) {
        notify(player, T("You may not link something to itself."));
        return;
      }
      /* abode */
      if (!controls(player, room) && !Abode(room)) {
        notify(player, T("Permission denied."));
        break;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else if (room == HOME) {
        notify(player, T("Can't set home to home."));
      } else {
        /* do the link */
        Home(thing) = room;     /* home */
        if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
          notify(player, T("Home set."));
      }
      break;
    case TYPE_ROOM:
      if ((room = parse_linkable_room(player, room_name)) == NOTHING)
        return;
      if ((room != HOME) && (!IsRoom(room))) {
        notify(player, T("That is not a room!"));
        return;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else {
        /* do the link, in location */
        Location(thing) = room; /* dropto */
        notify(player, T("Dropto set."));
      }
      break;
    default:
      notify(player, T("Internal error: weird object type."));
      do_log(LT_ERR, NOTHING, NOTHING,
             "Weird object! Type of #%d is %d", thing, Typeof(thing));
      break;
    }
  }
}
Example #28
0
static void unparse_boolexp1( dbref player, BOOLEXP *b, char outer_type, int format ) {
    ATTR *ap;

    char sep_ch;

    char *buff;

    if( b == TRUE_BOOLEXP ) {
        if( format == F_EXAMINE ) {
            safe_str( ( char * ) "*UNLOCKED*", boolexp_buf, &buftop );
        }
        return;
    }
    switch( b->type ) {
    case BOOLEXP_AND:
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( AND_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_OR:
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( '(', boolexp_buf, &buftop );
        }
        unparse_boolexp1( player, b->sub1, b->type, format );
        safe_chr( OR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub2, b->type, format );
        if( outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND ) {
            safe_chr( ')', boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_NOT:
        safe_chr( '!', boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_INDIR:
        safe_chr( INDIR_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_IS:
        safe_chr( IS_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CARRY:
        safe_chr( CARRY_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_OWNER:
        safe_chr( OWNER_TOKEN, boolexp_buf, &buftop );
        unparse_boolexp1( player, b->sub1, b->type, format );
        break;
    case BOOLEXP_CONST:
        if( !mudstate.standalone ) {
            switch( format ) {
            case F_QUIET:

                /*
                 * Quiet output - for dumps and internal use.
                 * Always #Num
                 */

                safe_str( ( char * ) unparse_object_quiet( player,
                          b->thing ), boolexp_buf, &buftop );
                break;
            case F_EXAMINE:

                /*
                 * Examine output - informative. *
                 * Name(#Num) or Name
                 */

                buff = unparse_object( player, b->thing, 0 );
                safe_str( buff, boolexp_buf, &buftop );
                free_lbuf( buff );
                break;
            case F_DECOMPILE:

                /*
                 * Decompile output - should be usable on
                 * other MUSHes. *Name if player, Name if
                 * thing, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                case TYPE_THING:
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
                break;
            case F_FUNCTION:

                /*
                 * Function output - must be usable by @lock
                 * cmd.  *Name if player, else #Num
                 */

                switch( Typeof( b->thing ) ) {
                case TYPE_PLAYER:
                    safe_chr( '*', boolexp_buf, &buftop );
                    safe_name( b->thing, boolexp_buf,
                               &buftop );
                    break;
                default:
                    safe_dbref( boolexp_buf, &buftop,
                                b->thing );
                    break;
                }
            }
        } else {
            safe_str( ( char * ) unparse_object_quiet( player,
                      b->thing ), boolexp_buf, &buftop );
        }
        break;
    case BOOLEXP_ATR:
    case BOOLEXP_EVAL:
        if( b->type == BOOLEXP_EVAL ) {
            sep_ch = '/';
        } else {
            sep_ch = ':';
        }
        ap = atr_num( b->thing );
        if( ap && ap->number ) {
            safe_str( ( char * ) ap->name, boolexp_buf, &buftop );
        } else {
            safe_ltos( boolexp_buf, &buftop, b->thing );
        }
        safe_chr( sep_ch, boolexp_buf, &buftop );
        safe_str( ( char * ) b->sub1, boolexp_buf, &buftop );
        break;
    default:
        log_write_raw( 1, "ABORT! unparse.c, bad boolexp type in unparse_boolexp1().\n" );
        abort();
        break;
    }
}
Example #29
0
/*
 * do_create
 *
 * Use this to create an object.
 */
void
do_create(dbref player, char *name, char *acost)
{
    dbref loc;
    dbref thing;
    int cost;

    static char buf[BUFFER_LEN];
    char buf2[BUFFER_LEN];
    char *rname, *qname;

    if (!Builder(player)) {
        anotify_nolisten2(player, CFAIL NOBBIT_MESG);
        return;
    }

    if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    }

    strcpy(buf2, acost);
    for (rname = buf2; (*rname && (*rname != '=')); rname++) ;
    qname = rname;
    if (*rname)
        *(rname++) = '\0';
    while ((qname > buf2) && (isspace(*qname)))
        *(qname--) = '\0';
    qname = buf2;
    for (; *rname && isspace(*rname); rname++) ;

    cost = atoi(qname);
    if (*name == '\0') {
        anotify_nolisten2(player, CINFO "Create what?");
        return;
    } else if (!ok_name(name)) {
        anotify_nolisten2(player, CINFO "That's a silly name for a thing!");
        return;
    } else if (cost < 0) {
        anotify_nolisten2(player,
                          CINFO
                          "You can't create an object for less than nothing!");
        return;
    } else if (cost < tp_object_cost) {
        cost = tp_object_cost;
    }
    if (!payfor(player, cost)) {
        anotify_fmt(player, CFAIL "You don't have enough %s.", tp_pennies);
        return;
    } else {
        /* create the object */
        thing = new_object(player);

        /* initialize everything */
        NAME(thing) = alloc_string(name);
        DBFETCH(thing)->location = player;
        OWNER(thing) = OWNER(player);
        DBFETCH(thing)->sp.thing.value = OBJECT_ENDOWMENT(cost);
        DBFETCH(thing)->exits = NOTHING;
        FLAGS(thing) = TYPE_THING;

        /* endow the object */
        if (DBFETCH(thing)->sp.thing.value > tp_max_object_endowment) {
            DBFETCH(thing)->sp.thing.value = tp_max_object_endowment;
        }
        if ((loc = DBFETCH(player)->location) != NOTHING
            && controls(player, loc)) {
            DBFETCH(thing)->sp.thing.home = loc; /* home */
        } else {
            DBFETCH(thing)->sp.thing.home = player;
            /* set thing's home to player instead */
        }

        /* link it in */
        PUSH(thing, DBFETCH(player)->contents);
        DBDIRTY(player);

        /* and we're done */
        sprintf(buf, CSUCC "Object %s created.", unparse_object(player, thing));
        anotify_nolisten2(player, buf);
        DBDIRTY(thing);
    }
    if (*rname) {
        PData pdat;

        sprintf(buf, CINFO "Registered as $%s", rname);
        anotify_nolisten2(player, buf);
        sprintf(buf, "_reg/%s", rname);
        pdat.flags = PROP_REFTYP;
        pdat.data.ref = thing;
        set_property(player, buf, &pdat);

    }
}
Example #30
0
/*
 * do_dig
 *
 * Use this to create a room.
 */
void
do_dig(int descr, dbref player, const char *name, const char *pname)
{
    char *rname, *qname;
    dbref newparent;
    char rbuf[BUFFER_LEN];
    char qbuf[BUFFER_LEN];
    char buf[BUFFER_LEN];
    dbref room;
    struct match_data md;
    dbref parent;

    if (!Builder(player) && !tp_all_can_build_rooms) {
        anotify_nolisten2(player, CFAIL NOBBIT_MESG);
        return;
    }

    if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    }

    if (*name == '\0') {
        anotify_nolisten2(player, CINFO "You need name for the room.");
        return;
    }

    if (!ok_name(name)) {
        anotify_nolisten2(player, CINFO "That's a silly name for a room!");
        return;
    }

    if (!payfor(player, tp_room_cost)) {
        anotify_fmt(player, CFAIL "You don't have enough %s to dig a room.",
                    tp_pennies);
        return;
    }
    room = new_object(player);

    /* Initialize everything */
    newparent = DBFETCH(DBFETCH(player)->location)->location;
    while ((OkObj(newparent)) && !(FLAGS(newparent) & ABODE)
           && !(FLAG2(newparent) & F2PARENT))
        newparent = DBFETCH(newparent)->location;
    if (!OkObj(newparent)) {
        if (OkObj(tp_default_parent))
            newparent = tp_default_parent;
        else
            newparent = GLOBAL_ENVIRONMENT;
    }

    NAME(room) = alloc_string(name);
    DBFETCH(room)->location = newparent;
    OWNER(room) = OWNER(player);
    DBFETCH(room)->exits = NOTHING;
    DBFETCH(room)->sp.room.dropto = NOTHING;
    FLAGS(room) = TYPE_ROOM | (FLAGS(player) & JUMP_OK);
    PUSH(room, DBFETCH(newparent)->contents);
    DBDIRTY(room);
    DBDIRTY(newparent);

    sprintf(buf, CSUCC "Room %s created.", unparse_object(player, room));
    anotify_nolisten2(player, buf);

    strcpy(buf, pname);
    for (rname = buf; (*rname && (*rname != '=')); rname++) ;
    qname = rname;
    if (*rname)
        *(rname++) = '\0';
    while ((qname > buf) && (isspace(*qname)))
        *(qname--) = '\0';
    qname = buf;
    for (; *rname && isspace(*rname); rname++) ;
    rname = strcpy(rbuf, rname);
    qname = strcpy(qbuf, qname);

    if (*qname) {
        anotify_nolisten2(player, CNOTE "Trying to set parent...");
        init_match(descr, player, qname, TYPE_ROOM, &md);
        match_absolute(&md);
        match_registered(&md);
        match_here(&md);
        if ((parent = noisy_match_result(&md)) == NOTHING
            || parent == AMBIGUOUS) {
            anotify_nolisten2(player, CINFO "Parent set to default.");
        } else {
            if ((!can_link_to(player, Typeof(room), parent)
                 && !(FLAG2(parent) & F2PARENT)) || room == parent) {
                anotify_nolisten2(player,
                                  CFAIL
                                  "Permission denied.  Parent set to default.");
            } else {
                moveto(room, parent);
                sprintf(buf, CSUCC "Parent set to %s.",
                        unparse_object(player, parent));
                anotify_nolisten2(player, buf);
            }
        }
    }

    if (*rname) {
        PData pdat;

        sprintf(buf, "_reg/%s", rname);
        pdat.flags = PROP_REFTYP;
        pdat.data.ref = room;
        set_property(player, buf, &pdat);
        sprintf(buf, CINFO "Room registered as $%s", rname);
        anotify_nolisten2(player, buf);
    }
}