home *** CD-ROM | disk | FTP | other *** search
- #include "headers.h" /* includes all important stuff */
-
- /* this binds and listens for a client.. */
- void initconn()
- {
- curPid = 0;
-
- if (mainfd > 0)
- {
- close(mainfd);
- mainfd = 0;
- }
-
- mainfd = socket(AF_INET, SOCK_STREAM, 0);
- if (mainfd == ERROR)
- {
- error("error with socket(): %s\n\n", strerror(errno));
- quit(ERROR);
- }
-
- setsockopts();
-
- laddr.sin_family = AF_INET;
- laddr.sin_port = htons(locPort);
- laddr.sin_addr.s_addr = INADDR_ANY;
- memset(&laddr.sin_zero, 0, sizeof(laddr.sin_zero));
-
- while(1)
- {
- if (bind(mainfd, (struct sockaddr *) &laddr,
- sizeof(struct sockaddr)) == ERROR)
- {
- if (errno == EINTR) continue;
- error("error with bind(): %s\n\n", strerror(errno));
-
- (void)sleep(MAXPAUSE * 3);
- }
-
- else break;
- }
-
- if (listen(mainfd, MAXCONNS) == ERROR)
- {
- error("error with listen(): %s\n\n", strerror(errno));
- quit(ERROR);
- }
- }
-
-
- /* ----------------------- */
-
-
- /* get the connection, process it, etc. (this most of the work) */
- int getconn()
- {
- register int i;
-
- int res;
- int ssize;
-
- int hnamelen = 0;
-
- struct hostent *hent = NULL; /* client's host entry */
-
- /*
- If we ever implement it to malloc() client space dynamically
- (rather than all the necessary mem for the clients at once),
- we would need to include this code. For now, we don't need it
-
- clients[++curClient] = (struct client *)malloc(sizeof(struct client *));
-
- if (clients[curClient] == NULL)
- {
- error("error with malloc(): %s\n\n", strerror(errno));
- quit(ERROR);
- }
- */
-
- curClient = ERROR;
-
- for (i = 0; i < MAXCONNS; i++)
- {
- if ((clients[i]).free == 1)
- {
- curClient = i, curPid = 0;
-
- if (debugging == 1)
- {
- (void)putchar('\n');
- (void)write(dblogfd, "\n", 1);
- }
-
- debug("next client will get clients[%d]\n", i);
-
- memset(&clients[i], 0, sizeof(struct client));
- clients[i].free = ERROR;
- clients[i].sockfd = ERROR;
- clients[i].numSubIDs = 0;
-
- break;
- }
- }
-
- if (curClient == ERROR)
- {
- if (nofree != 1)
- {
- nofree = 1;
- error("couldn't find a free structure.. restarting\n\n");
- }
-
- return ERROR;
- }
-
- memset(&clients[curClient].saddr, 0, sizeof(clients[curClient].saddr));
- ssize = sizeof(struct sockaddr_in);
-
- debug("now waiting for a new client to connect..\n\n");
-
- while(1)
- {
- clients[curClient].sockfd =
- accept(mainfd, (struct sockaddr *) &(clients[curClient]).saddr,
- &ssize);
-
- if ((clients[curClient]).sockfd == ERROR)
- {
- if (errno == EINTR) continue;
-
- (void)fputc('\n', stderr);
- error("error with accept(): %s\n\n", strerror(errno));
-
- /* static - dont need this.
- free(clients[curClient--]); */
-
- memset((char *) &clients[curClient], 0, sizeof(struct client));
- clients[curClient].free = 1;
-
- return ERROR;
- }
-
- else break;
- }
-
- /* initiate the SSL parts */
- # ifndef NOSSL
- res = seteuid(0);
- if (res == ERROR)
- {
- error("error with seteuid: %s\n\n", res);
- quit(ERROR);
- }
-
- makeSSLconn(clients[curClient].sockfd);
-
- res = seteuid(pwd->pw_uid);
- if (res == ERROR)
- {
- error("error with seteuid: %s\n\n", res);
- quit(ERROR);
- }
- # endif
-
- errno = 0;
- hent = gethostbyaddr((char *) &(clients[curClient]).saddr.sin_addr,
- sizeof(struct in_addr), (clients[curClient]).saddr.sin_family);
-
- if (hent == NULL)
- {
- if (h_errno == HOST_NOT_FOUND)
- error("error with gethostbyaddr: host not found\n\n");
-
- else if (h_errno == TRY_AGAIN)
- error("error with gethostbyaddr: non-auth'd host/server failure\n\n");
-
- else if (h_errno == NO_RECOVERY)
- error("error with gethostbyaddr: non-recoverable error\n\n");
-
- else if (h_errno == NO_DATA)
- error("error with gethostbyaddr: no data request for that type\n\n");
-
- else if (h_errno == NO_ADDRESS)
- error("error with gethostbyaddr: no address\n\n");
-
- if (debugging == 1)
- {
- (void)putchar('\n');
- (void)write(dblogfd, "\n", 1);
- }
- }
-
- if (hent && hent->h_name)
- {
- (void)printf("%connection from %s (%s)...\n\n",
- (debugging != 1 ? 'C' : 'c'), hent->h_name,
- (char *)inet_ntoa((clients[curClient]).saddr.sin_addr));
-
- hnamelen = strlen(hent->h_name) + 1;
-
- clients[curClient].hname = (char *)malloc(hnamelen+1);
- if (clients[curClient].hname == NULL)
- {
- error("error malloc()'ing hostname\n\n");
- quit(ERROR);
- }
-
- memset(clients[curClient].hname, 0, hnamelen+1);
- strcpy(clients[curClient].hname, hent->h_name);
- }
-
- else
- {
- (void)printf("%connection from %s...\n\n",
- (debugging != 1 ? 'C' : 'c'),
- (char *)inet_ntoa((clients[curClient]).saddr.sin_addr));
-
- hnamelen = strlen(inet_ntoa(clients[curClient].saddr.sin_addr)) + 1;
-
- clients[curClient].hname = (char *)malloc(hnamelen+1);
- if (clients[curClient].hname == NULL)
- {
- error("error malloc()'ing hostname\n\n");
- quit(ERROR);
- }
-
- memset(clients[curClient].hname, 0, hnamelen+1);
- (void)strcpy(clients[curClient].hname,
- inet_ntoa((clients[curClient]).saddr.sin_addr));
- }
-
- if (hnamelen-1 > 0)
- {
- char lochname[hnamelen+1];
- memset(lochname, 0, sizeof(lochname));
-
- res = gethostname(lochname, sizeof(lochname)-1);
- if (res == ERROR)
- {
- signal(SIGPIPE, SIG_IGN);
-
- error("error with gethostname(): %s\n\n", strerror(errno));
-
- if (debugging == 1)
- {
- (void)putchar('\n');
- (void)write(dblogfd, "\n", 1);
- }
-
- send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
-
- close(clients[curClient].sockfd);
- clients[curClient].free = 1;
-
- return ERROR;
- }
-
- /*
- We're going to allow connections from the localhost in case we
- should ever need to (though to emulate the customer's situation,
- it's better to use different hosts.
-
- if ((strncmp(clients[curClient].hname, "127.0.0.1", 9) == 0) ||
- (strncmp(clients[curClient].hname, "localhost", 9) == 0) ||
- (strncmp(clients[curClient].hname, lochname,
- strlen(lochname) == 0) ||
- (strncmp(clients[curClient].hname,
- inet_ntoa(laddr.sin_addr), strlen) == 0))
- {
- signal(SIGPIPE, SIG_IGN);
-
- error("warning: received a connection from the localhost\n\n");
- send_data(clients[curClient].sockfd, "ERROR: %s\n", NOLOCERROR);
-
- close(clients[curClient].sockfd);
- clients[curClient].free = 1;
-
- return ERROR;
- }
- */
- }
-
- else
- {
- error("(in getconn) hostname length < 0, killing client\n\n");
- return ERROR;
- }
-
- /* ----------------- */
-
- if ((ntohs(clients[curClient].saddr.sin_port) < 512) ||
- (ntohs(clients[curClient].saddr.sin_port) > IPPORT_RESERVED-1))
- {
- send_data(clients[curClient].sockfd, "ERROR: %s\n", PORTERROR);
- return ERROR;
- }
-
- else send_data(clients[curClient].sockfd, "SUCCESSFUL connect\n");
-
- return 0;
- }
-
-
- /* -------------------------------- */
-
-
- /* set socket options */
- void setsockopts()
- {
- int res;
- int val = 1;
-
- /* probe remote host occasionally to make sure we're still connected */
- /* ----------------------------------------------------------------- */
-
-
- # ifdef SO_KEEPALIVE
- /* val = 1; */
- res = setsockopt(mainfd, SOL_SOCKET, SO_KEEPALIVE,
- (char *)&val, sizeof(val));
-
- if (res == ERROR)
- {
- error("error with setsockopt (SO_KEEPALIVE): %s\n\n", strerror(errno));
- quit(ERROR);
- }
-
- # ifdef TCP_KEEPALIVE
- val = PROBETIME; /* PROBETIME */
-
- res = setsockopt(mainfd, IPPROTO_TCP, TCP_KEEPALIVE,
- (char *)&val, sizeof(val));
-
- if (res == ERROR)
- {
- error("error with setsockopt (TCP_KEEPALIVE): %s\n\n", strerror(errno));
- quit(ERROR);
- }
-
- # endif
- # endif
-
- /* SO_KEEPALIVE must be set first */
-
-
- /* allow us to reuse the same port with bind */
- /* ----------------------------------------- */
-
- val = 1; /* enable it */
-
- # ifdef SO_REUSEADDR
- res = setsockopt(mainfd, SOL_SOCKET, SO_REUSEADDR,
- (char *)&val, sizeof(val));
-
- if (res == ERROR)
- {
- error("error with setsockopt (SO_REUSEADDR): %s\n\n", strerror(errno));
- quit(ERROR);
- }
- # endif
- }
-
-