/* 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"); }