#TESTPROT= smtps
EXTIP = safemail3.safe.ca
EXTPORT = 25
-TESTITER= 3
+TESTITER= 4
#--------------------------------------------------------------------
#testing feed
FEEDPAR = \
-r $(TESTDIR) \
smtps:$(TESTIP):1065:1
+#VALKIND= "definite,possible,indirect,reachable"
VALKIND = "definite,possible,indirect"
valrcvr : prepare #valgring of emlrcvr
@ echo "emlrec valgrind test"
--show-leak-kinds=$(VALKIND) \
$(TESTDIR)/$(SBINDIR)/emlrcvr \
-f \
+ -d 3 \
$(EMLPAR)
# --track-fds=yes \
#-----------------------------------------------------------
MA-0.6-dvl, certificat exchange is working properly
#-----------------------------------------------------------
+#Format for trans file
+status date delta session from rcpt
+Char long int char * char * char *
+status can be:
+ D delayed
+ R Ready
+ S Sent
+#-----------------------------------------------------------
R:220 mailleur.example.com ESMTP (cleartext) emlrcvr...
C:ORGN 127.127.0.2
R:220 mailleur.example.com ESMTP (cleartext) emlrcvr...
+C:WAIT 100
#====================================================
S:HELO example.com
-R:250-mailleur.example.com, link (cleartext) ready, your IP/FQDN=[127.127.0.2/feed2.example.com]
+#R:250-mailleur.example.com, link (cleartext) ready, your IP/FQDN=[127.127.0.2/feed2.example.com]
+R:250-mailleur.example.com, link (cleartext) ready,...
S:MAIL FROM: <postmaster@example.com>
R:250 2.1.3 postmaster@example.com.. sender ok
S:RCPT TO: <postmaster@example.com>
R:250 2.6.2 Address accepted
+S:RCPT TO: <webmaster@example.com>
+R:250 2.6.2 Address accepted
#-------------------------------------------------------------------------
#-sending data
C:DATA
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //do we have a log name?
if (logname==(char *)0) {
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //do we have a log reference?
if (log==(LOGTYP *)0)
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //is the connect still active
if (soc->connected==false) //no!, no need to shutdown
"(errno=<%s>)",
OPEP,soc->ip,soc->port,strerror(errno));
}
+ (void) rou_alert(0,"JMPDBG %s sleep in",OPEP,phase);
+ (void) sleep(1); //JMPDBG
+ (void) rou_alert(0,"JMPDBG %s sleep out",OPEP,phase);
break;
default : //SAFE Guard
proceed=false;
(void) freeaddrinfo(tobind);
break;
case 4 : //listening on socket
- (void) prc_settitle("monitoring %02d contacts on %s:%s",
- soc->iteration,soc->ip,soc->port);
+ (void) prc_settitle("%s, monitoring %02d contacts on %s:%s",
+ appname,soc->iteration,soc->ip,soc->port);
if (listen(soc->handle,soc->iteration+4)<0) {
(void) rou_alert(0,"%s, Unable to listen at address "
"IP:port '%s:%s' (error='%s')",
}
break;
case 1 : //display ready on process status;
- (void) prc_settitle("%s waiting on [%s:%s] (%02d/%02d)",
+ (void) prc_settitle("%s, waiting on [%s:%s] (%02d/%02d)",
appname,soc->ip,soc->port,pos,soc->iteration);
break;
case 2 : //waiting for new connection
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //link still open?
if (soc_receive(socptr)<0) {
got=soc_waitforchar(socptr,secwait*1000);
switch (got) {
case -2 : //remote is disconnectd
+ (void) rou_alert(0,"%s remote is disconnected",OPEP);
break;
case -1 : //trouble? signal?
if ((hangup==true)||(reload==true))
#include <arpa/inet.h>
#include <sys/types.h>
+#include <errno.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
#include <unistd.h>
#include "subrou.h"
if (contact!=(CONTYP *)0) {
contact->sqlptr=sql_closesql(contact->sqlptr);
contact->logptr=log_closelog(contact->logptr);
+ contact->rcptto=(char **)rou_freelist((void **)contact->rcptto,
+ (freehandler_t)rou_freestr);
+ contact->mailfrom=rou_freestr(contact->mailfrom);
contact->cursesid=rou_freestr(contact->cursesid);
contact->mainsesid=rou_freestr(contact->mainsesid);
contact->fqdn=rou_freestr(contact->fqdn);
phase=999; //trouble trouble
break;
case 1 : //write data to trans file;
+ if (eml_mktransfile(contact,trans)==false) {
+ (void) eml_closeqfile(trans);
+ phase=999; //Trouble trouble
+ }
break;
case 2 : //closing transfile
if (eml_closeqfile(trans)<0)
rcptto[strlen(rcptto)-1]='\000';
(void) memmove(rcptto,rcptto+1,strlen(rcptto));
break;
- case 2 : //everything ok
+ case 2 : //Storing rcpt to
+ contact->rcptto=(char **)rou_addlist((void **)contact->rcptto,
+ (void *)strdup(rcptto));
+ break;
+ case 3 : //everything ok
(void) transmit(contact,"%d 2.6.2 Address accepted",CMDOK);
break;
default : //SAFE guard
/********************************************************/
/* */
/* Procedure to wait for a remote client. */
-/* return all reference to contact. */
+/* return the frreed memory contact (NULL pointer) */
/* */
/********************************************************/
PUBLIC CONTYP *eml_dropcontact(CONTYP *contact)
phase=0;
proceed=true;
while (proceed==true) {
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase){
case 0 : //check for binding
if (contact==(CONTYP *)0) {
(void) rou_alert(0,"Contact from peer <%s> to port <%s> terminated",
contact->peerip,contact->locserv);
contact->socptr=soc_release(contact->socptr);
+ //(void) kill(getppid(),SIGCHLD);
+ //(void) rou_alert(0,"%s JMPDBG signal SIGCHLD sent to='%d'",OPEP,getppid());
break;
case 2 : //freeing contact memory
contact=freecontact(contact);
return contact;
#undef OPEP
}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to generate transfile contents */
+/* return all reference to contact. */
+/* */
+/********************************************************/
+PUBLIC _Bool eml_mktransfile(CONTYP *contact,FILE *qfile)
+
+{
+#define OPEP "lvleml.c:eml_mktrans"
+
+_Bool status;
+
+if ((contact!=(CONTYP *)0)&&(contact->rcptto!=(char **)0)) {
+ char **ptr;
+
+ ptr=contact->rcptto;
+ while (*ptr!=(char *)0) {
+ time_t isnow;
+
+ status=true;
+ isnow=time((time_t *)0);
+ if (fprintf(qfile,"%c %ld %d %s %s %s\n",
+ 'R',isnow,0,contact->cursesid,contact->mailfrom,*ptr)<0) {
+ (void) rou_alert(0,"%s Unable to write transfile (error=<%s>)",
+ OPEP,strerror(errno));
+ status=false;
+ }
+ ptr++;
+ }
+ }
+return status;
+#undef OPEP
+}
#ifndef LVLEML
#define LVLEML
+#include <stdio.h>
+
#include "devsoc.h"
#include "devsql.h"
#include "gestcp.h"
char *mainsesid;//session main ID
char *cursesid; //current session ID
char *mailfrom; //current mail from originator
+ char **rcptto; //List of mail recipient
LOGPTR *logptr; //reference to session log
}CONTYP;
//drop contact established by remote
extern CONTYP *eml_dropcontact(CONTYP *contact);
+
+//generate trans file contents
+extern _Bool eml_mktransfile(CONTYP *contact,FILE *qfile);
#endif
phase=0;
proceed=true;
while (proceed==true) {
- //(void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
+ (void) rou_alert(0,"JMPDBG %s phase='%d'",OPEP,phase);
switch (phase) {
case 0 : //waiting contact
(void) rou_checkleak(true);
phase=999; //No contact!
break;
case 1 : //within forked process
- (void) prc_settitle("Processing incoming contact from [%s] on [%s:%s]",
- contact->peerip,contact->locname,contact->locserv);
+ (void) prc_settitle("%s, incoming contact from [%s] on [%s:%s]",
+ appname,contact->peerip,contact->locname,contact->locserv);
break;
case 2 : //do contact
intstat=eml_docontact(contact);
switch (intstat) {
- case 1 : //quit done
+ case 1 : //command 'quit' receoved
break;
case 0 : //exit under timeout
(void) rou_alert(0,"Contact timeout with peer <%s>",contact->peerip);
case 3 : //connection terminated
contact=eml_dropcontact(contact);
(void) rou_checkleak(false);
+ (void) rou_alert(0,"%s JMPBG apres checleak",OPEP);
break;
default : //SAFE guard
proceed=false;
(void) docontact(socptr,i+1);
(void) exit(0);
break;
- default : //Main process
+ default : //Main process relax
(void) usleep(10000);
break;
}
}
- if ((hangup==true)||(reload==true))
- phase=999;
break;
case 3 : //Relax time
- if ((hangup==false)&&(reload==false))
- phase=0; //lets continue to check childs
if (foreground==true)
phase=999; //foreground ->one shot deal
break;
+ case 4 : //Relax time
+ phase=0; //lets continue to check childs
+ (void) rou_alert(0,"%s, start sleep",OPEP);
+ (void) sleep(10); //signal received to exit fast.
+ if (childout==true) {
+ (void) rou_alert(0,"%s, Got child out",OPEP);
+ childout=false;
+ }
+ (void) rou_alert(0,"%s, Exit from sleep",OPEP);
+ if ((hangup==true)||(reload==true))
+ phase=999; //exiting under signal
+ break;
default : //SAFE Guard
(void) prc_killchilds(childs,iterations,maxretry);
(void) free(childs);
/* Module for signal handling level */
/* */
/********************************************************/
+#include <errno.h>
#include <sys/wait.h>
+#include <sys/signalfd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
PUBLIC _Bool hangup; //Hangup signal received
PUBLIC _Bool reload; //reload configuration signal received
PUBLIC _Bool wakeup; //application wakeup under an alarm
+PUBLIC _Bool childout; //application child signal
static _Bool modopen; //boolean module open/close
+static int sfd; //Signal detail information
/*
\f
*/
{
#define OPEP "unisig.c:sig_alrm"
-(void) rou_alert(10,"%s, signal <%s> received",OPEP,strsignal(sig));
+(void) rou_alert(0,"%s, signal <%s> received",OPEP,strsignal(sig));
switch (sig)
{
- case SIGCHLD :
+ case SIGCHLD : {
+/*
+ struct signalfd_siginfo sfd_si;
+
+ if (read(sfd,&sfd_si,sizeof(sfd_si))<0) {
+ (void) rou_alert(0,"%s, Unable to get siginfo (error=<%s>)",
+ OPEP,strerror(errno));
+ }
+ */
+ childout=true;
while (waitpid(-1,(int *)0,WNOHANG)>0);
+ }
break;
case SIGQUIT :
case SIGTERM :
}
//able to receive next signal
(void) signal(sig,sig_alrm);
+(void) rou_alert(0,"%s, signal <%s> exited",OPEP,strsignal(sig));
#undef OPEP
}
/*
PUBLIC void sig_trapsignal(_Bool onoff,sighandler_t trap)
{
-#define OPEP "modbck.c:settrap"
-#define NUMINTR 7
+#define OPEP "unisig.c:settrap"
+#define NUMINTR 9
static struct sigaction *olds[NUMINTR];
static _Bool alldone=false;
}
}
if (onoff==true) {
+ sigset_t mask;
struct sigaction *newsa;
int i;
+ (void) sigemptyset(&mask);
+ (void) sigaddset(&mask,SIGCHLD);
newsa=(struct sigaction *)calloc(1,sizeof(struct sigaction));
newsa->sa_flags=0;
newsa->sa_handler=trap;
(void) sigaction(SIGQUIT,newsa,olds[4]);
(void) sigaction(SIGHUP,newsa,olds[5]);
(void) sigaction(SIGALRM,newsa,olds[6]);
- (void) sigaction(SIGPIPE,newsa,olds[6]);
+ (void) sigaction(SIGPIPE,newsa,olds[7]);
+ (void) sigaction(SIGCHLD,newsa,olds[8]);
(void) free(newsa);
+ if ((sfd=signalfd(-1, &mask, 0))<0) {
+ (void) rou_alert(0,"%s Unable to set signalfd (error=<%s>)",
+ OPEP,strerror(errno));
+ }
}
else {
int i;
- (void) sigaction(SIGPIPE,olds[6],(struct sigaction *)0);
+ (void) sigaction(SIGCHLD,olds[8],(struct sigaction *)0);
+ (void) sigaction(SIGPIPE,olds[7],(struct sigaction *)0);
(void) sigaction(SIGALRM,olds[6],(struct sigaction *)0);
(void) sigaction(SIGHUP,olds[5],(struct sigaction *)0);
(void) sigaction(SIGQUIT,olds[4],(struct sigaction *)0);
extern _Bool hangup; //Hangup signal received
extern _Bool reload; //reload configuration signal received
extern _Bool wakeup; //just got a signal
+extern _Bool childout; //A child process just vanished
//"standard" signal trap
extern void sig_alrm(int sig);