]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Better kill/stop program handling
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Fri, 2 Aug 2024 13:41:59 +0000 (09:41 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Fri, 2 Aug 2024 13:41:59 +0000 (09:41 -0400)
lib/gestcp.c
lib/gestcp.h
lib/modrec.c
lib/subrou.c
lib/subrou.h
lib/unieml.h
lib/uniprc.c
lib/uniprc.h
lib/unisoc.c
lib/unisoc.h

index 9a83ca9820355d965116703c725eb90c0762da58..9a99bd75a6c549a9a9e6a9c222b6f773dc43da32 100644 (file)
@@ -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
index b28b752071d89a1dcecb48983c011cba1213baa1..7e35a9a45137d44625fd986479dd37f99c45f655 100644 (file)
 
 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);
 
index 7686f736fb4f777c0f55fa6dd8b0be1860f9356b..0748c14c8acf5d2df7f0bae60d5c05eefe4bb947 100644 (file)
@@ -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;i<binding->iteration;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;i<nbrbind;i++) {
         (void) prc_nozombie();
-        if ((*ptr)->waiter==(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;i<nbrbind;i++) {
         int offset;
 
         offset=random()%10;
-        if ((*ptr)->waiter!=(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;
     }
index cdae49828a07b96a04973a55be7e586a506d0caf..e1493ac9c9785c20e21614cb8e10ff79bd33fb19 100644 (file)
@@ -12,6 +12,7 @@
 #include        <stdlib.h>
 #include        <string.h>
 #include        <syslog.h>
+#include        <time.h>
 #include        <unistd.h>
 
 #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;
 }
 /*
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     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;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                     */
+/*     Subroutine to add a pointer (not null)          */
 /*     to a list of pointer.                           */
 /*                                                     */
 /********************************************************/
index 49be2741fafcaf83258f5d1e1e301fa108025906..96d425a4d471a6daa52ef0c864048f3f1e69bb2b 100644 (file)
@@ -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);
 
index e5194e4ddc534008ca61d65f1362fa1782e6ac7e..7c2b2c5844adc1ce8b64c98b452d3c9eb95e2041 100644 (file)
@@ -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.
index 040eb6bb7907418a353bd55657f2d71b1541ba1f..5b6cb3f78a71d76b8e066340f43a2aad030ab446 100644 (file)
@@ -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<num;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--;
+  }
+return remain;
+}
+/*
+^L
+*/
+/********************************************************/
+/*                                                      */
 /*     Procedure to set/unset a lock                   */
 /*     return true if successful,                      */
 /*     false otherwise.                                */
index 66a3207fd6d33d908c74022cb8566ec1b60dd15f..5e2c5c2f2e8f0a65b2a814fd8552461c833c30db 100644 (file)
@@ -42,6 +42,9 @@ extern void prc_nozombie();
 //routine to check if a proces is still up and running
 extern _Bool prc_checkprocess(pid_t pidnumber);
 
+//Routine to kill a list of subprocess
+extern _Bool prc_killchilds(pid_t *childs,int num,int maxretry);
+
 //lock application (to avoid running multiple daemon)
 extern _Bool prc_locking(const char *lockname,int lock,int tentative);
 
index c787862014d005334ef5f0c4e35abfdf914c3a3a..eb2d39f3b30d3256e19c08c4c7aa862f1216b1b8 100644 (file)
@@ -142,9 +142,10 @@ return handle;
 /*     Procedure fine the hostname related to an       */
 /*      address, if local is true return the local      */
 /*      hostname.                                       */
+/*      if trouble, return a NULL pointer.              */
 /*                                                     */
 /********************************************************/
-PUBLIC char *soc_getaddrname(int handle,_Bool local,const char *unknown)
+PUBLIC char *soc_getaddrname(int handle,_Bool local)
 
 {
 #define OPEP    "unisoc.c:soc_getaddrname"
@@ -155,20 +156,18 @@ socklen_t taille;
 int status;
 char host[NI_MAXHOST];
 
-name=(char *)unknown;
-if (name==(char *)0)
-  name="NO_HOST_NAME";
+name=(char *)0;
 taille=sizeof(connip);
 if (local==true) {
   if ((status=getsockname(handle,&connip,&taille))==0) {
     if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NAMEREQD)==0)
-      name=host;
+      name=strdup(host);
     }
   }
 else {
   if ((status=getpeername(handle,&connip,&taille))==0) {
     if (getnameinfo(&connip,taille,host,sizeof(host),(char *)0,0,NI_NUMERICHOST)==0)
-      name=host;
+      name=strdup(host);
     }
   }
 if (status<0) {
@@ -181,7 +180,7 @@ if (status<0) {
       break;
     }
   }
-return strdup(name);
+return name;
 #undef  OPEP
 }
 /*
index bea272678d340f6b6d7aec9f5781b252616a4fb0..f9dc0eac1060e3c5b9a1dc1ecf791a5366d019b5 100644 (file)
@@ -30,11 +30,10 @@ typedef struct  {
         time_t lasttry; //successful binding last time
         int iteration;  //number of soc slot used on the IP
         int handle;     //connexion handle
-        pid_t waiter;   //binding manager
         }SOCTYP;
 
 //procedure to get peer or local name related to a socket
-extern char *soc_getaddrname(int handle,_Bool local,const char *unknown);
+extern char *soc_getaddrname(int handle,_Bool local);
 
 //procedure to free all memory used by a TCP socket
 //definition (once closed)