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/
/*
 * UDP port handling code. Version 0.61
 * Written by Nostradamus for Zebedee.
 * Developed from an original concept by Alvin@Sushi.
 */

#pragma strict_types
#include <newudp.h>
#include <socket.h>

/* --- Configurable definitions. --- */

/* CD muds will probably need these include file. */
/* #include <std.h> */
/* #include "/config/sys/local.h" */

/* Public commands which will be accessible to any unlisted muds.
 * PING, QUERY and REPLY are included by default. */
#define COMMANDS \
({ "channel", "finger", "ftp", "locate", "man", "tell", "who" })

/* Define this to the object that receives incoming packets and passes
 * them to the inetd. Undefine for no receive_udp() security.
 * NOTE: The string must be of the format that file_name() returns. */
/* #define UDP_MASTER    __MASTER_OBJECT__ */
/* #define UDP_MASTER    SECURITY    // CD */
#define UDP_MASTER    "/single/master"
/* #define UDP_MASTER    "obj/master" */

/* How to set the euid for this object if using native mode.
 * Ensure that it can read the INETD_HOSTS file. */
/* #define SET_EUID        seteuid("root") */
#define SET_EUID        seteuid(getuid())

/* Define these as appropriate if you do not have the relevant efuns. */
/* #define to_int(x)        atoi(x)            // MudOS & CD */
#define to_string(x)        ("" + x)        // CD 
/* #define copy_mapping(x)    copy(x)            // MudOS  */
#define copy_mapping(x)    (x + ([ ]))        // CD 
/* #define send_imp(host, port, data) \
        SECURITY->send_udp_message(host, port, data)    // CD

/* Define if casts can only be used on unknown or mixed types. (CD) */
#define RESTRICTED_CASTS

/* Define if your system does not support the a[n..] indexing notation. (CD) */
#undef USE_EXTRACT

/* Define this if you are running another intermud package concurrently. */
/* #define RECEIVE_UDP_COMPAT(sender, packet) \
        UDP_MANAGER->incoming_udp(sender, packet)    // CD */

/* Define this if you are running another intermud package concurrently and
 * have a compatability module for it. */
/* #define SEND_UDP_COMPAT(mudname, data, expect_reply) \
        "/secure/udp_compat"->send_udp(mudname, data, expect_reply) */

/* The maximum number of characters we can send in one packet.
 * You may need to reduce this, but 512 should be safe. */
#define MAX_PACKET_LEN    1024

/* You shouldn't need to change anything below. */

#ifdef ZEBEDEE
#include <defs.h>
#endif

#ifndef DATE
#define DATE        ctime(time())[4..15]
#endif

/* --- End of Config. Do not alter anything below. --- */

#define UNKNOWN        0
#define UP        time()
#define DOWN        (-time())

#define DELIMITER    "|"
#define RETRY        "_RETRY"

#define DEBUG(msg)    if (find_player("pinkfish"))\
            tell_object(find_player("pinkfish"), msg)

private mapping hosts, pending_data, incoming_packets;
private int packet_id;
private int socket;

void set_host_list();
varargs int send_udp(string mudname, mapping data, int expect_reply);
void receive_udp(string sender, string message);

int atoi(string str) {
  int bing;

  sscanf(str, bing);
  return bing;
} /* atoi() */

mapping m_delete(mapping map, mixed key) {
  map = map + ([ ]);
  map_delete(map, key);
  return map;
} /* m_delete() */

int send_imp(string host, string port, mixed data) {
  int blue;

  blue = socket_create(DATAGRAM, "out_read_callback", "out_close_callback");
  if (blue >= 0) {
    socket_write(blue, data, host+" "+port);
  } else {
    printf("Failure into the night.\n");
  }
  socket_close(blue);
  return 1;
} /* send_imp() */

void setup_server() {
  socket = socket_create(DATAGRAM, "in_read_callback", "in_close_callback");
  if (socket >= 0) {
    if (socket_bind(socket, LOCAL_UDP_PORT) < 0) {
      printf("Failed to bind socket.\n");
      socket_close(socket);
    }
  } else {
    printf("Failed to create socket.\n");
  }
} /* setup_server() */

#define m_indices(map) keys(map)

void in_read_callback(int socket, string message, string addr) {
  string port;

  sscanf(addr, "%s %s", addr, port);
  receive_udp(addr, message);
} /* in_read_callback() */

#if !defined(COMPAT_FLAG) || defined(ZEBEDEE)
void create() {
#ifndef COMPAT_FLAG
    SET_EUID;
#endif
#else
void reset(mixed arg) {
    if (arg)
    return;
#endif
    packet_id = 0;
    pending_data = ([ ]);
    incoming_packets = ([ ]);
    hosts = ([ ]);
    set_host_list();
    if (!this_player())
    call_out("startup", 1);
} /* create() */

void set_host_list() {
    mapping old_hosts;
    mixed data;

    old_hosts = copy_mapping(hosts);
    if (data = read_file(HOST_FILE)) {
    int i, stat;
    string *local_cmds;
    string name;
    mixed tmp;

    for(i = sizeof(data = explode(data, "\n")); i--; ) {
        if (data[i] == "" || data[i][0] == '#')
        continue;
        if (sizeof(data[i] = explode(data[i], ":")) < 5) {
        log_file(INETD_LOG_FILE, "*Parse error in hosts file: line " +
        (i + 1) + "\n");
        continue;
        }
        name = lower_case(data[i][HOST_NAME]);
        /* Don't discard existing host int. */
        if (tmp = old_hosts[name])
        stat = tmp[HOST_STATUS];
        else
        stat = UNKNOWN;
        if (member_array("*",
        local_cmds = explode(data[i][LOCAL_COMMANDS], ",")) != -1)
        local_cmds = local_cmds - ({ "*" }) + COMMANDS;
        hosts[name] = ({
        capitalize(data[i][HOST_NAME]),
        data[i][HOST_IP],
        to_int(data[i][HOST_UDP_PORT]),
        local_cmds,
        explode(data[i][HOST_COMMANDS], ","),
        stat
        });
    }
    }
} /* set_host_list() */

void startup() {
    string *muds;
    int i;

    setup_server();
    for(i = sizeof(muds = m_indices(hosts)); i--; )
    send_udp(muds[i], ([ REQUEST: PING ]), 1);
} /* startup() */

mixed decode(string arg) {
    if (arg[0] == '$')
#ifdef USE_EXTRACT
    return extract(arg, 1);
#else
    return arg[1..10000];
#endif
#ifdef RESTRICTED_CASTS
    if (to_string(to_int(arg)) == arg)
    return to_int(arg);
#else
    if ((arg) == arg)
    return arg;
#endif
    return arg;
} /* decode() */

mixed decode_packet(string packet) {
    string *data;
    mapping ret;
    string info, tmp;
    mixed class_i;
    int i;

    data = explode(packet, DELIMITER);
    /* If this packet has been split, handle buffering. */
    if (data[0][0..strlen(PACKET)] == PACKET + ":") {
    int id, n;

    if (sscanf(
#ifdef USE_EXTRACT
    extract(data[0], strlen(PACKET)+1)
#else
    data[0][strlen(PACKET)+1..10000]
#endif
    , "%s:%d:%d/%d", class_i, id, i, n) != 4)
        return 0;
    class_i = lower_case(class_i) + ":" + id;
    if (pointerp(incoming_packets[class_i])) {
        incoming_packets[class_i][i-1] =
#ifdef USE_EXTRACT
        extract(packet, strlen(data[0])+1);
#else
        packet[strlen(data[0])+1..10000];
#endif
        if (member_array(0, incoming_packets[class_i]) == -1) {
        ret = decode_packet(implode(incoming_packets[class_i], ""));
        incoming_packets = m_delete(incoming_packets, class_i);
        return ret;
        }
    } else {
        incoming_packets[class_i] = allocate(n);
        incoming_packets[class_i][i-1] =
#ifdef USE_EXTRACT
        extract(packet, strlen(data[0])+1);
#else
        packet[strlen(data[0])+1..10000];
#endif
        /* If no timeout is running then start one. */
        if (!pending_data[class_i])
        call_out("incoming_time_out", REPLY_TIME_OUT, class_i);
    }
    return 1;
    }
    ret = ([ ]);
    for(i = 0; i < sizeof(data); i++) {
    if (sscanf(data[i], "%s:%s", tmp, info) != 2)
        return 0;
    switch((string)(class_i = decode(tmp))) {
        case DATA:
        return ret + ([ DATA: decode(
#ifdef USE_EXTRACT
            extract(implode(data[i..sizeof(data)-1], DELIMITER)
            , strlen(DATA)+1)
#else
            implode(data[i..10000], DELIMITER)[strlen(DATA)+1..10000]
#endif
            )
        ]);
        default:
        ret[class_i] = decode(info);
        continue;
    }
    }
    return ret;
} /* decode_packet() */

private int valid_request(mapping data) {
    mixed host_data;
    string req;
    
    if (!data[NAME] || !data[UDP_PORT] || !(req = data[REQUEST])) {
    log_file(INETD_LOG_FILE, DATE + ": Illegal packet.\n");
    return 0;
    }
    if (host_data = hosts[lower_case(data[NAME])]) {
#if 0
    if (data[HOST] != host_data[HOST_IP]) {
        log_file(INETD_LOG_FILE, DATE + ": Host mismatch.\n");
        return 0;
    }
    if (data[UDP_PORT] != host_data[HOST_UDP_PORT]) {
        log_file(INETD_LOG_FILE, DATE + ": Port mismatch.\n");
        return 0;
#else
    if (data[HOST] != host_data[HOST_IP]) {
        log_file(INETD_LOG_FILE, DATE + ": Host change:\n" +
        host_data[HOST_NAME] + ": " + host_data[HOST_IP] + " -> " +
        data[HOST] + "\n\n");
        host_data[HOST_IP] = data[HOST];
    }
    if (data[UDP_PORT] != host_data[HOST_UDP_PORT]) {
        log_file(INETD_LOG_FILE, DATE + ": Port change:\n" +
        host_data[HOST_NAME] + " (" + host_data[HOST_IP] + "): " +
        host_data[HOST_UDP_PORT] + " -> " + data[UDP_PORT] + "\n\n");
        host_data[HOST_UDP_PORT] = data[UDP_PORT];
    }
#endif
    } else {
    host_data = hosts[lower_case(data[NAME])] = ({
        data[NAME],
        data[HOST],
        data[UDP_PORT],
        COMMANDS,
        ({ "*" }),
        UP
    });
    log_file(INETD_LOG_FILE, DATE + ": New mud.\n" + data[NAME] + ":" +
    data[HOST] + ":" + data[UDP_PORT] + "\n\n");
    }
    if (req != PING && req != QUERY && req != REPLY &&
    member_array(data[REQUEST], host_data[LOCAL_COMMANDS]) == -1) {
    /* This should probably send a system message too. */
    send_udp(host_data[HOST_NAME], ([
        REQUEST: REPLY,
        RECIPIENT: data[SENDER],
        ID: data[ID],
        DATA: "Invalid request @" + LOCAL_NAME + ": " +
        capitalize(data[REQUEST]) + "\n"
    ]) );
    log_file(INETD_LOG_FILE, DATE + ": Invalid request.\n");
    return 0;
    }
    return 1;
} /* valid_request() */

void receive_udp(string sender, string packet) {
    mapping data;
    string req, err;

/*
#ifdef UDP_MASTER
    if (!previous_object() ||
    file_name(previous_object()) != UDP_MASTER) {
    log_file(INETD_LOG_FILE, DATE + ": Illegal call of receive_udp() by " +
    file_name(previous_object()) + "\n\n");
    return;
    }
#endif
 */
    if (!mapp(data = decode_packet(packet))) {
    if (!data)
#ifdef RECEIVE_UDP_COMPAT
        RECEIVE_UDP_COMPAT(sender, packet);
#else
        log_file(INETD_LOG_FILE, DATE + ": Received invalid packet.\nSender: " +
        sender + "\nPacket:\n" + packet + "\n\n");
#endif
    return;
    }
    data[HOST] = sender;
    if (!valid_request(data)) {
    log_file(INETD_LOG_FILE, "Sender: " + sender + "\nPacket:\n" +
    packet + "\n\n");
    return;
    }
    hosts[lower_case(data[NAME])][HOST_STATUS] = UP;
    req = data[REQUEST];
    if (req == REPLY) {
        mapping pending;

    /* If we can't find the reply in the pending list then bin it. */
    if (!(pending = pending_data[lower_case(data[NAME]) + ":" + data[ID]]))
        return;
    data[REQUEST] = pending[REQUEST];
#ifdef INETD_DIAGNOSTICS
    data[PACKET_LOSS] = pending[PACKET_LOSS];
    data[RESPONSE_TIME] = time() - pending[RESPONSE_TIME];
#endif
    pending_data =
    m_delete(pending_data, lower_case(data[NAME]) + ":" + data[ID]);
    }
    if (err = catch(
    call_other(UDP_CMD_DIR + req, "udp_" + req, copy_mapping(data)))) {
    send_udp(data[NAME], ([
        REQUEST: REPLY,
        RECIPIENT: data[SENDER],
        ID: data[ID],
        DATA: capitalize(req)+ " request failed @" + LOCAL_NAME + ".\n"
    ]) );
    log_file(INETD_LOG_FILE, DATE + ": " + data[REQUEST] + " from " +
    data[NAME] + " failed.\n" + err + packet + "\n\n");
    }
} /* recieve_udp() */

int match_mud_name(string mudname, string match_str) {
    return mudname[0..strlen(match_str)-1] == match_str;
} /* match_mud_name() */

string encode(mixed arg) {
    if (objectp(arg))
    return file_name(arg);
    if (stringp(arg) && (arg[0] == '$' ||
#ifdef RESTRICTED_CASTS
    to_string(to_int(arg)) == (string)arg))
#else
    (string)to_int(arg) == (string)arg))
#endif
    return "$" + arg;
    return to_string(arg);
} /* encode() */

string encode_packet(mapping data) {
    int i;
    mixed indices;
    string header, body, t1, t2, ret;
    int data_flag;

    for(i = sizeof(indices = m_indices(data)); i--; ) {
    if (indices[i] == DATA) {
        data_flag = 1;
        continue;
    }
    header = encode(indices[i]);
    body = encode(data[indices[i]]);
    if (sscanf(header, "%s" + DELIMITER + "%s", t1, t2) ||
    sscanf(body, "%s" + DELIMITER + "%s", t1, t2))
        return 0;
    if (ret)
        ret +=
        DELIMITER + header + ":" + body;
    else
        ret = header + ":" + body;
    }
    if (ret) {
    if (data_flag)
        ret += DELIMITER + DATA + ":" + encode(data[DATA]);
    return ret;
    }
} /* encode_packet() */

string *explode_packet(string packet, int len) {
    if (strlen(packet) <= len)
    return ({ packet });
    return ({ packet[0..len-1] }) +
    explode_packet(
#ifdef USE_EXTRACT
    extract(packet, len)
#else
    packet[len..10000]
#endif
    , len);
} /* explode_packet() */

varargs string send_udp(string mudname, mapping data, int expect_reply) {
    mixed host_data;
    string *packet_arr;
    string packet;
    int i;

    mudname = lower_case(mudname);
    if (!(host_data = hosts[mudname])) {
    string *names;

    if (sizeof(names = filter_array(
    m_indices(hosts), "match_mud_name", this_object(), mudname)) == 1)
        host_data = hosts[mudname = names[0]];
    else
#ifdef SEND_UDP_COMPAT
        return (string)SEND_UDP_COMPAT(mudname, data, expect_reply);
#else
        return "Unknown mud: " + capitalize(mudname) + "\n";
#endif
    }
    if (data[REQUEST] != PING &&
    data[REQUEST] != QUERY &&
    data[REQUEST] != REPLY &&
    member_array("*", host_data[HOST_COMMANDS]) == -1 &&
    member_array(data[REQUEST], host_data[HOST_COMMANDS]) == -1)
    return capitalize(data[REQUEST]) + ": Command unavailable @" +
    host_data[HOST_NAME] + "\n";
    data += ([ NAME: LOCAL_NAME, UDP_PORT: LOCAL_UDP_PORT ]);
    if (expect_reply) {
    /* Don't use zero. */
    data[ID] = ++packet_id;
    /* Don't need copy_mapping() as we are changing the mapping size. */
    pending_data[mudname + ":" + packet_id] =
#ifdef INETD_DIAGNOSTICS
    data + ([ NAME: host_data[HOST_NAME], RESPONSE_TIME: time() ]);
#else
    data + ([ NAME: host_data[HOST_NAME] ]);
#endif
    call_out("reply_time_out", REPLY_TIME_OUT, mudname + ":" + packet_id);
    }
    if (!(packet = encode_packet(data))) {
    if (expect_reply)
        pending_data = m_delete(pending_data, mudname + ":" + packet_id);
    log_file(INETD_LOG_FILE, DATE + ": Illegal packet sent by " +
    file_name(previous_object()) + "\n\n");
    return "inetd: Illegal packet.\n";
    }
    if (strlen(packet) <= MAX_PACKET_LEN)
    packet_arr = ({ packet });
    else {
    string header;
    int max;

    header = PACKET + ":" + lower_case(LOCAL_NAME) + ":" +
    (expect_reply ? packet_id : ++packet_id) + ":";
    packet_arr = explode_packet(packet,
    /* Allow 8 extra chars: 3 digits + "/" + 3 digits + DELIMITER */
    MAX_PACKET_LEN - (strlen(header) + 8));
    for(i = max = sizeof(packet_arr); i--; )
        packet_arr[i] =
        header + (i+1) + "/" + max + DELIMITER + packet_arr[i];
    }
    for(i = sizeof(packet_arr); i--; ) {
    if (!send_imp(
    host_data[HOST_IP], host_data[HOST_UDP_PORT], packet_arr[i]))
        return "inetd: Error in sending packet.\n";
    }
    return 0;
} /* send_udp() */

void incoming_time_out(string id) {
    incoming_packets = m_delete(incoming_packets, id);
} /* incoming_time_out() */

void reply_time_out(mixed id) {
    mapping data;

    if (data = pending_data[id]) {
    object ob;

#ifdef INETD_DIAGNOSTICS
    data[PACKET_LOSS]++;
#endif
    if (data[RETRY] < RETRIES) {
        mapping send;

        data[RETRY]++;
        /* We must use a copy so the NAME field in pending_data[id]
         * isn't corrupted by send_udp(). */
        send = copy_mapping(data);
        send = m_delete(send, RETRY);
#ifdef INETD_DIAGNOSTICS
        send = m_delete(send, PACKET_LOSS);
        send = m_delete(send, RESPONSE_TIME);
#endif
        call_out("reply_time_out", REPLY_TIME_OUT, id);
        send_udp(data[NAME], send);
        return;
    }
    data = m_delete(data, RETRY);
#ifdef INETD_DIAGNOSTICS
    data = m_delete(data, RESPONSE_TIME);
#endif
    catch(call_other(UDP_CMD_DIR + REPLY, "udp_" + REPLY,
    data + ([ SYSTEM: TIME_OUT ])));
    /* It's just possible this was removed from the host list. */
    if (hosts[lower_case(data[NAME])])
        hosts[lower_case(data[NAME])][HOST_STATUS] = DOWN;
    incoming_time_out(lower_case(data[NAME]) + ":" + id);
    }
    pending_data = m_delete(pending_data, id);
} /* reply_time_out() */

varargs mixed query(string what) {
    switch(what) {
    case "commands":
        return COMMANDS;
    case "hosts":
        return copy_mapping(hosts);
    case "pending":
        return copy_mapping(pending_data);
    case "incoming":
        return copy_mapping(incoming_packets);
    }
} /* query() */

int query_host(string str) {
  if (hosts[str]) return 1;
} /* query_host() */

mixed query_host_info(string str) {
  return hosts[str];
} /* query_host_info() */

void dest_me() {
  socket_close(socket);
  destruct(this_object());
} /* dest_me() */

void remove() {
  dest_me();
} /* remove() */