lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

/*
** mailbox.c -- a mailbox to hold message references
**
** 950701, Deathblade: Created.
*/

#include <mudlib.h>
#include <security.h>
#include <classes.h>
#include <flags.h>

inherit M_ACCESS;

inherit CLASS_MAILMSG;

/*
** mailbox: maps message keys to flags
*/
private mapping mailbox = ([ ]);

/*
** Flags for the mail
*/
#define F_UNREAD	1
//### code assumes zero/non-zero; fix if more flags are added

/*
** Who is this mailbox for?
*/
private nosave string owner;

/*
** What is the current message index.  This value is 0-based and represents
** a message index for messages from the user's perspective.  The value 1
** corresponds to the first key in the (ordered) set of message keys in the
** mailbox.
*/
private nosave int message_index = 0;


private nomask string get_fname()
{
    return sprintf("/data/mail/mbox/%c/%s", owner[0], owner);
}

nomask void create(string the_owner)
{
    if ( !clonep() )
	return;

    if ( file_name(previous_object()) != MAILBOX_D )
	error("*Security violation: invalid creation");

    owner = the_owner;
    unguarded(1, (: restore_object, get_fname(), 1 :));
}
private nomask void save_me()
{
    unguarded(1, (: save_object, get_fname() :));
}
nomask void remove()
{
    destruct();
}

nomask string query_owner()
{
    return owner;
}

nomask class mail_msg get_one_message(int message_key)
{
    class mail_msg msg;

//### need some work on ensuring the call stack is correct
//    if ( !check_privilege(owner) )
    if ( this_user()->query_userid() != owner )
	error("security violation: you are not allowed to use this mailbox\n");

    if ( undefinedp(mailbox[message_key]) )
	return 0;

    msg = MAIL_D->get_one_message(message_key);
    if ( !msg )
    {
	/* damn. bad message. remove it from the mailbox. */
	map_delete(mailbox, message_key);
	save_me();
    }

    return msg;
}

nomask int query_message_index()
{
    return message_index;
}
nomask void set_message_index(int new_message_index)
{
    message_index = new_message_index;
}

nomask int * query_message_keys()
{
    return sort_array(keys(mailbox), 1);
}
nomask int query_message_count()
{
    return sizeof(mailbox);
}

nomask int query_message_read(int message_key)
{
    return mailbox[message_key];
}
nomask void set_message_read(int message_key)
{
    if ( mailbox[message_key] )
    {
	mailbox[message_key] = 0;
	save_me();
    }
}
nomask int query_unread_count()
{
    return implode(values(mailbox), (: $1 + $2 :));
}
nomask int first_unread_message()
{
    int * message_keys = query_message_keys();
    int message_key;
    int message_index;

    foreach ( message_key in message_keys )
    {
	if ( mailbox[message_key] )
	    return message_index;

	++message_index;
    }

    return -1;
}

nomask void delete_message(int message_key)
{
//### need some work on ensuring the call stack is correct
//    if ( !check_privilege(owner) )
    if ( this_user()->query_userid() != owner )
	error("security violation: you are not allowed to read this mail\n");

    if ( undefinedp(mailbox[message_key]) )
	error("non-existent message\n");

    MAIL_D->delete_mail(message_key, owner);
    if( query_unread_count() <= message_index ) message_index--;
    map_delete(mailbox, message_key);

    save_me();
}

nomask void nuke_mailbox()
{
    if ( !check_previous_privilege(1) )
	error("security violation: illegal nuke of mailbox\n");

    foreach ( int message_key in keys(mailbox) )
	MAIL_D->delete_mail(message_key, owner);

    mailbox = ([ ]);
    unguarded(1, (: rm, get_fname() + __SAVE_EXTENSION__ :));
}

//### temp functions?  wait and see

nomask void receive_new_message(int message_key)
{
    object user;

//    if( previous_object() != find_object( MAIL_D ) )
//	return;

    mailbox[message_key] = F_UNREAD;
    save_me();

    if ( (user = find_user(owner)) &&
	 user->query_body()->test_flag(F_BIFF) )
	tell(user, ">>You have new mail<<\n");
}