/*
 * pure-server.c : common server process for PURE network service.
 *
 * $Id: pure-server.c,v 1.1 2000/12/30 16:31:42 simm Exp $
 */

#include "pure.h"

const u_short PURE_PORT_MIN =  1024;
const u_short PURE_PORT_MAX = 65535;

static int pure_server_listen( net_peer* peer )
{
	int sock, len;
	struct sockaddr_in sv;

	if ( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) return -1;

	len = sizeof( sv );
	memset( &sv, 0, len );
	sv.sin_family = AF_INET;
	sv.sin_addr.s_addr = htonl( INADDR_ANY );
	if ( PURE_PORT_MIN < peer->bport || peer->eport < PURE_PORT_MAX ) {
		sv.sin_port = htons( peer->port = peer->bport );
		while ( bind( sock, (struct sockaddr*)&sv, len ) < 0 ) {
			sv.sin_port = htons( ++(peer->port) );
			if ( peer->eport < peer->port ) return -2;
		}
	} else {
		sv.sin_port = htons( 0 );
		if ( bind( sock, (struct sockaddr*)&sv, len ) < 0 ) return -2;
	}

	if ( listen( sock, 1 ) < 0 ) return -3;
	if ( getsockname( sock, (struct sockaddr*)&sv, &len ) < 0 ) return -4;
	peer->port = ntohs( sv.sin_port );

	return sock;
}

int pure_server_wait( net_peer* peer, int offset )
{
	int sock, slen;
	struct in_addr iaddr;
	struct sockaddr_in saddr;

	pure_getmyaddr( peer );
	if ( peer->bport < PURE_PORT_MIN || PURE_PORT_MAX < peer->bport )
		peer->bport = PURE_PORT_MIN;
	if ( peer->eport < PURE_PORT_MIN || PURE_PORT_MAX < peer->eport )
		peer->eport = PURE_PORT_MAX;
	if ( peer->eport < peer->bport ) {
		u_short dummy = peer->eport;
		peer->eport = peer->bport;
		peer->bport = dummy;
	}
	if ( ( sock = pure_server_listen( peer ) ) < 0 ) return -2;
	iaddr.s_addr = htonl(peer->address);
	printf( "[INFO] Listen %s %u %d\n", inet_ntoa(iaddr), peer->port, offset );

	slen = sizeof(saddr);
	peer->handle = accept( sock, (struct sockaddr*)&saddr, &slen );
	close( sock );
	printf( "[INFO] Connected\n" );

	return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1