clamd/tcpserver.c
b151ef55
 /*
  *  Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
  *
  *  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; either version 2 of the License, or
  *  (at your option) any later version.
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
8b242bb9
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
b151ef55
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
e8217f5a
 #include <arpa/inet.h>
b151ef55
 #include <clamav.h>
 #include <errno.h>
d3472eb6
 #include <netdb.h>
b151ef55
 
e8217f5a
 
b151ef55
 #include "options.h"
36f2038b
 #include "cfgparser.h"
b151ef55
 #include "defaults.h"
 #include "others.h"
 #include "server.h"
36f2038b
 #include "output.h"
b151ef55
 
 int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct cl_node *root)
 {
 	struct sockaddr_in server;
 	int sockfd, backlog;
 	struct cfgstruct *cpt;
13847a2d
 	struct cfgstruct *taddr;
d3472eb6
 	struct hostent *he;
b151ef55
 	char *estr;
4be012e9
 	int true = 1;
b151ef55
 
     memset((char *) &server, 0, sizeof(server));
     server.sin_family = AF_INET;
     server.sin_port = htons(cfgopt(copt, "TCPSocket")->numarg);
13847a2d
 
4be012e9
 
d3472eb6
     if((taddr = cfgopt(copt, "TCPAddr"))) {
 	if ((he = gethostbyname(taddr->strarg)) == 0) {
 	    logg("!gethostbyname(%s) error: %s\n", taddr->strarg, strerror(errno));
 	    exit(1);
 	}
 	server.sin_addr = *(struct in_addr *) he->h_addr_list[0];
     } else
4cd4319e
 	server.sin_addr.s_addr = INADDR_ANY;
b151ef55
 
 
     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 	estr = strerror(errno);
8a05efc5
 	/*
 	fprintf(stderr, "ERROR: socket() error: %s\n", estr);
 	*/
b151ef55
 	logg("!socket() error: %s\n", estr);
 	exit(1);
     }
 
4be012e9
     if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &true, sizeof(true)) == -1) {
 	logg("!setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
     }
 
b151ef55
     if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) == -1) {
 	estr = strerror(errno);
8a05efc5
 	/* 
 	fprintf(stderr, "ERROR: can't bind(): %s\n", estr);
 	*/
b151ef55
 	logg("!bind() error: %s\n", estr);
 	exit(1);
4cd4319e
     } else {
13847a2d
 	if ( taddr != NULL && *taddr->strarg )
 	    logg("Bound to address %s on port %d\n", taddr->strarg, cfgopt(copt, "TCPSocket")->numarg);
4cd4319e
 	else
 	    logg("Bound to port %d\n", cfgopt(copt, "TCPSocket")->numarg);
     }
b151ef55
 
     if((cpt = cfgopt(copt, "MaxConnectionQueueLength")))
 	backlog = cpt->numarg;
     else
 	backlog = CL_DEFAULT_BACKLOG;
 
     logg("Setting connection queue length to %d\n", backlog);
 
     if(listen(sockfd, backlog) == -1) {
 	estr = strerror(errno);
8a05efc5
 	/*
 	fprintf(stderr, "ERROR: listen() error: %s\n", estr);
 	*/
b151ef55
 	logg("!listen() error: %s\n", estr);
 	exit(1);
     }
 
50099661
     /* if(cfgopt(copt, "UseProcesses"))
3c572030
 	acceptloop_proc(sockfd, root, copt);
50099661
     else */
3c572030
 	acceptloop_th(sockfd, root, copt);
 
b151ef55
     return 0;
 }