/* * POP3Lite - 3lite POP3 Daemon * Copyright (C) 2000, 2001 Gergely Nagy <8@free.bsd.hu> * * This file is part of POP3Lite. * * POP3Lite 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; either version 2 of the License, or * (at your option) any later version. * * POP3LIte 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Original source: tcputils 0.6.2 by Thomas Bellman * tcputils is in the public domain. */ #ifdef HAVE_CONFIG_H # include #endif #ifdef WITH_STANDALONE_SUPPORT #include #include #include #include #include #include #include #include #include #include #include "standalone.h" static const char rcsid[]="$Id: standalone.c,v 1.6 2001/01/12 15:59:00 algernon Exp $"; /* * Fill in ADDR from HOST, SERVICE and PROTOCOL. * PROTOCOL can be tcp or udp. * Supplying a null pointer for HOST means use INADDR_ANY. * Supplying a null pointer for SERVICE, means use port 0, i.e. no port. * * Returns negative on errors, zero or positive if everything ok. */ int get_inaddr ( struct sockaddr_in *addr, const char *host, const char *service, const char *protocol ) { memset ( addr, 0, sizeof *addr ); addr->sin_family = AF_INET; /* * Set host part of ADDR */ if ( host == NULL ) addr->sin_addr.s_addr = INADDR_ANY; else { addr->sin_addr.s_addr = inet_addr ( host ); if ( addr->sin_addr.s_addr == ( unsigned long ) - 1 ) { struct hostent* hp; hp = gethostbyname ( host ); if ( hp == NULL ) return -1; memcpy ( &addr->sin_addr, hp->h_addr, hp->h_length ); addr->sin_family = hp->h_addrtype; } } /* * Set port part of ADDR */ if ( service == NULL ) addr->sin_port = htons ( 0 ); else { char *end; long portno; portno = strtol ( service, &end, 10 ); if ( portno > 0 && portno <= 65535 && end != service && *end == '\0' ) addr->sin_port = htons ( portno ); else { struct servent *serv; serv = getservbyname ( service, protocol ); if ( serv == NULL ) return -1; addr->sin_port = serv->s_port; } } return 0; } /* * Open a TCP socket listening on address LOCAL. * Returns the file descriptor for the socket, or negative * on errors. */ int tcp_listen_2 ( const struct sockaddr_in *local ) { int s; struct protoent *proto; proto = getprotobyname ( "tcp" ); if ( proto == NULL ) return -1; s = socket ( PF_INET, SOCK_STREAM, proto->p_proto ); if ( s < 0 ) return -1; { int yes = 1; setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof yes ); } if ( bind ( s, (struct sockaddr *)local, sizeof *local ) < 0 ) { close ( s ); return -1; } if ( listen ( s, 256 ) < 0 ) { close ( s ); return -1; } return s; } int tcp_listen ( const char *interface, const char *port ) { int s; struct sockaddr_in server; if ( get_inaddr ( &server, interface, port, "tcp" ) < 0 ) return -1; s = tcp_listen_2 ( &server ); return s; } #endif /* WITH_STANDALONE_SUPPORT */