From: Jean-Marc Pigeon (Delson) Date: Fri, 2 Aug 2024 13:41:59 +0000 (-0400) Subject: Better kill/stop program handling X-Git-Tag: tag-0.4~27 X-Git-Url: https://jmp-git.ovh.safe.ca/?a=commitdiff_plain;h=87c087b6d5a8b9444f7b76dcfce0c1790fd1a344;p=jmp%2Fmailleur Better kill/stop program handling --- diff --git a/lib/gestcp.c b/lib/gestcp.c index 9a83ca9..9a99bd7 100644 --- a/lib/gestcp.c +++ b/lib/gestcp.c @@ -26,6 +26,29 @@ static _Bool modopen; //boolean module open/close */ /********************************************************/ /* */ +/* Procedure to free memory used by contact */ +/* */ +/********************************************************/ +PUBLIC CONTYP *tcp_freecontact(CONTYP *contact) + +{ +if (contact!=(CONTYP *)0) { + if (contact->channel>=0) + (void) close(contact->channel); + if (contact->peerip!=(char *)0) + (void) free(contact->peerip); + if (contact->locname!=(char *)0) + (void) free(contact->locname); + (void) free(contact); + contact=(CONTYP *)0; + } +return contact; +} +/* +^L +*/ +/********************************************************/ +/* */ /* Procedure to send data to a tcp socket. */ /* return the number of character transmitted, is */ /* unable to send char return -1; */ @@ -45,7 +68,7 @@ switch (got) { errno=EAGAIN; switch (errno) { case EAGAIN : - sent=send(contact->channel,buffer,parnum,MSG_DONTWAIT); + sent=send(contact->channel,buffer,parnum,0); break; default : (void) fprintf(stderr,"Got '%02d' error=<%s> (errno='%d')\n", @@ -93,22 +116,32 @@ while (proceed==true) { case 1 : //waiting from contact if ((contact->channel=soc_accept(binding,&addr))<0) { (void) rou_alert(0,"%s Unable to open contact",OPEP); - (void) free(contact); - contact=(CONTYP *)0; + contact=tcp_freecontact(contact); phase=999; //no contact } break; - case 2 : //send signon to contact + case 2 : //check socket components + contact->locname=soc_getaddrname(contact->channel,true); + contact->peerip=soc_getaddrname(contact->channel,false); + if ((contact->locname==(char *)0)||(contact->peerip==(char *)0)) { + (void) rou_alert(0,"%s Unable to establish contact entities",OPEP); + contact=tcp_freecontact(contact); + phase=999; //no identity + } + break; + case 3 : //contact is good sending signon if (contact!=(CONTYP *)0) { //always - #define FMT "220 %s ESMTP %s-%s;\n" + #define FMT "%d %s ESMTP %s-%s; %s%s" char signon[100]; - (void) snprintf(signon,sizeof(signon),FMT,"test",appname,rou_getversion()); + (void) snprintf(signon,sizeof(signon),FMT, + SIGNON,contact->locname, + appname,rou_getversion(), + rou_ascsysstamp(time((time_t *)0)),CRLF); if (tcp_write(contact,signon,strlen(signon))<0) { (void) rou_alert(0,"%s Unable to send signon to remote",OPEP); - (void) free(contact); - contact=(CONTYP *)0; + contact=tcp_freecontact(contact); phase=999; //no contact } #undef FMT diff --git a/lib/gestcp.h b/lib/gestcp.h index b28b752..7e35a9a 100644 --- a/lib/gestcp.h +++ b/lib/gestcp.h @@ -13,10 +13,15 @@ typedef struct { int channel; //exchange channel handle + char *locname; //socket local hostname + char *peerip; //socket remote peer IP SOCKADDR addr; //remote address (see getnameinfo) SOCTYP *binding;//established contact context }CONTYP; +//procedure to free contact +extern CONTYP *tcp_freecontact(CONTYP *contact); + //Transmit formated data to the contact channel extern int tcp_write(CONTYP *contact,char *buffer,int parnum); diff --git a/lib/modrec.c b/lib/modrec.c index 7686f73..0748c14 100644 --- a/lib/modrec.c +++ b/lib/modrec.c @@ -32,7 +32,7 @@ void docontact(SOCTYP *binding,int pos) { #define OPEP "modrec.c:contact" -#define TESTL 30 +#define TESTL 8 CONTYP *contact; int phase; @@ -62,10 +62,8 @@ while (proceed==true) { if ((hangup==true)||(reload==true)) break; - printf("send string\n"); sprintf(buffer,"Remote pid=%d iter=%d/%d\n",getpid(),i,TESTL); sent=tcp_write(contact,buffer,strlen(buffer)); - printf("string sent '%d'\n",sent); if (sent<0) { (void) rou_alert(0,"%s, Unable to send data to remote",OPEP); break; @@ -142,26 +140,7 @@ while (proceed==true) { phase=0; //lets continue to check childs break; default : //SAFE Guard - while (maxretry>0) { - int remain; - - remain=0; - for (int i=0;iiteration;i++) { - (void) prc_nozombie(); - if (childs[i]==(pid_t)0) - continue; - if (prc_checkprocess(childs[i])==false) { - childs[i]=(pid_t)0; - continue; - } - remain++; - (void) kill(childs[i],SIGTERM); - } - if (remain==0) - break; - (void) sleep(1); - maxretry--; - } + (void) prc_killchilds(childs,binding->iteration,maxretry); proceed=false; break; } @@ -233,49 +212,52 @@ PUBLIC void rec_handlesmtp() #define OPEP "modrec.c:rec_handlesmtp" #define LINE "---------------------------------" -int maxretry; //how long checking sub process to be out +pid_t *childs; +int nbrbind; SOCTYP **bindings; int phase; _Bool proceed; -maxretry=30; //5 seconds max retry +childs=(pid_t)0; bindings=(SOCTYP **)0; bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",3); bindings=soc_mkbindinf(bindings,pro_smtp,"192.219.254.70","2525",3); bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1); +nbrbind=rou_nbrlist((void **)bindings); phase=0; proceed=true; +if (nbrbind==0) { + (void) rou_alert(0,"No bindings definition found! (config?)"); + proceed=false; + } while (proceed==true) { switch (phase) { case 0 : //looping forever email receiving processes (void) rou_alert(0,LINE); (void) prc_settitle("Emlrec Daemon"); (void) rou_alert(0,"Starting Emlrec daemon"); - if (bindings==(SOCTYP **)0) { - (void) rou_alert(0,"No bindings definition found!"); - phase=999; //No need to go further - } + childs=(pid_t *)calloc(nbrbind,sizeof(pid_t)); break; case 1 : //Opening ALL channels - for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + for (int i=0;iwaiter==(pid_t)0) + if (childs[i]==(pid_t)0) continue; - if (prc_checkprocess((*ptr)->waiter)==false) - (*ptr)->waiter=(pid_t)0; + if (prc_checkprocess(childs[i])==false) + childs[i]=(pid_t)0; } break; case 2 : //starting restarting all waiter process - for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { + for (int i=0;iwaiter!=(pid_t)0) + if (childs[i]!=(pid_t)0) continue; - (*ptr)->waiter=fork(); - if ((*ptr)->waiter==(pid_t)0) { + childs[i]=fork(); + if (childs[i]==(pid_t)0) { (void) closelog(); - (void) startwaiter(*ptr,offset); + (void) startwaiter(bindings[i],offset); (void) exit(0); } (void) usleep(10000); //avoid avalanche @@ -286,37 +268,14 @@ while (proceed==true) { if ((hangup==false)&&(reload==false)) phase=0; //Normal process, lets restart break; - case 4 : //we got a signal - for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { - if ((*ptr)->waiter==(pid_t)0) - continue; - if (prc_checkprocess((*ptr)->waiter)==false) { - (*ptr)->waiter=(pid_t)0; - continue; - } - if ((hangup==true)||(reload==true)) - (void) kill((*ptr)->waiter,SIGTERM); - } - break; - case 5 : //making sur all waiter procees are gone - maxretry--; - (void) sleep(1); - //(void) rou_alert(0,"JMPDBG cleanup! maxretry='%d'",maxretry); - for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) { - (void) prc_nozombie(); - if ((*ptr)->waiter==(pid_t)0) - continue; - if (prc_checkprocess((*ptr)->waiter)==true) { - if (maxretry>0) - phase--; //retrying - } - else - (*ptr)->waiter=(pid_t)0; - } + case 4 : //we got a signal, kill all childs + (void) prc_killchilds(childs,nbrbind,10); break; default : //SAFE Guard (void) rou_alert(0,"Stopping Emlrec daemon"); (void) rou_alert(0,LINE); + if (childs!=(pid_t *)0) + (void) free(childs); proceed=false; break; } diff --git a/lib/subrou.c b/lib/subrou.c index cdae498..e1493ac 100644 --- a/lib/subrou.c +++ b/lib/subrou.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "subrou.h" @@ -19,7 +20,7 @@ //version definition #define VERSION "0.3" -#define RELEASE "14" +#define RELEASE "15" //Public variables PUBLIC int debug=0; //debug level @@ -55,6 +56,26 @@ dropzone=rou_apppath("/tmp/"APPNAME"-crash"); return dropzone; } /* + +*/ +/********************************************************/ +/* */ +/* Procedure to transform the local system time in */ +/* ASCII time stamp. */ +/* Stored in STATIC memory area. */ +/* */ +/********************************************************/ +char *rou_ascsysstamp(time_t curtime) + +{ +#define TSTAMP "%a, %d %b %Y %T %z" + +static char ascstamp[100]; + +(void) strftime(ascstamp,sizeof(ascstamp),TSTAMP,localtime(&curtime)); +return ascstamp; +} +/* ^L */ /********************************************************/ @@ -91,7 +112,31 @@ return str; */ /********************************************************/ /* */ -/* Subroutine to get add a pointer (not null) */ +/* Subroutine to count the number of items within */ +/* a list of pointer. */ +/* */ +/********************************************************/ +PUBLIC int rou_nbrlist(void **list) + + +{ +int num; + +num=0; +if (list!=(void **)0) { + while (*list!=(void *)0) { + num++; + list++; + } + } +return num; +} +/* + +*/ +/********************************************************/ +/* */ +/* Subroutine to add a pointer (not null) */ /* to a list of pointer. */ /* */ /********************************************************/ diff --git a/lib/subrou.h b/lib/subrou.h index 49be274..96d425a 100644 --- a/lib/subrou.h +++ b/lib/subrou.h @@ -25,6 +25,9 @@ extern char *appname; //application "official" name //--- Routines implemented within subrou.c --------- +//transform local system time in ASCII stamp. +extern char *rou_ascsysstamp(time_t curtime); + //return program version extern const char *rou_getversion(); @@ -32,6 +35,9 @@ extern const char *rou_getversion(); //a NULL pointer extern char *rou_freestr(char *str); +//to return the number of element within a list +extern int rou_nbrlist(void **list); + //to add a not null pointer to a list of pointer extern void **rou_addlist(void **list,void *entry); diff --git a/lib/unieml.h b/lib/unieml.h index e5194e4..7c2b2c5 100644 --- a/lib/unieml.h +++ b/lib/unieml.h @@ -8,6 +8,7 @@ #ifndef UNIEML #define UNIEML +#define CRLF "\r\n" //EOL within SMTP protocol #define SIGNON 220 //signon information //homework to be done before starting/stopping module. diff --git a/lib/uniprc.c b/lib/uniprc.c index 040eb6b..5b6cb3f 100644 --- a/lib/uniprc.c +++ b/lib/uniprc.c @@ -118,6 +118,42 @@ return status; */ /********************************************************/ /* */ +/* procedure to kill a set of process within a */ +/* list, return return the number of process */ +/* still up; */ +/* */ +/********************************************************/ +PUBLIC _Bool prc_killchilds(pid_t *childs,int num,int maxretry) + +{ +int remain; + +remain=num; +while (maxretry>0) { + remain=0; + for (int i=0;i