/*
 * UDP port handling code. Version 0.7a
 * Written by Nostradamus for Zebedee.
 * Developed from an original concept by Alvin@Sushi.
 */

#pragma strict_types
#pragma no_clone
#pragma no_shadow
#pragma no_inherit
#pragma verbose_errors
//#pragma pedantic
#pragma no_range_check
#pragma no_warn_deprecated


#include <living/comm.h>
#define ZDEBUG(x)        if (find_player("zesstra"))\
            find_player("zesstra")->ReceiveMsg(x, \
                MT_DEBUG|MSG_DONT_STORE,0,"IM: ",this_object())

//#define ZDEBUG(x)

#include <udp.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", "tell", "who", "mail", "www", "htmlwho", "locate" })

//({ "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 object_name() returns. */
#define UDP_MASTER                __MASTER_OBJECT__

/* 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(getuid())

/* 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. */

#define USE_OLD_DELIMITER
//#define DELIMITER_COMPAT
#define USE_OLD_DATA_FORMAT

#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 NEW_DELIMITER        "\n"
#ifdef USE_OLD_DELIMITER
#define DELIMITER        "|"
#else
#define DELIMITER        "\n"
#endif
#define OLD_DELIMITER        "|"
#define HOSTFILE_DEL        ":"
#define HOSTFILE_DEL2        ","
#define RETRY                "_RETRY"

private nosave mapping hosts, pending_data, incoming_packets;
private nosave mapping static_host_list;
private nosave string *received_ids;
private nosave int packet_id;

void set_host_list();
varargs string _send_udp(string mudname, mapping data, int expect_reply);

#define DEBUG(msg)

void my_create() {
#ifndef COMPAT_FLAG
    SET_EUID;
#endif
    packet_id = 0;
    pending_data = ([ ]);
    incoming_packets = ([ ]);
    hosts = ([ ]);
    received_ids = ({ });
    set_host_list();
    if (!this_player())
        call_out("startup", 1, 0);
}

#ifdef CREATE_FUN
CREATE_FUN() {
#elif !defined(COMPAT_FLAG) || defined(ZEBEDEE)
void create() {
#else
void reset(arg) {
    if (arg)
        return;
#endif
    my_create();
}

status check_system_field(mapping data, string field) {
    return data[SYSTEM] && member(data[SYSTEM], field) != -1;
}

mapping add_system_field(mapping data, string field) {
    if (data[SYSTEM]) {
        if (!check_system_field(data, field))
            data[SYSTEM] += ({ field });
    }
    else
        data[SYSTEM] = ({ field });
    return data;
}

private mapping read_host_list(string file) {

  mixed data = (read_file(file));
  if (!data) {
    log_file(INETD_LOG_FILE, "*Error in reading host file: "
        + file +"\n\n");
    return 0;
  }

  data = old_explode(data, "\n");
  mapping new_hosts = m_allocate(sizeof(data),1);

  foreach(string line: data) {
    if (line == "" || line[0] == '#')
      continue;
    mixed fields = old_explode(line, HOSTFILE_DEL);
    if (sizeof(fields) < 5) {
      log_file(INETD_LOG_FILE, sprintf(
            "*Parse error in hosts file: %s, Line: %s\n", file, line));
      continue;
    }

    string name = lower_case(fields[HOST_NAME]);
    if (member(new_hosts, name))
      continue; // mud already in list

    string *local_cmds = old_explode(fields[LOCAL_COMMANDS],HOSTFILE_DEL2);
    if (member(local_cmds,"*") != -1)
        local_cmds = local_cmds - ({ "*" }) + COMMANDS;
    
    new_hosts[name] = ({ capitalize(fields[HOST_NAME]),
                     fields[HOST_IP],
                     to_int(fields[HOST_UDP_PORT]),
                     local_cmds,
                     old_explode(fields[HOST_COMMANDS], HOSTFILE_DEL2),
                     UNKNOWN
                   });
    /*
     * Get existing host status from current active host lost as long as the
     * IP and UDP ports are the same.
     */
    if (hosts[name] &&
        hosts[name][HOST_IP] == new_hosts[name][HOST_IP] &&
        hosts[name][HOST_UDP_PORT] == new_hosts[name][HOST_UDP_PORT])
        new_hosts[name][HOST_STATUS] = hosts[name][HOST_STATUS];
  }
  return new_hosts;
}

/*
 * Read the INETD_HOSTS file and set the "hosts" mapping from it.
 * Retain existing HOST_STATUS fields.
 * Reads INETD_HOSTSS and INETD_HOSTS.dump
 * Hosts from INETD_HOSTS are included in the static host list.
 */
void set_host_list() {

  // read the static host file and the last host file dump.
  mapping static_hosts = read_host_list(HOST_FILE);
  if (!static_hosts)
      return; // retain the old list(s)

  // remember the static hosts
  static_host_list = m_reallocate(static_hosts,0);
  
  // read the last host file dump and add the static hosts. Then the static
  // hosts have precedence over the ones from the dump.
  hosts = (read_host_list(HOST_FILE".dump") || ([])) + static_hosts;

}

mixed get_hosts() {return copy(hosts);}

int  dump_hosts_list() {
  
  write_file(HOST_FILE+".dump", sprintf(
    "#Hostlist dump from "MUDNAME", created %s\n", strftime()), 1);

  foreach(string mudname, mixed tmp : hosts) {
    // skip muds we did not hear from for 2 days.
//    if (tmp[HOST_STATUS] + 172800 < time())
//      continue;
    write_file(HOST_FILE+".dump",
        sprintf("%s:%s:%d:%s:%s\n",tmp[0],tmp[1],tmp[2],implode(tmp[3],","),
          implode(tmp[4],",")));
  }
  return 1;
}

/*
 * Make a PING request to all muds in the "hosts" mapping to set
 * HOST_STATUS information.
 * But don't ping all muds at once, because that may overflow the callout
 * table during mud startup, when hundreds of objects make callouts.
 */
void startup(string *muds) {

    if (!pointerp(muds))
      muds=m_indices(hosts);
    if (!sizeof(muds))
      return;
    string *part;
    if (sizeof(muds) > 9)
      part=muds[0..9];
    else
      part=muds;
    foreach(string mud: part) 
      _send_udp(mud, ([ REQUEST: PING ]), 1);
    muds -= part;
    if (sizeof(muds))
      call_out(#'startup, 4, muds);
}

/*
 * Remove a buffered packet from the "incoming_packets" mapping.
 */
void remove_incoming(string id) {
    m_delete(incoming_packets, id);
}

/*
 * Decode a string from a UDP packet.
 * Returns:   The actual value of the argument (either int or string)
 */
mixed decode(string arg) {

    if (sizeof(arg) && arg[0] == '$')
        return arg[1..];
#ifdef RESTRICTED_CASTS
    if (to_string(to_int(arg)) == arg)
        return to_int(arg);
#else
    if ((string)((int)arg) == arg)
        return (int)arg;
#endif
    return arg;
}

/*
 * Decode a UDP packet.
 * Arguments: UDP packet as a string.
 * Returns:   The decoded information as a mapping, 1 for succes but no
 *            output (buffered packet), or 0 on error.
 */
mixed decode_packet(string packet, string delimiter) {
    string *data;
    mapping ret;
    string info, tmp;
    mixed class;
    int i, id, n;

    /* If this packet has been split, handle buffering. */
    if (packet[0..sizeof(PACKET)] == PACKET + ":") {
        if (sscanf(packet, PACKET + ":%s:%d:%d/%d" + delimiter + "%s",
        class, id, i, n, tmp) != 5)
            return 0;
        class = lower_case(class) + ":" + id;
        if (pointerp(incoming_packets[class])) {
            incoming_packets[class][i-1] = tmp;
            if (member(incoming_packets[class], 0) == -1) {
                ret =
                decode_packet(implode(incoming_packets[class], ""), delimiter);
                remove_incoming(class);
                return ret;
            }
        } else {
            incoming_packets[class] = allocate(n);
            incoming_packets[class][i-1] = tmp;
/* Is it possible to already have a timeout running here ?!? */
            /* If no timeout is running then start one. */
            if (!pending_data[class]) {
                call_out("remove_incoming",
                REPLY_TIME_OUT + REPLY_TIME_OUT * RETRIES, class);
            } else {
                DEBUG("\nINETD: *** Buffered packet Timeout already running! ***\n");
            }
        }
        return 1;
    }
    ret = ([ ]);
    for(i = 0, n = sizeof(data = old_explode(packet, delimiter)); i < n; i++) {
        /* DATA fields can be denoted by a preceeding blank field. */
        if (data[i] == "") {
            tmp = DATA;
            /* Test for illegal packet length (no DATA) */
            if (++i >= n)
                return 0;
            info = data[i];
        }
        else if (sscanf(data[i], "%s:%s", tmp, info) != 2)
            return 0;
        switch((string)(class = decode(tmp))) {
            case DATA:
#ifdef USE_EXTRACT
                return ret + ([ DATA: decode(implode(
                    ({ info }) + extract(data, i+1), delimiter)) ]);
#else
                return ret + ([ DATA: decode(implode(
                    ({ info }) + data[i+1..], delimiter)) ]);
#endif
            case SYSTEM:
                ret[class] = old_explode(info, ":");
                continue;
            default:
                ret[class] = decode(info);
                continue;
        }
    }
    return ret;
}

/* Check wether a UDP packet was valid.
 * Logs are made and "host" information is updated as appropriate.
 * Arguments: Decoded UDP packet (mapping)
 * Returns:   0 for valid packets, an error string otherwise.
 */
string valid_request(mapping data) {
    mixed host_data;
    string *muds;
    string req;
    int i;
    
    if (!data[NAME] || !data[UDP_PORT])
        return DATE + ": Illegal packet.\n";
    if (host_data = hosts[lower_case(data[NAME])]) {
        if (data[HOST] != host_data[HOST_IP]) {
            if (data[NAME] == LOCAL_NAME)
                return DATE + ": *** FAKE MUD ***\n";
            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]) {
            if (data[NAME] == LOCAL_NAME)
                return DATE + ": *** FAKE MUD ***\n";
            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];
        }
    } else {
        if (lower_case(data[NAME]) == lower_case(LOCAL_NAME))
            return DATE + ": *** FAKE MUD ***\n";
        for(i = sizeof(muds = m_indices(hosts)); i--; ) {
            host_data = hosts[muds[i]];
            if (data[HOST] == host_data[HOST_IP] &&
            data[UDP_PORT] == host_data[HOST_UDP_PORT]) {
                log_file(INETD_LOG_FILE, DATE + ": Name change:\n" +
                    host_data[HOST_NAME] + " (" + host_data[HOST_IP] +
                    ") -> " + data[NAME] + "\n\n");
                host_data[HOST_NAME] = data[NAME];
                hosts[lower_case(data[NAME])] = host_data;
                m_delete(hosts, muds[i]);
                i = -2;
                break;
            }
        }
        if (i != -2) {
            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 = data[REQUEST]))
        return DATE + ": System message.\n";
    if (req != PING &&
        req != QUERY &&
        req != REPLY &&
        member(host_data[LOCAL_COMMANDS], req) == -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"
        ]) );
        return DATE + ": Invalid request.\n";
    }
    return 0;
}

/*
 * Incoming UDP packets are sent to this function to be interpretted.
 * The packet is decoded, checked for validity, HOST_STATUS is updated
 * and the appropriate udp module called.
 * Arguments: Senders IP address (string)
 *            UDP packet (string)
 */
void _receive_udp(string sender, string packet) {
    mapping data;
    string req, err, id;

#ifdef UDP_MASTER
    if (!previous_object() ||
    object_name(previous_object()) != UDP_MASTER) {
        log_file(INETD_LOG_FILE, DATE + ": Illegal call of _receive_udp() by " +
        object_name(previous_object()) + "\n\n");
        return;
    }
#endif

    ZDEBUG(sprintf("%O -> %.500O\n",sender, packet));
    if (
#ifdef DELIMITER_COMPAT
#ifdef USE_EXTRACT
        (!(data = decode_packet(packet, NEW_DELIMITER))
#else
        (!(data = decode_packet(packet, NEW_DELIMITER))
#endif
        || (data[HOST] = sender) && (err = valid_request(data))) &&
        (!(data = decode_packet(packet, OLD_DELIMITER)) ||
        (data[HOST] = sender) && (err = valid_request(data)))
#else
#ifdef USE_EXTRACT
        !(data = decode_packet(packet, DELIMITER))
#else
        !(data = decode_packet(packet, DELIMITER))
#endif
#endif
    ) {
        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;
    }
#ifdef DELIMITER_COMPAT
    if (!mappingp(data))
        return;
    if (err)
#else
          if (!mappingp(data))
                  return;
    data[HOST] = sender;
    if (err = valid_request(data))
#endif
    {
        log_file(INETD_LOG_FILE, err + "Sender: " + sender + "\nPacket:\n" +
        packet + "\n\n");
        return;
    }
    hosts[lower_case(data[NAME])][HOST_STATUS] = UP;
    if ((req = data[REQUEST]) == 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;
        /* Set data[REQUEST] correctly, but still send to (req = REPLY) */
        data[REQUEST] = pending[REQUEST];
#ifdef INETD_DIAGNOSTICS
        data[PACKET_LOSS] = pending[PACKET_LOSS];
        data[RESPONSE_TIME] = time() - pending[RESPONSE_TIME] + 1;
#endif
#if 0
/* channel replies may not include a recipient, and shouldn't have one set */
        /* Restore the RECIPIENT in replies if none given and it is known. */
        if (!data[RECIPIENT] && pending[SENDER])
            data[RECIPIENT] = pending[SENDER];
#endif
        m_delete(pending_data, lower_case(data[NAME]) + ":" + data[ID]);
    }
    else if (data[ID]) {
      id = lower_case(data[NAME]) + ":" + data[ID];
      if (member(received_ids, id) == -1)
      {
        received_ids += ({ id });
        call_out("remove_received_id",
              REPLY_TIME_OUT + REPLY_TIME_OUT * (RETRIES + 1), id);
      }
      else
            add_system_field(data, REPEAT);
    }
    if (err = catch(
        call_other(UDP_CMD_DIR + req, "udp_" + req, deep_copy(data));publish))
    {
        _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");
    }
}

int do_match(string mudname, string match_str) {
    return mudname[0..sizeof(match_str)-1] == match_str;
}

#ifdef NO_CLOSURES

status greater(mixed a, mixed b) {
    return a > b;
}

string *expand_mud_name(string name) {
    return sort_array(
        filter(m_indices(hosts), "do_match", this_object(), name),
        "greater",
        this_object()
    );
}

#else

string *expand_mud_name(string name) {
    return sort_array(
        filter(m_indices(hosts), #'do_match, name),
        #'>
    );
}

#endif

string encode(mixed arg) {
    if (objectp(arg))
        return object_name(arg);
    if (stringp(arg) && sizeof(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);
}

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

    for(ret = ({ }), 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:%s", t1, t2) ||
            sscanf(header + body, "%s" + DELIMITER + "%s", t1, t2)
        )
            return 0;
        
        ret += ({ header + ":" + body });
    }
    if (data_flag)
#ifdef USE_OLD_DATA_FORMAT
        ret += ({ DATA + ":" + encode(data[DATA]) });
#else
        ret += ({ "", encode(data[DATA]) });
#endif
    return implode(ret, DELIMITER);
}

// Funktion explode_
// Die Funktion zerlegt den String packet in gleich lange Teilstrings
// der Laenge len und gibt die Teilstrings als Array zurueck. Der letzte
// Teilstring kann kuerzer sein als die anderen.
string *explode_packet(string packet, int len) {

  int ptr, m_ptr,size;
  string *result;

  // Variablen initialisieren
  m_ptr=ptr=0;
  size=sizeof(packet);
  result=({});

  // Um Arrayadditionen zu vermeiden wird vorher allokiert. Die Division 
  // durch 0 ist nicht abgefangen, da bei len=0 was im Aufruf falch ist.
  result=allocate((size/len+1));

  while (ptr<size) {
    result[m_ptr] = // Aktuellen Teilstring speichern
#ifdef USE_EXTRACT
            extract(packet,ptr,ptr+len-1);
#else
            packet[ptr..ptr+len-1]; 
#endif
    ptr+=len;// Neuen Pointer im String berechnen
    m_ptr++; // Neuen Pointer im Mapping berechnen. Hier nutze ich eine
             // Variable mehr als noetig, weil das billiger ist, als jedes
             // mal ptr=m_ptr*len auszurechnen. Lieber zwei Additionen als 
             // eine Multiplikation und eine Addtion.
  }

  // Wenn size/len aufgeht, ist das Result-Feld zu gross. Dann bleibt 
  // ein Element leer, das wird hier gestrippt. Das ist billiger als
  // jedesmal auszurechnen, ob size/len aufgeht.
  return result-({0});
 
}

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 = expand_mud_name(mudname)) == 1)
            host_data = hosts[mudname = names[0]];
        else
#ifdef SEND_UDP_COMPAT
            return (string)SEND_UDP_COMPAT(mudname, data, expect_reply);
#else
        if (!sizeof(names))
            return "Unbekannter Mudname: " + capitalize(mudname) + "\n";
        else
            return break_string("Mudname ("+capitalize(mudname)+
            ") nicht eindeutig, es passen: "+implode(map(names,#'capitalize),", ")+
            ".\n",78);
#endif
    }
    
    if (data[REQUEST] != PING &&
        data[REQUEST] != QUERY &&
        data[REQUEST] != REPLY &&
        member(host_data[HOST_COMMANDS], "*") == -1 &&
        member(host_data[HOST_COMMANDS], data[REQUEST]) == -1)
        return capitalize(data[REQUEST]) + ": Command unavailable @" +
                   host_data[HOST_NAME] + "\n";
    
    data[NAME] = LOCAL_NAME;
    data[UDP_PORT] = LOCAL_UDP_PORT;
    
    if (expect_reply) {
        /* Don't use zero. */
        data[ID] = ++packet_id;
        /* Don't need deep_copy() 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
    }
    if (!(packet = encode_packet(data))) {
        if (expect_reply)
            pending_data = m_copy_delete(pending_data, mudname + ":" + packet_id);
        log_file(INETD_LOG_FILE, DATE + ": Illegal packet sent by " +
        object_name(previous_object()) + "\n\n");
        return "inetd: Illegal packet.\n";
    }
    if (expect_reply)
        call_out("reply_time_out", REPLY_TIME_OUT, mudname + ":" + packet_id);

    if (sizeof(packet) <= MAX_PACKET_LEN)
        packet_arr = ({ packet });
    else {
        string header;
        int max;

        /* Be careful with the ID.  data[ID] could have been set up by RETRY */
        header =
            PACKET + ":" + lower_case(LOCAL_NAME) + ":" +
            ((expect_reply || data[REQUEST] != REPLY)&& data[ID] ?
            data[ID] : ++packet_id) + ":";
        
        /* Allow 8 extra chars: 3 digits + "/" + 3 digits + DELIMITER */
        packet_arr = explode_packet(packet,
            MAX_PACKET_LEN - (sizeof(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--; )
    {
      ZDEBUG(sprintf("%O <- %.500O\n",host_data[HOST_IP], packet_arr[i]));
      if (!send_udp(
        host_data[HOST_IP], host_data[HOST_UDP_PORT], packet_arr[i]))
            return "inetd: Error in sending packet.\n";
    }
    return 0;
}

void reply_time_out(string 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 = deep_copy(data);
            send = m_copy_delete(send, RETRY);
#ifdef INETD_DIAGNOSTICS
            send = m_copy_delete(send, PACKET_LOSS);
            send = m_copy_delete(send, RESPONSE_TIME);
#endif
            call_out("reply_time_out", REPLY_TIME_OUT, id);
            _send_udp(data[NAME], send);
            return;
        }
        data = m_copy_delete(data, RETRY);
#ifdef INETD_DIAGNOSTICS
        data = m_copy_delete(data, RESPONSE_TIME);
#endif
        catch(call_other(UDP_CMD_DIR + REPLY, "udp_" + REPLY,
        add_system_field(data, TIME_OUT));publish);
        /* 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;
        remove_incoming(lower_case(data[NAME]) + ":" + id);
    }
    pending_data = m_copy_delete(pending_data, id);
}

void remove_received_id(string id) {
    received_ids -= ({ id });
}

varargs mixed query(string what, mixed extra1, mixed extra2) {
    mixed data;

    switch(what) {
        case "commands":
            return COMMANDS;
        case "hosts":
            return deep_copy(hosts);
        case "pending":
            return deep_copy(pending_data);
        case "incoming":
            return deep_copy(incoming_packets);
        case "received":
            return ({ }) + received_ids;
        /* args: "valid_request", request, mudname */
        case "valid_request":
            if (data = hosts[extra2])
                return member(data[HOST_COMMANDS], "*") != -1 ||
                        member(data[HOST_COMMANDS], extra1) != -1;
            return 0;
    }
    return(0);
}

