/* * Copyright (c) 2002, 2004, 2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: netsocklisten.c,v 1.5 2005/01/18 00:07:58 ca Exp $") #include "sm/assert.h" #include "sm/error.h" #include "sm/memops.h" #include "sm/fcntl.h" #include "sm/net.h" /* ** NET_SERVER_LISTEN_ADDR -- Create a socket, bind, and listen. ** ** Parameters: ** addr -- address to bind to. ** addrlen -- len of address to bind to. ** backlog -- Backlog of connections to accept (man listen(2)) ** ** Returns: ** New socket fd or -1 on error. */ int net_server_listen_addr(sockaddr_T *addr, int addrlen, int backlog) { int listenfd; int sockopt; SM_ASSERT(addr != NULL); SM_ASSERT(backlog > 0); sockopt = 1; listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == INVALID_SOCKET) return sm_error_perm(SM_EM_NET, errno); if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt, sizeof(sockopt)) == -1) { closesocket(listenfd); return sm_error_perm(SM_EM_NET, errno); } if (bind(listenfd, (struct sockaddr *) addr, addrlen) == -1) { closesocket(listenfd); return sm_error_perm(SM_EM_NET, errno); } if (listen(listenfd, backlog) == -1) { closesocket(listenfd); return sm_error_perm(SM_EM_NET, errno); } return listenfd; } /* ** NET_SERVER_LISTEN -- Create a socket, bind, and listen. ** ** Parameters: ** ip -- IPv4 address to bind to. ** port -- Port to bind to. ** backlog -- Backlog of connections to accept (listen(2)) ** ** Returns: ** New socket fd or -1 on error. */ sm_ret_T net_server_listen(const char *ip, int port, int backlog) { struct sockaddr_in servaddr; ulong hostaddr; SM_ASSERT(port > 0); sm_memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; if ((hostaddr = inet_addr(ip)) == INADDR_NONE) return sm_error_perm(SM_EM_NET, errno); sm_memcpy(&servaddr.sin_addr, &hostaddr, sizeof(hostaddr)); servaddr.sin_port = htons(port); return net_server_listen_addr((sockaddr_T *)&servaddr, sizeof(servaddr), backlog); }