ldmud-3.3.719/
ldmud-3.3.719/doc/
ldmud-3.3.719/doc/efun.de/
ldmud-3.3.719/doc/efun/
ldmud-3.3.719/doc/man/
ldmud-3.3.719/doc/other/
ldmud-3.3.719/mud/
ldmud-3.3.719/mud/heaven7/
ldmud-3.3.719/mud/lp-245/
ldmud-3.3.719/mud/lp-245/banish/
ldmud-3.3.719/mud/lp-245/doc/
ldmud-3.3.719/mud/lp-245/doc/examples/
ldmud-3.3.719/mud/lp-245/doc/sefun/
ldmud-3.3.719/mud/lp-245/log/
ldmud-3.3.719/mud/lp-245/obj/Go/
ldmud-3.3.719/mud/lp-245/players/lars/
ldmud-3.3.719/mud/lp-245/room/death/
ldmud-3.3.719/mud/lp-245/room/maze1/
ldmud-3.3.719/mud/lp-245/room/sub/
ldmud-3.3.719/mud/lp-245/secure/
ldmud-3.3.719/mud/sticklib/
ldmud-3.3.719/mud/sticklib/src/
ldmud-3.3.719/mudlib/deprecated/
ldmud-3.3.719/mudlib/uni-crasher/
ldmud-3.3.719/pkg/
ldmud-3.3.719/pkg/debugger/
ldmud-3.3.719/pkg/diff/
ldmud-3.3.719/pkg/misc/
ldmud-3.3.719/src/
ldmud-3.3.719/src/autoconf/
ldmud-3.3.719/src/ptmalloc/
ldmud-3.3.719/src/util/
ldmud-3.3.719/src/util/erq/
ldmud-3.3.719/src/util/indent/hosts/next/
ldmud-3.3.719/src/util/xerq/
ldmud-3.3.719/src/util/xerq/lpc/
ldmud-3.3.719/src/util/xerq/lpc/www/
ldmud-3.3.719/test/generic/
ldmud-3.3.719/test/inc/
ldmud-3.3.719/test/t-0000398/
ldmud-3.3.719/test/t-0000548/
ldmud-3.3.719/test/t-030925/
ldmud-3.3.719/test/t-040413/
ldmud-3.3.719/test/t-041124/
ldmud-3.3.719/test/t-language/
#include "socket.h"
#include <errno.h>

#define LUSER      0
#define RUSER      1
#define HOST       2
#define CONTINUED  3

mapping sockets;

void callback(int fd, int act, mixed a, mixed b);

status main(string str)
{
    string user, host;
    int sock;
    if (!sockets) sockets = allocate_mapping(0, 4);
    if (!adminp(this_player())) return 0;
    if (!str) str="";
    host = __HOST_NAME__;
    user = str;
    sscanf(str, "%s@%s", user, host);

    sock = SOCKETD->socket_connect(host, 79, #'callback);
    sockets[sock, LUSER] = this_player();
    sockets[sock, RUSER] = user;
    sockets[sock, HOST]  = host;
    printf("[finger to: %s@%s]\n", user, host);
    call_out("time_out", 90, sock);
    return 1;
}

void callback(int sock, int act, mixed a, mixed b)
{
    if (!sockets[sock, LUSER] && act != SOCKET_CLOSE) {
	SOCKETD->socket_close(sock);
	return;
    }
    switch(act) {
      case SOCKET_READY:
	SOCKETD->socket_write(sock, sprintf("%s\r\n", sockets[sock, RUSER]));
	break;
      case SOCKET_READ:
	if (!sockets[sock, CONTINUED]) {
            tell_object(sockets[sock, LUSER], sprintf("[%s@%s]\n",
	      sockets[sock, RUSER],
	      sockets[sock, HOST]));
	    sockets[sock, CONTINUED] = 1;
	}
	tell_object(sockets[sock, LUSER], a);
	break;
      case SOCKET_CLOSE:
	m_delete(sockets, sock);
	break;
      case SOCKET_ERROR: {
	string err;
	switch(a) {
          case ECONNREFUSED:
	    err = "Connection Refused";
            break;
          case EHOSTUNREACH:
            err = "Host Unreachable";
            break;
          case ENETUNREACH:
            err = "Net Unreachable";
            break;
          default:
            err = sprintf("Code %d", a);
            break;
	}
	tell_object(sockets[sock, LUSER],
          sprintf("ifinger: Error in connection to %s: %s.\n",
            sockets[sock, HOST],
            err));
	m_delete(sockets, sock);
      }
      break;
    }
    return;
}

void help()
{
    write("Usage: ifinger [[<user>]@<host>]\n"
          "Send an internet finger request.\n");
    return;
}

void time_out(int sock)
{
    if (sockets[sock, LUSER])
	tell_object(sockets[sock, LUSER],
          sprintf("Finger to %s@%s timed out.\n",
            sockets[sock, RUSER],
            sockets[sock, HOST]));
	m_delete(sockets, sock);
	return;
}

mapping query_sockets() { return copy_mapping(sockets); }