/* /lib/obj/post.c * from Foundation II * the user front end to the IIPS version 3.1 * created by Descartes of Borg 940509 */ #include <lib.h> #include <daemons.h> #include <iips.h> #include "include/post.h" inherit LIB_ITEM; static private int __Screen, __Lines, __NumLetters; static private int __Begin,__Current,__CommandLine,__FromMenu,__IncomingFlag; static private string __Folder, __Owner, __CurrentMenu; static private mapping __Options, __TmpPost, __ChangedOptions; static private int *__Delete; static private string *__FwdRply; static private mapping *__BoxInfo, *__PostalOptions; void create() { item::create(); SetKeyName("post box"); SetId( ({ "post box", "box", POSTAL_ID }) ); SetAdjectives( ({ "post", "a", "imaginary" }) ); SetShort("a post box"); SetLong("A post box."); SetProperty("no steal", 1); SetInvis(1); SetMass(0); SetValue(0); SetPreventGet( (: Destruct :) ); SetPreventDrop( (: Destruct :) ); SetPreventPut( (: Destruct :) ); __PostalOptions = ({ ([ "key":"askcc", "value":({"N","Y"}), "desc":"Prompt for cc when " "sending mail:" ]), (["key":"quit", "value":({"N","Y"}), "desc":"Confirm quit from mail:"]), (["key":"metoo", "value":({"N","Y"}),"desc":"Send mail to yourself " "with you in alias:"]), (["key":"delete", "value":({"N","Y"}), "desc":"Confirm deletion of " "letters:" ]), (["key":"notify", "value":({"N","Y"}), "desc":"Notify me when new mail " "is received:" ]), ([ "key":"message", "value":"New mail has arrived from $N\n" "Subject: $S", "desc":"Mail message when notify occurs:" ]), ([ "key": "content", "value":({"message only", "header and message"}), "desc":"Content of letters when reading mail:" ]), ([ "key":"forward", "value":"none", "desc":"Address to forward " "incoming mail to:" ]), ([ "key":"sig file", "value":"none", "desc":"Signature file:" ]), ([ "key":"commands", "value":({"N","Y"}), "desc":"Exclude command " "listing from menus:" ]), ([ "key":"read", "value":({"N","Y"}), "desc":"Read letter when you make " "it current:" ]) }); } string tmpmail(){ mixed tmpmaildir = homedir(this_player()); if(!tmpmaildir || !directory_exists(tmpmaildir)) return "/tmp/"+this_player()->GetKeyName(); else return tmpmaildir+"/tmp/mail.tmp"; } void init() { item::init(); if(this_player() != environment(this_object())) { this_object()->eventDestruct(); return; } __Options = (mapping)OPTIONS_D->query_options(__Owner = (string)this_player()->GetKeyName()); if(!(__Lines = to_int((string)this_player()->GetEnvVar("LINES")))) __Lines = 24; if(!(__Screen = to_int((string)this_player()->GetEnvVar("SCREEN")))) __Screen = 80; if((__NumLetters = __Lines - 10) < 0) __NumLetters = 5; } static private void restore_box(string folder) { int x; if(!pointerp(__BoxInfo=(mapping *)FOLDERS_D->query_box_info(__Owner, folder))) __BoxInfo = ({}); __Folder = folder; __TmpPost = ([]); __Delete = allocate(x = sizeof(__BoxInfo)); if(!x) __Current = -1; else __Current = 0; __Begin = 0; } static private void save_box() { FOLDERS_D->delete_posts(__Owner, __Folder, __Delete); } static private void destruct_box(string str) { message("mail", str, this_player()); this_object()->eventDestruct(); } static private int valid_folder(string str) { int i; if(str == "" || !str) return 0; if(str[0] != '=' && str != "new") return 0; i = strlen(str = lower_case(str)); while(i-- > 1) if(str[i] < 'a' || str[i] > 'z') return 0; return 1; } static private int set_current(mixed val) { int i; if(intp(val)) __Current = val; else { i = sizeof(__BoxInfo); while(i--) { if(__BoxInfo[i]["id"] == val) { __Current = i; break; } } } if(__Current < __Begin) __Begin = __Current; else if(__Current >= __Begin+10) __Begin = __Current-9; return __Current; } void start_post(string str) { string *args; int i, maxi;; if(str && str != "") { maxi = sizeof(args = explode(str, ",")); if(args[0][0] == '-' && strlen(args[0]) == 2) { switch(args[0][1]) { case 'r': restore_box("new"); index_cmd(""); return; case 'f': if(maxi < 2) { message("mail", "No folder named.", this_player()); this_object()->eventDestruct(); return; } else if(maxi>2 || (!valid_folder(args[1]) && args[1] != "new")) { message("mail", "Illegal folder name.", this_player()); this_object()->eventDestruct(); return; } else { restore_box(args[1]); indices(0); return; } case 'a': __CommandLine = 1; if(maxi < 2) index_cmd("a"); else index_cmd(implode(args[1..maxi-1], " ")); return; } } __CommandLine = 1; __TmpPost = ([]); __FwdRply = 0; send_letter(args); return; } restore_box("new"); indices(0); } static private void primary_prompt() { message("prompt", "\nCommand: \n", this_player()); } static private void secondary_prompt() { message("prompt", sprintf("\nCommand (%s for %s menu): \n", __CurrentMenu[0..0], __CurrentMenu), this_player()); } varargs static private void postal_error(string str, string ind, mixed args) { message("mail", sprintf("\n%%^RED%%^%s\n", str), this_player()); primary_prompt(); if(args) input_to(sprintf("%s_cmd", (ind ? ind : __CurrentMenu)), args); else input_to(sprintf("%s_cmd", (ind ? ind : __CurrentMenu))); } varargs static private void postal_success(string str,string ind,mixed args) { message("mail", sprintf("\n%%^GREEN%%^%s\n", str), this_player()); secondary_prompt(); if(args) input_to(sprintf("%s_cmd", (ind ? ind : __CurrentMenu)), args); else input_to(sprintf("%s_cmd", (ind ? ind : __CurrentMenu))); } varargs static void indices(int x, string str) { int i, maxi; __CurrentMenu = "index"; if(str && str != "") { index_cmd(str); return; } __Begin = x; __FromMenu = 1; message("mail", "\n%^INITTERM%^Imaginary Intermud Postal Service " "(IIPS) 3.1 Descartes of Borg 1993, 1994", this_player()); message("mail", sprintf("\n%%^CYAN%%^%s", center(sprintf("Folder is %s " "with %s.\n",__Folder,consolidate(maxi=sizeof(__BoxInfo),"one letter\n")), __Screen)), this_player()); if(!maxi) __Current = -1; else for(i=x; i<maxi && i < x+__NumLetters; i++) message("mail", sprintf("%s%s) %s %s %s %s %s\n", (__Current == i ? "%^YELLOW%^BOLD%^*" : " "), ((i+1 > 99) ? (""+(i+1)) : ((i+1 > 9) ? (" "+(i+1)) : (" "+(i+1)))), (__BoxInfo[i]["read"] ? " " : "N"), (__Delete[i] ? "D" : " "), arrange_string(capitalize(__BoxInfo[i]["from"]), 30), arrange_string(postal_time(__BoxInfo[i]["date"]), 7), arrange_string(__BoxInfo[i]["subject"], __Screen-40)), this_player()); index_menu(); } varargs static void aliases(string str) { __CurrentMenu = "alias"; if(str && str != "") { alias_cmd(str); return; } message("mail", "\n%^INITTERM%^Imaginary Intermud Postal Service " "(IIPS) 3.1 Descartes of Borg 1993, 1994", this_player()); message("mail", sprintf("\n%%^CYAN%%^%s", center(sprintf("%s and " "Personal Alias Menu", mud_name()))), this_player()); message("mail", sprintf("\n%s\n", format_page(keys((mapping)OPTIONS_D->query_groups(__Owner) + (mapping)LOCALPOST_D->query_mud_groups()),__Screen/20)),this_player()); alias_menu(); } varargs static void options(string str) { string tmp; int i, maxi; __CurrentMenu = "option"; if(str && str != "") { option_cmd(str); return; } message("mail", "\n%^INITTERM%^Imaginary Intermud Postal Service " "(IIPS) 3.1 Descartes of Borg 1993, 1994", this_player()); message("mail", sprintf("\n%%^CYAN%%^%s", center("IIPS 3.1 Options Menu\n", __Screen)), this_player()); maxi = sizeof(__PostalOptions); for(i=0; i<maxi; i++) { if(pointerp(__PostalOptions[i]["value"])) tmp = __PostalOptions[i]["value"][__Options[__PostalOptions[i]["key"]]]; else if(!(tmp = __Options[__PostalOptions[i]["key"]])) tmp = __PostalOptions[i]["value"]; message("mail", sprintf("%s) %-45s %s\n", (i+1>9) ? (i+1)+"" :" "+(i+1), __PostalOptions[i]["desc"], tmp), this_player()); } option_menu(); } static private void help(string arg, string ind) { if(!ind) ind = __CurrentMenu; if(arg && arg != "") { help_cmd(arg, ind); return; } message("mail", "\n%^INITTERM%^Imaginary Intermud Postal Service " "(IIPS) 3.1 Descartes of Borg 1993, 1994", this_player()); message("mail",sprintf("\n%%^CYAN%%^%s\n",center("IIPS 3.1 Help Menu", __Screen)), this_player()); help_menu(ind); } static private void index_menu() { if(__Options["commands"]) { primary_prompt(); input_to("index_cmd"); return; } message("mail", "\n"+center("a)lias menu, c)hange folder, d)elete, " "f)orward, h)elp, m)ail,", __Screen), this_player()); message("mail", center("n)ext letter, o)ptions menu, p)revious " "letter, q)uit, Q)uit without saving,", __Screen), this_player()); message("mail", center("s)ave to folder, S)ave to file, " "u)ndelete", __Screen), this_player()); message("mail", center("<return> to read selected letter\n", __Screen), this_player()); primary_prompt(); input_to("index_cmd"); } static private void alias_menu() { if(__Options["commands"]) { primary_prompt(); input_to("alias_cmd"); return; } message("mail", center("d)elete from an alias, e)nter into an alias, " "h)elp, i)ndex menu, ", __Screen), this_player()); message("mail", center("l)ist an alias, m)ake an alias, o)ptions menu, " "q)uit, Q)uit without saving, ", __Screen), this_player()); message("mail", center("r)emove an alias\n", __Screen),this_player()); primary_prompt(); input_to("alias_cmd"); } static private void option_menu() { if(__Options["commands"]) { primary_prompt(); input_to("option_cmd"); return; } message("mail", "\n"+center("Enter the number of an option to " "change it.", __Screen), this_player()); message("mail", center("a)lias menu, h)elp, i)ndex menu, " "q)uit, Q)uit without saving,", __Screen), this_player()); message("mail", center("s)ave option changes\n", __Screen), this_player()); primary_prompt(); input_to("option_cmd"); } static private void help_menu(string ind) { int i, maxi; message("help", "\n\n\tEnter one of the following to visit " "another menu:", this_player()); message("help", center("a)lias menu, i)ndex menu, o)ptions menu", __Screen), this_player()); message("help", "\n\tOr enter one of the following for detailed help:", this_player()); switch(ind) { case "index": message("help", center("c)hange folder, d)elete, f)orward, " "m)ail letter, n)ext letter,", __Screen), this_player()); message("help", center("p)revious letter, q)uit, " "Q)uit without saving, r)eply,", __Screen), this_player()); message("help", center("s)ave to folder, S)ave to file,", __Screen), this_player()); message("help", center("x) help from another menu, y) detailed " "IIPS user manual\n", __Screen), this_player()); break; case "alias": message("help", center("d)elete from an alias, e)nter into " "an alias, m)ake an alias, q)uit,", __Screen), this_player()); message("help", center("Q)uit without saving, r)emove " "an alias,", __Screen), this_player()); message("help", center("x) help from another menu, y) detailed " "IIPS user manual\n", __Screen), this_player()); break; case "option": for(i=0, maxi = sizeof(__PostalOptions); i<maxi;i++) message("help", center(sprintf("%d) %s", (i+1), __PostalOptions[i]["desc"]), __Screen), this_player()); message("help", sprintf("\n%s",center("Also: q)uit, Q)uit without " "saving, s)ave option changes,", __Screen)), this_player()); message("help", center("x) help from another menu, y) detailed " "IIPS user manual\n", __Screen), this_player()); break; default: postal_error("Invalid postal menu."); return; } primary_prompt(); input_to("help_cmd", ind); } static void index_cmd(string str) { string cmd, args; string *tmp; int x; __CurrentMenu = "index"; if(__IncomingFlag) { __IncomingFlag = 0; postal_error("New mail has arrived!\nCommand Ignored."); return; } if(str == "" || !str) { if(__Current < 0 || __Current >= sizeof(__BoxInfo)) { postal_error("No current letter set."); return; } if(__FromMenu) read_letter(__Current); else if(set_current(__Current+1) < sizeof(__BoxInfo)) read_letter(__Current); else read_letter(set_current(__Current - 1)); return; } if(sscanf(str, "%d", x) && x) { if(x>0 && x <= sizeof(__BoxInfo)) { if(__Options["read"]) read_letter(set_current(x-1)); else { set_current(x-1); indices(__Begin); } } else postal_error("Invalid letter number."); return; } if(!sizeof(tmp = explode(str, " "))) cmd = ""; else cmd = tmp[0][0..0]; if(sizeof(tmp) > 1) args = implode(tmp = tmp[1..sizeof(tmp)-1], " "); else { args = ""; tmp = ({}); } switch(cmd) { case "a": aliases(args); return; case "c": change_folder(args); return; case "d": case "u": delete_letter(cmd, args); return; case "f": forward_letter(args, 0); return; case "h": help(args, "index"); return; case "i": indices(__Current < __Begin+__NumLetters ? __Begin : __Current-(__NumLetters-1), args); return; case "m": __FwdRply = 0; __TmpPost = ([]); send_letter(tmp); return; case "n": index_cmd(""+(__Current+2)); return; case "o": options(args); return; case "p": index_cmd(""+(__Current)); return; case "q": case "Q": quit_box(cmd); return; case "r": reply(args); return; case "s": case "S": save_letter(cmd, args); return; default: postal_error("Invalid postal command."); return; } } static void alias_cmd(string str) { string cmd, args; string *tmp; __CurrentMenu = "alias"; if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias command."); else postal_error("Invalid alias command."); return; } cmd = (tmp = explode(str, " "))[0][0..0]; if(sizeof(tmp) > 1) args = implode(tmp[1..sizeof(tmp)-1], " "); else args = ""; switch(cmd) { case "a": aliases(args); return; case "d": case "e": alias_members(cmd, args); return; case "m": case "r": alias_creation(cmd, args); return; case "h": help(args, "alias"); return; case "i": indices(__Current < __Begin+__NumLetters ? __Begin : __Current-(__NumLetters-1), args); return; case "l": list_alias(args); return; case "o": options(args); return; case "q": case "Q": quit_box(cmd); return; case "s": aliases(args); return; default: alias_cmd(0); return; } } static void option_cmd(string str) { string cmd, args; string *tmp; int x; __CurrentMenu = "option"; if(str == "" || !str) { postal_error("Invalid option command."); return; } if(sscanf(str, "%d", x) && x) { change_option(x-1); return; } cmd = (tmp = explode(str, " "))[0][0..0]; if(sizeof(tmp) > 1) args = implode(tmp[1..sizeof(tmp)-1], " "); else args = ""; switch(cmd) { case "a": aliases(args); return; case "h": help(args, "option"); return; case "i": indices(__Current < __Begin+__NumLetters ? __Begin : __Current-(__NumLetters-1), args); return; case "o": options(args); return; case "q": case "Q": quit_box(cmd); return; case "s": save_options(); return; default: option_cmd(0); return; } } static void help_cmd(string str, string ind) { string tmp, file; if(str == "" || !str) { postal_error("Invalid help command.", "help", ind); return; } switch(str = str[0..0]) { case "a": aliases(""); return; case "i": indices(__Begin); return; case "o": options(""); return; case "q": case "Q": file = "quitting"; break; } if(!(tmp = read_file(DIR_POSTAL_HELP+"/"+file))) tmp = "Not found.\n"; this_player()->eventPage(explode(tmp, "\n"), "help", (: end_help :)); } void end_help() { secondary_prompt(); input_to("help_cmd"); } static private string postal_time(mixed val) { string *parts; string heure; int x; if(stringp(val) && x = to_int(val)) heure = ctime(time()); else if(stringp(val)) heure = val; else heure = ctime(val); parts = explode(replace_string(heure, " ", " "), " "); return sprintf("%s %s", parts[2], parts[1]); } static private string header(mapping borg) { int x; return sprintf("%s from %%^GREEN%%^%s%%^RESET%%^\nTo: %s%s" "Subject: %%^GREEN%%^%s", (stringp(borg["date"]) ? ((x=to_int(borg["date"])) ? ctime(x) : borg["date"]) : ctime(borg["date"])), capitalize(borg["from"]), wrap(implode(borg["to"], ", "), __Screen), (sizeof(borg["cc"]) ? sprintf("Cc: %s",wrap(implode(borg["cc"], ", "), __Screen)) : ""), borg["subject"]); } static void change_folder(string str) { if(str == "" || !str) { message("prompt", "Change to which folder? \n", this_player()); input_to("get_folder"); return; } if(!valid_folder(str)) { __FromMenu = 1; postal_error("Invalid folder name."); return; } if(!__Options["delete"] || member_array(1, __Delete) == -1) next_folder("", str); else { message("prompt", "Delete marked letters (default 'y')? \n", this_player()); input_to("next_folder", str); } } static void next_folder(string str, string folder) { if(str == "" || !str) str = "y"; else str = (lower_case(str)[0..0]); if(str == "y") save_box(); else if(str != "n") { message("prompt", "Invalid command. Enter 'y' or 'n': \n",this_player()); input_to("next_folder"); } restore_box(folder); indices(__Begin); } static void get_folder(string str) { if(str == "" || !str) { __FromMenu = 1; postal_error("Invalid folder name."); return; } change_folder(str); } static private void delete_letter(string cmd, string args) { int x, i, from, to, maxi; if(args == "" || !args) { from = __Current; to = __Current; } else { sscanf(args, "%d-%d", from, to); if(!to) to = from-1; else to--; from--; } if(from > to || from < 0 || to >= sizeof(__BoxInfo)) { postal_error("Invalid letter range."); return; } for(i= from; i < to+1; i++) { if(cmd == "u" && !__Delete[i]) { __FromMenu = 1; postal_error(sprintf("Letter %d is not marked for deletion!",i+1)); } else if(cmd == "d" && __Delete[i]) postal_error(sprintf("Letter %d is already marked for deletion!",i+1)); else if(!__BoxInfo[i]["read"] && cmd == "d" && !__Options["unread delete"]) { message("mail", sprintf("\n%%^RED%%^Letter %d is still unread!", i+1), this_player()); message("prompt","Delete it anyways (default n): \n",this_player()); input_to("unread_delete", ({ i+1, to+1 })); return; } else __Delete[i] = (cmd == "u" ? 0 : 1); } if(cmd == "d" && (args == "" || !args)) { for(i=__Current, maxi = sizeof(__BoxInfo); i<maxi; i++) { if(!__Delete[i]) { set_current(i); if(!__FromMenu) { read_letter(__Current); return; } else { indices(__Current < __Begin+__NumLetters ? __Begin : __Current-(__NumLetters-1)); return; } } } } if(__FromMenu) { indices(__Current < __Begin+__NumLetters ? __Begin : __Current-(__NumLetters-1)); return; } if(to == from) postal_success(sprintf("Letter %d %s",from+1, (cmd == "d" ? "marked for deletion" : "undeleted"))); else postal_error(sprintf("Letters %d through %d %s.", (from+1), (to+1), (cmd == "d" ? "marked for deletion" : "undeleted"))); } static void unread_delete(string str, int *milk) { if(str == "" || !str) str = "y"; else str = lower_case(str[0..0]); if(str == "y") __Delete[milk[0]-1] = 1; if(milk[0] < milk[1]) { delete_letter("d", milk[0]+"-"+milk[1]); return; } __FromMenu = 1; secondary_prompt(); input_to("index_cmd"); } static private void quit_box(string cmd) { int i; if(__Options["quit"]) { message("prompt", "Do you really wish to quit (default 'n')? \n", this_player()); input_to("confirm_quit", cmd); return; } really_quit(cmd); } static private void really_quit(string cmd) { int i; if(cmd == "Q") { message("mail", "\nExiting from IIPS without saving deletions.\n", this_player()); this_object()->eventDestruct(); return; } if(!__Options["delete"]) { save_box(); message("mail", "\nExiting from IIPS.\n", this_player()); this_object()->eventDestruct(); return; } i = sizeof(__Delete); while(i--) { if(__Delete[i]) { message("prompt", "Delete marked letters (default 'y')? \n", this_player()); input_to("confirm_delete"); return; } } message("mail", "\nExiting from IIPS.\n", this_player()); this_object()->eventDestruct(); } static void confirm_quit(string str, string cmd) { if(str == "" || !str) str = "n"; else str = lower_case(str)[0..0]; if(str == "y") { really_quit(cmd); return; } else if(str == "n") { indices(__Current < __Begin+__NumLetters ? __Begin : __Current - (__Lines-1)); return; } message("prompt", "Answer 'y' or 'n': \n", this_player()); input_to("confirm_quit", cmd); } static void confirm_delete(string str) { if(str == "" || !str) str = "y"; else str = lower_case(str)[0..0]; if(str == "y") { save_box(); message("mail", "\nExiting from IIPS.\n", this_player()); this_object()->eventDestruct(); return; } else if(str == "n") { message("mail", "\nMarked letters will remain undeleted.\n" "Exiting from IIPS.\n", this_player()); this_object()->eventDestruct(); return; } message("prompt", "Answer 'y' or 'n': \n", this_player()); input_to("confirm_delete"); } static private void save_letter(string cmd, string args) { string *tmp; string folder; int letter, i, maxi; if(args && args != "") { if(sizeof(tmp = explode(args, " ")) == 2) { if(!sscanf(tmp[0], "%d", letter) || !letter) { sscanf(tmp[1], "%d", letter); folder = tmp[0]; } else folder = tmp[1]; } else if(!sscanf(args, "%d", letter) || !letter) folder = args; else folder = args; } else { folder = 0; letter = 0; } if(!letter) letter = __Current; else letter--; if(!folder) { if(cmd == "S") message("prompt","Save to which file? \n",this_player()); else message("prompt", sprintf("Save to which folder (default %s)? \n", sprintf("=%s", convert_name(__BoxInfo[letter]["from"]))), this_player()); input_to("get_save_location", ({ letter, cmd })); return; } if(cmd == "s") { if(!valid_folder(folder)) { postal_error("Invalid folder name."); return; } FOLDERS_D->add_post(__Owner, folder, __BoxInfo[letter]); message("mail", "\nLetter saved.\n", this_player()); set_current(letter); __Delete[__Current] = 1; } else if(cmd == "S") { folder = absolute_path((string)this_player()->get_path(), folder); if(!creatorp(this_player()) || !((int)master()->valid_write(folder, this_player()))) { postal_error("Access denied."); return; } write_file(folder, (string)LETTERS_D->query_letter(__BoxInfo[letter]["id"])); message("mail", sprintf("Letter saved to %s.\n", folder), this_player()); set_current(letter); __Delete[__Current] = 1; } if(!__FromMenu) for(i=__Current, maxi = sizeof(__BoxInfo); i<maxi; i++) { if(!__Delete[i]) { read_letter(__Current); return; } } secondary_prompt(); input_to("index_cmd"); } static void get_save_location(string str, mixed *vals) { if(str == "" || !str) { if(vals[1] == "s") str = sprintf("=%s", convert_name(__BoxInfo[vals[0]]["from"])); else { postal_error("Invalid file name."); return; } } save_letter(vals[1], sprintf("%d %s", vals[0]+1, str)); } static private void read_letter(int x) { string tmp; if(__Options["content"]) message("Nmail", sprintf("\n%%^INITTERM%%^Letter %d%s\n", (x+1), (__Delete[x] ? " [DELETED]:" : ":")), this_player()); else message("Nmail", "\n%^INITTERM%^\n", this_player()); if(__Options["content"]) tmp = header(__BoxInfo[x])+"\n"; else tmp = ""; tmp+=sprintf("\n%s\n",(string)LETTERS_D->query_letter(__BoxInfo[x]["id"])); if(!__BoxInfo[x]["read"]) FOLDERS_D->mark_read(__Owner, __Folder, x); __BoxInfo[x]["read"] = 1; this_player()->eventPage(explode(tmp, "\n"), "mail", (: end_read :)); } void end_read() { __FromMenu = 0; secondary_prompt(); input_to("index_cmd"); } static private void alias_members(string cmd, string args) { string *members, *old_members; string grp; if(args == "" || !args) { message("prompt", sprintf("%s which alias? \n", (cmd == "e" ? "Enter into" : "Delete from")), this_player()); input_to("get_alias", cmd); return; } if(sizeof(members = explode(args, " ")) == 1) { message("prompt", sprintf("%s which members? \n", (cmd == "e" ? "Enter" : "Delete")), this_player()); input_to("get_members", ({ cmd, args })); return; } if(!sizeof(members -= ({ grp = members[0] }))) { if(__CommandLine) destruct_box("Invalid alias member."); else postal_error("Invalid alias member."); return; } if(user_exists(grp = lower_case(grp)) || (string *)LOCALPOST_D->query_mud_group(grp)) { if(__CommandLine) destruct_box("Invalid alias."); else postal_error("Invalid alias."); return; } if(!(old_members = (string *)OPTIONS_D->query_group(__Owner, grp))) { if(__CommandLine) destruct_box("No such alias."); else postal_error(sprintf("No such alias %s.", grp)); return; } if(cmd == "e") members = distinct_array(members + old_members); else if(!sizeof(members = old_members - members)) members = 0; OPTIONS_D->set_group(__Owner, grp, members); if(cmd == "d") { if(!members) message("mail", "\n%^GREEN%^All members deleted.\n", this_player()); else message("mail", "\n%^GREEN%^Members deleted from alias.\n", this_player()); } else message("mail", "\n%^GREEN%^Members entered into alias.\n", this_player()); if(__CommandLine) this_object()->eventDestruct(); else { secondary_prompt(); input_to("alias_cmd"); } } static void get_alias(string str, string cmd) { if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias name."); else postal_error("Invalid alias name."); return; } alias_members(cmd, str); } static void get_members(string str, string *args) { if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias members."); else postal_error("Invalid alias members."); return; } alias_members(args[0], sprintf("%s %s", args[1], str)); } static private void alias_creation(string cmd, string args) { string *members; if(args == "" || !args) { message("prompt", sprintf("Name of alias to %s: \n", (cmd == "m" ? "make" : "remove")), this_player()); input_to("get_alias_name", cmd); return; } if(cmd == "m" && sizeof(members=explode(args=lower_case(args)," ")) == 1) { message("prompt", "Enter members for the alias: \n", this_player()); input_to("get_new_alias_members", ({ cmd, args })); return; } else if(cmd == "m") members = members - ({ args = members[0] }); else members = 0; if(cmd == "m" && (user_exists(args) || (mapping)LOCALPOST_D->query_mud_group(args))) { if(__CommandLine) destruct_box("Invalid alias name."); else postal_error("Invalid alias name."); return; } if(!((string *)OPTIONS_D->query_group(__Owner, args))) { if(cmd == "r") { if(__CommandLine) destruct_box("No such alias to remove."); else postal_error("No such alias to remove."); return; } } else if(cmd == "m") { if(__CommandLine) destruct_box("Alias already exists."); else postal_error("That alias already exists."); return; } OPTIONS_D->set_group(__Owner, args, members); if(__CommandLine) destruct_box(sprintf("Alias %s.", (cmd == "m" ? "made" : "removed"))); else postal_success(sprintf("Alias %s.", (cmd == "m" ? "made" : "removed"))); } static void get_alias_name(string str, string cmd) { if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias name."); else postal_error("Invalid alias name."); return; } alias_creation(cmd, lower_case(str)); } static void get_new_alias_members(string str, string *args) { if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias members."); else postal_error("Invalid alias members."); return; } alias_creation(args[0], sprintf("%s %s", args[1], lower_case(str))); } static private void list_alias(string str) { string *who; if(str == "" || !str) { if(__CommandLine) destruct_box("Invalid alias name."); else postal_error("Invalid alias name."); return; } if(!(who = (string *)LOCALPOST_D->query_mud_group(str=lower_case(str)))) { who = (string *)OPTIONS_D->query_group(__Owner, str); } if(!who) { if(__CommandLine) destruct_box("No such alias exists."); else postal_error("No such alias exists."); return; } message("mail", "\n%^INITTERM%^"+center(sprintf("Alias: %s", str), __Screen), this_player()); message("mail", "\n\n"+implode(who, ", "), this_player()); if(__CommandLine) this_object()->eventDestruct(); else { secondary_prompt(); input_to("alias_cmd"); } } static private void save_options() { string *cles; int i; if(!__ChangedOptions) { postal_error("No options have changed."); return; } i = sizeof(cles = keys(__ChangedOptions)); while(i--) OPTIONS_D->set_option(__Owner, cles[i], __ChangedOptions[cles[i]]); __Options = (mapping)OPTIONS_D->query_options(__Owner); postal_success("New options now saved."); } static private void change_option(int x) { if(pointerp(__PostalOptions[x]["value"])) { message("mail", sprintf("%s\n\t0) %s\n\t1) %s\n", __PostalOptions[x]["desc"], __PostalOptions[x]["value"][0], __PostalOptions[x]["value"][1]), this_player()); } else message("mail", __PostalOptions[x]["desc"], this_player()); message("prompt", "Enter in a proper value: \n", this_player()); input_to("really_change_option", 0, x); } static void really_change_option(string str, int x) { int y; if(!__ChangedOptions) __ChangedOptions = ([]); if(pointerp(__PostalOptions[x]["value"])) { if((y=to_int(str)) != 0 && y != 1) { postal_error("Invalid value. No option has changed."); return; } __ChangedOptions[__PostalOptions[x]["key"]] = y; } else __ChangedOptions[__PostalOptions[x]["key"]] = (str == "" ? 0 : str); postal_success("You must remember to save for this option to take effect."); } static private void reply(string str) { int x, i; if(str == "" || !str) x = __Current; else x = to_int(str)-1; if(x < 0 || x >= sizeof(__BoxInfo)) { postal_error("Invalid letter number for reply."); return; } set_current(x); __TmpPost = ([ "date":time(), "from": (string)this_player()->GetKeyName()]); if((__TmpPost["subject"] = __BoxInfo[x]["subject"])[0..2] != "Re:") __TmpPost["subject"] = sprintf("Re: %s", __TmpPost["subject"]); message("prompt", "Include original text (default 'n'): \n", this_player()); input_to("get_reply_confirm"); } static void get_reply_confirm(string str) { if(str == "" || !str) str = "n"; else str = lower_case(str)[0..0]; if(str == "y") __FwdRply = ({ "r", query_reply_text() }); else if(str != "n") { message("prompt", "Answer 'y' or 'n': \n", this_player()); input_to("get_reply_confirm"); return; } else __FwdRply = 0; message("mail", sprintf("\n%s", center("Reply to: a)ll, c)c list and " "sender, s)ender only, t)o list and sender",__Screen)), this_player()); message("prompt", "\nEnter choice (default 's'): \n", this_player()); input_to("get_reply_list"); } static void get_reply_list(string str) { int i; if(str == "" || !str) str = "s"; else str = lower_case(str)[0..0]; __TmpPost["to"] = ({ convert_name(__BoxInfo[__Current]["from"]) }); switch(str) { case "a": __TmpPost["to"] += __BoxInfo[__Current]["to"]; __TmpPost["cc"] = __BoxInfo[__Current]["cc"]; break; case "c": __TmpPost["cc"] = __BoxInfo[i]["cc"]; break; case "s": __TmpPost["cc"] = ({}); break; case "t": __TmpPost["to"] += __BoxInfo[__Current]["to"]; __TmpPost["cc"] = ({}); break; default: message("prompt","Invalid choice. Choose again: \n", this_player()); input_to("get_reply_list"); return; } if(!__Options["askcc"]) get_cc(""); else { message("prompt", "Copies to: \n", this_player()); input_to("get_cc"); } } static private string query_reply_text() { string tmp; tmp = (string)LETTERS_D->query_letter(__BoxInfo[__Current]["id"]); return sprintf("\n>%s\n", replace_string(tmp, "\n", "\n>")); } static private void forward_letter(string str, int flag) { string *args; int i, x; if(str == "" || !str) { message("prompt", "To: \n", this_player()); input_to("get_forward_list"); return; } i = sizeof(args = explode(lower_case(str), " ")); if(!flag) { while(i--) if(sscanf(args[i], "%d", x) && x) break; if(!x) x = __Current; else { x--; if( !i ) { if(sizeof(args) == 1) args = ({}); else args = args[1..]; } else if( i == sizeof(args)) { args = args[0..<2]; } else if(sizeof(args) == 1) args = ({}); else args = args[0..(i-1)] + args[(i+1)..]; } if(x < 0 || x > sizeof(__BoxInfo)) { postal_error("Letter number is out of range."); return; } if(!sizeof(args)) { forward_letter(0, 1); return; } } set_current(x); __TmpPost["to"] = args; if((__TmpPost["subject"]=__BoxInfo[__Current]["subject"])[0..4] != "(fwd)") __TmpPost["subject"] = sprintf("(fwd) %s",__TmpPost["subject"]); __TmpPost["from"] = (string)this_player()->GetKeyName(); __TmpPost["date"] = time(); message("prompt", "Comment on original letter (default 'n')? \n", this_player()); input_to("confirm_comments"); } static void get_forward_list(string str) { if(str == "" || !str) { message("prompt","Invalid recipients. Abort forward (default 'y')? \n", this_player()); input_to("confirm_forward_abort"); return; } else forward_letter(str, 1); } static void confirm_comments(string str) { if(str == "" || !str) str = "n"; else str = lower_case(str)[0..0]; if(str == "y") __FwdRply = ({ "f", query_forward_text() }); else if(str == "n") { __FwdRply = 0; __TmpPost["message"] = query_forward_text(); } else { message("prompt", "Answer 'y' or 'n': \n", this_player()); input_to("confirm_comments"); return; } if(!__Options["askcc"]) get_cc(""); else { message("prompt", "Copies to: \n", this_player()); input_to("get_cc"); } } static private string query_forward_text() { string tmp; tmp = (string)LETTERS_D->query_letter(__BoxInfo[__Current]["id"]); tmp = ">"+replace_string(tmp, "\n", "\n>"); return sprintf("Original letter sent by %s %s:\n%s\n%s\n", capitalize(__BoxInfo[__Current]["from"]), postal_time(__BoxInfo[__Current]["date"]), center("--- --- Begin Forwarded Text --- ---"), tmp); } static void confirm_forward_abort(string str) { if(str == "" || !str) str = "y"; else str = lower_case(str)[0..0]; if(str == "y") { postal_error("Forward aborted."); return; } else if(str != "n") { message("prompt", "Answer 'y' or 'n': \n", this_player()); input_to("confirm_forward_abort"); return; } message("prompt", "To: \n", this_player()); input_to("get_forward_list"); } static private void send_letter(string *args) { string flag, tmp; int j, i, maxi, x; if(!args || !sizeof(args)) { message("prompt", "To: \n", this_player()); input_to("get_to"); return; } __FwdRply = 0; __TmpPost = ([ "from": (string)this_player()->GetKeyName(),"date":time()]); for(i=0, maxi = sizeof(args); i<maxi; i++) { if(args[i] == "" || !args[i]) continue; if(!flag && i < maxi-1 && args[i][0] == '-' && strlen(args[i]) > 1) { if(member_array(args[i][1..1], ({"c","s","i"})) == -1) continue; else flag = args[i][1..1]; } else if(!flag && args[i][0] == '\\' && strlen(args[i]) > 1) args[i] = args[i][1..strlen(args[1])-1]; else if(flag) { if(args[i][0] != '\'') tmp = args[i]; else if(args[i][x=strlen(args[i])-1] =='\'') tmp =args[i][1..x-1]; else { tmp = args[j=i][1..x]; while(++j < maxi && args[j][x=strlen(args[j])-1] != '\'') if(x > 0) tmp += " "+args[j][0..x-1]; if(args[j][x] == '\'' && x > 1) tmp += " "+args[j][0..x-1]; i = j; } switch(flag) { case "c": if(!__TmpPost["cc"]) __TmpPost["cc"] = ({}); __TmpPost["cc"] += ({ convert_name(tmp) }); break; case "s": __TmpPost["subject"] = tmp; break; case "i": tmp=absolute_path((string)this_player()->get_path(),tmp); if(sscanf(tmp,user_path(this_player())+"%s", flag) != 1 || !((int)master()->valid_read(tmp,this_player()))) { if(__CommandLine) { this_object()->eventDestruct(); return; } __TmpPost = ([]); postal_error("Access denied."); return; } if(!file_exists(tmp)) { if(__CommandLine) { this_object()->eventDestruct(); return; } __TmpPost = ([]); postal_error(sprintf("File %s does not exist.",tmp)); return; } if(!(__TmpPost["message"] = read_file(tmp))) __TmpPost["message"] = "EMPTY FILE"; break; } flag = 0; } else { if(!grepp(args[i],"@")){ if(!__TmpPost["to"]) __TmpPost["to"] = ({ trim(convert_name(args[i])) }); else __TmpPost["to"] += ({ trim(convert_name(args[i])) }); } else { if(!__TmpPost["to"]) __TmpPost["to"] = ({ trim(args[i]) }); else __TmpPost["to"] += ({ trim(args[i]) }); } } } if(!__TmpPost["to"]) { message("prompt", "To: \n", this_player()); input_to("get_to"); return; } if(!__TmpPost["subject"]) { message("prompt", "Subject:\n ", this_player()); input_to("get_subject"); return; } else message("mail", sprintf("Subject: %s", __TmpPost["subject"]), this_player()); if(!__TmpPost["cc"] && __Options["askcc"]) { message("prompt", "Copies to: \n", this_player()); input_to("get_cc"); return; } else if(!__TmpPost["cc"]) __TmpPost["cc"] = ({}); if(!__TmpPost["message"]) get_cc(""); else { __TmpPost["message"] = sprintf("%s%s", __TmpPost["message"], query_signature()); confirm_send(); } } static void get_to(string str) { if(str == "" || !str) { if(__CommandLine) { this_object()->eventDestruct(); return; } postal_error("No recipients given. Mail aborted."); return; } send_letter(explode(str, ",")); } static void get_subject(string str) { string tmp; if(str == "" || !str) { message("prompt", "No subject given. Continue (default 'n')? \n", this_player()); input_to("confirm_subject"); return; } __TmpPost["subject"] = str; if(!__TmpPost["cc"] && __Options["askcc"]) { message("prompt", "Copies to: \n", this_player()); input_to("get_cc"); return; } else if(!__TmpPost["cc"]) __TmpPost["cc"] = ({}); if(!__TmpPost["message"]) get_cc(""); else { __TmpPost["message"] = sprintf("%s%s", __TmpPost["message"], query_signature()); confirm_send(); } } static void confirm_subject(string str) { if(str == "" || !str) str = "n"; else str = lower_case(str)[0..0]; if(str == "n") { if(__CommandLine) { this_object()->eventDestruct(); return; } __TmpPost = ([]); postal_error("Mail aborted."); return; } else if(str == "y") get_subject("[No Subject]"); else { message("prompt", "Answer 'y' or 'n': /n", this_player()); input_to("confirm_subject"); return; } } static void get_cc(string str) { string tmp; if(!__TmpPost["cc"]) __TmpPost["cc"] = ({}); if(str && str != "") __TmpPost["cc"] += explode(str, ","); if(__TmpPost["message"]) { __TmpPost["message"] = sprintf("%s%s", __TmpPost["message"], query_signature()); confirm_send(); return; } if(file_exists(tmp = tmpmail())) rm(tmp); if(!__FwdRply || __FwdRply[0] == "f") { message("mail",sprintf("\n%%^INITTERM%%^%s", header(__TmpPost)), this_player()); this_player()->eventEdit(tmp, (: complete_send :)); return; } write_file(tmp, __FwdRply[1]); message("mail", sprintf("\n%%^INITTERM%%^%s", header(__TmpPost)), this_player()); this_player()->eventEdit(tmp, (: complete_send :)); } void complete_send() { string str; if( !(str = read_file(tmpmail()))) str = "No message."; if(__FwdRply && __FwdRply[0] == "f") str = sprintf("%s\n%s\n%s", str, __FwdRply[1], query_signature()); else str = sprintf("%s%s", str, query_signature()); __TmpPost["message"] = str; __FwdRply = 0; confirm_send(); } static private string query_signature() { string tmp; if(!__Options["sig file"]) return ""; if(strsrch(__Options["sig file"], " ") != -1) return sprintf("\n%s", __Options["sig file"]); tmp = absolute_path(homedir(this_player()), __Options["sig file"]); if(!((int)master()->valid_read(tmp, this_player())) || !file_exists(tmp)) { return sprintf("\n%s", __Options["sig file"]); } return read_file(tmp); } static private void confirm_send() { message("mail", center("e)dit, f)orget, s)end", __Screen), this_player()); message("prompt", "\nCommand (default 's'): \n", this_player()); input_to("handle_send_choice"); } static void handle_send_choice(string str) { string tmp; if(str == "" || !str) str = "s"; else str = lower_case(str)[0..0]; switch(str) { case "s": notify_send((string *)LOCALPOST_D->send_post(copy(__TmpPost))); break; case "f": __TmpPost = ([]); postal_error("Mail aborted!"); break; case "e": if(file_exists(tmpmail())) rm(tmp); write_file(tmp, __TmpPost["message"]); map_delete(__TmpPost, "message"); this_player()->eventEdit(tmp, (: complete_send :)); break; default: message("prompt", "Invalid command. Command: \n", this_player()); input_to("handle_send_choice"); break; } } static private void notify_send(string *failures) { string *arr; string tmp; if(!sizeof(failures)) message("mail", "\n\t%^GREEN%^Mail successfully sent!", this_player()); else { message("mail", sprintf("\nFailed to send to: %s", implode(failures, ", ")), this_player()); if(creatorp(this_player())) { write_file(tmp=homedir()+"/tmp/dead.letter", __TmpPost["message"]); } else write_file(tmp = sprintf("%s/%s.letter", homedir()+"/tmp", (string)this_player()->GetKeyName()), __TmpPost["message"]); message("mail", sprintf("A copy of the letter was saved to %s", tmp), this_player()); } if(sizeof(arr=distinct_array(__TmpPost["to"]+__TmpPost["cc"])-failures)) message("mail", sprintf("Mail sent to: %s", implode(arr,", ")), this_player()); if(__CommandLine) { this_object()->eventDestruct(); return; } secondary_prompt(); input_to("index_cmd"); } void incoming_post() { mixed tmp; string id; int *delete; if(__Folder != "new") return; if(file_name(previous_object()) != FOLDERS_D) return; id = (__Current < 0 ? 0 : __BoxInfo[__Current]["id"]); delete =map_array(tmp=(mapping)FOLDERS_D->query_box_info(__Owner,"new"), "order_box", this_object()); __BoxInfo = copy(tmp); set_current(id); __Delete = copy(delete); __IncomingFlag = 1; } int order_box(mapping borg) { int i; i = sizeof(__BoxInfo); while(i--) if(__BoxInfo[i]["id"] == borg["id"]) return __Delete[i]; return 0; }