#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>

char user_name[0x100];

char *
get_auth_name(int remote, int local_port, int remote_port)
{
    struct sockaddr_in sa;
    int s, flags;
    char buf[0x100];
    char inbuf[0x100];
    int buflen;
    int i;
    struct timeval timeout;
    fd_set fs;

    if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
	return "";
    }
    memset((char *)&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(113);
    sa.sin_addr.s_addr = remote;
    if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1)
    {
	close(s);
	return "";
    }
    sprintf(buf, "%u , %u\r\n", remote_port, local_port);
    buflen = strlen(buf);
    flags = fcntl(s, F_GETFL);
    fcntl(s, F_SETFL, flags | O_NDELAY);

    FD_ZERO(&fs);
    FD_SET(s, &fs);
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    if (select(s + 1, NULL, &fs, NULL, &timeout) == 0 ||
	!FD_ISSET(s, &fs))
    {
	close(s);
	return "";
    }
    if (write(s, buf, buflen) != buflen)
    {
	close(s);
	return "";
    }

    i = 0;
    buf[0] = 0;
    FD_ZERO(&fs);
    FD_SET(s, &fs);
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    if (select(s + 1, &fs, NULL, NULL, &timeout) == 0 ||
	!FD_ISSET(s, &fs))
    {
	close(s);
	return "";
    }
    
    do
    {
	FD_ZERO(&fs);
	FD_SET(s, &fs);
	timeout.tv_sec = 1;
	timeout.tv_usec = 0;
	if (select(s + 1, &fs, NULL, NULL, &timeout) == 0 ||
	    !FD_ISSET(s, &fs))
	    break;
	
	if (read(s, buf + i, 1) != 1)
	    break;

	if (buf[i] != ' ' && buf[i] != '\t' && buf[i] != '\r')
	    i++;
    }
    while (buf[i - 1] != '\n' && i < 0xff) ;
    buf[i] = 0;
    close(s);
    
    if(sscanf(buf, "%*d,%*d: USERID :%*[^:]:%s", user_name) != 1)
	return "";
    else
	return user_name;
}

int
main()
{
    char buf[0x100];
    char *port1;
    char *port2;
    unsigned long addr;
    struct hostent *hp;
    char *name;
    
/*fprintf(stderr, "hname starts\n");*/
    printf("\n");
    fflush(stdout);
    for(;;) {
	if (gets(buf) == NULL)
	    break;
	port1 = strchr(buf, ';');
	if (port1)
	{
	    *port1 = 0;
	    port1++;
	    port2 = strchr(port1, ',');
	    if (port2)
	    {
		*port2 = 0;
		port2++;
	    }
	}
	else
	    port2 = 0;
	
	addr = inet_addr(buf);
	if (addr != -1) {
	    if (port2)
		name = get_auth_name(addr, atoi(port1), atoi(port2));
	    else
		name = "";
	    hp = gethostbyaddr((char *)&addr, 4, AF_INET);
	    if (!hp) {
		sleep(5);
	        hp = gethostbyaddr((char *)&addr, 4, AF_INET);
	    }
	    if (hp) {
/*fprintf(stderr, "hname sends %s...", hp->h_name);*/
		if (port2)
		    printf("%s %s,%s,%s:%s\n", buf, hp->h_name,
			   port1,port2,name);
		else
		    printf("%s %s\n", buf, hp->h_name);
		fflush(stdout);
	    }
	    else if (port2)
	    {
		printf("%s %s,%s,%s:%s\n", buf, buf, port1, port2, name);
		fflush(stdout);
	    }
	    
	}
    }
    /*fprintf(stderr, "hname exits\n");*/
}