/* Module to handle all email incoming */
/* */
/********************************************************/
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
PUBLIC void rec_handlesmtp()
{
+#define OPEP "modrec.c:rec_handlesmtp"
+
SOCTYP **bindings;
int phase;
_Bool proceed;
bindings=(SOCTYP **)0;
bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.25","2525",10);
+bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",10);
phase=0;
proceed=true;
while (proceed==true) {
case 0 : //looping forever email receiving processes
(void) prc_settitle("emlrec with pid='%06d'",getpid());
break;
- case 1 : //Opening ONE channel
- if (soc_setbind(*bindings)<0)
- phase=999; //doc not open!
+ case 1 : //Opening ALL channels
+ if (soc_mullisten(bindings)==false)
+ (void) rou_alert(0,"%s, Unable to open ALL socket (config?)",OPEP);
break;
case 2 : //Terminating all remaining process
(void) fprintf(stderr,"JMPDBG wait 5 sec\n");
(void) sleep(5);
(void) fprintf(stderr,"JMPDBG wleep completed\n");
break;
+ case 3 : //closing all socket openend
+ (void) soc_mulclose(bindings);
+ break;
default : //SAFE Guard
proceed=false;
break;
phase++;
}
bindings=soc_freebindinf(bindings);
+#undef OPEP
}
/*
^L
/* return zero if everything right */
/* */
/********************************************************/
-int rec_modemodrec(_Bool mode)
+PUBLIC int rec_modemodrec(_Bool mode)
{
#define OPEP "mode.c:rec_modemoderec"
/* list */
/* */
/********************************************************/
-ARGTYP *par_freeparams(ARGTYP *params)
+PUBLIC ARGTYP *par_freeparams(ARGTYP *params)
{
if (params!=(ARGTYP *)0) {
/* on error return an null argtype */
/* */
/********************************************************/
-ARGTYP *par_getparams(int argc,char * const argv[],const char *optstring)
+PUBLIC ARGTYP *par_getparams(int argc,char * const argv[],const char *optstring)
{
ARGTYP *params;
break;
case 'f' : //background/daemon mode
foreground=true;
- (void) fprintf(stderr,"%s-%s, foreground mode requested\n",shortname,rou_getversion());
+ (void) fprintf(stderr,"%s-%s, foreground mode requested\n",
+ shortname,rou_getversion());
break;
case 'h' : //requestion program help
(void) fprintf(stderr,"%s-%s\n",shortname,rou_getversion());
rootdir=strdup(optarg);
break;
case 'v' :
- (void) fprintf(stderr,"%s:\tVersion <%s>\n",shortname,rou_getversion());
+ (void) fprintf(stderr,"%s:\tVersion <%s>\n",
+ shortname,rou_getversion());
(void) exit(0); //just display version
break;
default :
/* return zero if everything right */
/* */
/********************************************************/
-int par_modeunipar(_Bool mode)
+PUBLIC int par_modeunipar(_Bool mode)
{
#define OPEP "unipar.c:uni_modeunipar"
/* kernel.core_pattern=./core.%e.%p */
/* */
/********************************************************/
-void prc_allow_core_dump()
+PUBLIC void prc_allow_core_dump()
{
struct rlimit limites;
/* to leave the zombie stat. */
/* */
/********************************************************/
-void prc_nozombie()
+PUBLIC void prc_nozombie()
{
while (waitpid(-1,(int *)0,WNOHANG)>0);
/* still up and running. */
/* */
/********************************************************/
-_Bool prc_checkprocess(pid_t pidnum)
+PUBLIC _Bool prc_checkprocess(pid_t pidnum)
{
#define SIGCHECK 0 //signal to check if process
/* false otherwise. */
/* */
/********************************************************/
-_Bool prc_locking(const char *lockname,int lock,int tentative)
+PUBLIC _Bool prc_locking(const char *lockname,int lock,int tentative)
{
#define OPEP "uniprc.c:lck_locking,"
/* Return the child process id. */
/* */
/********************************************************/
-pid_t prc_divedivedive()
+PUBLIC pid_t prc_divedivedive()
{
#define OPEP "uniprc:rou_divedivedive,"
/* Procedure to free used by "title" struct memory.*/
/* */
/********************************************************/
-void prc_cleantitle()
+PUBLIC void prc_cleantitle()
{
if (title!=(TITLTYP *)0) {
/* from proc (ps ax) */
/* */
/********************************************************/
-void prc_preptitle(int argc,char *argv[],char *env[])
+PUBLIC void prc_preptitle(int argc,char *argv[],char *env[])
{
char *lastend;
/* CLI (commande line interface) "ps" */
/* */
/********************************************************/
-void prc_settitle(const char *fmt,...)
+PUBLIC void prc_settitle(const char *fmt,...)
{
va_list args;
/* return zero if everything right */
/* */
/********************************************************/
-int prc_modeuniprc(_Bool mode)
+PUBLIC int prc_modeuniprc(_Bool mode)
{
#define OPEP "unipar.c:prc_modeuniprc"
/* flag accordingly; */
/* */
/********************************************************/
-void sig_alrm(int sig)
+PUBLIC void sig_alrm(int sig)
{
#define OPEP "unisig.c:sig_alrm"
/* bay application */
/* */
/********************************************************/
-void sig_trapsignal(_Bool onoff,sighandler_t trap)
+PUBLIC void sig_trapsignal(_Bool onoff,sighandler_t trap)
{
#define OPEP "modbck.c:settrap"
/* return zero if everything right */
/* */
/********************************************************/
-int sig_modeunisig(_Bool mode)
+PUBLIC int sig_modeunisig(_Bool mode)
{
#define OPEP "unisig.c:sig_modeunisig"
#include "subrou.h"
#include "unisoc.h"
+#include "unisoc.h"
//Need to have GNU_SOURCE define within CFLAGS
#ifdef AI_ALL
*/
/********************************************************/
/* */
-/* Procedure to bind the socketc. */
-/* IP/PORT. */
+/* Procedure to bind to one socket and return the */
+/* socket handle */
/* */
/********************************************************/
-PUBLIC int soc_setbind(SOCTYP *binding)
+PUBLIC int soc_onelisten(SOCTYP *binding)
{
-#define OPEP "unisoc.c:soc_setbind"
-
+#define OPEP "unisoc.c:soc_onelisten"
int soc;
struct addrinfo hints;
^L
*/
/********************************************************/
+/* */
+/* Procedure to unbind from one socket. */
+/* */
+/********************************************************/
+PUBLIC void soc_oneclose(SOCTYP *binding)
+
+{
+#define OPEP "unisoc.c:soc_oneclose"
+
+int phase;
+_Bool proceed;
+
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //sanity check
+ if (binding==(SOCTYP *)0) {
+ (void) rou_alert(0,"%s binding pointer is NULL (Bug!?)",OPEP);
+ phase=999; //not going further
+ }
+ break;
+ case 1 : //check if socket already close
+ if (binding->handle<0) {
+ phase=999; //yes, no need to go further
+ }
+ break;
+ case 2 : //check if time to retry binding
+ if (shutdown(binding->handle,SHUT_RDWR)<0)
+ (void) rou_alert(0,"%s Unbale to shutdown socket (Bug!?, error=<%s>)",
+ OPEP,strerror(errno));
+
+ break;
+ case 3 : //closing the the socket
+ if (close(binding->handle)<0)
+ (void) rou_alert(0,"%s Unbale to close socket (Bug!?, error=<%s>)",
+ OPEP,strerror(errno));
+ binding->handle=-1;
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to bind to a set of socket and return */
+/* true if all socket are open ready. */
+/* */
+/********************************************************/
+PUBLIC int soc_mullisten(SOCTYP **bindings)
+
+{
+#define OPEP "unisoc.c:soc_mullisten"
+
+_Bool ready;
+uid_t gid;
+uid_t uid;
+int phase;
+_Bool proceed;
+
+ready=false;
+gid=getegid(); //let be back to root if needed
+uid=geteuid(); //to open device on < 1024 por
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //checking if the point is ready;
+ if (bindings==(SOCTYP **)0) {
+ (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP);
+ phase=999; //not going further
+ }
+ break;
+ case 1 : //
+ if ((setegid(getgid())<0)||(seteuid(getuid())<0)) {
+ (void) rou_core_dump("%s, Unable to get root privilege! "
+ "(program config? error=<%s>)",
+ OPEP,strerror(errno));
+ //program is crashing HARD
+ }
+ break;
+ case 2 : //binding on all interface
+ ready=true;
+ while (*bindings!=(SOCTYP *)0) {
+ (*bindings)->handle=soc_onelisten(*bindings);
+ if ((*bindings)->handle<0)
+ ready=false; //Trouble?
+ bindings++;
+ }
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+(void) setegid(gid); //set back the user,group ID
+(void) seteuid(uid);
+return ready;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to close all socket within a socket */
+/* list. */
+/* */
+/********************************************************/
+PUBLIC void soc_mulclose(SOCTYP **bindings)
+
+{
+#define OPEP "unisoc.c:soc_mulclose"
+
+int phase;
+_Bool proceed;
+
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //checking if the point is ready;
+ if (bindings==(SOCTYP **)0) {
+ (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP);
+ phase=999; //not going further
+ }
+ break;
+ case 1 : //
+ while (*bindings!=(SOCTYP *)0) {
+ (void) soc_oneclose(*bindings);
+ bindings++;
+ }
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
/* */
/* Procedure to "open/close" module and do */
/* homework purpose */
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(SOCTYP *binding);
+//procedure to open ONE socket and return handle to socket
+extern int soc_onelisten(SOCTYP *binding);
+
+//procedure to close ONE socket
+extern void soc_oneclose(SOCTYP *binding);
+
+//procedure to open multiple socket and return true if
+//all socket are open
+extern int soc_mullisten(SOCTYP **bindings);
+
+//procedure to close all sockets
+extern void soc_mulclose(SOCTYP **bindings);
//homework to be done before starting/stopping module.
extern int soc_modeunisoc(_Bool mode);