final_realms_fluffos_v1/
final_realms_fluffos_v1/bin/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/ChangeLog.old/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/Win32/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/simuls/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/clone/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/command/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/data/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/etc/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/master/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/log/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/compiler/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/efuns/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/operators/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/u/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/tmp/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/windows/
final_realms_fluffos_v1/lib/baseobs/guilds/
final_realms_fluffos_v1/lib/baseobs/misc/
final_realms_fluffos_v1/lib/baseobs/races/shadows/
final_realms_fluffos_v1/lib/cmds/god/
final_realms_fluffos_v1/lib/cmds/handlers/
final_realms_fluffos_v1/lib/cmds/handlers/cmds/
final_realms_fluffos_v1/lib/d/heaven/
final_realms_fluffos_v1/lib/d/heaven/heaven/ave/
final_realms_fluffos_v1/lib/d/mudlib/
final_realms_fluffos_v1/lib/d/newbie/
final_realms_fluffos_v1/lib/d/newbie/docs/
final_realms_fluffos_v1/lib/d/newbie/drow/armour/
final_realms_fluffos_v1/lib/d/newbie/drow/items/
final_realms_fluffos_v1/lib/d/newbie/drow/mobs/
final_realms_fluffos_v1/lib/d/newbie/drow/oldmobs/
final_realms_fluffos_v1/lib/d/newbie/drow/weapons/
final_realms_fluffos_v1/lib/d/newbie/duergar/weapons/
final_realms_fluffos_v1/lib/d/newbie/dwarf/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/cafe/
final_realms_fluffos_v1/lib/d/newbie/elf/chars/equip/
final_realms_fluffos_v1/lib/d/newbie/elf/items/armours/
final_realms_fluffos_v1/lib/d/newbie/elf/items/obj/
final_realms_fluffos_v1/lib/d/newbie/elf/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/quick_fix/
final_realms_fluffos_v1/lib/d/newbie/gnome/armour/
final_realms_fluffos_v1/lib/d/newbie/gnome/buildings/
final_realms_fluffos_v1/lib/d/newbie/gnome/items/
final_realms_fluffos_v1/lib/d/newbie/gnome/npcs/clones/
final_realms_fluffos_v1/lib/d/newbie/gnome/rooms/northrooms/
final_realms_fluffos_v1/lib/d/newbie/gnome/weapons/
final_realms_fluffos_v1/lib/d/newbie/goblin/armour/
final_realms_fluffos_v1/lib/d/newbie/goblin/items/
final_realms_fluffos_v1/lib/d/newbie/grads/log/
final_realms_fluffos_v1/lib/d/newbie/grads/npcs/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/cave1/
final_realms_fluffos_v1/lib/d/newbie/grads/temp/
final_realms_fluffos_v1/lib/d/newbie/guests/weapons/
final_realms_fluffos_v1/lib/d/newbie/half-elf/items/
final_realms_fluffos_v1/lib/d/newbie/half-elf/newroomss/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/castle/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/drows/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/savannah/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/secret/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/town/
final_realms_fluffos_v1/lib/d/newbie/halfling/
final_realms_fluffos_v1/lib/d/newbie/halfling/misc/
final_realms_fluffos_v1/lib/d/newbie/halfling/rooms/cave/
final_realms_fluffos_v1/lib/d/newbie/human/
final_realms_fluffos_v1/lib/d/newbie/human/armour/
final_realms_fluffos_v1/lib/d/newbie/human/monsters/
final_realms_fluffos_v1/lib/d/newbie/human/obj/
final_realms_fluffos_v1/lib/d/newbie/human/weapons/
final_realms_fluffos_v1/lib/d/newbie/lizard/armour/
final_realms_fluffos_v1/lib/d/newbie/lizard/items/
final_realms_fluffos_v1/lib/d/newbie/lizard/underwater/
final_realms_fluffos_v1/lib/d/newbie/lizard/weapons/
final_realms_fluffos_v1/lib/d/newbie/logs/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/rooms/
final_realms_fluffos_v1/lib/d/newbie/newelf/
final_realms_fluffos_v1/lib/d/newbie/newelf/chars/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/recopied/
final_realms_fluffos_v1/lib/d/newbie/newelf/obj/
final_realms_fluffos_v1/lib/d/newbie/newelf/quest_docs./
final_realms_fluffos_v1/lib/d/newbie/newken/
final_realms_fluffos_v1/lib/d/newbie/newken/chars/
final_realms_fluffos_v1/lib/d/newbie/newken/misc/
final_realms_fluffos_v1/lib/d/newbie/newken/npcs/
final_realms_fluffos_v1/lib/d/newbie/newken/obj/
final_realms_fluffos_v1/lib/d/newbie/newliz/
final_realms_fluffos_v1/lib/d/newbie/newliz/cave/
final_realms_fluffos_v1/lib/d/newbie/newliz/npcs/
final_realms_fluffos_v1/lib/d/newbie/orc/items/misc/
final_realms_fluffos_v1/lib/d/newbie/orc/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/orc/tower/
final_realms_fluffos_v1/lib/d/vehicle/
final_realms_fluffos_v1/lib/doc/
final_realms_fluffos_v1/lib/doc/driver/
final_realms_fluffos_v1/lib/doc/driver/concepts/
final_realms_fluffos_v1/lib/doc/driver/driver/
final_realms_fluffos_v1/lib/doc/driver/efuns/arrays/
final_realms_fluffos_v1/lib/doc/driver/efuns/bitstrings/
final_realms_fluffos_v1/lib/doc/driver/efuns/communication/
final_realms_fluffos_v1/lib/doc/driver/efuns/core/
final_realms_fluffos_v1/lib/doc/driver/efuns/debugging/
final_realms_fluffos_v1/lib/doc/driver/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/driver/efuns/interactive/
final_realms_fluffos_v1/lib/doc/driver/efuns/mappings/
final_realms_fluffos_v1/lib/doc/driver/efuns/objects/
final_realms_fluffos_v1/lib/doc/driver/efuns/security/
final_realms_fluffos_v1/lib/doc/driver/efuns/strings/
final_realms_fluffos_v1/lib/doc/driver/efuns/system/
final_realms_fluffos_v1/lib/doc/driver/efuns/types/
final_realms_fluffos_v1/lib/doc/driver/lpc/constructs/
final_realms_fluffos_v1/lib/doc/driver/lpc/types/
final_realms_fluffos_v1/lib/doc/driver/platforms/
final_realms_fluffos_v1/lib/doc/lpc/
final_realms_fluffos_v1/lib/doc/mail/
final_realms_fluffos_v1/lib/doc/man/
final_realms_fluffos_v1/lib/doc/man/html/
final_realms_fluffos_v1/lib/doc/man/html/applies/
final_realms_fluffos_v1/lib/doc/man/html/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/html/driver/
final_realms_fluffos_v1/lib/doc/man/html/efuns/
final_realms_fluffos_v1/lib/doc/man/html/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/html/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/html/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/html/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/html/efuns/general/
final_realms_fluffos_v1/lib/doc/man/html/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/
final_realms_fluffos_v1/lib/doc/man/local/applies/
final_realms_fluffos_v1/lib/doc/man/local/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/local/applies/master/
final_realms_fluffos_v1/lib/doc/man/local/concepts/
final_realms_fluffos_v1/lib/doc/man/local/defines/
final_realms_fluffos_v1/lib/doc/man/local/driver/
final_realms_fluffos_v1/lib/doc/man/local/efuns/
final_realms_fluffos_v1/lib/doc/man/local/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/local/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/local/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/local/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/local/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/local/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/local/efuns/general/
final_realms_fluffos_v1/lib/doc/man/local/efuns/interactive/
final_realms_fluffos_v1/lib/doc/man/local/efuns/internals/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/local/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/objects/
final_realms_fluffos_v1/lib/doc/man/local/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/efuns/sockets/
final_realms_fluffos_v1/lib/doc/man/local/efuns/strings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/system/
final_realms_fluffos_v1/lib/doc/man/local/historical/
final_realms_fluffos_v1/lib/doc/man/local/lfun/QC/
final_realms_fluffos_v1/lib/doc/man/local/lfun/events/
final_realms_fluffos_v1/lib/doc/man/local/lfun/monster/
final_realms_fluffos_v1/lib/doc/man/local/lfun/properties/
final_realms_fluffos_v1/lib/doc/man/local/lpc/
final_realms_fluffos_v1/lib/doc/man/local/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/local/lpc/types/
final_realms_fluffos_v1/lib/doc/man/local/standards/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/basic/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/intermediate/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/concepts/
final_realms_fluffos_v1/lib/doc/man/mudos/driver/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/general/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mixed/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/types/
final_realms_fluffos_v1/lib/doc/races/
final_realms_fluffos_v1/lib/doc/races/old_race/
final_realms_fluffos_v1/lib/global/virtual/
final_realms_fluffos_v1/lib/global/wiz_backup/
final_realms_fluffos_v1/lib/net/config/
final_realms_fluffos_v1/lib/net/daemon/chars/
final_realms_fluffos_v1/lib/net/inherit/
final_realms_fluffos_v1/lib/net/intermud3/
final_realms_fluffos_v1/lib/net/intermud3/cmds/
final_realms_fluffos_v1/lib/net/intermud3/save/
final_realms_fluffos_v1/lib/net/intermud3/services/
final_realms_fluffos_v1/lib/net/obj/
final_realms_fluffos_v1/lib/net/old/
final_realms_fluffos_v1/lib/net/old/intermud/
final_realms_fluffos_v1/lib/net/old/intermud/adm/
final_realms_fluffos_v1/lib/net/old/intermud/services/
final_realms_fluffos_v1/lib/net/old/intermud/udp/
final_realms_fluffos_v1/lib/net/virtual/
final_realms_fluffos_v1/lib/obj/b_day/
final_realms_fluffos_v1/lib/obj/chars/
final_realms_fluffos_v1/lib/obj/handlers/lists/
final_realms_fluffos_v1/lib/obj/handlers/useless/
final_realms_fluffos_v1/lib/obj/monsters/
final_realms_fluffos_v1/lib/obj/roomgen/
final_realms_fluffos_v1/lib/obj/soul/
final_realms_fluffos_v1/lib/obj/vegetation/
final_realms_fluffos_v1/lib/obj/weapons/oldsys/
final_realms_fluffos_v1/lib/open/
final_realms_fluffos_v1/lib/players/g/
final_realms_fluffos_v1/lib/releasefiles/d/heaven/
final_realms_fluffos_v1/lib/releasefiles/d/mudlib/
final_realms_fluffos_v1/lib/releasefiles/d/newbie/
final_realms_fluffos_v1/lib/releasefiles/doc/
final_realms_fluffos_v1/lib/releasefiles/players/g/
final_realms_fluffos_v1/lib/releasefiles/save/
final_realms_fluffos_v1/lib/releasefiles/save/environ/
final_realms_fluffos_v1/lib/releasefiles/save/roomgen/
final_realms_fluffos_v1/lib/releasefiles/secure/
final_realms_fluffos_v1/lib/releasefiles/w/
final_realms_fluffos_v1/lib/releasefiles/w/god/
final_realms_fluffos_v1/lib/room/
final_realms_fluffos_v1/lib/save/
final_realms_fluffos_v1/lib/save/environ/
final_realms_fluffos_v1/lib/save/roomgen/
final_realms_fluffos_v1/lib/scripts/
final_realms_fluffos_v1/lib/secure/crerem/
final_realms_fluffos_v1/lib/secure/dom/
final_realms_fluffos_v1/lib/secure/log/
final_realms_fluffos_v1/lib/secure/misc/
final_realms_fluffos_v1/lib/std/adnd/
final_realms_fluffos_v1/lib/std/commands/shadows/
final_realms_fluffos_v1/lib/std/creator/
final_realms_fluffos_v1/lib/std/curses/
final_realms_fluffos_v1/lib/std/curses/old_sys/
final_realms_fluffos_v1/lib/std/curses/shadows/
final_realms_fluffos_v1/lib/std/dom/
final_realms_fluffos_v1/lib/std/effects/
final_realms_fluffos_v1/lib/std/effects/healing/
final_realms_fluffos_v1/lib/std/effects/other/
final_realms_fluffos_v1/lib/std/effects/poisons/
final_realms_fluffos_v1/lib/std/environ/
final_realms_fluffos_v1/lib/std/guilds/
final_realms_fluffos_v1/lib/std/guilds/priests/samples/
final_realms_fluffos_v1/lib/std/guilds/wizards/
final_realms_fluffos_v1/lib/std/living/baldy/
final_realms_fluffos_v1/lib/std/living/divstuff/
final_realms_fluffos_v1/lib/std/paran/
final_realms_fluffos_v1/lib/std/poisons/
final_realms_fluffos_v1/lib/std/poisons/shadows/
final_realms_fluffos_v1/lib/std/poisons/weapons/
final_realms_fluffos_v1/lib/std/race_groups/
final_realms_fluffos_v1/lib/std/room/
final_realms_fluffos_v1/lib/std/room/old/
final_realms_fluffos_v1/lib/std/rooms/
final_realms_fluffos_v1/lib/std/shadows/
final_realms_fluffos_v1/lib/std/shadows/test_shad/
final_realms_fluffos_v1/lib/std/socket/
final_realms_fluffos_v1/lib/std/spells/
final_realms_fluffos_v1/lib/std/vaults/
final_realms_fluffos_v1/lib/tmp/
final_realms_fluffos_v1/lib/w/
final_realms_fluffos_v1/lib/w/god/
final_realms_fluffos_v1/old/
final_realms_fluffos_v1/win32/
// From Descartes .. who knows when and where...
// Changed TP->getenv() to TP->query_property, Radix July 1996
// Added age_mail() call to postal_d.c, Radix March 7, 1997
// Added MAIL_UNREAD_HEADERS property option for immorts : Radix - April 4, 1997

#include <ed.h>
#include <post.h>

inherit "/std/object";

mapping *box_info;
mapping my_groups;
static int current;
static mapping mud_groups, tmp_post;
static string owner;
static int just_sending, fwd_flag;
static int *delete;

void headers(int x);
void do_mail(string str);
void get_to(string str);
void add_group(string str);
void remove_group(string str);
void do_groups(string str);
void do_help(string str);
void do_save(string cmd, string str);
void do_reply(string cmd, string arg);
void do_forward(string cmd, string arg);
void do_quit(string cmd);
void verify_quit(string str);
void really_quit(string str);
void handle_delete(string cmd, string arg);
void do_header(string str);
void read_mail(int x);
void get_cc(string str);
string letter_head(mapping this_letter, int ansi);
string get_header_time(int x);

void create() {
    ::create();
    set_name("carrier pigeon");
    set_aliases(({ "pigeon","dead pigeon","carrier pigeon","box", "post box", POST_ID }) );
   set_short("A dead carrier pigeon");
    set_long("You mail with this.\n");
    fwd_flag = -1;
    box_info = ({});
    my_groups = ([]);
    mud_groups = ([]);
    tmp_post = ([]);
    seteuid("Root");
}

void init() {
    int i;

    if(this_player() != environment(this_object())) {
      call_out("dest_me",0,0);
        return;
    }
    box_info = ({});
    my_groups = ([]);
    mud_groups = (mapping)POSTAL_D->query_mud_groups();
    owner = (string)this_player()->query_name();
    restore_object(DIR_POSTAL+"/"+owner);
//   POSTAL_D->age_mail(owner);
    if(!(i=sizeof(box_info))) {
        current = 0;
        return;
    }
    current = -1;
    for(i=0; i<sizeof(box_info) && current == -1; i++)
      if(!box_info[i]["read"]) current = i;
    delete = allocate(sizeof(box_info));
}

void start_mail(string str) {
    if(str && str != "") {
        str = (string)this_player()->expand_nickname(str);
        just_sending = 1;
        do_mail(str);
        return;
    }
    write("Imaginary Intermud Postal Service (IIPS) 1.0 for the Discworld Mudlib\n");
    write("Descartes of Borg 1993    (type \"?\" for help)\n");
    write("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
    if(this_player()->query_property("MAIL_NO_HEADERS"))
    {
       do_mail(0);
       return;
    }
    if(this_player()->query_property("MAIL_UNREAD_HEADERS"))
    {
       headers(-1);
       do_mail(0);
       return;
    }
    headers(0);
}

void do_mail(string str) {
    if(str) get_to(str);
    else {
        write(POST_PROMPT);
        input_to("postal_cmd");
    }
}

void postal_cmd(string str) {
    string cmd, arg;
    string *args;
    int x, i;

    if(!str || str == "") {
        for(current=-1,i=0,x=sizeof(box_info); i<x && current==-1; i++)
          if(!box_info[i]["read"]) current = i;
        cmd = (current+1)+"";
    }
    else cmd = str;
    if(sscanf(cmd, "%d", x)) {
        if(x>0 && x<=sizeof(box_info)) {
            read_mail(current = x-1);
            return;
        }
        else {
            write("Invalid letter number (\"?\" for help)\n");
            do_mail(0);
            return;
        }
    }
    cmd = (args = explode(str, " "))[0][0..0];
    if(sizeof(args) > 1) arg = implode(args[1..sizeof(args)-1], " ");
    else arg = "";
    arg = (string)this_player()->expand_nickname(arg);
    switch(cmd) {
        case "a": add_group(arg); break;
        case "x": remove_group(arg); break;
        case "g": do_groups(arg); return;
        case "?": do_help(arg); return;
        case "s": case "S": 
            if(!wizardp(this_player())) 
              write("Save option only available to immortals.\n");
            else do_save(cmd, arg);
            break;
        case "R": case "r": do_reply(cmd, arg); return;
        case "F": case "f": do_forward(cmd, arg); return;
        case "Q": case "q": do_quit(cmd); return;
        case "m": get_to(arg); return;
        case "d": case "u": handle_delete(cmd, arg); break;
        case "h": do_header(arg); return;
        default:
          write("Invalid postal command (\"?\" for help)\n");
    }
    do_mail(0);
}

void do_groups(string str) {
    if(!str || str == "") {
      write("Personal and "+mud_name()+" groups for the IIPS:\n");
      this_player()->set_finish_func("do_mail", this_object());
      this_player()->more_string(format_page(keys(mud_groups)+keys(my_groups),
        4));
      return;
    }
    if(!mud_groups[str] && !my_groups[str]) {
      write("Group "+str+" does not exist.\n");
    }
    else if(mud_groups[str]) {
      write("Members of the "+mud_name()+" IIPS group "+str+":\n");
      write(format_page(mud_groups[str], 4));
    }
    else {
      write("Members of your personal IIPS group "+str+":\n");
      write(format_page(my_groups[str], 4));
    }
    do_mail(0);
}

void add_group(string str) {
    string *members;
    string grp;
    int i;

    if(!str || str == "") {
        write("No group specified.\n");
        return;
    }
    grp = (members=explode(lower_case(str), " "))[0];
    i = sizeof(members -= ({ grp }));
    if(member_array(grp, members) != -1) {
        write("You cannot define a group as a member of itself.\n");
        return;
    }
    if(mud_groups[grp]) {
        write(mud_name()+" has already defined a group called "+grp+".\n");
        return;
    }
    if(user_exists(grp)) {
        write("A player by the name "+grp+" already exists.\n");
        return;
    }
    if(!my_groups[grp]) my_groups[grp] = ({});
    my_groups = (mapping)POSTAL_D->add_group(owner, grp, members);
    write("Group "+grp+" added to.\n");
}

void remove_group(string str) {
    string *members;
    string grp;

    if(!str || str == "") {
        write("No group specified.\n");
        return;
    }
    grp = (members = explode(str, " "))[0];
    if(!my_groups[grp]) {
        write("No such group "+grp+".\n");
        return;
    }
    if(!sizeof((members = members-({grp})))) members = my_groups[grp];
    my_groups = (mapping)POSTAL_D->remove_group(owner, grp, members);
    write("Members removed from group "+grp+".\n");
}

void do_help(string str) {
    if(!str) str = "";
    switch(str) {
        case "r": case "R":
          write("Commands r and R\n");
          write("Syntax: <r (#) (all)>\n");
          write("        <R (#) (all)>\n\n");
          write(wrap("Allows you to reply to the author of the "
          "current letter or of the letter specified.  If you "
          "specify \"all\" as a parameter, the reply goes to the author "
          "of the letter as well as all people originally addessed.  "
          "The \"R\" command differs from the \"r\" command in that "
          "the \"R\" command includes the original text in your reply."));
          break;
        case "f": case "F":
          write("Commands f and F\n");
          write("Syntax: <f (#) ([list])\n        <F (#) ([list])\n\n");
          write(wrap("Forwards a copy of the current letter or of "
          "the letter specified to the recipient list.  "
          "The \"F\" command allows you to add text."));
          break;
        case "q": case "Q":
          write("Commands q and Q\n");
          write("Syntax: <q>\n        <Q>\n");
          write(wrap("Quits out of the mailer.  The \"Q\" command"
          "quits without making any changes to the mail (nothing "
          "is deleted).  \"q\" deleteds letters marked for delteion"));
          break;
        case "a":
          write("Command a\nSyntax: <a [group] [list]>\n\n");
          write(wrap("Adds a list of players to an individualized "
          "mailer group.  If no such group exists, one is created."));
          break;
        case "x":
          write("Command x\nSyntax: <x [group] [list]>\n\n");
          write(wrap("Deletes a list of players from your mailer group "
          "of choice.  If no player list is given, the whole "
          "groups is deleted."));
          break;
        case "g":
          write("Command g\nSyntax: <g ([group])>\n\n");
          write(wrap("Lists mud and personal groups for the IIPS mailer.  "
          "If no group is specified, all group names are listed.  Otherwise the "
          "members of the group named are listed."));
          break;
        case "s": case "S":
          write("Commands s and S\nSyntax: <s (#) [filename]>\n");
            write("        <S (#) [filename]>\n\n");
          write(wrap("Only available to immortals.  Saves the post specified "
          "or the current post to the file filename in the wizards mail save "
          "directory."));
          break;
        case "u":
          write("Command u\nSyntax: <u (#)>\n\n");
          write(wrap("Undeletes a letter marked for deletion."));
          break;
        case "d":
          write("Command d\nSyntax: <d (#)>\n\n");
          write(wrap("Marks a letter for deletion upon quitting mail."));
        case "h":
          write("Command h\nSyntax: <h (#)>\n\n");
          write(wrap("Lists the headers for all letters, or letters "
          "beginning at the letter number specified."));
          break;
        case "m":
          write("Command m\nSyntax: <m [list]>\n\n");
          write(wrap("Allows you to create a letter and send it to "
          "the list of players and groups you specify.  You will "
          "be prompted at the end of creating the mail for a list "
          "of players or groups who should get carbon copies."));
          break;
        default:
            this_player()->set_finish_func("do_mail", this_object());
            this_player()->more_string(read_file(wizardp(this_player()) ?
                POST_IMMORTAL_HELP : POST_USER_HELP));
          return;
    }
    do_mail(0);
}

void do_save(string cmd, string str) {
    string tmp, where;
    int i, x;

    if(!str || !(i=strlen(str))) {
        write("You must specify the name of a file to save to.\n");
        return;
    }
    if(sscanf(str, "%d %s", x, where) != 2) where = str;
    else {
        i = strlen(where);
        current = x-1;
    }
    if(current < 0 || current >= sizeof(box_info)) {
        write("Invalid letter number  (\"?\" for help).\n");
        return;
    }
    while(i--)
      if(lower_case(where)[i] < 'a' || lower_case(where)[i] > 'z') {
          write("You may only use alphabetic characters.\n");
          return;
      }
    tmp = "/w/"+owner+"/"+where;
    if(file_size(tmp) > -1) x = 1;
    else x = 0;
    write_file(tmp, (string)LETTER_D->get_message(box_info[current]["id"]));
    if(!x) write("Letter written to new file: "+tmp+".\n");
    else write("Letter appended to file: "+str+".\n");
    if(cmd == "S") delete[current] = 1;
    return;
}

void do_header(string str) {
    int x;

    if(!str || str == "") headers(0);
    else {
        x = atoi(str);
        if(x > 0 && x<=sizeof(box_info)) headers(x-1);
        else {
            write("Invalid letter number (\"?\" for help).\n");
            do_mail(0);
        }
    }
}

void headers(int x) {
    string lines;
    int i;

    if(!(i=sizeof(box_info))) {
        write("No letters are currently in your post box.\n");
        current = 0;
        do_mail(0);
        return;
    }
    if(x == -1) {
       lines = "";
       for(x=0; x<i; x++)
       {
          if(!box_info[x]["read"])
          {
              lines+= (x+1)+" (new)"+(x==current ? ">" : (delete[x] ?
               "*" : " "))+
              arrange_string(capitalize(box_info[x]["from"]),16)+" "+
              arrange_string(get_header_time(box_info[x]["date"]), 12)+
              box_info[x]["subject"]+"\n";
          }
       }
    }
    else
    {
        for(lines = ""; x<i; x++) {
          lines += (x+1)+" "+(box_info[x]["read"] ? "     " :
              "(new)")+(x==current ? ">" : (delete[x] ? "*" : " "))+
              arrange_string(capitalize(box_info[x]["from"]), 16)+" "+
              arrange_string(get_header_time(box_info[x]["date"]), 12)+
              box_info[x]["subject"]+"\n";
        }
    }
    this_player()->set_finish_func("do_mail", this_object());
    this_player()->more_string(lines);
}

string get_header_time(int x) {
    string a, b, c, d;

    if(sscanf(ctime(x), "%s %s  %s %s", a, b, c, d) != 4)
      sscanf(ctime(x), "%s %s %s %s", a, b, c, d);
    return a+" "+b+" "+c;
}


void old_handle_delete(string cmd,string arg)
{
    if(arg && arg != "") current = atoi(arg)-1;
    if(current < 0 || current >= sizeof(box_info)) {
        write("Invalid letter number (\"?\" for help).\n");
        return;
    }
    if(cmd == "u" && !delete[current]) {
        write("Letter "+(current+1)+" is not marked for deletion.\n");
        return;
    }
    if(cmd == "d" && delete[current]) {
        write("Letter "+(current+1)+" is already marked for deletion.\n");
        return;
    }
    if(cmd == "u") {
        delete[current] = 0;
        write("Letter "+(current+1)+" is no longer marked for deletion.\n");
        return;
    }
    delete[current] = 1;
    write("Letter "+(current+1)+" is now marked for deletion.\n");
    return;
}
void handle_delete(string cmd, string arg) {
   string *list;
   int i;
   int start,end;
   if(!arg || arg == "")
   {
      old_handle_delete(cmd,arg);
      return;
   }
   list = explode(arg,",");
   switch(sizeof(list))
   {
    case 0:
      write("Invalid letter number \"?\" for help.\n");
   break;
   case 1:
      old_handle_delete(cmd,arg);
    break;
   case 2:
    start = atoi(list[0]);
      end = atoi(list[1]);
      if(start >=0 && end > start)
      for(i = start; i <=end; i++) old_handle_delete(cmd,sprintf("%d",i));
    break;
   default:
     for(i = 0; i < sizeof(list); i++)
   {
      old_handle_delete(cmd,list[i]);
    }
   break;
   }
}

void do_quit(string str) {
    if(!this_player()->query_property("MAIL_DELETE_PROMPT") || str == "Q")
        really_quit(str);
    else if(member_array(1, delete) == -1) really_quit(str);
    else {
        write("Delete all marked letters? (y/n) ");
        input_to("verify_quit");
    }
}

void verify_quit(string str) {
    if(!str || str == "" || lower_case(str[0..0]) == "y") really_quit("q");
    else if(lower_case(str[0..0]) == "n") {
        write("Files will remain undeleted.\n");
        really_quit("Q");
    }
    else {
        write("Invalid input.\nDelete all marked letters? (y/n) ");
        input_to("verify_quit");
    }
}

void really_quit(string str) {
    int i, x;

    if(str == "Q") {
        write("No letters deleted or marked as read.\n");
        dest_me();
        if(this_object()) destruct(this_object());
        return;
    }
    i = sizeof(box_info);
    while(i--) {
        if(delete[i]) {
            x++;
            POSTAL_D->remove_post(owner, box_info[i]["id"]);
        }
    }
    POSTAL_D->flush_files();
    write(x+" letters deleted.\n");
    dest_me();
    if(this_object()) destruct(this_object());
}

void get_to(string str) {
    if(!str || str == "") {
        write("No users or groups named.\n");
        do_mail(0);
        return;
    }
    tmp_post = ([]);

    // Fix by Aragorn
    str = replace_string(str,"@@","");

    tmp_post["to"] = explode(str, " ");
    tmp_post["from"] = (string)this_player()->query_name();
    tmp_post["date"] = time();
    write("Subject: ");
    input_to("get_subject");
}

void get_subject(string str) {

    if(!str || str == "") str = "[No subject]";

    str = replace_string(str,"@@","");
    tmp_post["subject"] = str;
    write(letter_head(tmp_post, (int)this_player()->query_ansi()));
    this_player()->do_edit(0, "get_text", this_object());
}

void abort() {
    if(just_sending) {
        dest_me();
        if(this_object()) destruct(this_object());
        return;
    }
    do_mail(0);
}

void get_text(string str) {
    if(!str) {
        abort();
        return;
    }
    if(fwd_flag != -1) {
        str += "\n-----\n"+
          "Original message sent by "+capitalize(box_info[fwd_flag]["from"])+
          " to "+capitalize(owner)+" on "+ctime(box_info[fwd_flag]["date"])+
          ":\n-----\n"+(string)LETTER_D->get_message(box_info[fwd_flag]["id"]);
        fwd_flag = -1;
    }

    // Fix by Aragorn
    str = replace_string(str, "@@","");

    tmp_post["message"] = str+"\n";
    tmp_post["message"] += (string)POSTAL_D->read_sig(owner);
    if(!this_player()->query_property("MAIL_NO_CC")) {
        write("Cc: ");
        input_to("get_cc");
        return;
    }
    get_cc("");
}

void get_cc(string str) {
    string dead;
    string *who, *diff, *orig;

    if(!tmp_post["cc"]) tmp_post["cc"] = ({});

    // Fix by Aragorn
    if (str) str = replace_string(str,"@@","");
    if(str && str != "") tmp_post["cc"] += explode(lower_case(str), " ");
    orig = uniq_array(tmp_post["to"]+tmp_post["cc"]);
    diff = orig - (who=(string *)POSTAL_D->post_mail(tmp_post));
    if(sizeof(who)) 
        write("Mail sent successfully to:\n"+format_page(who, 3)+"\n");
    else {
        if(wizardp(this_player())) dead = "/w/"+owner+"/dead.letter";
        else dead = DIR_TMP+"/post/"+owner+".dead";
        write("No recipients found.  Appending to "+dead+".\n");
        write_file(dead, tmp_post["message"]+"\n");
    }
    MAIL_S->flush_mail_queue();
    POSTAL_D->flush_files();
    if(just_sending) {
        dest_me();
        if(this_object()) destruct(this_object());
        return;
    }
    do_mail(0);
}

void do_reply(string cmd, string arg) {
    string recep;
    int x;

    if(arg && arg != "") {
        if(sscanf(arg, "%d %s", x, recep) != 2) {
            if(!sscanf(arg, "%d", x)) recep = arg;
            else {
                recep = "";
                current = x-1;
            }
        }
        else current = x-1;
    }
    else recep = "";
    if(current < 0 || current >= sizeof(box_info)) {
        write("Invalid letter number (\"?\" for help).\n");
        do_mail(0);
        return;
    }
    else if(recep != "" && recep != "all" && recep != "to") {
        write("Invalid reply parameter: "+recep+" (\"?\" for help).\n");
        do_mail(0);
        return;
    }
    tmp_post["from"] = (string)this_player()->query_name();
    if(recep == "") {
        tmp_post["to"] = ({ box_info[current]["from"] });
        tmp_post["cc"] = ({});
    }
    else if(recep == "to") {
        tmp_post["to"] = ({box_info[current]["from"] })+box_info[current]["to"];
        tmp_post["cc"] = ({});
    }
    else {
        tmp_post["to"] = ({box_info[current]["from"] })+box_info[current]["to"];
        tmp_post["cc"] = box_info[current]["cc"];
    }
    tmp_post["date"] = time();
    if(strlen(box_info[current]["subject"]) < 4 ||
      box_info[current]["subject"][0..3] != "RE: ")
        tmp_post["subject"] = "RE: "+box_info[current]["subject"];
    else tmp_post["subject"] = box_info[current]["subject"];
    write(letter_head(tmp_post, (int)this_player()->query_ansi()));
    this_player()->do_edit( (cmd == "R" ?
      "On "+ctime(box_info[current]["date"])+", "+
      capitalize(box_info[current]["from"])+" wrote:\n>\n>"+
      replace_string((string)LETTER_D->get_message(box_info[current]["id"]),
      "\n", "\n> ")+"\n" : 0), "get_text", this_object());
}

void do_forward(string cmd, string arg) {
    string recep;
    int x;

    if(!arg || arg == "") {
        write("Recepient for forward missing (\"?\" for help).\n");
        do_mail(0);
        return;
    }
    if(sscanf(arg, "%d %s", x, recep) == 2) {
        current = x-1;
        tmp_post["to"] = explode(lower_case(recep), " ");
    }
    else tmp_post["to"] = explode(lower_case(arg), " ");
    if(current < 0 || current >= sizeof(box_info)) {
        write("Invalid letter number (\"?\" for help).\n");
        do_mail(0);
        return;
    }
    tmp_post["from"] = (string)this_player()->query_name();
    tmp_post["date"] = time();
    if(strlen(box_info[current]["subject"]) < 10 ||
      box_info[current]["subject"][0..9] != "(forward) ")
        tmp_post["subject"] = "(forward) "+box_info[current]["subject"];
    else tmp_post["subject"] = box_info[current]["subject"];
    tmp_post["cc"] = ({});
    write(letter_head(tmp_post, (int)this_player()->query_ansi()));
    if(cmd == "F") {
        fwd_flag = current;
        this_player()->do_edit(0, "get_text", this_object());
    }
    else {
        get_text("\n-----\nOriginal letter sent by "+capitalize(box_info[current]["from"])+" to "+capitalize(owner)+" "+ctime(box_info[current]["date"])+":\n"+
          "-----
"+(string)LETTER_D->get_message(box_info[current]["id"])+"\n");
    }
}

void read_mail(int x) {
    string borg;

    borg = "Letter "+(x+1)+(delete[x] ? "[DELETED]:\n" : ":\n");
    borg += letter_head(box_info[x], (int)this_player()->query_ansi());
    borg += "\n"+(string)LETTER_D->get_message(box_info[x]["id"])+"\n";
    POSTAL_D->mark_read(owner, box_info[x]["id"]);
    box_info[x]["read"] = 1;
    this_player()->set_finish_func("do_mail", this_object());
    this_player()->more_string(borg);
}

string letter_head(mapping this_letter, int ansi) {
    int i, max;
    string ret;

  ret = ctime((int)this_letter["date"])+" from ";
    ret += "%^GREEN%^"+capitalize(this_letter["from"])+"%^RESET%^\n";
    ret += "To: ";
    for(i=0, max = sizeof(this_letter["to"]); i<max; i++)
      ret += capitalize(this_letter["to"][i])+" ";
    if(!sizeof(this_letter["cc"])) ret = wrap(ret,0);
    else {
        ret = wrap(ret,0)+"Cc: ";
        for(i=0, max = sizeof(this_letter["cc"]); i<max; i++)
          ret += capitalize(this_letter["cc"][i])+" ";
        ret = wrap(ret);
    }
    ret += "Subject: %^GREEN%^"+this_letter["subject"]+"%^RESET%^\n";
    return ret;
}

int valid_shadow() { return 1; }

int drop () { return 1; }

int get() { return 0; }