Generic Large-Capacity Mail Recipient #9

Parent #37Owner #29Flags read, fertileSource hellcore/hellcore.db

Aliases: Generic Large-Capacity Mail Recipient

43 verbs · 35 properties · 2 children

Verbs

VerbSpecFlagsDefinerLines
_genpropthis none thisrxd#910
_makethis none thisrxd#97
_killthis none thisrxd#95
_getthis none thisrxd#91
_putthis none thisrxd#91
_ordthis none thisrxd#91
_makemsgthis none thisrxd#910
_killmsgthis none thisrxd#95
_message_numthis none thisrxd#91
_message_datethis none thisrxd#91
_message_hdrthis none thisrxd#91
_message_textthis none thisrxd#95
_lt_msgnumthis none thisrxd#91
_lt_msgdatethis none thisrxd#91
receive_batchthis none thisrxd#920
receive_messagethis none thisrxd#98
messages_in_seqthis none thisrxd#920
display_seq_headersthis none thisrxd#929
display_seq_fullthis none thisrxd#922
list_rmmthis none thisrxd#934
undo_rmmthis none thisrxd#925
expunge_rmmthis none thisrxd#914
rm_message_seqthis none thisrxd#933
renumberthis none thisrxd#957
length_all_msgsthis none thisrxd#91
length_num_lethis none thisrxd#91
length_date_lethis none thisrxd#91
exists_num_eqthis none thisrxd#91
new_message_numthis none thisrxd#911
from_msg_seqthis none thisrxd#927
%from_msg_seqthis none thisrxd#929
to_msg_seqthis none thisrxd#928
%to_msg_seqthis none thisrxd#929
subject_msg_seqthis none thisrxd#922
body_msg_seqthis none thisrxd#930
date_sortthis none thisrxd#91
_fix_last_msg_datethis none thisrxd#92
__fixthis none thisrxd#920
init_for_corethis none thisrxd#95
length_date_gtthis none thisrxd#96
_repairthis none thisrx#9147
repairthis none nonerxd#917
restore_fromthis none thisrxd#966

Properties

PropertyDefinerFlagsOwnerValue
summary_uses_body#9rc#290
_mgr#9rc#29#7
mowner#9r#29#29
_genprop#9r#29""
moderator_notify#37rc#29<clear>
last_msg_date#37r#290
messages_going#37#29{}
moderated#37rc#29<clear>
moderator_forward#37rc#29<clear>
writers#37rc#29<clear>
readers#37rc#29<clear>
mail_notify#37r#29{}
mail_forward#37r#29<clear>
expire_period#37r#29<clear>
last_used_time#37r#29<clear>
messages#37#29<clear>
rmm_own_msgs#37rc#29<clear>
guests_can_send_here#37rc#29<clear>
messages_kept#37r#29<clear>
registered_email#37#29<clear>
email_validated#37#29<clear>
validation_password#37#29<clear>
barcolor#37rc#29<clear>
hidden_subjects#37rc#29<clear>
hidden_content#37rc#29<clear>
aliases#1r#29{"Generic Large-Capacity Mail Recipient"}
description#1rc#29
list of 41{"Generic Large Capacity Mail Recipient", "-------------------------------------", "Since any modifications to large lists entail copying the entire list over, operations on ordinary mail recipients having large numbers of messages, that actually change the content of .messages will take inordinately long. Thus we have this version which makes use of the $biglist package, scattering the messages onto numerous properties so that write operations involving only a few messages will not require recopying of the entire list.", "", "In nearly all respects it behaves as the ordinary Mail Recipient, except that it is faster for certain kinds of operations.", "", "Certain unimplemented verbs, like :date_sort(), and :messages() currently return E_VERBNF.", "", "To convert an existing $mail_recipient-child (call it #MR) into a $big_mail_recipient-child the basic procedure is", "", " ;;something.foo= #MR:messages();", " @rmm 1-$ from #MR", " @unrmm expunge", " @chparent #MR to $big_mail_recipient", " ;#MR:receive_batch(@something.foo);", "", "Reconstructing Damaged Big Mail Recipients", "------------------------------------------", "On rare occasions, the tree structure created by $biglist can be corrupted (this can happen on lists sufficiently large that a list-modification operation (e.g., @rmm, @renumber) runs out of ticks/seconds). In the vast majority of such cases, your messages are all still there; it's simply that the tree we use for finding/searching them is messed up.", "", "To recover messages from a damaged big mail recipient (#DBMR)", " --- read to the end before you start typing any commands ---", "", "create a fresh $big_mail_recipient (#NEWBMR) and then do the following:", "", " ;#NEWBMR:restore_from(#DBMR)", "", "When this finishes, #NEWBMR will contain all of the mail messages we were able to find. (note that this will include messages that you had deleted from #DBMR but not expunged). #NEWMBR should thenceforth be useable in place of #DBMR, however if #DBMR contains custom verbs and non-clear properties, these will also need to be copied over.", "", "Alternatively, one may do", "", " @copyobject #DBMR to #TEMPBMR", " ;#DBMR:restore_from(#TEMPBMR)", "", "to rebuild #DBMR in place. This, however, will take about twice as long.", "", "oooooooooooooooooooooooooooooooo", "WARNING!!! WARNING!!! WARNING!!!", "oooooooooooooooooooooooooooooooo", "", "Calling #OBJ:restore_from(...) COMPLETELY AND IRREVOCABLY REMOVES ALL MESSAGES from the object that it is run on (#OBJ); you MUST be sure to EITHER have made a copy of #OBJ OR be doing the restore to a DIFFERENT object."}
object_size#1r#29{37720, 1298433815}
hidden_verbs#1rc#29<clear>
phelp_msg#1rc#29<clear>
weight#1rc#29<clear>
owner_verbs#1rc#29<clear>
plural_name#1rc#29<clear>
client_image#1rc#29<clear>
listening#1rc#29<clear>

Ancestry

Ancestors (nearest first): #37 Generic Mail Recipient#1 root

Children: #12 Player-Creation-Log, #82 Password-Request-Log

Call graph

calls n9_1 #9:_make n9_0 #9:_genprop n9_1->n9_0 n9_6 #9:_makemsg n9_6->n9_1 n9_7 #9:_killmsg n9_2 #9:_kill n9_7->n9_2 n9_11 #9:_message_text n37_3 #37:is_readable_by n9_11->n37_3 n9_14 #9:receive_batch n9_14->n9_6 n37_2 #37:is_writable_by n9_14->n37_2 n9_28 #9:new_message_num n9_14->n9_28 n48_7 #48:running_out_of_time n9_14->n48_7 n107_43 #107:tell n9_14->n107_43 n37_13 #37:ok n9_28->n37_13 n9_8 #9:_message_num n9_28->n9_8 n9_15 #9:receive_message n9_15->n9_6 n9_15->n37_2 n9_15->n9_28 n9_9 #9:_message_date n9_15->n9_9 n9_16 #9:messages_in_seq n9_16->n9_11 n9_16->n37_13 n9_16->n9_8 n48_8 #48:suspend_if_needed n9_16->n48_8 n9_17 #9:display_seq_headers n9_17->n107_43 n9_17->n37_13 n9_17->n48_8 n27_18 #27:contract n9_17->n27_18 n37_15 #37:parse_message_seq n9_17->n37_15 n27_2 #27:complement n9_17->n27_2 n9_24 #9:length_all_msgs n9_17->n9_24 n6_12 #6:linelen n9_17->n6_12 n20_2 #20:right n9_17->n20_2 n37_24 #37:msg_summary_line n9_17->n37_24 n9_24->n37_13 n9_18 #9:display_seq_full n9_18->n9_11 n9_18->n9_9 n9_18->n37_13 n9_18->n9_8 n9_18->n48_8 n37_32 #37:msg_full_text n9_18->n37_32 n9_19 #9:list_rmm n9_19->n107_43 n9_19->n37_13 n9_19->n9_8 n9_19->n20_2 n9_19->n37_24 n9_20 #9:undo_rmm n37_14 #37:ok_write n9_20->n37_14 n27_3 #27:union n9_20->n27_3 n27_17 #27:expand n9_20->n27_17 n9_36 #9:_fix_last_msg_date n9_20->n9_36 n9_21 #9:expunge_rmm n9_21->n37_14 n9_22 #9:rm_message_seq n9_22->n107_43 n9_22->n37_13 n9_22->n9_8 n9_22->n48_8 n9_22->n27_18 n9_22->n37_14 n9_22->n9_36 n37_19 #37:own_messages_filter n9_22->n37_19 n27_20 #27:intersection n9_22->n27_20 n27_4 #27:tostr n9_22->n27_4 n9_23 #9:renumber n9_23->n48_7 n9_23->n107_43 n9_23->n37_14 n9_23->n9_21 n9_25 #9:length_num_le n9_25->n37_13 n9_26 #9:length_date_le n9_26->n37_13 n9_27 #9:exists_num_eq n9_27->n37_13 n9_27->n9_8 n9_29 #9:from_msg_seq n9_29->n37_13 n9_29->n48_8 n27_0 #27:add n9_29->n27_0 n20_6 #20:english_list n9_29->n20_6 n9_30 #9:%from_msg_seq n9_30->n37_13 n9_30->n48_8 n9_30->n27_0 n9_30->n20_6 n9_31 #9:to_msg_seq n9_31->n37_13 n9_31->n48_8 n9_31->n27_0 n9_31->n20_6

Showing 48 of 68 verbs; 20 not shown.

Source

_genprop

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1gp = this._genprop;
2ngp = "";
3for i in [1..length(gp)]
4if (gp[i] != "z")
5ngp = (ngp + "bcdefghijklmnopqrstuvwxyz"[index("abcdefghijklmnopqrstuvwxy", gp[i])]) + gp[i + 1..length(gp)];
6return " " + (this._genprop = ngp);
7endif
8ngp = ngp + "a";
9endfor
10return " " + (this._genprop = ngp + "a");

_make

Spec this none thisFlags rxdOwner #361Definer #9

Referenced by

Source

1":_make(...) => new node with value {...}";
2if (!(caller in {this._mgr, this}))
3return E_PERM;
4endif
5prop = this:_genprop();
6`add_property(this, prop, args, {this.mowner, ""}) ! ANY';
7return prop;

_kill

Spec this none thisFlags rxdOwner #361Definer #9

Referenced by

Source

1":_kill(node) destroys the given node.";
2if (!(caller in {this, this._mgr}))
3return E_PERM;
4endif
5`delete_property(this, args[1]) ! ANY';

_get

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return (caller == this._mgr) ? `this.(args[1]) ! ANY' | E_PERM;

_put

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return (caller == this._mgr) ? this.(args[1]) = listdelete(args, 1) | E_PERM;

_ord

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return args[1][2..3];

_makemsg

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1":_makemsg(ord,msg) => leafnode for msg";
2"msg = $mail_agent:__convert_new(@args[2])";
3msg = args[2];
4if (caller != this)
5return E_PERM;
6elseif (h = "" in msg)
7return {this:_make(@msg[h + 1..$]), args[1], @msg[1..h - 1]};
8else
9return {0, args[1], @msg};
10endif

_killmsg

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (caller != this._mgr)
2return E_PERM;
3elseif (node = args[1][1])
4this:_kill(node);
5endif

_message_num

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1return args[2];

_message_date

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1return args[3];

_message_hdr

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1return args[3..$];

_message_text

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1if ((caller == this) || this:is_readable_by(caller_perms()))
2return {@args[3..$], @args[1] ? {"", @this.(args[1])} | {}};
3else
4return E_PERM;
5endif

_lt_msgnum

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return args[1] < args[2][1];

_lt_msgdate

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return args[1] < args[2][2];

receive_batch

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:is_writable_by(caller_perms()))
2return E_PERM;
3else
4new = this:new_message_num();
5msgtree = this.messages;
6for m in (args)
7msgtree = this._mgr:insert_last(msgtree, this:_makemsg(new, m[2]));
8new = new + 1;
9if ($command_utils:running_out_of_time())
10this.messages = msgtree;
11player:tell("... ", new);
12suspend(0);
13msgtree = this.messages;
14new = this:new_message_num();
15endif
16endfor
17this.messages = msgtree;
18this.last_used_time = time();
19return 1;
20endif

receive_message

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:is_writable_by(caller_perms()))
2return E_PERM;
3else
4this.messages = this._mgr:insert_last(this.messages, msg = this:_makemsg(new = this:new_message_num(), args[1]));
5this.last_msg_date = this:_message_date(@msg);
6this.last_used_time = time();
7return new;
8endif

messages_in_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:ok(caller, caller_perms()))
2return E_PERM;
3elseif (typeof(seq = args[1]) != LIST)
4x = this._mgr:find_nth(this.messages, seq);
5return {this:_message_num(@x), this:_message_text(@x)};
6else
7msgs = {};
8while (seq)
9handle = this._mgr:start(this.messages, seq[1], seq[2] - 1);
10while (handle)
11for x in (handle[1])
12msgs = {@msgs, {this:_message_num(@x), this:_message_text(@x)}};
13endfor
14handle = this._mgr:next(@listdelete(handle, 1));
15$command_utils:suspend_if_needed(0);
16endwhile
17seq = seq[3..$];
18endwhile
19return msgs;
20endif

display_seq_headers

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1":display_seq_headers(msg_seq[,cur[,last_read_date]])";
2"This is the default header display routine.";
3"Prints a list of headers of messages on this to player.  msg_seq is the handle returned by this:parse_message_seq(...).  cur is the player's current message.  last_read_date is the date of the last of the already-read messages.";
4if (!this:ok(caller, caller_perms()))
5return E_PERM;
6endif
7getmsg = this.summary_uses_body ? "_message_text" | "_message_hdr";
8{seq, ?cur = 0, ?last_old = $maxint} = args;
9keep_seq = {@$seq_utils:contract(this:kept_msg_seq(), $seq_utils:complement(seq, 1, this:length_all_msgs())), $maxint};
10k = 1;
11mcount = 0;
12width = player:linelen();
13while (seq)
14handle = this._mgr:start(this.messages, seq[1], seq[2] - 1);
15while (handle)
16for x in (handle[1])
17$command_utils:suspend_if_needed(0);
18if (keep_seq[k] <= (mcount = mcount + 1))
19k = k + 1;
20endif
21annot = (x[3] > last_old) ? "+" | ((k % 2) ? " " | "=");
22line = tostr($string_utils:right(x[2], 5, (cur == x[2]) ? ">" | " "), ":", annot, " ", this:msg_summary_line(@this:(getmsg)(@x)));
23player:tell(line[1..min(width, $)]);
24endfor
25handle = this._mgr:next(@listdelete(handle, 1));
26endwhile
27seq = seq[3..$];
28endwhile
29player:tell("-----+");

display_seq_full

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":display_seq_full(msg_seq[,preamble]) => {cur}";
2"This is the default message display routine.";
3"Prints the indicated messages on folder to player.  msg_seq is the handle returned by folder:parse_message_seq(...).  Returns the number of the final message in the sequence (to be the new current message number).";
4if (!this:ok(caller, caller_perms()))
5return E_PERM;
6endif
7{seq, ?preamble = ""} = args;
8cur = date = 0;
9while (seq)
10handle = this._mgr:start(this.messages, seq[1], seq[2] - 1);
11while (handle)
12for x in (handle[1])
13cur = this:_message_num(@x);
14date = this:_message_date(@x);
15player:display_message(preamble ? strsub(preamble, "%d", tostr(cur)) | {}, this:msg_full_text(@this:_message_text(@x)));
16endfor
17handle = this._mgr:next(@listdelete(handle, 1));
18$command_utils:suspend_if_needed(0);
19endwhile
20seq = seq[3..$];
21endwhile
22return {cur, date};

list_rmm

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:ok(caller, caller_perms()))
2return E_PERM;
3endif
4len = 0;
5getmsg = this.summary_uses_body ? "_message_text" | "_message_hdr";
6going = this.messages_going;
7if (going && ((!going[1]) || (typeof(going[1][2]) == INT)))
8kept = {@going[1], $maxint};
9going = going[2];
10else
11kept = {$maxint};
12endif
13k = 1;
14mcount = 0;
15for s in (going)
16if (kept[k] <= (mcount = mcount + s[1]))
17k = k + 1;
18endif
19len = len + s[2][2];
20handle = this._mgr:start(s[2], 1, s[2][2]);
21while (handle)
22for x in (handle[1])
23if (kept[k] <= (mcount = mcount + 1))
24k = k + 1;
25endif
26player:tell($string_utils:right(this:_message_num(@x), 4), (k % 2) ? ":  " | ":= ", this:msg_summary_line(@this:(getmsg)(@x)));
27endfor
28handle = this._mgr:next(@listdelete(handle, 1));
29endwhile
30endfor
31if (len)
32player:tell("----+");
33endif
34return len;

undo_rmm

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:ok_write(caller, caller_perms()))
2return E_PERM;
3endif
4msgtree = this.messages;
5seq = {};
6last = 0;
7"there are two possible formats here:";
8"OLD: {{n,msgs},{n,msgs},...}";
9"NEW: {kept_seq, {{n,msgs},{n,msgs},...}}";
10going = this.messages_going;
11if (going && ((!going[1]) || (typeof(going[1][2]) == INT)))
12kept = going[1];
13going = going[2];
14else
15kept = {};
16endif
17for s in (going)
18msgtree = this._mgr:insert_after(msgtree, s[2], last + s[1]);
19seq = {@seq, (last + s[1]) + 1, (last = (last + s[1]) + s[2][2]) + 1};
20endfor
21this.messages = msgtree;
22this.messages_going = {};
23this.messages_kept = $seq_utils:union(kept, $seq_utils:expand(this.messages_kept, seq));
24this:_fix_last_msg_date();
25return seq;

expunge_rmm

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1if (!this:ok_write(caller, caller_perms()))
2return E_PERM;
3endif
4len = 0;
5going = this.messages_going;
6if (going && ((!going[1]) || (typeof(going[1][2]) == INT)))
7going = going[2];
8endif
9for s in (going)
10len = len + s[2][2];
11this._mgr:kill(s[2], "_killmsg");
12endfor
13this.messages_going = {};
14return len;

rm_message_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1seq = args[1];
2if (!(this:ok_write(caller, caller_perms()) || (this:ok(caller, caller_perms()) && (seq = this:own_messages_filter(caller_perms(), @args)))))
3return E_PERM;
4endif
5msgtree = this.messages;
6save = nums = {};
7onext = 1;
8rmmed = 0;
9for i in [1..length(seq) / 2]
10if ($command_utils:suspend_if_needed(0))
11player:tell("... rmm ", onext);
12suspend(0);
13endif
14start = seq[(2 * i) - 1];
15next = seq[2 * i];
16{msgtree, zmsgs} = this._mgr:extract_range(msgtree, start - rmmed, (next - 1) - rmmed);
17save = {@save, {start - onext, zmsgs}};
18nums = {@nums, this:_message_num(@this._mgr:find_nth(zmsgs, 1)), this:_message_num(@this._mgr:find_nth(zmsgs, zmsgs[2])) + 1};
19onext = next;
20rmmed = (rmmed + next) - start;
21endfor
22tmg = this.messages_going;
23save_kept = $seq_utils:intersection(this.messages_kept, seq);
24this.messages_kept = $seq_utils:contract(this.messages_kept, seq);
25this.messages_going = save_kept ? {save_kept, save} | save;
26fork (0)
27for s in (tmg)
28this._mgr:kill(s[2], "_killmsg");
29endfor
30endfork
31this.messages = msgtree;
32this:_fix_last_msg_date();
33return $seq_utils:tostr(nums);

renumber

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":renumber([cur]) renumbers caller.messages, doing a suspend() if necessary.";
2"  => {number of messages,new cur}.";
3if (!this:ok_write(caller, caller_perms()))
4return E_PERM;
5endif
6{?cur = 0} = args;
7this:expunge_rmm();
8"... blow away @rmm'ed messages since there's no way to tell what their new numbers should be...";
9if (!(msgtree = this.messages))
10return {0, 0};
11endif
12if (cur)
13cur = this._mgr:find_ord(msgtree, cur - 1, "_lt_msgnum") + 1;
14endif
15while (1)
16"...find first out-of-sequence message...";
17n = 1;
18subtree = msgtree;
19if (msgtree[3][1] == 1)
20while ((node = this.(subtree[1]))[1])
21"...subtree[3][1]==n...";
22kids = node[2];
23n = n + subtree[2];
24i = length(kids);
25while ((n = n - kids[i][2]) != kids[i][3][1])
26i = i - 1;
27endwhile
28subtree = kids[i];
29endwhile
30leaves = node[2];
31n = ((firstn = n) + length(leaves)) - 1;
32while (n != leaves[(n - firstn) + 1][2])
33n = n - 1;
34endwhile
35n = n + 1;
36endif
37"... n == first out-of-sequence ...";
38"...renumber as many messages as we have time for...";
39while ((n <= msgtree[2]) && (!$command_utils:running_out_of_time()))
40msg = this._mgr:find_nth(msgtree, n);
41msgtree = this._mgr:set_nth(msgtree, n, listset(msg, n, 2));
42n = n + 1;
43endwhile
44this.messages = msgtree;
45if (n > msgtree[2])
46return {n - 1, cur};
47endif
48player:tell("...(renumbering to ", n - 1, ")");
49suspend(0);
50"...start over... may have received new mail, rmm'ed stuff, etc...";
51"...so who knows what's there now?...";
52if (this.messages_going)
53player:tell("Renumber aborted.");
54return;
55endif
56msgtree = this.messages;
57endwhile

length_all_msgs

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1return this:ok(caller, caller_perms()) ? this.messages ? this.messages[2] | 0 | E_PERM;

length_num_le

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return this:ok(caller, caller_perms()) ? this._mgr:find_ord(this.messages, args[1], "_lt_msgnum") | E_PERM;

length_date_le

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return this:ok(caller, caller_perms()) ? this._mgr:find_ord(this.messages, args[1], "_lt_msgdate") | E_PERM;

exists_num_eq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return this:ok(caller, caller_perms()) ? (i = this._mgr:find_ord(this.messages, args[1], "_lt_msgnum")) && ((this:_message_num(@this._mgr:find_nth(this.messages, i)) == args[1]) && i) | E_PERM;

new_message_num

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1if (this:ok(caller, caller_perms()))
2new = (msgtree = this.messages) ? this:_message_num(@this._mgr:find_nth(msgtree, msgtree[2])) + 1 | 1;
3if (rmsgs = this.messages_going)
4lbrm = rmsgs[$][2];
5return max(new, this:_message_num(@this._mgr:find_nth(lbrm, lbrm[2])) + 1);
6else
7return new;
8endif
9else
10return E_PERM;
11endif

from_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":from_msg_seq(object or list)";
2" => msg_seq of messages from any of these senders";
3if (!this:ok(caller, caller_perms()))
4return E_PERM;
5elseif (!this.messages)
6return {};
7endif
8{plist, ?mask = {1, this.messages[2] + 1}} = args;
9if (typeof(plist) != LIST)
10plist = {plist};
11endif
12fseq = {};
13for m in [1..length(mask) / 2]
14handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
15while (handle)
16for msg in (handle[1])
17fromline = msg[4];
18if (toobj(fromline[rindex(fromline, "(") + 1..rindex(fromline, ")") - 1]) in plist)
19fseq = $seq_utils:add(fseq, i, i);
20endif
21i = i + 1;
22$command_utils:suspend_if_needed(0);
23endfor
24handle = this._mgr:next(@listdelete(handle, 1));
25endwhile
26endfor
27return fseq || ("%f %<has> no messages from " + $string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%n (%#)", plist), "no one", " or "));

%from_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":%from_msg_seq(string or list of strings)";
2" => msg_seq of messages with one of these strings in the from line";
3if (!this:ok(caller, caller_perms()))
4return E_PERM;
5elseif (!this.messages)
6return {};
7endif
8{nlist, ?mask = {1, this.messages[2] + 1}} = args;
9if (typeof(nlist) != LIST)
10nlist = {nlist};
11endif
12fseq = {};
13for m in [1..length(mask) / 2]
14handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
15while (handle)
16for msg in (handle[1])
17fromline = " " + msg[4];
18for n in (nlist)
19if (index(fromline, n))
20fseq = $seq_utils:add(fseq, i, i);
21endif
22endfor
23i = i + 1;
24$command_utils:suspend_if_needed(0);
25endfor
26handle = this._mgr:next(@listdelete(handle, 1));
27endwhile
28endfor
29return fseq || ("%f %<has> no messages from " + $string_utils:english_list($list_utils:map_arg($string_utils, "print", nlist), "no one", " or "));

to_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":to_msg_seq(object or list) => msg_seq of messages to those people";
2if (!this:ok(caller, caller_perms()))
3return E_PERM;
4elseif (!this.messages)
5return {};
6endif
7{plist, ?mask = {1, this.messages[2] + 1}} = args;
8if (typeof(plist) != LIST)
9plist = {plist};
10endif
11seq = {};
12for m in [1..length(mask) / 2]
13handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
14while (handle)
15for msg in (handle[1])
16toline = msg[5];
17for r in ($mail_agent:parse_address_field(toline))
18if (r in plist)
19seq = $seq_utils:add(seq, i, i);
20endif
21endfor
22i = i + 1;
23$command_utils:suspend_if_needed(0);
24endfor
25handle = this._mgr:next(@listdelete(handle, 1));
26endwhile
27endfor
28return seq || ("%f %<has> no messages to " + $string_utils:english_list($list_utils:map_arg(2, $string_utils, "pronoun_sub", "%n (%#)", plist), "no one", " or "));

%to_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":%to_msg_seq(string or list of strings)";
2" => msg_seq of messages containing one of strings in the to line";
3if (!this:ok(caller, caller_perms()))
4return E_PERM;
5elseif (!this.messages)
6return {};
7endif
8{nlist, ?mask = {1, this.messages[2] + 1}} = args;
9if (typeof(nlist) != LIST)
10nlist = {nlist};
11endif
12seq = {};
13for m in [1..length(mask) / 2]
14handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
15while (handle)
16for msg in (handle[1])
17toline = " " + msg[5];
18for n in (nlist)
19if (index(toline, n))
20seq = $seq_utils:add(seq, i, i);
21endif
22endfor
23i = i + 1;
24$command_utils:suspend_if_needed(0);
25endfor
26handle = this._mgr:next(@listdelete(handle, 1));
27endwhile
28endfor
29return seq || ("%f %<has> no messages to " + $string_utils:english_list($list_utils:map_arg($string_utils, "print", nlist), "no one", " or "));

subject_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":subject_msg_seq(target) => msg_seq of messages with target in the Subject:";
2if (!this:ok(caller, caller_perms()))
3return E_PERM;
4elseif (!this.messages)
5return {};
6endif
7{target, ?mask = {1, this.messages[2] + 1}} = args;
8seq = {};
9for m in [1..length(mask) / 2]
10handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
11while (handle)
12for msg in (handle[1])
13if (((subject = msg[6]) != " ") && index(subject, target))
14seq = $seq_utils:add(seq, i, i);
15endif
16i = i + 1;
17$command_utils:suspend_if_needed(0);
18endfor
19handle = this._mgr:next(@listdelete(handle, 1));
20endwhile
21endfor
22return seq || (("%f %<has> no messages with subjects containing `" + target) + "'");

body_msg_seq

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1":body_msg_seq(target) => msg_seq of messages with target in the body";
2if (!this:ok(caller, caller_perms()))
3return E_PERM;
4elseif (!this.messages)
5return {};
6endif
7{target, ?mask = {1, this.messages[2] + 1}} = args;
8seq = {};
9for m in [1..length(mask) / 2]
10handle = this._mgr:start(this.messages, i = mask[(2 * m) - 1], mask[2 * m] - 1);
11while (handle)
12for msg in (handle[1])
13if ((msg[1] && (body = this.(msg[1]))) && index(tostr(@body), target))
14seq = $seq_utils:add(seq, i, i);
15"Above saves ticks. Munges the whole message into one string and indexes it. Old code follows.";
16"l = length(body);";
17"while (!index(body[l], target) && (l = l - 1))";
18"$command_utils:suspend_if_needed(0);";
19"endwhile";
20"if (l)";
21"seq = $seq_utils:add(seq, i, i);";
22"endif";
23endif
24i = i + 1;
25$command_utils:suspend_if_needed(0);
26endfor
27handle = this._mgr:next(@listdelete(handle, 1));
28endwhile
29endfor
30return seq || tostr("%f %<has> no messages containing `", target, "' in the body.");

date_sort

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1return E_VERBNF;

_fix_last_msg_date

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

Source

1msgtree = this.messages;
2this.last_msg_date = (msgtree && this:_message_hdr(@this._mgr:find_nth(msgtree, msgtree[2]))[1]) || 0;

__fix

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (!this:ok_write(caller, caller_perms()))
2return E_PERM;
3endif
4{?doit = 0} = args;
5msgtree = this.messages;
6for n in [1..msgtree[2]]
7msg = this._mgr:find_nth(msgtree, n);
8msg = {@msg[1..2], @$mail_agent:__convert_new(@msg[3..$])};
9if (doit)
10msgtree = this._mgr:set_nth(msgtree, n, msg);
11endif
12if ($command_utils:running_out_of_time())
13suspend(0);
14if (this.messages != msgtree)
15player:notify("urk.  someone played with this folder.");
16return 0;
17endif
18endif
19endfor
20return 1;

init_for_core

Spec this none thisFlags rxdOwner #361Definer #9

Referenced by

Source

1if (caller_perms().wizard)
2pass();
3this._mgr = $biglist;
4this.mowner = $mail_recipient.owner;
5endif

length_date_gt

Spec this none thisFlags rxdOwner #29Definer #9

Referenced by

none

Source

1if (this:ok(caller, caller_perms()))
2date = args[1];
3return (this.last_msg_date <= date) ? 0 | (this.messages[2] - this._mgr:find_ord(this.messages, args[1], "_lt_msgdate"));
4else
5return E_PERM;
6endif

_repair

Spec this none thisFlags rxOwner #361Definer #9

Referenced by

Source

1c = callers();
2if ((caller != this) && (!((((length(c) > 1) && (c[1][1] == $list_utils)) && (c[1][2] == "map_arg")) && (c[2][1] == this))))
3raise(E_PERM);
4endif
5$command_utils:suspend_if_needed(0);
6biglist = this;
7propname = args[1];
8if (!propname)
9bestlevel = -1;
10best = {};
11for prop in (properties(biglist))
12$command_utils:suspend_if_needed(0);
13if (index(prop, " ") == 1)
14val = biglist.(prop);
15if (typeof(val[1]) == INT)
16if (bestlevel < val[1])
17bestlevel = val[1];
18best = {prop};
19elseif (bestlevel == val[1])
20best = {@best, prop};
21endif
22endif
23endif
24endfor
25if (!best)
26player:notify("Can't find a root.");
27raise(E_INVARG);
28elseif (length(best) == 1)
29propname = best[1];
30else
31propname = best[1];
32val = biglist.(propname);
33for prop in (best[2..$])
34$command_utils:suspend_if_needed(0);
35val[2] = {@val[2], @biglist.(prop)[2]};
36endfor
37biglist.(propname) = val;
38"Now that the new value is safely stored, delete old values.";
39for prop in (best[2..$])
40$command_utils:suspend_if_needed(0);
41player:notify(tostr("Removing property ", toliteral(prop), ".  Its value, ", toliteral(biglist.(prop)), ", has been merged with property ", toliteral(propname), "."));
42delete_property(biglist, prop);
43endfor
44endif
45maxlevel = biglist.(propname)[1];
46player:notify(tostr("Maximum level is ", maxlevel, "."));
47items = $list_utils:make(maxlevel, {});
48"Arrgh.  Even after finding the root, some nodes might be detached!";
49player:notify("Checking for orphans...");
50for prop in (properties(biglist))
51$command_utils:suspend_if_needed(0);
52if (prop && (prop[1] == " "))
53val = biglist.(prop);
54if (((typeof(val) == LIST) && (typeof(level = val[1]) == INT)) && (level < maxlevel))
55items[level + 1] = {@items[level + 1], prop};
56endif
57endif
58endfor
59for prop in (properties(biglist))
60$command_utils:suspend_if_needed(0);
61if (prop && (prop[1] == " "))
62val = biglist.(prop);
63if (((typeof(val) == LIST) && (typeof(level = val[1]) == INT)) && (level > 0))
64for item in (val[2])
65items[level] = setremove(items[level], item[1]);
66endfor
67endif
68endif
69endfor
70player:notify(tostr("Orphans: ", toliteral(items)));
71backbone_prop = propname;
72level = maxlevel;
73while (level)
74backbone = biglist.(backbone_prop);
75lastkid = backbone_prop;
76for prop in (props = items[level])
77backbone[2] = {@backbone[2], {lastkid = prop, 0, {0, 0}}};
78endfor
79player:notify(tostr("Attaching ", nn = length(props), " propert", (nn == 1) ? "y" | "ies", " to property ", toliteral(backbone_prop), "..."));
80biglist.(backbone_prop) = backbone;
81backbone_prop = lastkid;
82level = level - 1;
83endwhile
84player:notify(tostr("Orphans repatriated."));
85endif
86toplevel = "(top level)";
87context = args[2] || toplevel;
88"This stuff is just paranoia in case something unexpected is in the data structure.  Normally there should be no blowouts here. --Minnie";
89if (typeof(propname) != STR)
90player:notify(tostr("Context=", context, " Prop Name=", toliteral(propname), " -- bad property name."));
91raise(E_INVARG);
92endif
93val = biglist.(propname);
94if (typeof(val) != LIST)
95player:notify(tostr("Context=", context, " Prop Name=", toliteral(propname), " -- contents invalid."));
96raise(E_INVARG);
97endif
98if (typeof(level = val[1]) != INT)
99player:notify(tostr("Context=", context, " Prop Name=", toliteral(propname), " -- contents invalid (bad first argument)."));
100raise(E_INVARG);
101endif
102"This is where the real work starts. --Minnie";
103"First check that the properties referred to really exist.  This must be done for all levels.";
104for item in (val[2])
105try
106biglist.(item[1]);
107except (E_PROPNF)
108player:notify(tostr("Item ", toliteral(item), " is invalid in property ", toliteral(propname), ".  It is being removed."));
109val[2] = setremove(val[2], item);
110continue item;
111endtry
112endfor
113"Next, only for upper levels, check that the message count for inferior levels is correct, but only after recursing into those levels and making repairs.";
114if (level > 0)
115new = $list_utils:map_arg(this, verb, $list_utils:slice(val[2]), propname);
116if (val[2] != new)
117player:notify(tostr("Changing ", toliteral(val[2]), " to ", toliteral(new), "."));
118val[2] = new;
119endif
120"Now that everything is correct, count size of inferiors.";
121endif
122"Bravely stuff the result back into place.";
123biglist.(propname) = val;
124"The result will be of the form:                               ";
125"  {propname, inferior_msgcount, {first_msgnum, first_time}}  ";
126if (level == 0)
127"Count the messages for message count.";
128"Use first message number and time for first_msgnum and first_time.";
129result = {propname, length(val[2]), val[2][1][2..3]};
130else
131"Use message count that is sum of inferior counts.";
132"Just propagate first node's first_msgnum and first_time upward literally.";
133n = 0;
134for subnode in (val[2])
135n = n + subnode[2];
136endfor
137result = {propname, n, val[2][1][3]};
138endif
139if (context == toplevel)
140if (result != biglist.messages)
141biglist.messages = result;
142player:notify(tostr("Property ", biglist, ".messages updated."));
143endif
144player:tell(biglist.messages[2], " messages repaired in ", $mail_agent:name(biglist), ".");
145endif
146return result;
147"Last modified Thu Feb 15 23:13:44 1996 MST by Minnie (#123).";

repair

Spec this none noneFlags rxdOwner #361Definer #9

Referenced by

none

Source

1"Syntax: repair <biglist>";
2"";
3"This tool makes a last-resort attempt to repair broken biglists (ones whose data structures are out of alignment due to an error such as \"out of ticks\" during some update operation leaving the b-tree in an inconsistent state).  This tool comes with no warranty of any kind.  You should only use it when you have no other choice, and you should make an attempt to @dump or fully copy or otherwise checkpoint your object before attempting to repair it so that you can recover from any failures this might produce.  This operation is NOT undoable.";
4if (!$perm_utils:controls(player, this))
5player:tell("You do not control that.");
6elseif (!$command_utils:yes_or_no("This tool can be used to repair some (but maybe not all) situations involving generic biglists that have had an error (usually \"out of ticks\") during an update operation and were left inconsistent.  Is this list really and truly broken in such a way?"))
7player:tell("No action taken.  PLEASE don't use this except in extreme cases.");
8elseif (!$command_utils:yes_or_no("Have you made a best effort to @dump or otherwise save the contents in case this make things worse?"))
9player:tell("No action taken.  PLEASE do any saving you can before proceeding.");
10elseif (!$command_utils:yes_or_no("This tool comes with no warranty of any kind.  Is this really your last resort and are you prepared to accept the consequences of utter failure?  There is no undoing the actions this takes.  Do you understand and accept the risks?"))
11player:tell("No action taken.  I'm not taking any responsibility for this failing.  It's gotta be your choice.");
12else
13player:tell("OK!  Going ahead with repair attempts...");
14this:_repair();
15player:tell("All done.  If this worked, you can thank Mickey.  If not, remember the promises you made above about accepting responsibility for failure.");
16endif
17"Last modified Fri Feb 16 08:36:27 1996 MST by Minnie (#123).";

restore_from

Spec this none thisFlags rxdOwner #361Definer #9

Referenced by

none

Source

1":restore_from(OLD_MAIL_RECIPIENT, LOST_STRING)";
2"This clears all biglist properties from this object, then";
3"scans the properties of OLD_MAIL_RECIPIENT, which must be a descendant";
4"of $big_mail_recipient, looking for those corresponding to mail messages,";
5"and then rebuilds the message tree entirely from scratch.";
6"";
7"No attempt is made to preserve the original tree structure.";
8"The live/deleted state of any given message is lost;";
9"all messages, including formerly rmm-ed ones, are restored to .messages";
10"";
11"In the (unlikely) event that message-body properties have been lost, the";
12"affected messages are given a one-line body consisting of LOST_STRING";
13"";
14{old, ?lost_body = "###BODY-LOST###"} = args;
15if (!($perm_utils:controls(caller_perms(), this) && $perm_utils:controls(caller_perms(), old)))
16raise(E_PERM);
17elseif (!$object_utils:isa(old, $big_mail_recipient))
18raise(E_TYPE, "First argument must be a $big_mail_recipient.");
19elseif (typeof(lost_body) != STR)
20raise(E_TYPE, "Second argument, if given, must be a string.");
21endif
22mgr = this._mgr;
23"...";
24"... destroy everything...";
25for p in (properties(this))
26delete_property(this, p);
27endfor
28this.messages = this.messages_going = {};
29"...";
30"... look at all properties...";
31msgcount = lostcount = 0;
32for p in (properties(old))
33if (index(p, " ") == 1)
34pvalue = old.(p);
35"... ignore everything except level-0 nodes...";
36if (pvalue[1..min(1, $)] == {0})
37for msg in (pvalue[2])
38if ((ticks_left() < 6000) || (seconds_left() < 2))
39player:tell("...", msgcount, " copied.");
40suspend(0);
41endif
42try
43body = old.(msg[1]);
44except e (E_PROPNF)
45body = {lost_body};
46lostcount = lostcount + 1;
47endtry
48msg[1] = this:_make(@body);
49msgtree = mgr:insert_last(this.messages, msg);
50msgcount = msgcount + 1;
51n = mgr:find_ord(msgtree, this:_message_num(@msg), "_lt_msgnum");
52if (n < msgcount)
53{msgtree, singleton} = mgr:extract_range(msgtree, msgcount, msgcount);
54msgtree = mgr:insert_after(msgtree, singleton, n);
55endif
56this.messages = msgtree;
57endfor
58endif
59endif
60endfor
61player:tell(msgcount, " messages installed on ", this.name, "(", this, ")");
62if (lostcount)
63player:tell(lostcount, " messages have missing bodies (indicated by ", toliteral(lost_body), ").");
64else
65player:tell("No message bodies were missing.");
66endif