Commit 3652f1ba authored by rswindell's avatar rswindell
Browse files

Added support for ctrl/services.ini (in addition-to/instead-of services.cfg).

The SERVICE_OPT_LOOP option flag now works for native static services.
New service option flag: SERVICE_OPT_NATIVE used to denote native (non-JS)
services, rather than the crude method of searching for ".js" in the cmdline.
parent aa27e580
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include "sbbs.h" #include "sbbs.h"
#include "services.h" #include "services.h"
#include "ident.h" /* identify() */ #include "ident.h" /* identify() */
#include "ini_file.h"
/* Constants */ /* Constants */
...@@ -97,6 +98,20 @@ typedef struct { ...@@ -97,6 +98,20 @@ typedef struct {
BOOL terminated; BOOL terminated;
} service_t; } service_t;
static ini_bitdesc_t service_options[] = {
{ BBS_OPT_NO_HOST_LOOKUP ,"NO_HOST_LOOKUP" },
{ BBS_OPT_GET_IDENT ,"GET_IDENT" },
{ BBS_OPT_NO_RECYCLE ,"NO_RECYCLE" },
{ BBS_OPT_MUTE ,"MUTE" },
{ SERVICE_OPT_UDP ,"UDP" },
{ SERVICE_OPT_STATIC ,"STATIC" },
{ SERVICE_OPT_STATIC_LOOP ,"LOOP" },
{ SERVICE_OPT_NATIVE ,"NATIVE" },
/* terminator */
{ -1 ,NULL }
};
typedef struct { typedef struct {
SOCKET socket; SOCKET socket;
SOCKADDR_IN addr; SOCKADDR_IN addr;
...@@ -110,7 +125,7 @@ typedef struct { ...@@ -110,7 +125,7 @@ typedef struct {
int udp_len; int udp_len;
} service_client_t; } service_client_t;
static service_t *service; static service_t *service=NULL;
static DWORD services=0; static DWORD services=0;
static int lprintf(char *fmt, ...) static int lprintf(char *fmt, ...)
...@@ -1070,8 +1085,10 @@ static void native_static_service_thread(void* arg) ...@@ -1070,8 +1085,10 @@ static void native_static_service_thread(void* arg)
else else
strcpy(cmd,service->cmd); strcpy(cmd,service->cmd);
sprintf(fullcmd,cmd,socket_dup); sprintf(fullcmd,cmd,socket_dup);
system(fullcmd); do {
system(fullcmd);
} while(!service->terminated && service->options&SERVICE_OPT_STATIC_LOOP);
thread_down(); thread_down();
lprintf("%04d %s static service thread terminated (%lu clients served)" lprintf("%04d %s static service thread terminated (%lu clients served)"
...@@ -1232,18 +1249,16 @@ void DLLCALL services_terminate(void) ...@@ -1232,18 +1249,16 @@ void DLLCALL services_terminate(void)
#define NEXT_FIELD(p) while(*p && *p>' ') p++; while(*p && *p<=' ') p++; #define NEXT_FIELD(p) while(*p && *p>' ') p++; while(*p && *p<=' ') p++;
static service_t* read_services_cfg(char* services_cfg, DWORD* services) static service_t* read_services_cfg(service_t* service, char* services_cfg, DWORD* services)
{ {
char* p; char* p;
char* tp; char* tp;
char line[1024]; char line[1024];
FILE* fp; FILE* fp;
service_t* service=NULL; service_t* np;
if((fp=fopen(services_cfg,"r"))==NULL) { if((fp=fopen(services_cfg,"r"))==NULL)
lprintf("!ERROR %d opening %s",errno,services_cfg); return(service);
return(NULL);
}
lprintf("Reading %s",services_cfg); lprintf("Reading %s",services_cfg);
for((*services)=0;!feof(fp) && (*services)<MAX_SERVICES;) { for((*services)=0;!feof(fp) && (*services)<MAX_SERVICES;) {
...@@ -1254,10 +1269,11 @@ static service_t* read_services_cfg(char* services_cfg, DWORD* services) ...@@ -1254,10 +1269,11 @@ static service_t* read_services_cfg(char* services_cfg, DWORD* services)
if(*p==0 || *p==';') /* ignore blank lines or comments */ if(*p==0 || *p==';') /* ignore blank lines or comments */
continue; continue;
if((service=(service_t*)realloc(service,sizeof(service_t)*((*services)+1)))==NULL) { if((np=(service_t*)realloc(service,sizeof(service_t)*((*services)+1)))==NULL) {
lprintf("!MALLOC FAILURE"); lprintf("!MALLOC FAILURE");
return(FALSE); return(service);
} }
service=np;
memset(&service[*services],0,sizeof(service_t)); memset(&service[*services],0,sizeof(service_t));
service[*services].socket=INVALID_SOCKET; service[*services].socket=INVALID_SOCKET;
...@@ -1284,6 +1300,53 @@ static service_t* read_services_cfg(char* services_cfg, DWORD* services) ...@@ -1284,6 +1300,53 @@ static service_t* read_services_cfg(char* services_cfg, DWORD* services)
return(service); return(service);
} }
static service_t* read_services_ini(service_t* service, char* services_ini, DWORD* services)
{
uint i,j;
FILE* fp;
char cmd[MAX_LINE_LEN+1];
char** sec_list;
service_t* np;
service_t serv;
if((fp=fopen(services_ini,"r"))==NULL)
return(service);
lprintf("Reading %s",services_ini);
sec_list = iniGetSectionList(fp,"");
for(i=0; sec_list!=NULL && sec_list[i]!=NULL; i++) {
memset(&serv,0,sizeof(service_t));
SAFECOPY(serv.protocol,sec_list[i]);
serv.socket=INVALID_SOCKET;
serv.port=iniGetShortInt(fp,sec_list[i],"Port",0);
serv.max_clients=iniGetInteger(fp,sec_list[i],"MaxClients",0);
serv.options=iniGetBitField(fp,sec_list[i],"Options",service_options,0);
SAFECOPY(serv.cmd,iniGetString(fp,sec_list[i],"Command","",cmd));
for(j=0;j<*services;j++)
if(service[j].port==serv.port && service[j].options==serv.options)
break;
if(j<*services) { /* ignore duplicate services */
lprintf("Ignoring duplicate service: %s",sec_list[i]);
continue;
}
if((np=(service_t*)realloc(service,sizeof(service_t)*((*services)+1)))==NULL) {
fclose(fp);
lprintf("!MALLOC FAILURE");
return(service);
}
service=np;
service[*services]=serv;
(*services)++;
}
iniFreeStringList(sec_list);
fclose(fp);
return(service);
}
static void cleanup(int code) static void cleanup(int code)
{ {
free_cfg(&scfg); free_cfg(&scfg);
...@@ -1446,12 +1509,20 @@ void DLLCALL services_thread(void* arg) ...@@ -1446,12 +1509,20 @@ void DLLCALL services_thread(void* arg)
if(startup->cfg_file[0]==0) if(startup->cfg_file[0]==0)
sprintf(startup->cfg_file,"%sservices.cfg",scfg.ctrl_dir); sprintf(startup->cfg_file,"%sservices.cfg",scfg.ctrl_dir);
if((service=read_services_cfg(startup->cfg_file, &services))==NULL) { service=read_services_cfg(service, startup->cfg_file, &services);
lprintf("!Failure reading configuration file");
if(startup->ini_file[0]==0)
sprintf(startup->ini_file,"%sservices.ini",scfg.ctrl_dir);
service=read_services_ini(service, startup->ini_file, &services);
if(service==NULL) {
lprintf("!Failure reading configuration file (%s or %s)"
,startup->cfg_file,startup->ini_file);
cleanup(1); cleanup(1);
return; return;
} }
/* Open and Bind Listening Sockets */ /* Open and Bind Listening Sockets */
total_sockets=0; total_sockets=0;
for(i=0;i<(int)services;i++) { for(i=0;i<(int)services;i++) {
...@@ -1537,10 +1608,10 @@ void DLLCALL services_thread(void* arg) ...@@ -1537,10 +1608,10 @@ void DLLCALL services_thread(void* arg)
/* start thread here */ /* start thread here */
SAFECOPY(cmd,service[i].cmd); SAFECOPY(cmd,service[i].cmd);
strlwr(cmd); strlwr(cmd);
if(strstr(cmd,".js")) /* JavaScript */ if(service[i].options&SERVICE_OPT_NATIVE) /* Native */
_beginthread(js_static_service_thread, 0, &service[i]);
else /* Native */
_beginthread(native_static_service_thread, 0, &service[i]); _beginthread(native_static_service_thread, 0, &service[i]);
else /* JavaScript */
_beginthread(js_static_service_thread, 0, &service[i]);
} }
/* signal caller that we've started up successfully */ /* signal caller that we've started up successfully */
...@@ -1785,10 +1856,10 @@ void DLLCALL services_thread(void* arg) ...@@ -1785,10 +1856,10 @@ void DLLCALL services_thread(void* arg)
SAFECOPY(cmd,service[i].cmd); SAFECOPY(cmd,service[i].cmd);
strlwr(cmd); strlwr(cmd);
if(strstr(cmd,".js")) /* JavaScript */ if(service[i].options&SERVICE_OPT_NATIVE) /* Native */
_beginthread(js_service_thread, 0, client);
else /* Native */
_beginthread(native_service_thread, 0, client); _beginthread(native_service_thread, 0, client);
else /* JavaScript */
_beginthread(js_service_thread, 0, client);
service[i].served++; service[i].served++;
served++; served++;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment