/
CDC-1.2b/
CDC-1.2b/src/
parent $mail_root
parent $named
object $mail_list

var $root child_index 6
var $root owners [$mail_list]
var $root owned [$mail_list]
var $root fertile 0
var $root inited 1
var $named name_aliases []
var $has_verbs verbs 0
var $mail_list notify [$mail_list]
var $mail_list last_received_on 0
var $mail_list senders 1
var $mail_list mail []
var $public public ['readable]
var $gendered gender $gender_neuter
var $described prose #[]
var $root manager $mail_list
var $root writable [$mail_list]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'mail_list
var $named name ['uniq, "mail_list"]
var $mail_list readers 0

method del_sender_from_notification
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.is_readable_by(who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = setremove(notify, who);
.

method add_sender_to_notification
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.is_readable_by(who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = [@notify, who];
.

method list_is_sendable_by
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(senders) == 'list)
        return who in senders;
    return senders;
.

method list_is_readable_by
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(readers) == 'list)
        return who in readers;
    return readers;
.

method set_name
    arg new_name, [args];
    var old_name;
    
    old_name = .name();
    if (new_name && ((new_name[1]) == "*"))
        new_name = substr(new_name, 2);
    (> pass(new_name, @args) <);
    (| $mail_db.key_changed(old_name, new_name) |);
.

method start
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    if (mail)
        return mail[1];
    return 0;
.

method last_received_on
    return last_received_on;
.

method recent_mail
    arg [threshold];
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    threshold = [@threshold, 30][1];
    if (listlen(mail) < threshold)
        return mail;
    return sublist(mail, listlen(mail) - threshold);
.

method set_notify
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    notify = new_value;
.

method set_senders
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    senders = new_value;
.

method notify
    (> .perms(sender(), 'manager) <);
    return notify;
.

method del_mail
    arg old_mail, [sender];
    
    sender = [@sender, sender()][1];
    if ((!($mail_utils.has_mail_perms(caller()))) && ((sender != (old_mail.from())) || (> .perms(sender()) <)))
        throw(~perm, ((sender.namef()) + " cannot remove ") + (old_mail.name()));
    old_mail.del_recipient(this());
    mail = mail.del(old_mail);
.

method _announce_new_mail
    arg new_mail;
    var line, who, n;
    
    (> .perms(sender(), 'this) <);
    if (!notify)
        return;
    line = ((((.mail_name()) + " has been sent new mail by ") + ((new_mail.from()).namef())) + ": ") + (new_mail.subject());
    for who in (notify)
        (| who.tell(line.chop(who.linelen())) |);
.

method mail
    if (!(.list_is_sendable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    return mail;
.

method add_mail
    var new_mail;
    
    (> .perms(caller(), $mail) <);
    last_received_on = time();
    new_mail = sender();
    
    // make sure we do not already have it
    if (new_mail in mail)
        return;
    
    // add it
    mail = mail.add(new_mail);
    ._announce_new_mail(new_mail);
.

method senders
    (> .perms(sender(), 'manager) <);
    return senders;
.

method mail_name
    return $mail_utils.mail_name(this());
.

method init_mail_list
    (> .perms(caller(), $root) <);
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [.manager()];
    if (!(.has_ancestor($user))) {
        readers = 1;
        (| $mail_db.insert(.name(), this()) |);
    } else {
        readers = [.manager()];
    }
.

method uninit_mail_list
    var m;
    
    (> .perms(caller(), $root) <);
    for m in (mail)
        .del_mail(let[1]);
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [];
    if (!(.has_ancestor($user)))
        (| $mail_db.remove(.name()) |);
.

method next
    arg current_mail;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return mail[(current_mail in mail) + 1];
.