/*
 * Get a UDP socket, bind it, figure out the port,
 * and advertise the port as program "prog".
 *
 * XXX - it would be nice if you could advertise ascii strings.
 */
int
udp_server(u_long prog, int rdwr)
{
	int	sock;
	struct	sockaddr_in s;

	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		exit(1);
	}
	sock_optimize(sock, rdwr);
	bzero((void*)&s, sizeof(s));
	s.sin_family = AF_INET;
#ifdef	NO_PORTMAPPER
	s.sin_port = htons(prog);
#endif
	if (bind(sock, (struct sockaddr*)&s, sizeof(s)) < 0) {
		perror("bind");
		exit(2);
	}
#ifdef PORTMAP
	(void)pmap_unset(prog, (u_long)1);
	if (!pmap_set(prog, (u_long)1, (u_long)IPPROTO_UDP,
	    (unsigned short)sockport(sock))) {
		perror("pmap_set");
		exit(5);
	}
#endif
	return (sock);
}
/*
 * "Connect" to the UCP socket advertised as "prog" on "host" and
 * return the connected socket.
 */
int
udp_connect(char *host, u_long prog, int rdwr)
{
	struct hostent *h;
	struct sockaddr_in sin;
	int	sock;
#ifndef	NO_PORTMAPPER
	u_short	port;
#endif

	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		exit(1);
	}
	sock_optimize(sock, rdwr);
	if (!(h = gethostbyname(host))) {
		perror(host);
		exit(2);
	}
	bzero((void *) &sin, sizeof(sin));
	sin.sin_family = AF_INET;
	bcopy((void*)h->h_addr, (void *) &sin.sin_addr, h->h_length);
#ifndef	PORTMAP
	sin.sin_port = htons(prog);
#else
	port = pmap_getport(&sin, prog, (u_long)1, IPPROTO_UDP);
	if (!port) {
		perror("lib UDP: No port found");
		exit(3);
	}
	sin.sin_port = htons(port);
#endif
	if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
		perror("connect");
		exit(4);
	}
	return (sock);
}
/*
 * Accept a connection and return it
 */
int
tcp_accept(int sock, int rdwr)
{
    struct sockaddr_in 	s;
    int 				newsock;
    socklen_t			namelen;

    namelen = sizeof(s);
    bzero((void*)&s, namelen);

retry:
    if ((newsock = accept(sock, (struct sockaddr*)&s, &namelen)) < 0) {
        if (errno == EINTR)
            goto retry;
        perror("accept");
        exit(6);
    }
#ifdef  LIBTCP_VERBOSE
    fprintf(stderr, "Server newsock port %d\n", sockport(newsock));
#endif
    sock_optimize(newsock, rdwr);
    return (newsock);
}