Skip to content
Snippets Groups Projects
mailsrvr.c 84.6 KiB
Newer Older
		if(initialized==0) {
			sprintf(path,"%smailsrvr.rec",scfg.ctrl_dir);
			t=fdate(path);
			if(t!=-1 && t>initialized)
				initialized=t;
		}

		while (server_socket!=INVALID_SOCKET) {

			sprintf(path,"%smailsrvr.rec",scfg.ctrl_dir);
			t=fdate(path);
			if(!active_clients && t!=-1 && t>initialized) {
				lprintf("0000 Recycle semaphore file (%s) detected",path);
			if(!active_clients && startup->recycle_now==TRUE) {
				lprintf("0000 Recycle semaphore signaled");
				startup->recycle_now=FALSE;
				break;
			}
			/* now wait for connection */

			FD_ZERO(&socket_set);
			FD_SET(server_socket,&socket_set);
			high_socket_set=server_socket+1;
			if(startup->options&MAIL_OPT_ALLOW_POP3 
				&& pop3_socket!=INVALID_SOCKET) {
				FD_SET(pop3_socket,&socket_set);
				if(pop3_socket+1>high_socket_set)
					high_socket_set=pop3_socket+1;
			if((i=select(high_socket_set,&socket_set,NULL,NULL,&tv))<1) {
				if(i==0) {
					mswait(1);
					continue;
				}
				if(ERROR_VALUE==EINTR)
					lprintf("0000 Mail Server listening interrupted");
				else if(ERROR_VALUE == ENOTSOCK)
            		lprintf("0000 Mail Server sockets closed");
				else
					lprintf("0000 !ERROR %d selecting sockets",ERROR_VALUE);
				break;
			if(FD_ISSET(server_socket,&socket_set)) {
				client_addr_len = sizeof(client_addr);
				client_socket = accept(server_socket, (struct sockaddr *)&client_addr
        			,&client_addr_len);

				if(client_socket == INVALID_SOCKET)
            			lprintf("0000 SMTP socket closed while listening");
					else
						lprintf("%04d !ERROR %d accept failed", server_socket, ERROR_VALUE);
					break;
				}
				if(startup->socket_open!=NULL)
					startup->socket_open(TRUE);
				sockets++;

				if(active_clients>=startup->max_clients) {
					lprintf("%04d !MAXMIMUM CLIENTS (%u) reached, access denied"
						,client_socket, startup->max_clients);
					sockprintf(client_socket,"421 Maximum active clients reached, please try again later.");
					mswait(3000);
					mail_close_socket(client_socket);
					continue;
				}
				if((i=ioctlsocket(client_socket, FIONBIO, &l))!=0) {
					lprintf("%04d !ERROR %d (%d) disabling blocking on socket"
						,client_socket, i, ERROR_VALUE);
					mail_close_socket(client_socket);
					continue;
				}
				if((smtp=malloc(sizeof(smtp_t)))==NULL) {
					lprintf("%04d !ERROR allocating %u bytes of memory for smtp_t"
						,client_socket, sizeof(smtp_t));
					mail_close_socket(client_socket);
					continue;
				}

				smtp->socket=client_socket;
				smtp->client_addr=client_addr;
				_beginthread (smtp_thread, 0, smtp);
			if(FD_ISSET(pop3_socket,&socket_set)) {
				client_addr_len = sizeof(client_addr);
				client_socket = accept(pop3_socket, (struct sockaddr *)&client_addr
        			,&client_addr_len);
				if(client_socket == INVALID_SOCKET)
				{
					if(ERROR_VALUE == ENOTSOCK)
            			lprintf("%04d POP3 socket closed while listening",pop3_socket);
					else
						lprintf("%04d !ERROR %d accept failed", pop3_socket, ERROR_VALUE);
					break;
				}
				if(startup->socket_open!=NULL)
					startup->socket_open(TRUE);
				sockets++;

				if(active_clients>=startup->max_clients) {
					lprintf("%04d !MAXMIMUM CLIENTS (%u) reached, access denied"
						,client_socket, startup->max_clients);
					sockprintf(client_socket,"-ERR Maximum active clients reached, please try again later.");
					mswait(3000);
					mail_close_socket(client_socket);
					continue;
				}
				l=1;

				if((i=ioctlsocket(client_socket, FIONBIO, &l))!=0) {
					lprintf("%04d !ERROR %d (%d) disabling blocking on socket"
						,client_socket, i, ERROR_VALUE);
					sockprintf(client_socket,"-ERR System error, please try again later.");
					mswait(3000);
					mail_close_socket(client_socket);
					continue;
				}

				if((pop3=malloc(sizeof(pop3_t)))==NULL) {
					lprintf("%04d !ERROR allocating %u bytes of memory for pop3_t"
						,client_socket,sizeof(pop3_t));
					sockprintf(client_socket,"-ERR System error, please try again later.");
					mswait(3000);
					mail_close_socket(client_socket);
					continue;
				}
				pop3->socket=client_socket;
				pop3->client_addr=client_addr;

				_beginthread (pop3_thread, 0, pop3);
			}
		if(active_clients) {
			lprintf("0000 Waiting for %d active clients to disconnect...", active_clients);
			start=time(NULL);
			while(active_clients) {
				if(time(NULL)-start>TIMEOUT_THREAD_WAIT) {
					lprintf("!TIMEOUT waiting for %u active clients ",active_clients);
					break;
				}
				mswait(100);
		if(sendmail_running) {
			mail_close_socket(server_socket);
			server_socket=INVALID_SOCKET; /* necessary to terminate sendmail_thread */
			mswait(2000);
		}
		if(sendmail_running) {
			lprintf("0000 Waiting for SendMail thread to terminate...");
			start=time(NULL);
			while(sendmail_running) {
				if(time(NULL)-start>TIMEOUT_THREAD_WAIT) {
					lprintf("!TIMEOUT waiting for sendmail thread to "
            			"terminate");
					break;
				}
				mswait(100);
		if(recycle_server) {
			lprintf("Recycling server...");