/*
 * Copyright (c) 1989,
 * 	National Center for Atmospheric Research
 *
 */
#if !defined(LINT) && !defined(VX)
static char rcsid[]="$Header: /net/src3/btcl/tclTCP2.1/src/RCS/svrStrmSock.c,v 1.3 1994/08/04 13:33:57 vanandel Exp $";
#endif

/* TkWin version 0.3 -- Tk for Windows
 * Copyright (C) 1994 K. K. Kubota
 * Mathematical Sciences Computing Facility, University of Kentucky,
 * Lexington, KY 40506, USA (e-mail: ken@ms.uky.edu)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose is granted without fee, provided that the above copyright notice
 * and the following paragraph appear in all copies of this software
 * and supporting documentation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  In no event shall the author be
 * liable to any party for direct, indirect, special, incidental, or
 * consequential damages arising out of the use of this software and its
 * documentation.
 */

/*
 * Revision history:
 * $Log: svrStrmSock.c,v $
 * Revision 1.3  1994/08/04  13:33:57  vanandel
 * cleanup compile warnings
 *
 * Revision 1.2  1994/07/12  20:58:47  vanandel
 * use memset() for SYS V compat
 * cleanup setsockopt call
 *
 * Revision 1.1  1994/03/09  18:46:39  vanandel
 * Initial revision
 *
 * Revision 1.1  1993/11/18  16:08:33  vanandel
 * Initial revision
 *
 * Revision 1.5  1992/09/25  15:34:52  vanandel
 * made host byte order independent for more portability
 * >> .
 *
 * Revision 1.4  1990/02/05  14:39:36  vanandel
 * fixed botch with not setting client_len before calling accept
 *
 * Revision 1.3  89/11/04  17:57:09  vanandel
 * fixed rcsid string
 * 
 * Revision 1.2  89/11/04  17:54:01  vanandel
 * added copyright header
 * 
 */

#ifdef TCL_MSDOS_PORT
#include "tkInt.h"
#include "tkPort.h"
#include <winsock.h>
#include "localTypes.h"
#else
#ifdef VX
#include "vxWorks.h"
#include "socket.h"
#include "in.h"

#else
#include <unistd.h>
#include <memory.h>
#include <string.h>

#include "localTypes.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/errno.h>

#endif
#endif /* TCL_MSDOS_PORT */


int
svrStrmSock (port, listeners)
int port;	/* what port to connect to */
int listeners;	/* how many listeners allowed */
{
#ifdef TCL_MSDOS_PORT
    SOCKET	sock;			/* socket fd's */
    u_long on = 1L;
#else
    int	sock;			/* socket fd's */
    int on = 1;
#endif
    struct sockaddr_in	serverAddr;	/* server's address */

    /* Zero out the sock_addr structures. */
    /* This MUST be done before the socket calls. */

#ifdef TCL_MSDOS_PORT
    memset((char *)&serverAddr, 0, sizeof (serverAddr));
#else
#ifdef BZERO
    bzero ((char *)&serverAddr, sizeof (serverAddr));
#else
    memset(&serverAddr, 0, sizeof (serverAddr));
#endif
#endif


    /* Open the socket. */
    /* Use ARPA Internet address format and stream sockets. */

    sock = socket (AF_INET, SOCK_STREAM, 0);
#ifdef TCL_MSDOS_PORT
    if (sock == INVALID_SOCKET) {
	return(ERROR_RETURN);
    }
#else
    if (sock == ERROR) {
	return(ERROR);
    }
#endif

    /* Set up our internet address, and bind it so the client can connect. */

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port   = htons(port);
#ifdef TCL_MSDOS_PORT
    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof on) == 
	SOCKET_ERROR) {
	(void) closesocket(sock);
	return(ERROR_RETURN);
    }
    if (bind (sock, (struct sockaddr *)&serverAddr, sizeof (serverAddr)) ==
	SOCKET_ERROR) {
        (void) closesocket (sock);
        return (ERROR_RETURN);
    }
#else
    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&on,sizeof on) == ERROR) {
	(void) close(sock);
	return(ERROR);
    }
    if (bind (sock, (struct sockaddr *)&serverAddr, sizeof (serverAddr)) == ERROR) {
        (void) close (sock);
        return (ERROR);
    }
#endif
 

    /* Listen, for the client to connect to us. */

#ifdef TCL_MSDOS_PORT
    if (listen (sock, listeners) == SOCKET_ERROR) {
	(void) closesocket (sock);
	return (ERROR_RETURN);
    }
#else
    if (listen (sock, listeners) == ERROR) {
	(void) close (sock);
	return (ERROR);
    }
#endif
    return(sock);
}
int
svrStrmAccept(sock)
int sock;
{
    struct sockaddr_in 	clientAddr;	/* client's address */
    int	client_len;			/* length of clientAddr */
    int snew;

    client_len = sizeof(clientAddr);
#ifdef TCL_MSDOS_PORT
    memset((char *)&clientAddr, 0, sizeof (clientAddr));
#else
#ifdef BZERO
    bzero ((char *)&clientAddr, sizeof(clientAddr));
#else
    memset(&clientAddr, 0, sizeof (clientAddr));
#endif
#endif
    snew = accept (sock, (struct sockaddr *)&clientAddr, &client_len);
    return(snew);
}
