Newer
Older
result = listen (pop3_socket, 1);
lprintf(LOG_ERR,"%04d !ERROR %d (%d) listening on POP3 socket"
,pop3_socket, result, ERROR_VALUE);
cleanup(1);
return;
sem_init(&sendmail_wakeup_sem,0,0);
if(!(startup->options&MAIL_OPT_NO_SENDMAIL))
_beginthread(sendmail_thread, 0, NULL);
lprintf(LOG_NOTICE,"%04d Mail Server thread started",server_socket);
status(STATUS_WFC);
initialized=time(NULL);
sprintf(path,"%smailsrvr.rec",scfg.ctrl_dir);
t=fdate(path);
if(t!=-1 && t>initialized)
initialized=t;
}
/* signal caller that we've started up successfully */
if(startup->started!=NULL)
startup->started(startup->cbdata);
while(server_socket!=INVALID_SOCKET && !terminate_server) {
if(!(startup->options&MAIL_OPT_NO_RECYCLE)) {
sprintf(path,"%smailsrvr.rec",scfg.ctrl_dir);
t=fdate(path);
if(!active_clients && t!=-1 && t>initialized) {
lprintf(LOG_NOTICE,"0000 Recycle semaphore file (%s) detected",path);
initialized=t;
break;
}
if(startup->recycle_sem!=NULL && sem_trywait(&startup->recycle_sem)==0)
startup->recycle_now=TRUE;
if(!active_clients && startup->recycle_now==TRUE) {
lprintf(LOG_NOTICE,"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;
tv.tv_sec=startup->sem_chk_freq;
tv.tv_usec=0;
if((i=select(high_socket_set,&socket_set,NULL,NULL,&tv))<1) {
continue;
if(ERROR_VALUE==EINTR)
lprintf(LOG_NOTICE,"0000 Mail Server listening interrupted");
else if(ERROR_VALUE == ENOTSOCK)
lprintf(LOG_NOTICE,"0000 Mail Server sockets closed");
lprintf(LOG_WARNING,"0000 !ERROR %d selecting sockets",ERROR_VALUE);
break;
if(server_socket!=INVALID_SOCKET && !terminate_server
&& 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(ERROR_VALUE == ENOTSOCK || ERROR_VALUE == EINVAL)
lprintf(LOG_NOTICE,"0000 SMTP socket closed while listening");
lprintf(LOG_WARNING,"%04d !ERROR %d accept failed", server_socket, ERROR_VALUE);
break;
}
if(startup->socket_open!=NULL)
startup->socket_open(startup->cbdata,TRUE);
sockets++;
if(trashcan(&scfg,inet_ntoa(client_addr.sin_addr),"ip-silent")) {
mail_close_socket(client_socket);
continue;
}
if(active_clients>=startup->max_clients) {
lprintf(LOG_WARNING,"%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(LOG_ERR,"%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(LOG_CRIT,"%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);
served++;
if(pop3_socket!=INVALID_SOCKET
&& 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(ERROR_VALUE == ENOTSOCK || ERROR_VALUE == EINVAL)
lprintf(LOG_NOTICE,"%04d POP3 socket closed while listening",pop3_socket);
lprintf(LOG_WARNING,"%04d !ERROR %d accept failed", pop3_socket, ERROR_VALUE);
break;
}
if(startup->socket_open!=NULL)
startup->socket_open(startup->cbdata,TRUE);
sockets++;
if(trashcan(&scfg,inet_ntoa(client_addr.sin_addr),"ip-silent")) {
mail_close_socket(client_socket);
continue;
}
if(active_clients>=startup->max_clients) {
lprintf(LOG_WARNING,"%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(LOG_ERR,"%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(LOG_CRIT,"%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);
served++;
if(active_clients) {
lprintf(LOG_DEBUG,"0000 Waiting for %d active clients to disconnect...", active_clients);
start=time(NULL);
while(active_clients) {
if(time(NULL)-start>TIMEOUT_THREAD_WAIT) {
lprintf(LOG_WARNING,"!TIMEOUT waiting for %d active clients ",active_clients);
break;
}
mswait(100);
if(sendmail_running) {
terminate_sendmail=TRUE;
sem_post(&sendmail_wakeup_sem);
mswait(100);
}
if(sendmail_running) {
lprintf(LOG_DEBUG,"0000 Waiting for SendMail thread to terminate...");
start=time(NULL);
while(sendmail_running) {
if(time(NULL)-start>TIMEOUT_THREAD_WAIT) {
lprintf(LOG_WARNING,"!TIMEOUT waiting for sendmail thread to "
"terminate");
break;
}
mswait(500);
if(!sendmail_running)
sem_destroy(&sendmail_wakeup_sem);
cleanup(0);
if(!terminate_server) {
lprintf(LOG_INFO,"Recycling server...");
} while(!terminate_server);