]> SAFE projects GIT repository - jmp/mailleur/commitdiff
Improving unisoc module
authorJean-Marc Pigeon (Delson) <jmp@safe.ca>
Fri, 12 Jul 2024 01:09:12 +0000 (21:09 -0400)
committerJean-Marc Pigeon (Delson) <jmp@safe.ca>
Fri, 12 Jul 2024 01:09:12 +0000 (21:09 -0400)
lib/modrec.c
lib/subrou.c
lib/subrou.h
lib/unisoc.c
lib/unisoc.h

index 243d0a9800e95f8b34d0e3712d90ccb8217d9793..7a23be059100f9e7a7e8bf5d4a08e61e0f169a31 100644 (file)
@@ -26,13 +26,12 @@ static  _Bool modopen;          //boolean module open/close
 PUBLIC void rec_handlesmtp()
 
 {
-BINTYP binding;
+SOCTYP **bindings;
 int phase;
 _Bool proceed;
 
-(void) memset(&binding,'\000',sizeof(BINTYP));
-binding.ip=strdup("127.0.0.25");
-binding.port=strdup("2525");
+bindings=(SOCTYP **)0;
+bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.25","2525",10);
 phase=0;
 proceed=true;
 while (proceed==true) {
@@ -40,8 +39,8 @@ while (proceed==true) {
     case 0      :       //looping forever email receiving processes
       (void) prc_settitle("emlrec with pid='%06d'",getpid());
       break;
-    case 1      :       //Opening a channel
-      if (soc_setbind(&binding)<0)
+    case 1      :       //Opening ONE channel
+      if (soc_setbind(*bindings)<0)
         phase=999;      //doc not open!
       break;
     case 2      :       //Terminating all remaining process
@@ -55,6 +54,7 @@ while (proceed==true) {
     }
   phase++;
   }
+bindings=soc_freebindinf(bindings);
 }
 /*
 ^L
index c3b48e86eef5ad08c3492df7e9e1b9604a657474..7c4a87b610d84afc32c5e30c8c3a2ae795fa5858 100644 (file)
@@ -62,12 +62,98 @@ return strdup(dropzone);
 /*      name.                                           */
 /*                                                      */
 /********************************************************/
-const char *rou_getversion()
+PUBLIC const char *rou_getversion()
 
 {
 return VERSION"."RELEASE;
 }
 /*
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to free memory used by a              */
+/*     string, do not proceed if pointer is NULL.       */
+/*                                                      */
+/********************************************************/
+char *rou_freestr(register char *str)
+
+{
+if (str!=(char *)0) {
+  (void) free(str);
+  str=(char *)0;
+  }
+return str;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                     */
+/*     Subroutine to get add a pointer (not null)      */
+/*     to a list of pointer.                           */
+/*                                                     */
+/********************************************************/
+PUBLIC void **rou_addlist(void **list,void *entry)
+
+{
+if (entry!=(void *)0) {
+  register int num;
+
+  num=0;
+  if (list==(void  **)0)
+    list=(void **)calloc(num+2,sizeof(void *));
+  else {
+    while (list[num]!=(void *)0) 
+      num++;
+    list=realloc((void *)list,(num+2)*sizeof(void *));
+    }
+  list[num]=entry;
+  num++;
+  list[num]=(void *)0;
+  }
+return list;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                     */
+/*     Procedure to free one entry part of list        */
+/*      return true if found, false otherwize.          */
+/*                                                     */
+/********************************************************/
+PUBLIC _Bool rou_rmlist(void **list,void *entry,freehandler_t handler)
+
+{
+_Bool found;
+
+found=false;
+if ((list!=(void **)0)&&(entry!=(void **)0)) {
+  void **ptr;
+
+  ptr=list;
+  while (*ptr!=(void *)0) {
+    if (*ptr==entry) {
+      void **nxt;
+    
+      nxt=ptr+1;
+      if (handler!=(freehandler_t)0)
+        (void) handler(*ptr);
+      while (*ptr!=(void *)0) {
+        *ptr=*nxt;
+        ptr++;
+        nxt++;
+        }
+      found=true;
+      break;
+      }
+    ptr++;
+    }
+  }
+return found;
+}
+/*
 ^L
 */
 /********************************************************/
@@ -76,7 +162,7 @@ return VERSION"."RELEASE;
 /*      logs.                                           */
 /*                                                      */
 /********************************************************/
-char *rou_setappname(const char *newname)
+PUBLIC char *rou_setappname(const char *newname)
 
 {
 char *name;
@@ -99,7 +185,7 @@ return name;
 /*      directory if needed                             */
 /*                                                     */
 /********************************************************/
-char *rou_apppath(const char *path)
+PUBLIC char *rou_apppath(const char *path)
 
 {
 char *root;
@@ -124,7 +210,7 @@ return newpath;
 /*     Subroutine to log event on syslog               */
 /*                                                     */
 /********************************************************/
-void rou_valert(const int dlevel,const char *fmt,va_list ap)
+PUBLIC void rou_valert(const int dlevel,const char *fmt,va_list ap)
 
 #define        DEBMAX  120
 
@@ -160,7 +246,7 @@ if (debug>=dlevel)
 /*     Subroutine to log event on syslog               */
 /*                                                     */
 /********************************************************/
-void rou_alert(const int dlevel,const char *fmt,...)
+PUBLIC void rou_alert(const int dlevel,const char *fmt,...)
 
 {
 va_list args;
@@ -170,41 +256,6 @@ va_start(args,fmt);
 va_end(args);
 }
 /*
-^L
-*/
-/********************************************************/
-/*                                                      */
-/*     Procedure to "open" usager to module.           */
-/*      homework purpose                                */
-/*      return zero if everything right                 */
-/*                                                      */
-/********************************************************/
-int rou_opensubrou()
-
-{
-int status;
-
-status=0;
-if (modopen==false) {
-  debug=0;
-  foreground=false;
-  off64_time=(time_t)0;
-  off_date=(time_t)0;
-  if (appname!=(char *)0)
-    (void) free(appname);
-  appname=strdup(APPNAME);
-  if (rootdir!=(char *)0) {
-    (void) free(rootdir);
-    status=-1;          //Rootdir should be found as NULL
-    }
-  rootdir=strdup("");
-  (void) openlog(APPNAME,LOG_PID,LOG_DAEMON);
-  (void) rou_alert(0,"Starting: %s-%s",APPNAME,rou_getversion());
-  modopen=true;
-  }
-return status;
-}
-/*
 \f
 */
 /********************************************************/
@@ -212,7 +263,7 @@ return status;
 /*     Subroutine to CORE-DUMP the application         */
 /*                                                     */
 /********************************************************/
-void rou_crash(const char *fmt,...)
+PUBLIC void rou_crash(const char *fmt,...)
 
 {
 #define        RELAX   5
@@ -238,7 +289,7 @@ va_end(args);
 /*     message and terminate application               */
 /*                                                     */
 /********************************************************/
-void rou_core_dump(const char *fmt,...)
+PUBLIC void rou_core_dump(const char *fmt,...)
 
 {
 #define MAXCRASH        10      //maximun crash file within drop zone
@@ -321,7 +372,7 @@ if (doabort==true)
 /*      return zero if everything right                 */
 /*                                                      */
 /********************************************************/
-int rou_modesubrou(_Bool mode)
+PUBLIC int rou_modesubrou(_Bool mode)
 
 {
 #define OPEP    "subrou.c:rou_modesubrou"
@@ -332,6 +383,8 @@ status=0;
 if (mode!=modopen) {
   switch ((int)mode) {
     case true     :
+      off64_time=(time_t)0;
+      off_date=(time_t)0;
       (void) srand(getpid()*355);
       if (foreground==true)
         (void) srand((int)(M_PI*100000000));
index 06038f17ec8c68b188bc49c5e206226fd7bd7721..49be2741fafcaf83258f5d1e1e301fa108025906 100644 (file)
@@ -14,6 +14,8 @@
 
 #define APPNAME "maild"         //application name
 
+typedef void (*freehandler_t)(void *);
+
 //---   Variables defined within subrou.c       ---------
 extern int             debug;  //application debug mode
 extern _Bool       foreground;  //process is in foreground mode
@@ -26,6 +28,17 @@ extern char          *appname;  //application "official" name
 //return program version
 extern const char *rou_getversion();
 
+//Procedure to free a string pointer and return 
+//a NULL pointer
+extern char *rou_freestr(char *str);
+
+//to add a not null pointer to a list of pointer
+extern void **rou_addlist(void **list,void *entry);
+
+//Procedure to free one entry part of list
+// return true if found, false otherwize. 
+extern _Bool rou_rmlist(void **list,void *entry,freehandler_t handler);
+
 //change the application name
 extern char *rou_setappname(const char *newname);
 
index 0a1e82ea4f0c97fe6856bc18b2149a75ba2ac03e..dcfdc000bfd86bdbfaf32e6fc555c4b83d1a7a1e 100644 (file)
@@ -7,9 +7,13 @@
 /********************************************************/
 #include        <sys/types.h>
 #include        <sys/socket.h>
+#include        <errno.h>
+#include        <fcntl.h>
 #include        <netdb.h>
 #include        <stdio.h>
+#include        <stdlib.h>
 #include        <string.h>
+#include        <unistd.h>
 
 #include       "subrou.h"
 #include       "unisoc.h"
 
 static  _Bool modopen;        //module open/close status
 /*
-^L
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to free memory used by a              */
+/*     binding info.                                   */
+/*                                                     */
+/*                                                      */
+/********************************************************/
+static SOCTYP *freebinding(SOCTYP *binding)
+
+{
+if (binding!=(SOCTYP *)0) {
+  binding->port=rou_freestr(binding->port);
+  binding->ip=rou_freestr(binding->ip);
+  (void) free(binding);
+  binding=(SOCTYP *)0; 
+  }
+return binding;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                      */
+/*     Procedure to bind a socket to a specific        */
+/*     address and return the linked handle            */
+/*                                                      */
+/********************************************************/
+static int bindhandle(struct addrinfo *ai,SOCTYP *binding)
+
+{
+#define        OPEP    "unisoc.c:bindhandle,"
+#define        BFSZ    30      //working buffer size
+
+int handle;
+struct linger slg;
+char *buf;
+int flags;
+int phase;
+_Bool proceed;
+
+handle=-1;
+(void) memset(&slg,'\000',sizeof(struct linger));
+buf=calloc(BFSZ,sizeof(char));
+flags=0;
+phase=0;
+proceed=true;
+while (proceed==true) {
+  switch (phase) {
+    case 0     :       //lets get a socket
+      if ((handle=socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol))<0) {
+        (void) rou_alert(0,"%s Unable to open socket for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+       phase=999;      //trouble trouble
+       }
+      break;
+    case 1     :       //setting socket option (address)
+      if (setsockopt(handle,SOL_SOCKET,SO_REUSEADDR,buf,BFSZ*sizeof(char))<0) {
+        (void) rou_alert(0,"%s Unable to get socket option "
+                           "SO_REUSEADDR for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+        }
+      break;
+    case 2     :       //setting socket option (port)
+      if (setsockopt(handle,SOL_SOCKET,SO_REUSEPORT,buf,BFSZ*sizeof(char))<0) {
+        (void) rou_alert(0,"%s Unable to get socket option "
+                           "SO_REUSEPORT for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+        }
+      break;
+    case 3     :       //SO_LINGER allow  Connection reset by peer"
+      if (setsockopt(handle,SOL_SOCKET,SO_LINGER,&slg,sizeof(slg))<0) {
+        (void) rou_alert(0,"%s Unable to set socket option "
+                           "SO_LINGER for <%s> (error='%s')",
+                         OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 4     :       /*getting socket option */
+      if ((flags=fcntl(handle,F_GETFL,0))<0) {
+        (void) rou_alert(0,"%s Unable to set socket descriptor "
+                           "for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 5     :       //setting the socket working setting
+      if (fcntl(handle,F_SETFL,flags|O_NONBLOCK|O_ASYNC)<0) {
+        (void) rou_alert(0,"%s Unable to set socket in none "
+                           "block mode for <%s> (error='%s')",
+                          OPEP,ai->ai_canonname,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 6     :       //getting socket option
+      if (bind(handle,ai->ai_addr,ai->ai_addrlen)<0) {
+       (void) rou_alert(0,"%s Unable to bind on IP/port <%s/%s> (error='%s')",
+                          OPEP,ai->ai_canonname,binding->port,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 7     :       /*preparing listen      */
+      if (listen(handle,5)<0) {
+       (void) rou_alert(0,"%s Unable to listen on IP/port <%s/%s> (error='%s')",
+                          OPEP,ai->ai_canonname,binding->port,strerror(errno));
+        phase=999;     //trouble cleanup phase
+       }
+      break;
+    case 8     :       /*reporting listen      */
+      (void) rou_alert(1,"Now Listening on IP/PORT <%s/%s>",
+                          ai->ai_canonname,binding->port);
+      proceed=false;    //evrything fine no need to go further
+      break;
+    default    :       /*SAFE Guard            */
+      if (handle>=0)
+        close(handle);
+      proceed=false;    
+      break;
+    }
+  phase++;
+  }
+(void) free(buf);
+return handle;
+#undef OPEP
+}
+/*
+\f
 */
 /********************************************************/
 /*                                                     */
-/*      Procedure to bind a sockt to a specific         */
-/*      IP/PORT.                                        */
+/*     Procedure to free memory used by a bind         */
+/*     definition.                                     */
+/*                                                     */
+/********************************************************/
+PUBLIC SOCTYP **soc_freebindinf(SOCTYP **bindref)
+
+{
+if (bindref!=(SOCTYP **)0) {
+  int i;
+
+  for (i=0;bindref[i]!=(SOCTYP *)0;i++) {
+    bindref[i]=freebinding(bindref[i]);
+    }
+  (void) free(bindref);
+  bindref=(SOCTYP **)0;
+  }
+return bindref;
+}
+/*
+\f
+*/
+/********************************************************/
+/*                                                     */
+/*     Procedure to set memory used by a bin           */
+/*     definition.                                     */
 /*                                                     */
 /********************************************************/
-static int bindhandle(struct addrinfo *ai,BINTYP *binding)
+PUBLIC SOCTYP **soc_mkbindinf(SOCTYP **bindings,PROTYP proto,
+                              const char *ip,const char *port,int iteration)
 
 {
-return -1;
+SOCTYP *bininf;
+
+bininf=(SOCTYP *)calloc(1,sizeof(SOCTYP));
+bininf->proto=proto;
+bininf->ip=strdup(ip);
+bininf->port=strdup(port);
+bininf->iteration=iteration;
+bindings=(SOCTYP **)rou_addlist((void **)bindings,(void *)bininf);
+return bindings;
 }
 /*
 ^L
@@ -46,7 +211,7 @@ return -1;
 /*      IP/PORT.                                        */
 /*                                                     */
 /********************************************************/
-PUBLIC int soc_setbind(BINTYP *binding)
+PUBLIC int soc_setbind(SOCTYP *binding)
 
 {
 #define OPEP    "unisoc.c:soc_setbind"
@@ -69,7 +234,7 @@ proceed=true;
 while (proceed==true) {
   switch (phase) {
     case 0      :       //sanity check
-      if (binding==(BINTYP *)0) {
+      if (binding==(SOCTYP *)0) {
         (void) rou_alert(0,"%s, socket binding reference is NULL (Bug!?)",OPEP);
         phase=999;      //no need to go further
         }
index b02b9431ee8f0625a80e6e0e7c5fbbb8048b5a9e..b636517841f51a4d1fec699d70ba24a8f1a47fac 100644 (file)
 #include        <stdbool.h>
 #include        <time.h>
 
+//defining email protocol value.
+typedef enum    {
+        pro_smtp,       //text SMTP protocol, in clear mode
+        pro_startls,    //Text SMTP protocol, encrypted upon request
+        pro_smtps,      //Text SMTP protocol, text encrypted from start
+        pro_unknwn      //Protcole undefined
+        }PROTYP;
+
 typedef struct  {
+        PROTYP proto;   //Connexion protocol type
         char *ip;       //Binding IP    //IPV4 or IPV6
         char *port;     //Binding Port
         time_t lasttry; //successful binding last time
-        }BINTYP;
+        int iteration;  //number of handle ready on the soc
+        int handle;     //connexion handle
+        }SOCTYP;
+
+//procedure to free all memory used by a TCP socket
+//definition (once closed) 
+extern SOCTYP **soc_freebindinf(SOCTYP **bindref);
+
+//procedure to assign memory to be used by a TCP socket
+//definition
+extern SOCTYP **soc_mkbindinf(SOCTYP **bindings,PROTYP proto,
+                              const char *ip,const char *port,int iteration);
 
 //procedure to open a socketand retunr handle to socket
-extern int soc_setbind(BINTYP *binding);
+extern int soc_setbind(SOCTYP *binding);
 
 //homework to be done before starting/stopping module.
 extern int soc_modeunisoc(_Bool mode);