#include <krb.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>       /* obligatory includes */
#include <signal.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>

#define MAXHOSTNAME REALM_SZ

main()
{ 
    int s, t;
    fd_set read_fd;
    
    if ((s= establish()) < 0) {  /* plug in the phone */
	perror("establish");
	exit(1);
    }
    
    while(1) {                          /* loop for phone calls */
	FD_ZERO(&read_fd);
	FD_SET(s, &read_fd);
	select(s+1, &read_fd, (fd_set *)0, (fd_set *)0, NULL);

	if ((t= get_connection(s)) < 0) { /* get a connection */
	    if (errno == EINTR)             /* EINTR might happen on accept(), */
		continue;                     /* try again */
	    perror("accept");               /* bad */
	    exit(1);
	}
	do_something(t);
	close(t);
	listen(s, 1);
    }
}



int establish()
{ 
    char   myname[MAXHOSTNAME+1];
    int    s;
    u_short portnum;
    struct sockaddr_in sa;
    struct hostent *hp;
    struct servent *sp;

#ifdef TERMPORT
    portnum = TERMPORT;
#else
    if ((sp = getservbyname("kerberos", "tcp")) == NULL) {
	perror("getservbyname");
	return(-1);
    }	
    portnum = sp->s_port;
#endif /* TERMPORT */

    bzero(&sa,sizeof(struct sockaddr_in));      /* clear our address */
    gethostname(myname,MAXHOSTNAME);            /* who are we? */
    hp= gethostbyname(myname);                  /* get our address info */
    if (hp == NULL)                             /* we don't exist !? */
	return(-1);
    sa.sin_family= hp->h_addrtype;              /* this is our host address */
    sa.sin_port= htons(portnum);                /* this is our port number */
    if ((s= socket(AF_INET,SOCK_STREAM,0)) < 0) /* create socket */
	return(-1);
    if (bind(s,&sa,sizeof sa,0) < 0) {
	close(s);
	return(-1);                               /* bind address to socket */
    }
    listen(s, 1);                               /* max # of queued connects */
    return(s);
}


int get_connection(s)
int s;                    /* socket created with establish() */
{ 
    struct sockaddr_in isa; /* address of socket */
    int i;                  /* size of address */
    int t;                  /* socket of connection */
    
    i = sizeof(isa);                   /* find socket's address */
    getsockname(s,&isa,&i);            /* for accept() */
    
    if ((t = accept(s,&isa,&i)) < 0)   /* accept connection if there is one */
	return(-1);
    return(t);
}

do_something(t)
int t;
{
    char realm[REALM_SZ];
    u_char size;
    int retval;
    KTEXT_ST pkt;
    KTEXT_ST rpkt;

    memset(rpkt.dat, 0, sizeof(rpkt.dat));
    rpkt.length = 0;

    recv(t, &size, 1, 0);
    recv(t, realm, size+1, 0);
    recv(t, &size, 1, 0);		/* High byte of pkt->len */
    pkt.length = size * 256;
    recv(t, &size, 1, 0);		/* Low order byte */
    pkt.length += size;
    recv(t, pkt.dat, pkt.length, 0);

    retval = send_to_kdc(&pkt, &rpkt, realm);
    if (retval != KSUCCESS)
	printf("Error in send_to_kdc, %d\n", retval);

    rpkt.length = sizeof(rpkt.dat);
/*    printf("Length == %d\n", rpkt.length); */

    retval = htonl(retval);
    send(t, (char *) &retval, sizeof(retval), 0);
    size = rpkt.length/256;
    send(t, &size, 1, 0);
    size = rpkt.length%256;
    send(t, &size, 1, 0);
    send(t, (char *) rpkt.dat, rpkt.length, 0);
}
