/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * END COPYRIGHT BLOCK **/
/*
 * install.c: Routines shared among server (not to be confused with
 *            Netsite) installation programs
 * 
 * Rob McCool
 */


#include "libadmin/libadmin.h"
#include "libadmin/install.h"

#include "base/systems.h"      /* ZERO */
#include "base/util.h"         /* sprintf */

#include <string.h>

#ifdef XP_WIN32
#define EACCES WSAEACCES
#define EADDRINUSE WSAEADDRINUSE
#include <winsock.h>
#include <io.h>
#else
#include <arpa/inet.h>
#endif /* XP_WIN32 */

/* -------------------------------- try_* --------------------------------- */


/* robm This doesn't use net_ abstractions because they drag in SSL */
NSAPI_PUBLIC int try_bind(char *addr, int port)
{
    int sd;
    struct sockaddr_in sa_server;
    int ret;

#ifdef XP_WIN32
    WSADATA wsd;

    if(WSAStartup(MAKEWORD(1, 1), &wsd) != 0)
        return -1;
#endif

    if ((sd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1)
        goto you_lose;

/*
    if((setsockopt(sd, SOL_SOCKET, SO_REUSEADDR,
                   (void *)&one, sizeof(one))) == -1) 
        goto you_lose;
*/

    ZERO((char *) &sa_server, sizeof(sa_server));
    sa_server.sin_family=AF_INET;
    sa_server.sin_addr.s_addr = (addr ? inet_addr(addr) : htonl(INADDR_ANY));
    sa_server.sin_port=htons(port);
    ret = bind(sd, (struct sockaddr *) &sa_server,sizeof(sa_server));
/*
    if(ret != -1)
        listen(sd, 5);
*/
#ifdef XP_UNIX
    close(sd);
#else
    closesocket(sd);
    WSACleanup();
#endif
    return ret;

  you_lose:
#ifdef XP_WIN32
    WSACleanup();
#endif
    return -1;
}
