/* a remote TCP connection. */
/* */
/********************************************************/
-void docontact(SOCTYP *binding)
+void docontact(SOCTYP *binding,int pos)
{
#define OPEP "modrec.c:contact"
#define TESTL 4
CONTYP *contact;
-pid_t child;
int phase;
_Bool proceed;
while (proceed==true) {
switch (phase) {
case 0 : //display waiting contact
- (void) prc_settitle("Waiting contact on %s:%s",binding->ip,binding->port);
+ (void) prc_settitle("Waiting contact (%02d/%02d) on %s:%s",
+ pos,binding->iteration,binding->ip,binding->port);
break;
case 1 : //do we have a contact
- if ((contact=tcp_getcontact(binding))==(CONTYP *)0) {
+ if ((contact=tcp_getcontact(binding))==(CONTYP *)0)
phase=999; //No contact!
- }
break;
case 2 : //forking process
printf("New client connected: %d\n",contact->channel);
- if ((child=fork())!=(pid_t)0) {
- (void) close(contact->channel);
- (void) free(contact);
- contact=(CONTYP *)0;
- phase=999; //no need to go further
- }
break;
case 3 : //do contact
- (void) close(binding->handle);
printf("Client channel=%d (pid=%d)\n",contact->channel,getpid());
for (int i=0;i<TESTL;i++) {
(void) dprintf(contact->channel,"Remote pid=%d iter=%d/%d\n",
(void) rou_alert(0,"Contact IP/PORT=<%s/%s> Exiting",
binding->ip,binding->port);
contact=tcp_dropcontact(contact);
- (void) exit(0); //exiting sub process
break;
default : //SAFE guard
proceed=false;
*/
/********************************************************/
/* */
-/* Procedure to dispatch sub process */
+/* Procedure to activate child process if necessary*/
/* */
/********************************************************/
-static void dispatching(SOCTYP *binding)
+static void setready(SOCTYP *binding)
{
-#define OPEP "modrec.c:dispatching"
+#define OPEP "modrec.c:setready"
+pid_t *childs;
+int maxretry;
int phase;
_Bool proceed;
+childs=(pid_t *)calloc(binding->iteration,sizeof(pid_t));
+maxretry=5;
phase=0;
proceed=true;
while (proceed==true) {
+ //(void) fprintf(stderr,"setready phase='%d'\n",phase);
switch (phase) {
- case 0 : //dispatched process still alive
- (void) prc_nozombie();
+ case 0 : //empty phase
+ break;
+ case 1 : //check need to dispatch a process
+ for (int i=0;i<binding->iteration;i++) {
+ (void) prc_nozombie();
+ if (prc_checkprocess(childs[i])==true)
+ continue;
+ childs[i]=fork();
+ switch (childs[i]) {
+ case -1 : //trouble trouble to fork?
+ childs[i]=(pid_t)0;
+ (void) sleep(1); //Weathering the storm
+ break;
+ case 0 : //Child process itself
+ (void) docontact(binding,i+1);
+ (void) exit(0);
+ break;
+ default : //Main process
+ (void) usleep(10000);
+ break;
+ }
+ }
+ if ((hangup==true)||(reload==true))
+ phase=999;
break;
- case 1 : //dispating need process
- (void) docontact(binding); //waiting, handling remote contact
+ case 2 : //Relax time
+ (void) sleep(5);
+ if ((hangup==false)&&(reload==false))
+ 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--;
+ }
proceed=false;
break;
}
phase++;
}
+(void) free(childs);
#undef OPEP
}
/*
*/
/********************************************************/
/* */
-/* Procedure to activate child process if necessary*/
+/* Procedure to start a binding+waiting process */
/* */
/********************************************************/
-static void activate(SOCTYP **bindings)
+PUBLIC void startwaiter(SOCTYP *binding,int offset)
{
-#define OPEP "modrec.c:activate"
+#define OPEP "moderec.c:startwaiter"
int phase;
_Bool proceed;
proceed=true;
while (proceed==true) {
switch (phase) {
- case 0 : //making sur the list is defined
- if (bindings==(SOCTYP **)0) {
- (void) rou_alert(0,"%s bindings list pointer is NULL (Bug!?)",OPEP);
- phase=999; //not going further
- }
+ case 0 : //Opening logs
+ (void) openlog(appname,LOG_NDELAY|LOG_PID,LOG_DAEMON);
+ (void) prc_settitle("Daemon Waiting on %s:%s (Num of channels='%02d')",
+ binding->ip,binding->port,binding->iteration);
break;
- case 1 : //check need to dispatch a process
- while (*bindings!=(SOCTYP *)0) {
- (void) dispatching(*bindings);
- bindings++;
+ case 1 : //binding on channel
+ if (soc_openbinding(binding)==false) {
+ (void) rou_alert(0,"%s Aborting binding on <%s:%s> (config?)",
+ OPEP,binding->ip,binding->port);
+ phase=999; //no need to go further
}
break;
+ case 2 : //waiting
+ (void) rou_alert(0,"JMPDBG waiter starting");
+ (void) setready(binding);
+ (void) rou_alert(0,"JMPDBG waiter exiting");
+ break;
+ case 3 : //stop binding
+ (void) soc_closebinding(binding);
+ break;
default : //SAFE Guard
+ (void) closelog();
proceed=false;
break;
}
*/
/********************************************************/
/* */
-/* Procedure to start a binding+waiting process */
-/* */
-/********************************************************/
-PUBLIC pid_t startwaiter(SOCTYP *binding)
-
-{
-pid_t waiter;
-
-if ((waiter=fork())==(pid_t)0) {
- (void) closelog();
- (void) openlog("Waiter",LOG_NDELAY|LOG_PID,LOG_DAEMON);
- (void) prc_settitle("Daemon Waiting on %s:%s (Num of channels='%02d')",
- binding->ip,binding->port,binding->iteration);
- (void) rou_alert(0,"JMPDBG starting waiter");
- (void) sleep(20);
- (void) rou_alert(0,"JMPDBG waiter exiting");
- (void) closelog();
- (void) exit(0);
- }
-return waiter;
-}
-/*
-\f
-*/
-/********************************************************/
-/* */
/* Waiting and handling smtp request */
/* */
/********************************************************/
maxretry=30; //5 seconds max retry
bindings=(SOCTYP **)0;
-bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",1);
-//bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1);
+bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.1","2525",3);
+bindings=soc_mkbindinf(bindings,pro_smtp,"127.0.0.26","2626",1);
phase=0;
proceed=true;
while (proceed==true) {
switch (phase) {
case 0 : //looping forever email receiving processes
- (void) prc_settitle("Emlrec Daemon");
(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!");
break;
case 2 : //starting restarting all waiter process
for (SOCTYP **ptr=bindings;(*ptr)!=(SOCTYP *)0;ptr++) {
+ int offset;
+
+ offset=random()%10;
if ((*ptr)->waiter!=(pid_t)0)
continue;
- (*ptr)->waiter=startwaiter(*ptr);
+ (*ptr)->waiter=fork();
+ if ((*ptr)->waiter==(pid_t)0) {
+ (void) closelog();
+ (void) startwaiter(*ptr,offset);
+ (void) exit(0);
+ }
+ (void) usleep(10000); //avoid avalanche
}
break;
case 3 : //relax time