More memory leak fixes, added command thread to mbtask

This commit is contained in:
Michiel Broek 2003-12-06 16:35:33 +00:00
parent 07012fa3e1
commit d55d4e0df1
13 changed files with 500 additions and 399 deletions

View File

@ -59,6 +59,11 @@ v0.39.3 26-Nov-2003
mbtask: mbtask:
The ping function now runs in a separate thread. The ping function now runs in a separate thread.
Changed some ping timer logic. Changed some ping timer logic.
Added a "secret" commandline parameter to allow mbtask to run
under control of debuggers.
The client command server runs in a separate thread.
Fixed some small memory leaks which had no effect on long term
running of mbtask, only leaks during program stop.
mbpasswd: mbpasswd:
Fixed a small memory leak. Fixed a small memory leak.

View File

@ -14,12 +14,12 @@
</HEAD> </HEAD>
<BODY> <BODY>
<BLOCKQUOTE> <BLOCKQUOTE>
<div align="right"><h5>Last update 23-Mar-2002</h5></div> <div align="right"><h5>Last update 06-Dec-2003</h5></div>
<div align="center"><H1>mbtask - MBSE BBS Taskmanager</H1></div> <div align="center"><H1>mbtask - MBSE BBS Taskmanager</H1></div>
<H3>Sysopsis.</H3> <H3>Sysopsis.</H3>
<P> <P>
<code><strong>mbtask</strong></code> <code><strong>mbtask</strong> [-nd]</code>
<P>&nbsp;<P> <P>&nbsp;<P>
<H3>Description.</H3> <H3>Description.</H3>
@ -119,6 +119,10 @@ the chance that numbers are repeated on your system are almost zero. The first
time the counter is initialized it is set to the current unix time in seconds time the counter is initialized it is set to the current unix time in seconds
since 1 januari 1970. This counter is used by several programs to create unique since 1 januari 1970. This counter is used by several programs to create unique
.pkt filenames, msgid numbers etc. .pkt filenames, msgid numbers etc.
<P>
The commandline option <b>-nd</b> is only for debugging, it allows to start
without becoming a daemon, <b>mbtask</b> will run in the foreground. This
option is only usefull for developers.
<P>&nbsp;<P> <P>&nbsp;<P>
<H3>Environment.</H3> <H3>Environment.</H3>

View File

@ -489,7 +489,7 @@ char *printable(char *s, int l)
len=-l; len=-l;
} }
pbuff=(char*)xmalloc(len*4+1); pbuff=(char*)xmalloc(len*3+1);
p=pbuff; p=pbuff;
while (len--) { while (len--) {
if (isprint(*(unsigned char*)s)) if (isprint(*(unsigned char*)s))

View File

@ -4,7 +4,7 @@
* Purpose ...............: Fidonet mailer * Purpose ...............: Fidonet mailer
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2002 * Copyright (C) 1997-2003
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -49,194 +49,199 @@ extern int Loaded;
extern int mypid; extern int mypid;
/*
* Encode EMSI string. If called with a NULL pointer memory is freed.
*/
char *emsiencode(char *s) char *emsiencode(char *s)
{ {
char Base16Code[]="0123456789ABCDEF"; char Base16Code[]="0123456789ABCDEF";
static char *buf; static char *buf;
char *p, *q; char *p, *q;
if (buf) if (buf)
free(buf); free(buf);
if ((buf = malloc(2 * strlen(s) + 1 * sizeof(char))) == NULL) { buf = NULL;
Syslog('+', "emsiencode:out of memory:string too long:\"%s\"", s); if (s == NULL)
return s; return NULL;
if ((buf = malloc(2 * strlen(s) + 1 * sizeof(char))) == NULL) {
Syslog('+', "emsiencode:out of memory:string too long:\"%s\"", s);
return s;
}
for (p = s, q = buf; *p != '\0';) {
switch (*p) {
case '\\': *q++ = '\\'; *q++ = *p++; break;
case '[':
case ']':
case '{':
case '}': *q++ = '\\';
*q++ = Base16Code[(*p >> 4) & 0x0f];
*q++ = Base16Code[*p & 0x0f];
p++; break;
default: *q++ = *p++; break;
} }
for (p = s, q = buf; *p != '\0';) { }
switch (*p) { *q = '\0';
case '\\': *q++ = '\\'; *q++ = *p++; break;
case '[':
case ']':
case '{':
case '}': *q++ = '\\';
*q++ = Base16Code[(*p >> 4) & 0x0f];
*q++ = Base16Code[*p & 0x0f];
p++; break;
default: *q++ = *p++; break;
}
}
*q = '\0';
return buf; return buf;
} }
char *mkemsidat(int caller) char *mkemsidat(int caller)
{ {
time_t tt; time_t tt;
char cbuf[16]; char cbuf[16], *p;
char *p; faddr *primary;
faddr *primary; int i;
int i;
p = xstrcpy((char *)"EMSI_DAT0000{EMSI}{"); p = xstrcpy((char *)"EMSI_DAT0000{EMSI}{");
primary = bestaka_s(remote->addr); primary = bestaka_s(remote->addr);
p = xstrcat(p, ascfnode(primary, 0x1f)); p = xstrcat(p, ascfnode(primary, 0x1f));
for (i = 0; i < 40; i++) for (i = 0; i < 40; i++)
if ((CFG.aka[i].node) && (CFG.akavalid[i]) && if ((CFG.aka[i].node) && (CFG.akavalid[i]) &&
((CFG.aka[i].zone != primary->zone) || ((CFG.aka[i].zone != primary->zone) || (CFG.aka[i].net != primary->net) ||
(CFG.aka[i].net != primary->net) || (CFG.aka[i].node != primary->node) || (CFG.aka[i].point!= primary->point))) {
(CFG.aka[i].node != primary->node) || p = xstrcat(p, (char *)" ");
(CFG.aka[i].point!= primary->point))) { p = xstrcat(p, aka2str(CFG.aka[i]));
p = xstrcat(p, (char *)" ");
p = xstrcat(p, aka2str(CFG.aka[i]));
}
p=xstrcat(p,(char *)"}{");
tidy_faddr(primary);
if (emsi_local_password)
p=xstrcat(p,emsi_local_password);
else
if (strlen(nodes.Spasswd)) {
p = xstrcat(p, nodes.Spasswd);
}
if (emsi_local_opts & OPT_EII) {
p = xstrcat(p, (char *)"}{");
if (emsi_local_lcodes & LCODE_FNC)
p = xstrcat(p, (char *)"FNC,");
if (emsi_local_lcodes & LCODE_RMA)
p = xstrcat(p, (char *)"RMA,");
if (emsi_local_lcodes & LCODE_RH1)
p = xstrcat(p, (char *)"RH1,");
if (emsi_local_lcodes & LCODE_PUA)
p=xstrcat(p,(char *)"PUA,");
else if (emsi_local_lcodes & LCODE_PUP)
p=xstrcat(p,(char *)"PUP,");
else if (emsi_local_lcodes & LCODE_NPU)
p=xstrcat(p,(char *)"NPU,");
if (emsi_local_lcodes & LCODE_HAT)
p=xstrcat(p,(char *)"HAT,");
if (emsi_local_lcodes & LCODE_HXT)
p=xstrcat(p,(char *)"HXT,");
if (emsi_local_lcodes & LCODE_HRQ)
p=xstrcat(p,(char *)"HRQ,");
if (*(p+strlen(p)-1) == ',')
*(p+strlen(p)-1) = '}';
else
p=xstrcat(p,(char *)"}");
} else {
p=xstrcat(p,(char *)"}{8N1");
if (emsi_local_lcodes & LCODE_RH1)
p = xstrcat(p, (char *)",RH1");
if (caller) {
if (emsi_local_lcodes & LCODE_PUA)
p=xstrcat(p,(char *)",PUA");
else if (emsi_local_lcodes & LCODE_PUP)
p=xstrcat(p,(char *)",PUP");
else if (emsi_local_lcodes & LCODE_NPU)
p=xstrcat(p,(char *)",NPU");
} else {
if (emsi_local_lcodes & LCODE_HAT)
p=xstrcat(p,(char *)",HAT");
if (emsi_local_lcodes & LCODE_HXT)
p=xstrcat(p,(char *)",HXT");
if (emsi_local_lcodes & LCODE_HRQ)
p=xstrcat(p,(char *)",HRQ");
}
p = xstrcat(p, (char *)"}");
} }
p=xstrcat(p,(char *)"{"); p=xstrcat(p,(char *)"}{");
if (emsi_local_protos & PROT_TCP) tidy_faddr(primary);
p=xstrcat(p,(char *)"TCP,");
if (emsi_local_protos & PROT_HYD) if (emsi_local_password)
p=xstrcat(p,(char *)"HYD,"); p=xstrcat(p,emsi_local_password);
if (emsi_local_protos & PROT_JAN) else if (strlen(nodes.Spasswd)) {
p=xstrcat(p,(char *)"JAN,"); p = xstrcat(p, nodes.Spasswd);
if (emsi_local_protos & PROT_ZAP) }
p=xstrcat(p,(char *)"ZAP,");
if (emsi_local_protos & PROT_ZMO) if (emsi_local_opts & OPT_EII) {
p=xstrcat(p,(char *)"ZMO,"); p = xstrcat(p, (char *)"}{");
if (emsi_local_protos & PROT_DZA);
p=xstrcat(p,(char *)"DZA,"); if (emsi_local_lcodes & LCODE_FNC)
if (emsi_local_protos & PROT_KER) p = xstrcat(p, (char *)"FNC,");
p=xstrcat(p,(char *)"KER,"); if (emsi_local_lcodes & LCODE_RMA)
if (emsi_local_protos == 0) p = xstrcat(p, (char *)"RMA,");
p=xstrcat(p,(char *)"NCP,"); if (emsi_local_lcodes & LCODE_RH1)
if (emsi_local_opts & OPT_NRQ) p = xstrcat(p, (char *)"RH1,");
p=xstrcat(p,(char *)"NRQ,");
if (emsi_local_opts & OPT_ARC) if (emsi_local_lcodes & LCODE_PUA)
p=xstrcat(p,(char *)"ARC,"); p=xstrcat(p,(char *)"PUA,");
if (emsi_local_opts & OPT_XMA) else if (emsi_local_lcodes & LCODE_PUP)
p=xstrcat(p,(char *)"XMA,"); p=xstrcat(p,(char *)"PUP,");
if (emsi_local_opts & OPT_FNC) else if (emsi_local_lcodes & LCODE_NPU)
p=xstrcat(p,(char *)"FNC,"); p=xstrcat(p,(char *)"NPU,");
if (emsi_local_opts & OPT_CHT) if (emsi_local_lcodes & LCODE_HAT)
p=xstrcat(p,(char *)"CHT,"); p=xstrcat(p,(char *)"HAT,");
if (emsi_local_opts & OPT_SLK) if (emsi_local_lcodes & LCODE_HXT)
p=xstrcat(p,(char *)"SLK,"); p=xstrcat(p,(char *)"HXT,");
if (emsi_local_opts & OPT_EII) if (emsi_local_lcodes & LCODE_HRQ)
p=xstrcat(p,(char *)"EII,"); p=xstrcat(p,(char *)"HRQ,");
if (emsi_local_opts & OPT_DFB)
p=xstrcat(p,(char *)"DFB,");
if (emsi_local_opts & OPT_FRQ)
p=xstrcat(p,(char *)"FRQ,");
if (*(p+strlen(p)-1) == ',') if (*(p+strlen(p)-1) == ',')
*(p+strlen(p)-1) = '}'; *(p+strlen(p)-1) = '}';
else else
p=xstrcat(p,(char *)"}"); p=xstrcat(p,(char *)"}");
} else {
p=xstrcat(p,(char *)"}{8N1");
if (emsi_local_lcodes & LCODE_RH1)
p = xstrcat(p, (char *)",RH1");
if (caller) {
if (emsi_local_lcodes & LCODE_PUA)
p=xstrcat(p,(char *)",PUA");
else if (emsi_local_lcodes & LCODE_PUP)
p=xstrcat(p,(char *)",PUP");
else if (emsi_local_lcodes & LCODE_NPU)
p=xstrcat(p,(char *)",NPU");
} else {
if (emsi_local_lcodes & LCODE_HAT)
p=xstrcat(p,(char *)",HAT");
if (emsi_local_lcodes & LCODE_HXT)
p=xstrcat(p,(char *)",HXT");
if (emsi_local_lcodes & LCODE_HRQ)
p=xstrcat(p,(char *)",HRQ");
}
sprintf(cbuf,"{%X}",PRODCODE); p = xstrcat(p, (char *)"}");
p=xstrcat(p,cbuf); }
p=xstrcat(p,(char *)"{mbcico}{");
p=xstrcat(p,(char *)VERSION);
p=xstrcat(p,(char *)"}{");
p=xstrcat(p,(char *)__DATE__);
p=xstrcat(p,(char *)"}{IDENT}{[");
p=xstrcat(p,name?emsiencode(name):(char *)"Unknown");
p=xstrcat(p,(char *)"][");
p=xstrcat(p,emsiencode(CFG.location));
p=xstrcat(p,(char *)"][");
p=xstrcat(p,emsiencode(CFG.sysop_name));
p=xstrcat(p,(char *)"][");
p=xstrcat(p,phone?emsiencode(phone):(char *)"-Unpublished-");
p=xstrcat(p,(char *)"][");
if (CFG.Speed)
sprintf(cbuf,"%ld",CFG.Speed);
else
strcpy(cbuf,"9600");
p=xstrcat(p,cbuf);
p=xstrcat(p,(char *)"][");
p=xstrcat(p,flags?emsiencode(flags):(char *)"");
p=xstrcat(p,(char *)"]}{TRX#}{[");
tt = time(NULL);
sprintf(cbuf,"%08lX",mtime2sl(tt));
p=xstrcat(p,cbuf);
p=xstrcat(p,(char *)"]}{TZUTC}{[");
p=xstrcat(p,gmtoffset(tt));
p=xstrcat(p,(char *)"]}");
sprintf(cbuf,"%04X",(unsigned int)strlen(p+12)); p=xstrcat(p,(char *)"{");
memcpy(p+8,cbuf,4); if (emsi_local_protos & PROT_TCP)
Syslog('I',"Prepared: \"%s\"",p); p=xstrcat(p,(char *)"TCP,");
return p; if (emsi_local_protos & PROT_HYD)
p=xstrcat(p,(char *)"HYD,");
if (emsi_local_protos & PROT_JAN)
p=xstrcat(p,(char *)"JAN,");
if (emsi_local_protos & PROT_ZAP)
p=xstrcat(p,(char *)"ZAP,");
if (emsi_local_protos & PROT_ZMO)
p=xstrcat(p,(char *)"ZMO,");
if (emsi_local_protos & PROT_DZA);
p=xstrcat(p,(char *)"DZA,");
if (emsi_local_protos & PROT_KER)
p=xstrcat(p,(char *)"KER,");
if (emsi_local_protos == 0)
p=xstrcat(p,(char *)"NCP,");
if (emsi_local_opts & OPT_NRQ)
p=xstrcat(p,(char *)"NRQ,");
if (emsi_local_opts & OPT_ARC)
p=xstrcat(p,(char *)"ARC,");
if (emsi_local_opts & OPT_XMA)
p=xstrcat(p,(char *)"XMA,");
if (emsi_local_opts & OPT_FNC)
p=xstrcat(p,(char *)"FNC,");
if (emsi_local_opts & OPT_CHT)
p=xstrcat(p,(char *)"CHT,");
if (emsi_local_opts & OPT_SLK)
p=xstrcat(p,(char *)"SLK,");
if (emsi_local_opts & OPT_EII)
p=xstrcat(p,(char *)"EII,");
if (emsi_local_opts & OPT_DFB)
p=xstrcat(p,(char *)"DFB,");
if (emsi_local_opts & OPT_FRQ)
p=xstrcat(p,(char *)"FRQ,");
if (*(p+strlen(p)-1) == ',')
*(p+strlen(p)-1) = '}';
else
p=xstrcat(p,(char *)"}");
sprintf(cbuf,"{%X}",PRODCODE);
p=xstrcat(p,cbuf);
p=xstrcat(p,(char *)"{mbcico}{");
p=xstrcat(p,(char *)VERSION);
p=xstrcat(p,(char *)"}{");
p=xstrcat(p,(char *)__DATE__);
p=xstrcat(p,(char *)"}{IDENT}{[");
p=xstrcat(p,name?emsiencode(name):(char *)"Unknown");
p=xstrcat(p,(char *)"][");
p=xstrcat(p,emsiencode(CFG.location));
p=xstrcat(p,(char *)"][");
p=xstrcat(p,emsiencode(CFG.sysop_name));
p=xstrcat(p,(char *)"][");
p=xstrcat(p,phone?emsiencode(phone):(char *)"-Unpublished-");
p=xstrcat(p,(char *)"][");
if (CFG.Speed)
sprintf(cbuf,"%ld",CFG.Speed);
else
strcpy(cbuf,"9600");
p=xstrcat(p,cbuf);
p=xstrcat(p,(char *)"][");
p=xstrcat(p,flags?emsiencode(flags):(char *)"");
p=xstrcat(p,(char *)"]}{TRX#}{[");
tt = time(NULL);
sprintf(cbuf,"%08lX",mtime2sl(tt));
p=xstrcat(p,cbuf);
p=xstrcat(p,(char *)"]}{TZUTC}{[");
p=xstrcat(p,gmtoffset(tt));
p=xstrcat(p,(char *)"]}");
sprintf(cbuf,"%04X",(unsigned int)strlen(p+12));
memcpy(p+8,cbuf,4);
Syslog('I',"Prepared: \"%s\"",p);
emsiencode(NULL); /* Free memory */
return p;
} }
@ -244,42 +249,42 @@ char *mkemsidat(int caller)
char *sel_brace(char*); char *sel_brace(char*);
char *sel_brace(char *s) char *sel_brace(char *s)
{ {
static char *save; static char *save;
char *p,*q; char *p,*q;
int i; int i;
if (s == NULL) if (s == NULL)
s=save; s=save;
for (;*s && (*s != '{');s++); for (;*s && (*s != '{');s++);
if (*s == '\0') { if (*s == '\0') {
save=s; save=s;
return NULL; return NULL;
} else } else
s++; s++;
for (p=s,q=s;*p;p++) for (p=s,q=s;*p;p++)
switch (*p) { switch (*p) {
case '}': if (*(p+1) == '}') case '}': if (*(p+1) == '}')
*q++=*p++; *q++=*p++;
else { else {
*q='\0'; *q='\0';
save=p+1; save=p+1;
goto exit; goto exit;
} }
break; break;
case '\\': if (*(p+1) == '\\') case '\\': if (*(p+1) == '\\')
*q++=*p++; *q++=*p++;
else { else {
sscanf(p+1,"%02x",&i); sscanf(p+1,"%02x",&i);
*q++=i; *q++=i;
p+=2; p+=2;
} }
break; break;
default: *q++=*p; default: *q++=*p;
break; break;
} }
exit: exit:
return s; return s;
} }
@ -287,42 +292,42 @@ exit:
char *sel_bracket(char*); char *sel_bracket(char*);
char *sel_bracket(char *s) char *sel_bracket(char *s)
{ {
static char *save; static char *save;
char *p,*q; char *p,*q;
int i; int i;
if (s == NULL) if (s == NULL)
s=save; s=save;
for (;*s && (*s != '[');s++); for (;*s && (*s != '[');s++);
if (*s == '\0') { if (*s == '\0') {
save=s; save=s;
return NULL; return NULL;
} else } else
s++; s++;
for (p=s,q=s;*p;p++) for (p=s,q=s;*p;p++)
switch (*p) { switch (*p) {
case ']': if (*(p+1) == ']') case ']': if (*(p+1) == ']')
*q++=*p++; *q++=*p++;
else { else {
*q='\0'; *q='\0';
save=p+1; save=p+1;
goto exit; goto exit;
} }
break; break;
case '\\': if (*(p+1) == '\\') case '\\': if (*(p+1) == '\\')
*q++=*p++; *q++=*p++;
else { else {
sscanf(p+1,"%02x",&i); sscanf(p+1,"%02x",&i);
*q++=i; *q++=i;
p+=2; p+=2;
} }
break; break;
default: *q++=*p; default: *q++=*p;
break; break;
} }
exit: exit:
return s; return s;
} }

View File

@ -129,7 +129,7 @@ int tcprcvfiles(void)
{ {
int rc, bufl; int rc, bufl;
long filesize, filetime; long filesize, filetime;
char *filename, *p; char *filename = NULL, *p;
Syslog('+', "TCP: start receive files"); Syslog('+', "TCP: start receive files");
if (getsync()) { if (getsync()) {
@ -155,8 +155,12 @@ next:
} else } else
return rc==0?1:rc; return rc==0?1:rc;
if (strlen(filename) && filesize && filetime) if (strlen(filename) && filesize && filetime) {
rc = receivefile(filename,filetime,filesize); rc = receivefile(filename,filetime,filesize);
if (filename)
free(filename);
filename = NULL;
}
if (fout) { if (fout) {
if (closeit(0)) if (closeit(0))

View File

@ -33,7 +33,7 @@ install: all
@if [ "`id -un`" != "root" ] ; then \ @if [ "`id -un`" != "root" ] ; then \
echo; echo " Must be root to install!"; echo; exit 3; \ echo; echo " Must be root to install!"; echo; exit 3; \
fi fi
${INSTALL} -c -s -o `id -un` -g `id -gn` -m 6711 mbtask ${BINDIR} ${INSTALL} -c -o `id -un` -g `id -gn` -m 6755 mbtask ${BINDIR}
@if [ ! -f ${ETCDIR}/issue ]; then \ @if [ ! -f ${ETCDIR}/issue ]; then \
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 issue ${ETCDIR} ; \ ${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 issue ${ETCDIR} ; \
echo "${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 issue ${ETCDIR}"; \ echo "${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 issue ${ETCDIR}"; \

View File

@ -48,7 +48,7 @@
#include "mbtask.h" #include "mbtask.h"
#define NUM_THREADS 1 /* Max. nr of threads */ #define NUM_THREADS 2 /* Max. nr of threads */
/* /*
@ -110,7 +110,9 @@ extern int ipmailers; /* TCP/IP mail sessions */
extern int tosswait; /* Toss wait timer */ extern int tosswait; /* Toss wait timer */
extern pid_t mypid; /* Pid of daemon */ extern pid_t mypid; /* Pid of daemon */
int T_Shutdown = FALSE; /* Shutdown threads */ int T_Shutdown = FALSE; /* Shutdown threads */
int nodaemon = FALSE; /* Run in foreground */
extern int cmd_run; /* Cmd running */
extern int ping_run; /* Ping running */
/* /*
@ -118,7 +120,7 @@ int T_Shutdown = FALSE; /* Shutdown threads */
*/ */
int thr_id[NUM_THREADS]; /* thread ID's */ int thr_id[NUM_THREADS]; /* thread ID's */
pthread_t p_thread[NUM_THREADS]; /* thread's structure */ pthread_t p_thread[NUM_THREADS]; /* thread's structure */
pthread_mutex_t p_mutex = PTHREAD_MUTEX_INITIALIZER; /* Ping mutex */ // pthread_mutex_t p_mutex = PTHREAD_MUTEX_INITIALIZER; /* Ping mutex */
@ -443,33 +445,33 @@ void load_taskcfg(void)
*/ */
pid_t launch(char *cmd, char *opts, char *name, int tasktype) pid_t launch(char *cmd, char *opts, char *name, int tasktype)
{ {
char buf[PATH_MAX]; char buf[PATH_MAX], *vector[16];
char *vector[16]; int i, rc = 0;
int i, rc = 0; pid_t pid = 0;
pid_t pid = 0;
if (checktasks(0) >= MAXTASKS) { if (checktasks(0) >= MAXTASKS) {
Syslog('?', "Launch: can't execute %s, maximum tasks reached", cmd); Syslog('?', "Launch: can't execute %s, maximum tasks reached", cmd);
return 0; return 0;
} }
memset(vector, 0, sizeof(vector));
if (opts == NULL) if (opts == NULL)
sprintf(buf, "%s", cmd); sprintf(buf, "%s", cmd);
else else
sprintf(buf, "%s %s", cmd, opts); sprintf(buf, "%s %s", cmd, opts);
i = 0; i = 0;
vector[i++] = strtok(buf," \t\n\0"); vector[i++] = strtok(buf," \t\n\0");
while ((vector[i++] = strtok(NULL," \t\n")) && (i<16)); while ((vector[i++] = strtok(NULL," \t\n")) && (i<16));
vector[15] = NULL; vector[15] = NULL;
if (file_exist(vector[0], X_OK)) { if (file_exist(vector[0], X_OK)) {
Syslog('?', "Launch: can't execute %s, command not found", vector[0]); Syslog('?', "Launch: can't execute %s, command not found", vector[0]);
return 0; return 0;
} }
pid = fork(); pid = fork();
switch (pid) { switch (pid) {
case -1: case -1:
Syslog('?', "$Launch: error, can't fork grandchild"); Syslog('?', "$Launch: error, can't fork grandchild");
return 0; return 0;
@ -478,18 +480,18 @@ pid_t launch(char *cmd, char *opts, char *name, int tasktype)
(void)setsid(); /* It doesn't seem to help */ (void)setsid(); /* It doesn't seem to help */
close(0); close(0);
if (open("/dev/null", O_RDONLY) != 0) { if (open("/dev/null", O_RDONLY) != 0) {
Syslog('?', "$Launch: \"%s\": reopen of stdin to /dev/null failed", buf); Syslog('?', "$Launch: \"%s\": reopen of stdin to /dev/null failed", buf);
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
close(1); close(1);
if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) {
Syslog('?', "$Launch: \"%s\": reopen of stdout to /dev/null failed", buf); Syslog('?', "$Launch: \"%s\": reopen of stdout to /dev/null failed", buf);
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
close(2); close(2);
if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) {
Syslog('?', "$Launch: \"%s\": reopen of stderr to /dev/null failed", buf); Syslog('?', "$Launch: \"%s\": reopen of stderr to /dev/null failed", buf);
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
errno = 0; errno = 0;
rc = execv(vector[0],vector); rc = execv(vector[0],vector);
@ -498,33 +500,33 @@ pid_t launch(char *cmd, char *opts, char *name, int tasktype)
default: default:
/* grandchild's daddy's process */ /* grandchild's daddy's process */
break; break;
}
/*
* Add it to the tasklist.
*/
for (i = 0; i < MAXTASKS; i++) {
if (strlen(task[i].name) == 0) {
strcpy(task[i].name, name);
strcpy(task[i].cmd, cmd);
if (opts)
strcpy(task[i].opts, opts);
task[i].pid = pid;
task[i].status = 0;
task[i].running = TRUE;
task[i].rc = 0;
task[i].tasktype = tasktype;
break;
} }
}
/* ptimer = PAUSETIME;
* Add it to the tasklist.
*/
for (i = 0; i < MAXTASKS; i++) {
if (strlen(task[i].name) == 0) {
strcpy(task[i].name, name);
strcpy(task[i].cmd, cmd);
if (opts)
strcpy(task[i].opts, opts);
task[i].pid = pid;
task[i].status = 0;
task[i].running = TRUE;
task[i].rc = 0;
task[i].tasktype = tasktype;
break;
}
}
ptimer = PAUSETIME; if (opts)
Syslog('+', "Launch: task %d \"%s %s\" success, pid=%d", i, cmd, opts, pid);
if (opts) else
Syslog('+', "Launch: task %d \"%s %s\" success, pid=%d", i, cmd, opts, pid); Syslog('+', "Launch: task %d \"%s\" success, pid=%d", i, cmd, pid);
else return pid;
Syslog('+', "Launch: task %d \"%s\" success, pid=%d", i, cmd, pid);
return pid;
} }
@ -649,12 +651,13 @@ int checktasks(int onsig)
void die(int onsig) void die(int onsig)
{ {
int i, count; int i, count;
T_Shutdown = TRUE;
signal(onsig, SIG_IGN); signal(onsig, SIG_IGN);
if (onsig == SIGTERM) {
Syslog('+', "Starting normal shutdown"); if ((onsig == SIGTERM) || (nodaemon && (onsig == SIGINT))) {
T_Shutdown = TRUE; Syslog('+', "Starting normal shutdown (%s)", SigName[onsig]);
} else { } else {
Syslog('+', "Abnormal shutdown on signal %s", SigName[onsig]); Syslog('+', "Abnormal shutdown on signal %s", SigName[onsig]);
} }
@ -686,13 +689,28 @@ void die(int onsig)
} }
} }
if (cmd_run || ping_run)
Syslog('+', "Waiting for threads to stop");
while (cmd_run || ping_run) {
sleep(1);
}
if ((count = checktasks(0))) if ((count = checktasks(0)))
Syslog('?', "Shutdown with %d tasks still running", count); Syslog('?', "Shutdown with %d tasks still running", count);
else else
Syslog('+', "Good, no more tasks running"); Syslog('+', "Good, no more tasks running");
/*
* Free memory
*/
deinitnl(); deinitnl();
ulocktask(); ulocktask();
printable(NULL, 0);
/*
* Close socket
*/
if (sock != -1) if (sock != -1)
close(sock); close(sock);
if (ping_isocket != -1) if (ping_isocket != -1)
@ -700,6 +718,7 @@ void die(int onsig)
if (!file_exist(spath, R_OK)) { if (!file_exist(spath, R_OK)) {
unlink(spath); unlink(spath);
} }
Syslog(' ', "MBTASK finished"); Syslog(' ', "MBTASK finished");
exit(onsig); exit(onsig);
} }
@ -797,6 +816,7 @@ void ulocktask(void)
free(lockfile); free(lockfile);
return; return;
} }
if (fscanf(fp, "%u", &oldpid) != 1) { if (fscanf(fp, "%u", &oldpid) != 1) {
WriteError("$Can't read old pid from \"%s\"", lockfile); WriteError("$Can't read old pid from \"%s\"", lockfile);
fclose(fp); fclose(fp);
@ -805,6 +825,8 @@ void ulocktask(void)
return; return;
} }
fclose(fp);
if (oldpid == getpid()) { if (oldpid == getpid()) {
(void)unlink(lockfile); (void)unlink(lockfile);
} }
@ -877,16 +899,15 @@ void check_sema(void)
void scheduler(void) void scheduler(void)
{ {
struct passwd *pw; struct passwd *pw;
int running = 0, rc, i, rlen, found; int running = 0, i, found;
static int LOADhi = FALSE, oldmin = 70, olddo = 70, oldsec = 70; static int LOADhi = FALSE, oldmin = 70, olddo = 70, oldsec = 70;
char *cmd = NULL, opts[41], port[21]; char *cmd = NULL, opts[41], port[21];
static char doing[32], buf[2048]; static char doing[32];
time_t now; time_t now;
struct tm *tm, *utm; struct tm *tm, *utm;
#if defined(__linux__) #if defined(__linux__)
FILE *fp; FILE *fp;
#endif #endif
struct pollfd pfd;
int call_work = 0; int call_work = 0;
static int call_entry = MAXTASKS; static int call_entry = MAXTASKS;
double loadavg[3]; double loadavg[3];
@ -949,43 +970,16 @@ void scheduler(void)
} }
/* /*
* Install ping thread * Install threads
*/ */
thr_id[0] = pthread_create(&p_thread[0], NULL, (void (*))ping_thread, NULL); thr_id[0] = pthread_create(&p_thread[0], NULL, (void (*))ping_thread, NULL);
thr_id[1] = pthread_create(&p_thread[1], NULL, (void (*))cmd_thread, NULL);
/* /*
* Enter the mainloop (forever) * Enter the mainloop (forever)
*/ */
do { do {
/* sleep(1);
* Poll UNIX Datagram socket until the defined timeout of one second.
* This means we listen of a MBSE BBS client program has something
* to tell.
*/
pfd.fd = sock;
pfd.events = POLLIN | POLLPRI;
pfd.revents = 0;
rc = poll(&pfd, 1, 1000);
if (rc == -1) {
/*
* Poll can be interrupted by a finished child so that's not a real error.
*/
if (errno != EINTR) {
Syslog('?', "$poll() rc=%d sock=%d, events=%04x", rc, sock, pfd.revents);
}
} else if (rc) {
if (pfd.revents & POLLIN) {
/*
* Process the clients request
*/
memset(&buf, 0, sizeof(buf));
fromlen = sizeof(from);
rlen = recvfrom(sock, buf, sizeof(buf) -1, 0, (struct sockaddr *)&from, &fromlen);
do_cmd(buf);
} else {
Syslog('-', "Return poll rc=%d, events=%04x", rc, pfd.revents);
}
}
/* /*
* Check all registered connections and semafore's * Check all registered connections and semafore's
@ -1323,12 +1317,19 @@ int main(int argc, char **argv)
for (i = 0; i < NSIG; i++) { for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM)) if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM))
signal(i, (void (*))die); signal(i, (void (*))die);
else else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN); signal(i, SIG_IGN);
} }
init_pingsocket(); init_pingsocket();
/*
* Secret undocumented startup switch, ie: no help available.
*/
if ((argc == 2) && (strcmp(argv[1], "-nd") == 0)) {
nodaemon = TRUE;
}
/* /*
* mbtask is setuid root, drop privileges to user mbse. * mbtask is setuid root, drop privileges to user mbse.
* This will stay forever like this, no need to become * This will stay forever like this, no need to become
@ -1341,11 +1342,18 @@ int main(int argc, char **argv)
close(ping_isocket); close(ping_isocket);
exit(MBERR_INIT_ERROR); exit(MBERR_INIT_ERROR);
} }
/*
* If running in the foreground under valgrind the next call fails.
* Developers should know what they are doing so we are not bailing out.
*/
if (setgid(pw->pw_gid)) { if (setgid(pw->pw_gid)) {
perror(""); perror("");
fprintf(stderr, "can't setgid to bbs\n"); fprintf(stderr, "can't setgid to bbs\n");
close(ping_isocket); if (! nodaemon) {
exit(MBERR_INIT_ERROR); close(ping_isocket);
exit(MBERR_INIT_ERROR);
}
} }
umask(007); umask(007);
@ -1360,6 +1368,9 @@ int main(int argc, char **argv)
mypid = getpid(); mypid = getpid();
Syslog(' ', " "); Syslog(' ', " ");
Syslog(' ', "MBTASK v%s", VERSION); Syslog(' ', "MBTASK v%s", VERSION);
if (nodaemon)
Syslog('+', "Starting in no-daemon mode");
sprintf(tcfgfn, "%s/etc/task.data", getenv("MBSE_ROOT")); sprintf(tcfgfn, "%s/etc/task.data", getenv("MBSE_ROOT"));
load_taskcfg(); load_taskcfg();
status_init(); status_init();
@ -1381,63 +1392,71 @@ int main(int argc, char **argv)
if (!file_exist(spath, R_OK)) if (!file_exist(spath, R_OK))
unlink(spath); unlink(spath);
/* if (nodaemon) {
* Server initialization is complete. Now we can fork the /*
* daemon and return to the user. We need to do a setpgrp * For debugging, run in foreground mode
* so that the daemon will no longer be assosiated with the */
* users control terminal. This is done before the fork, so mypid = getpid();
* that the child will not be a process group leader. Otherwise, scheduler();
* if the child were to open a terminal, it would become } else {
* associated with that terminal as its control terminal. /*
*/ * Server initialization is complete. Now we can fork the
if ((pgrp = setpgid(0, 0)) == -1) { * daemon and return to the user. We need to do a setpgrp
Syslog('?', "$setpgid failed"); * so that the daemon will no longer be assosiated with the
die(MBERR_INIT_ERROR); * users control terminal. This is done before the fork, so
} * that the child will not be a process group leader. Otherwise,
* if the child were to open a terminal, it would become
* associated with that terminal as its control terminal.
*/
if ((pgrp = setpgid(0, 0)) == -1) {
Syslog('?', "$setpgid failed");
die(MBERR_INIT_ERROR);
}
frk = fork(); frk = fork();
switch (frk) { switch (frk) {
case -1: case -1:
Syslog('?', "$Unable to fork daemon"); Syslog('?', "$Unable to fork daemon");
die(MBERR_INIT_ERROR); die(MBERR_INIT_ERROR);
case 0: case 0:
/* /*
* Starting the deamon child process here. * Starting the deamon child process here.
*/ */
fclose(stdin); fclose(stdin);
if (open("/dev/null", O_RDONLY) != 0) { if (open("/dev/null", O_RDONLY) != 0) {
Syslog('?', "$Reopen of stdin to /dev/null failed"); Syslog('?', "$Reopen of stdin to /dev/null failed");
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
fclose(stdout); fclose(stdout);
if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) {
Syslog('?', "$Reopen of stdout to /dev/null failed"); Syslog('?', "$Reopen of stdout to /dev/null failed");
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
fclose(stderr); fclose(stderr);
if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) {
Syslog('?', "$Reopen of stderr to /dev/null failed"); Syslog('?', "$Reopen of stderr to /dev/null failed");
_exit(MBERR_EXEC_FAILED); _exit(MBERR_EXEC_FAILED);
} }
mypid = getpid(); mypid = getpid();
scheduler(); scheduler();
/* Not reached */ /* Not reached */
default: default:
/* /*
* Here we detach this process and let the child * Here we detach this process and let the child
* run the deamon process. Put the child's pid * run the deamon process. Put the child's pid
* in the lockfile before leaving. * in the lockfile before leaving.
*/ */
lockfile = calloc(PATH_MAX, sizeof(char)); lockfile = calloc(PATH_MAX, sizeof(char));
sprintf(lockfile, "%s/var/run/mbtask", pw->pw_dir); sprintf(lockfile, "%s/var/run/mbtask", pw->pw_dir);
if ((fp = fopen(lockfile, "w"))) { if ((fp = fopen(lockfile, "w"))) {
fprintf(fp, "%10u\n", frk); fprintf(fp, "%10u\n", frk);
fclose(fp); fclose(fp);
} }
free(lockfile); free(lockfile);
Syslog('+', "Starting daemon with pid %d", frk); Syslog('+', "Starting daemon with pid %d", frk);
pthread_exit(NULL); pthread_exit(NULL);
exit(MBERR_OK); exit(MBERR_OK);
}
} }
/* /*

View File

@ -620,6 +620,9 @@ int each(faddr *addr, char flavor, int isflo, char *fname)
sprintf((*tmp)->addr.domain, "%s", addr->domain); sprintf((*tmp)->addr.domain, "%s", addr->domain);
if (nlent->addr.domain) if (nlent->addr.domain)
free(nlent->addr.domain); free(nlent->addr.domain);
if (nlent->url)
free(nlent->url);
nlent->url = NULL;
(*tmp)->flavors = 0; (*tmp)->flavors = 0;
if (nlent->pflag != NL_DUMMY) { if (nlent->pflag != NL_DUMMY) {
(*tmp)->olflags = nlent->oflags; (*tmp)->olflags = nlent->oflags;

View File

@ -48,6 +48,7 @@ extern int internet; /* Internet is down */
extern int rescan; /* Master rescan flag */ extern int rescan; /* Master rescan flag */
struct in_addr paddr; /* Current ping address */ struct in_addr paddr; /* Current ping address */
extern int T_Shutdown; /* Program shutdown */ extern int T_Shutdown; /* Program shutdown */
int ping_run = FALSE; /* Thread runnning */
@ -244,7 +245,7 @@ int ping_send(struct in_addr addr)
int ping_receive(struct in_addr addr) int ping_receive(struct in_addr addr)
{ {
char buf[1024]; char buf[1024];
int len; int rc, len;
struct sockaddr_in ffrom; struct sockaddr_in ffrom;
struct icmphdr icmpp; struct icmphdr icmpp;
struct iphdr iph; struct iphdr iph;
@ -253,15 +254,17 @@ int ping_receive(struct in_addr addr)
pfd.fd = ping_isocket; pfd.fd = ping_isocket;
pfd.events = POLLIN; pfd.events = POLLIN;
pfd.revents = 0;
/* /*
* 100 mSec is enough, this function is called at regular intervals. * 100 mSec is enough, this function is called at regular intervals.
*/ */
if (poll(&pfd, 1, 100) < 0) { if ((rc = poll(&pfd, 1, 100) < 0)) {
if (icmp_errs < ICMP_MAX_ERRS) if (icmp_errs < ICMP_MAX_ERRS)
Syslog('?', "$poll/select failed"); Syslog('?', "$poll/select failed");
return -3; return -3;
} }
// Syslog('p', "poll_thread: poll interrupted rc=%d events=%04x", rc, pfd.revents);
if (pfd.revents & POLLIN || pfd.revents & POLLERR || pfd.revents & POLLHUP || pfd.revents & POLLNVAL) { if (pfd.revents & POLLIN || pfd.revents & POLLERR || pfd.revents & POLLHUP || pfd.revents & POLLNVAL) {
sl = sizeof(ffrom); sl = sizeof(ffrom);
@ -339,6 +342,7 @@ void *ping_thread(void)
pingresult[1] = pingresult[2] = FALSE; pingresult[1] = pingresult[2] = FALSE;
pingnr = 2; pingnr = 2;
internet = FALSE; internet = FALSE;
ping_run = TRUE;
while (! T_Shutdown) { while (! T_Shutdown) {
@ -438,6 +442,7 @@ void *ping_thread(void)
} }
} }
ping_run = FALSE;
Syslog('+', "Ping thread stopped"); Syslog('+', "Ping thread stopped");
pthread_exit(NULL); pthread_exit(NULL);
} }

View File

@ -86,6 +86,7 @@ void fill_portlist(pp_list **fdp, pp_list *new)
pp_list *tmp, *ta; pp_list *tmp, *ta;
tmp = (pp_list *)malloc(sizeof(pp_list)); tmp = (pp_list *)malloc(sizeof(pp_list));
memset(tmp, 0, sizeof(tmp));
tmp->next = NULL; tmp->next = NULL;
strncpy(tmp->tty, new->tty, 6); strncpy(tmp->tty, new->tty, 6);
tmp->mflags = new->mflags; tmp->mflags = new->mflags;

View File

@ -45,6 +45,9 @@ extern int sock; /* Server socket */
extern struct sockaddr_un from; /* From socket address */ extern struct sockaddr_un from; /* From socket address */
extern int fromlen; /* From address length */ extern int fromlen; /* From address length */
extern int logtrans; /* Log transactions */ extern int logtrans; /* Log transactions */
extern int T_Shutdown; /* Program shutdown */
int cmd_run = FALSE;/* cmd running */
/************************************************************************ /************************************************************************
@ -543,6 +546,7 @@ char *exe_cmd(char *in)
void do_cmd(char *);
void do_cmd(char *cmd) void do_cmd(char *cmd)
{ {
char buf[SS_BUFSIZE]; char buf[SS_BUFSIZE];
@ -570,3 +574,55 @@ void do_cmd(char *cmd)
} }
/*
* Thread that reads the command socket for new commands.
*/
void *cmd_thread(void)
{
int rlen, rc;
struct pollfd pfd;
static char buf[2048];
Syslog('+', "Starting cmd thread with pid %d", (int)getpid());
cmd_run = TRUE;
while (! T_Shutdown) {
/*
* Poll UNIX Datagram socket until the defined timeout of one second.
* This means we listen of a MBSE BBS client program has something
* to tell.
*/
pfd.fd = sock;
pfd.events = POLLIN;
pfd.revents = 0;
rc = poll(&pfd, 1, 1000);
// Syslog('c', "cmd_thread: poll interrupted rc=%d events=%04x", rc, pfd.revents);
if (rc == -1) {
/*
* Poll can be interrupted by a finished child so that's not a real error.
*/
// if (errno != EINTR) {
Syslog('?', "$poll() rc=%d sock=%d, events=%04x", rc, sock, pfd.revents);
// }
} else if (rc) {
if (pfd.revents & POLLIN) {
/*
* Process the clients request
*/
memset(&buf, 0, sizeof(buf));
fromlen = sizeof(from);
rlen = recvfrom(sock, buf, sizeof(buf) -1, 0, (struct sockaddr *)&from, &fromlen);
do_cmd(buf);
} else {
Syslog('-', "Return poll rc=%d, events=%04x", rc, pfd.revents);
}
}
}
cmd_run = FALSE;
Syslog('+', "Cmd thread stopped");
pthread_exit(NULL);
}

View File

@ -3,8 +3,7 @@
/* $Id$ */ /* $Id$ */
void *cmd_thread(void);
void do_cmd(char *);
#endif #endif

View File

@ -559,10 +559,10 @@ char *printable(char *s, int l)
if (len > -l) if (len > -l)
len=-l; len=-l;
} }
pbuff=(char*)xmalloc(len*4+1); pbuff=(char*)xmalloc(len*3+1);
p=pbuff; p=pbuff;
while (len--) { while (len--) {
if (*(unsigned char*)s >= ' ') if (isprint(*(unsigned char*)s))
*p++=*s; *p++=*s;
else switch (*s) { else switch (*s) {
case '\\': *p++='\\'; *p++='\\'; break; case '\\': *p++='\\'; *p++='\\'; break;
@ -570,7 +570,7 @@ char *printable(char *s, int l)
case '\n': *p++='\\'; *p++='n'; break; case '\n': *p++='\\'; *p++='n'; break;
case '\t': *p++='\\'; *p++='t'; break; case '\t': *p++='\\'; *p++='t'; break;
case '\b': *p++='\\'; *p++='b'; break; case '\b': *p++='\\'; *p++='b'; break;
default: sprintf(p,"\\%03o",*s); p+=4; break; default: sprintf(p,"\\%02x", (*s & 0xff)); p+=3; break;
} }
s++; s++;
} }