/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/*
 * This controls the write permisions for everything in the mud.
 * It defaults to 0 if all else fails.
 * Any permisions can be overridden by the global permision giving/
 * changeing code.
 *
 * The master.c's in the domain and wizard dirs will be checked if
 * any access is done to them.  This is a very flexible system,
 * but perhaps a little hard for some people to use.
 */
int     valid_write( string path, mixed euid, string func )
{
    string *path_array;
    string  master;

    if( objectp( euid ) )
	euid = geteuid( euid );

    /* if it's a high programmer they can write anywhere */
    if( high_programmer( euid ) )
	return 1;

    path_array = explode( path, "/" );

    /* if null return, else remove any "." and null dir names. */
    if( path_array )
	path_array = path_array - ({ ".", "" });
    else
	return 0;

    /* is it a /tmp object writing to /tmp? if so, it's ok */
    if( euid == "tmp" )
    {
	return path_array[ 0 ] == "tmp";
    }

    /* this lets anything write the file "ERROR_LOG" in any dir */
    if( path_array[ sizeof( path_array ) - 1 ] == ERROR_LOG )
	return 1;

    /* don't know what this does yet */
    if( check_permission( euid, path_array, WRITE_MASK ) )
	return 1;

    /* top level dir access */
    switch( path_array[ 0 ] )
    {
	case "log":
	    if( func == "log_file" )
	    {
		return 1;
	    }
	    break;

	case "open":
	case "ftp":
	case "tmp":
	    return 1;

	case "net":
	    return euid == "Network stuff";

	case "ims":
	case "obj":
	    if( euid == "ims" )
	    {
		return 1;
	    }
	    break;

	case "w":
	case "d":		/* if it's in /w, let the creator write to thier dir, */
	    /* high programs can write anywhere, */
	    /* dont know what: if sizeof path is 1 does. */
	    if( (path_array[ 0 ] == "w" ? path_array[ 1 ] :
		 capitalize( path_array[ 1 ] )) ==
		    euid || sizeof( path_array ) == 1 )
	    {
		return 1;
	    }

	    /* let lords write to /w */
	    if( (path_array[ 0 ] == "w") && query_lord( euid ) )
	    {
		return 1;
	    }

	    /* check for local master.c object */
	    master = path_array[ 0 ] + "/" + path_array[ 1 ] + "/master";

	    if( find_object( master ) &&
		    !checked_master[ master ] &&
/* File_size check added by Newstyle, 22/12/93. Merry Xmas */
		    file_size( master + ".c" ) > 0 &&
		    !catch( master->dead_frogs() ) )
	    {
		return( find_object( master ) == previous_object() ||
			find_object( master )->valid_write( path_array, euid, func ) );
	    }
	    checked_master[ master ] = 1;
	    break;

	case "save":		/* /room, and mailer can write to /save */
	    if( euid == "Room" ||
		    (sizeof( path_array ) == 3 &&
		     euid == "mailer" &&
		     path_array[ 1 ] == "post") )
	    {
		return 1;
	    }
    }				/* switch() */
    return 0;
}				/* valid_write() */