ldmud-3.2.9/doc/
ldmud-3.2.9/doc/efun/
ldmud-3.2.9/mud/
ldmud-3.2.9/mud/heaven7/
ldmud-3.2.9/mud/heaven7/lib/
ldmud-3.2.9/mud/lp-245/
ldmud-3.2.9/mud/lp-245/banish/
ldmud-3.2.9/mud/lp-245/doc/
ldmud-3.2.9/mud/lp-245/doc/examples/
ldmud-3.2.9/mud/lp-245/doc/sefun/
ldmud-3.2.9/mud/lp-245/log/
ldmud-3.2.9/mud/lp-245/obj/Go/
ldmud-3.2.9/mud/lp-245/players/lars/
ldmud-3.2.9/mud/lp-245/room/death/
ldmud-3.2.9/mud/lp-245/room/maze1/
ldmud-3.2.9/mud/lp-245/room/sub/
ldmud-3.2.9/mud/lp-245/secure/
ldmud-3.2.9/mud/morgengrauen/
ldmud-3.2.9/mud/morgengrauen/lib/
ldmud-3.2.9/mud/sticklib/
ldmud-3.2.9/mud/sticklib/src/
ldmud-3.2.9/mudlib/uni-crasher/
ldmud-3.2.9/pkg/
ldmud-3.2.9/pkg/debugger/
ldmud-3.2.9/pkg/diff/
ldmud-3.2.9/pkg/misc/
ldmud-3.2.9/src/autoconf/
ldmud-3.2.9/src/bugs/
ldmud-3.2.9/src/bugs/MudCompress/
ldmud-3.2.9/src/bugs/b-020916-files/
ldmud-3.2.9/src/bugs/doomdark/
ldmud-3.2.9/src/bugs/ferrycode/ferry/
ldmud-3.2.9/src/bugs/ferrycode/obj/
ldmud-3.2.9/src/bugs/psql/
ldmud-3.2.9/src/done/
ldmud-3.2.9/src/done/order_alist/
ldmud-3.2.9/src/done/order_alist/obj/
ldmud-3.2.9/src/done/order_alist/room/
ldmud-3.2.9/src/gcc/
ldmud-3.2.9/src/gcc/2.7.0/
ldmud-3.2.9/src/gcc/2.7.1/
ldmud-3.2.9/src/hosts/
ldmud-3.2.9/src/hosts/GnuWin32/
ldmud-3.2.9/src/hosts/amiga/NetIncl/
ldmud-3.2.9/src/hosts/amiga/NetIncl/netinet/
ldmud-3.2.9/src/hosts/amiga/NetIncl/sys/
ldmud-3.2.9/src/hosts/i386/
ldmud-3.2.9/src/hosts/msdos/byacc/
ldmud-3.2.9/src/hosts/msdos/doc/
ldmud-3.2.9/src/hosts/os2/
ldmud-3.2.9/src/hosts/win32/
ldmud-3.2.9/src/util/
ldmud-3.2.9/src/util/erq/
ldmud-3.2.9/src/util/indent/hosts/next/
ldmud-3.2.9/src/util/xerq/
ldmud-3.2.9/src/util/xerq/lpc/
ldmud-3.2.9/src/util/xerq/lpc/www/
/*---------------------------------------------------------------------------
 * XErq - Address Lookup
 * (C) Copyright 1995 by Brian Gerst.
 *---------------------------------------------------------------------------
 * Here are the function to lookup up internet addresses and names.
 * If the first lookup attempt doesn't succeed, a retry is attempted
 * five seconds later.
 *
 * TODO: The functions block the ERQ.
 *---------------------------------------------------------------------------
 */

#include "defs.h"

/*-------------------------------------------------------------------------*/
void
erq_rlookup(char *mesg, int msglen)

/* ERQ_RLOOKUP: look up a hostname by an address.
 */

{
    struct hostent *hp;
    int len;
    char addr[4];

    if (msglen != 13)
    {
        const char status=ERQ_E_ARGLENGTH;
        reply1(get_handle(mesg), &status, 1);
        return;
    }

    memcpy(addr, mesg+9, 4);

    XPRINTF((stderr, "%s rlookup %02x.%02x.%02x.%02x\n"
                   , time_stamp(), addr[0], addr[1], addr[2], addr[3]));

    hp = gethostbyaddr(addr, 4, AF_INET);
    if (!hp && mesg[8] == ERQ_RLOOKUP)
    {
        mesg[8]++; /* No second retry */
        XPRINTF((stderr, "%s   Retry in 5 seconds.\n", time_stamp()));
        add_retry(erq_rlookup, mesg, 13, 5);
        return;
    }

    if (hp)
    {
        XPRINTF((stderr, "%s   rlookup found '%s'\n", time_stamp(), hp->h_name));
        len = strlen(hp->h_name)+1;
    }
    else
    {
        XPRINTF((stderr, "%s   rlookup failed.\n", time_stamp()));
        len = 0;
    }

    if (hp)
        replyn(get_handle(mesg), 0, 2,
            mesg+9, 4,
            hp->h_name, len);
    else
        reply1(get_handle(mesg), mesg+9, 4);
} /* erq_rlookup() */

/*-------------------------------------------------------------------------*/
void
erq_lookup(char *mesg, int len)

/* ERQ_LOOKUP: look up an address by a hostname.
 */

{
    struct hostent *hp;
    char * msg;

    msg = mesg;
    if (mesg[len-1] != 0)
    {
        msg = malloc(len+1);
        if (!msg)
        {
            XPRINTF((stderr, "%s Out of memory.\n", time_stamp()));
            die();
        }
        memcpy(msg, mesg, len);
        msg[len] = 0;
        len++;
    }

    XPRINTF((stderr, "%s lookup '%s'\n", time_stamp(), msg+9));
    hp = gethostbyname(msg+9);
    if (!hp && msg[8] == ERQ_LOOKUP)
    {
        XPRINTF((stderr, "%s   Retry in 5 seconds.\n", time_stamp()));
        mesg[8]++; /* No second retry */
        add_retry(erq_lookup, msg, len, 5);
        if (msg != mesg)
            free(msg);
        return;
    }

    {
        char r_ok[] = { ERQ_OK };
        char r_notfound[] = { ERQ_E_NOTFOUND };
        char r_noaddr[] = { 0, 0, 0, 0 };

        if (hp)
            XPRINTF((stderr, "%s   lookup found %02x.%02x.%02x.%02x\n"
                           , time_stamp(), hp->h_addr[0], hp->h_addr[1]
                           , hp->h_addr[2], hp->h_addr[3]));
        else
            XPRINTF((stderr, "%s   lookup failed.\n", time_stamp()));
        replyn(get_handle(mesg), 0, 3,
            hp ? r_ok : r_notfound, 1,
            hp ? (char *) hp->h_addr : r_noaddr, 4,
            msg+9, len-9);
    }

    if (msg != mesg)
        free(msg);
} /* erq_lookup() */

/*-------------------------------------------------------------------------*/
#ifdef USE_IPV6

void
erq_rlookupv6(char *mesg, int msglen)

/* ERQ_RLOOKUPV6: look up an IPv6 address by a hostname.
 */

{
    int i;
    char *mbuff, *buf;
    size_t buflen;
    struct addrinfo req, *ai, *ai2;
    static char *msg_invalid = "invalid-format";
    static char *msg_nomem = "out-of-memory";

    buflen = msglen -9 +1;
    buf = malloc(msglen -9 +1);
    if (!buf)
    {
        reply1(get_handle(mesg), msg_nomem, strlen(msg_nomem)+1);
        return;
    }

    memcpy(buf, mesg+9, msglen-9);
    buf[buflen-1] = '\0';

    memset(&req, 0, sizeof(struct addrinfo));
    req.ai_family = AF_INET6;
    req.ai_flags = AI_CANONNAME;
    i = getaddrinfo(buf, NULL, &req, &ai);
    if (!i)
        for (ai2 = ai
            ; ai2 && (ai2->ai_family != AF_INET)
                  && (ai2->ai_family != AF_INET6)
            ; ai2 = ai2->ai_next) NOOP;

    if (!i && ai2 && ai2->ai_canonname)
    {
        mbuff = malloc(strlen(ai2->ai_canonname)+1+buflen);
        if (!mbuff)
        {
            free(buf);
            reply1(get_handle(mesg), msg_nomem, strlen(msg_nomem)+1);
            return;
        }
        strcpy(mbuff, buf);
        strcat(mbuff, " ");
        strcat(mbuff, ai2->ai_canonname);
        reply1(get_handle(mesg), mbuff, strlen(mbuff)+1);
        free(mbuff);
    }
    else
        reply1(get_handle(mesg), msg_invalid, strlen(msg_invalid)+1);

    if (!i)
        freeaddrinfo(ai);

    free(buf);
} /* erq_rlookupv6() */

#endif /* USE_IPV6 */

/***************************************************************************/