Merge remote-tracking branch 'origin/websrv2' into integration_2022_wk50
This commit is contained in:
@@ -19,8 +19,8 @@ in `telnetsrv.h`
|
||||
*/
|
||||
static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
static telnetshell_cmddef_t coding_cmdarray[] = {
|
||||
{"mode","[sse,avx2,stdc,none]",coding_setmod_cmd},
|
||||
{"","",NULL},
|
||||
{"mode", "[sse,avx2,stdc,none]", coding_setmod_cmd, {NULL}, 0, NULL},
|
||||
{"", "", NULL, {NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -109,8 +109,24 @@ The telnet server is dynamically loaded, to use the `add_telnetcmd` function, t
|
||||
|
||||
| Fields | type |Description |
|
||||
|:-----------|:------:|:-----------------------|
|
||||
| `cmdname` | `char[TELNET_CMD_MAXSIZE]` | command name, as tested by the telnet server to check it should call the `cmdfunc` function |
|
||||
| `helpstr` | `char[TELNET_HELPSTR_SIZE]` | character string to print when the elp`command is received from the telnet client |
|
||||
| `cmdfunc` | `cmdfunc_t` | pointer to the function implementing the `cmdname` sub command. |
|
||||
| `cmdname` | `char[TELNET_CMD_MAXSIZE]` | command name, as tested by the telnet server or web server to check it should call the `cmdfunc` or `webfunc` function |
|
||||
| `helpstr` | `char[TELNET_HELPSTR_SIZE]` | character string to print when the help`command is received from the telnet client |
|
||||
| `cmdfunc` | `cmdfunc_t` | pointer to the function implementing the `cmdname` telnet or web server sub command. |
|
||||
| `webfunc` | `webfunc_t` or `webfunc_getdata_t` | pointer to the function implementing the `cmdname` web server sub command. |
|
||||
| `cmdflags` | unsigned int bit mask | possible bits are defined in the next table |
|
||||
| `qptr` | pointer to a thread pool queue | when `TELNETSRV_CMDFLAG_PUSHINTPOOLQ` bit is set in `cmdflags` , contains the queue where the command is pushed|
|
||||
|
||||
### `cmdflags ` bit definitions
|
||||
These flags possibly modify the way the `telnetshell_cmddef_t` structure is used by the telnet server and/or the web server
|
||||
|
||||
| Fields | Description |
|
||||
|:------------------------------------:|:-----------------------|
|
||||
| TELNETSRV_CMDFLAG_PUSHINTPOOLQ | function defined in `cmdfunc` field is pushed in a thread pool queue instead of beeing executed synchronously. The queue is created by the telnet server code in the `add_telnetcmd` function|
|
||||
| TELNETSRV_CMDFLAG_GETWEBTBLDATA | web server will use the `webfunc_getdata_t` version of the `webfunc` union. command results are written in a `webdatadef_t` structure instead of being printed |
|
||||
| TELNETSRV_CMDFLAG_TELNETONLY | this command definition is only for the telnet server, web server is ignoring it |
|
||||
| TELNETSRV_CMDFLAG_WEBSRVONLY | this command definition is only for the web server, telnet server is ignoring it |
|
||||
| TELNETSRV_CMDFLAG_CONFEXEC | Currently only used by the web server, command execution has to be confirmed by user |
|
||||
| TELNETSRV_CMDFLAG_NEEDPARAM | Currently only used by the web server, user must provide a parameter before command execution |
|
||||
| TELNETSRV_CMDFLAG_WEBSRV_SETRETURNTBL | Currently only used by the web server, when a parameter modification requires a new page |
|
||||
| TELNETSRV_CMDFLAG_AUTOUPDATE | Currently only used by the web server, the command can be rescheduled for result update |
|
||||
[oai telnet server home](telnetsrv.md)
|
||||
|
||||
+249
-191
@@ -67,51 +67,53 @@ static telnetsrv_params_t telnetparams;
|
||||
#define TELNETSRV_OPTNAME_SHRMOD "shrmod"
|
||||
|
||||
paramdef_t telnetoptions[] = {
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* configuration parameters for telnet utility */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{"listenaddr", "<listen ip address>\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 },
|
||||
{"listenport", "<local port>\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 },
|
||||
{"listenstdin", "enable input from stdin\n", PARAMFLAG_BOOL, uptr:&(telnetparams.listenstdin), defuintval:0, TYPE_UINT, 0 },
|
||||
{"priority", "<scheduling policy (0-99)\n", 0, iptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 },
|
||||
{"debug", "<debug level>\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 },
|
||||
{"loopcount", "<loop command iterations>\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 },
|
||||
{"loopdelay", "<loop command delay (ms)>\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
|
||||
{"histfile", "<history file name>\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
|
||||
{"histsize", "<history sizes>\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
|
||||
{"phypbsize", "<phy dump buff size (bytes)>\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
|
||||
{TELNETSRV_OPTNAME_STATICMOD, "<static modules selection>\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
|
||||
{TELNETSRV_OPTNAME_SHRMOD, "<dynamic modules selection>\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
|
||||
};
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* configuration parameters for telnet utility */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{"listenaddr", "<listen ip address>\n", 0, uptr : &telnetparams.listenaddr, defstrval : "0.0.0.0", TYPE_IPV4ADDR, 0},
|
||||
{"listenport", "<local port>\n", 0, uptr : &(telnetparams.listenport), defuintval : 9090, TYPE_UINT, 0},
|
||||
{"listenstdin", "enable input from stdin\n", PARAMFLAG_BOOL, uptr : &(telnetparams.listenstdin), defuintval : 0, TYPE_UINT, 0},
|
||||
{"priority", "<scheduling policy (0-99)\n", 0, iptr : &telnetparams.priority, defuintval : 0, TYPE_INT, 0},
|
||||
{"debug", "<debug level>\n", 0, uptr : NULL, defuintval : 0, TYPE_UINT, 0},
|
||||
{"loopcount", "<loop command iterations>\n", 0, uptr : &(telnetparams.loopcount), defuintval : 10, TYPE_UINT, 0},
|
||||
{"loopdelay", "<loop command delay (ms)>\n", 0, uptr : &(telnetparams.loopdelay), defuintval : 5000, TYPE_UINT, 0},
|
||||
{"histfile", "<history file name>\n", PARAMFLAG_NOFREE, strptr : &(telnetparams.histfile), defstrval : "oaitelnet.history", TYPE_STRING, 0},
|
||||
{"histsize", "<history sizes>\n", 0, iptr : &(telnetparams.histsize), defuintval : 50, TYPE_INT, 0},
|
||||
{"logfile", "log file when redirecting", PARAMFLAG_NOFREE, strptr : &(telnetparams.logfile), defstrval : "oaisoftmodem.log", TYPE_STRING, 0},
|
||||
{"phypbsize", "<phy dump buff size (bytes)>\n", 0, uptr : &(telnetparams.phyprntbuff_size), defuintval : 65000, TYPE_UINT, 0},
|
||||
{TELNETSRV_OPTNAME_STATICMOD, "<static modules selection>\n", 0, strlistptr : NULL, defstrlistval : telnet_defstatmod, TYPE_STRINGLIST, (sizeof(telnet_defstatmod) / sizeof(char *))},
|
||||
{TELNETSRV_OPTNAME_SHRMOD, "<dynamic modules selection>\n", 0, strlistptr : NULL, defstrlistval : NULL, TYPE_STRINGLIST, 0}};
|
||||
|
||||
int get_phybsize(void) {
|
||||
return telnetparams.phyprntbuff_size;
|
||||
};
|
||||
int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd );
|
||||
int setoutput(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int wsetoutput(char *buff, int debug, telnet_printfunc_t prnt, ...);
|
||||
int setparam(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ...);
|
||||
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
|
||||
telnetshell_vardef_t telnet_vardef[] = {
|
||||
{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg},
|
||||
{"prio",TELNET_VARTYPE_INT32,&telnetparams.priority},
|
||||
{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount},
|
||||
{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay},
|
||||
{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size},
|
||||
{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize},
|
||||
{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile},
|
||||
{"",0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t telnet_vardef[] = {{"debug", TELNET_VARTYPE_INT32, 0, &telnetparams.telnetdbg},
|
||||
{"prio", TELNET_VARTYPE_INT32, 0, &telnetparams.priority},
|
||||
{"loopc", TELNET_VARTYPE_INT32, 0, &telnetparams.loopcount},
|
||||
{"loopd", TELNET_VARTYPE_INT32, 0, &telnetparams.loopdelay},
|
||||
{"phypb", TELNET_VARTYPE_INT32, 0, &telnetparams.phyprntbuff_size},
|
||||
{"hsize", TELNET_VARTYPE_INT32, 0, &telnetparams.histsize},
|
||||
{"hfile", TELNET_VARTYPE_STRING, TELNET_CHECKVAL_RDONLY, &telnetparams.histfile},
|
||||
{"logfile", TELNET_VARTYPE_STRING, 0, &telnetparams.logfile},
|
||||
{"", 0, 0, NULL}};
|
||||
|
||||
telnetshell_cmddef_t telnet_cmdarray[] = {
|
||||
{"redirlog","[here,file,off]",setoutput},
|
||||
{"param","[prio]",setparam},
|
||||
{"history","[list,reset]",history_cmd},
|
||||
{"","",NULL},
|
||||
telnetshell_cmddef_t telnet_cmdarray[] = {
|
||||
{"redirlog", "[here,file,off]", setoutput, {NULL}, TELNETSRV_CMDFLAG_TELNETONLY, NULL},
|
||||
{"redirlog file", "", setoutput, {NULL}, TELNETSRV_CMDFLAG_WEBSRVONLY, NULL},
|
||||
{"redirlog off", "", setoutput, {NULL}, TELNETSRV_CMDFLAG_WEBSRVONLY, NULL},
|
||||
{"param", "[prio]", setparam, {wsetparam}, 0, NULL},
|
||||
{"history", "[list,reset]", history_cmd, {NULL}, TELNETSRV_CMDFLAG_TELNETONLY, NULL},
|
||||
{"", "", NULL, {NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
|
||||
void client_printf(const char *message, ...) {
|
||||
va_list va_args;
|
||||
va_start(va_args, message);
|
||||
@@ -127,36 +129,39 @@ void client_printf(const char *message, ...) {
|
||||
return ;
|
||||
}
|
||||
|
||||
#define NICE_MAX 19
|
||||
#define NICE_MIN -20
|
||||
void set_sched(pthread_t tid, int pid, int priority) {
|
||||
int rt;
|
||||
struct sched_param schedp;
|
||||
int policy;
|
||||
char strpolicy[10];
|
||||
int niceval = 0;
|
||||
|
||||
//sched_get_priority_max(SCHED_FIFO)
|
||||
if (priority < NICE_MIN) {
|
||||
if (priority < -100 && priority > -200) { // RR priority 1 to 99 (high) mapped to oai priority -101 to -199 (high)
|
||||
policy = SCHED_RR;
|
||||
sprintf(strpolicy, "%s", "RR");
|
||||
schedp.sched_priority = -(priority + 100);
|
||||
} else if (priority < 0 && priority > -100) {
|
||||
policy=SCHED_FIFO;
|
||||
sprintf(strpolicy,"%s","fifo");
|
||||
schedp.sched_priority= NICE_MIN - priority ;
|
||||
|
||||
if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) ||
|
||||
(schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) {
|
||||
client_printf("Error: %i invalid prio, should be %i to %i, \n",
|
||||
priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO),
|
||||
NICE_MIN - sched_get_priority_max(SCHED_FIFO) );
|
||||
}
|
||||
} else if (priority > NICE_MAX) {
|
||||
schedp.sched_priority = -priority; // fifo priority 1 to 99 (high) mapped to oai priority -1 to -99 (high)
|
||||
} else if (priority >= 0 && priority <= (NICE_MAX - NICE_MIN)) { // other (normal) nice value -20 to 19 mapped to oai priority 0 to 39
|
||||
policy = SCHED_OTHER;
|
||||
sprintf(strpolicy, "%s", "other");
|
||||
schedp.sched_priority = 0;
|
||||
niceval = priority + NICE_MIN;
|
||||
} else if (priority > NICE_MAX - NICE_MIN && priority <= (2 * (NICE_MAX - NICE_MIN) + 1)) { // batch (normal) nice value -20 to 19 mapped to oai priority 40 to 79
|
||||
policy = SCHED_BATCH;
|
||||
sprintf(strpolicy, "%s", "batch");
|
||||
niceval = priority + NICE_MIN - (NICE_MAX - NICE_MIN + 1);
|
||||
schedp.sched_priority = 0;
|
||||
} else if (priority > (2 * (NICE_MAX - NICE_MIN) + 1)) { // idle mapped to oai priority >79
|
||||
policy=SCHED_IDLE;
|
||||
sprintf(strpolicy,"%s","idle");
|
||||
schedp.sched_priority=0;
|
||||
} else {
|
||||
policy=SCHED_OTHER;
|
||||
sprintf(strpolicy,"%s","other");
|
||||
schedp.sched_priority=0;
|
||||
client_printf("Error: %i invalid priority \n", priority);
|
||||
return;
|
||||
}
|
||||
|
||||
if( tid != 0) {
|
||||
rt = pthread_setschedparam(tid, policy, &schedp);
|
||||
} else if(pid > 0) {
|
||||
@@ -172,15 +177,14 @@ void set_sched(pthread_t tid, int pid, int priority) {
|
||||
} else {
|
||||
client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
|
||||
|
||||
if ( policy==SCHED_OTHER) {
|
||||
if (policy == SCHED_OTHER || policy == SCHED_BATCH) {
|
||||
rt = getpriority(PRIO_PROCESS,tid);
|
||||
|
||||
if (rt != -1) {
|
||||
rt = setpriority(PRIO_PROCESS,tid,priority);
|
||||
rt = setpriority(PRIO_PROCESS, tid, niceval);
|
||||
|
||||
if (rt < 0) {
|
||||
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n",
|
||||
errno,strerror(errno),tid,priority);
|
||||
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n", errno, strerror(errno), tid, niceval);
|
||||
}
|
||||
} else {
|
||||
client_printf("Error %i: %s trying to get nice value of thread %u \n",
|
||||
@@ -189,17 +193,17 @@ void set_sched(pthread_t tid, int pid, int priority) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( policy == SCHED_OTHER) {
|
||||
if (policy == SCHED_OTHER || policy == SCHED_BATCH) {
|
||||
if ( tid > 0 && tid != pthread_self()) {
|
||||
client_printf("setting nice value using a thread id not implemented....\n");
|
||||
} else if (pid > 0) {
|
||||
errno=0;
|
||||
rt = setpriority(PRIO_PROCESS,pid,priority);
|
||||
rt = setpriority(PRIO_PROCESS, pid, niceval);
|
||||
|
||||
if (rt != 0) {
|
||||
client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno));
|
||||
} else {
|
||||
client_printf("nice value set to %i\n",priority);
|
||||
client_printf("nice value set to %i\n", niceval);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,20 +240,30 @@ void redirstd(char *newfname,telnet_printfunc_t prnt ) {
|
||||
fd=freopen(newfname, "w", stdout);
|
||||
|
||||
if (fd == NULL) {
|
||||
prnt("ERROR: stdout redir to %s error %s",strerror(errno));
|
||||
prnt("ERROR: stdout redir to %s error %s\n", strerror(errno));
|
||||
} else {
|
||||
prnt("stdout redirected to %s\n", newfname);
|
||||
}
|
||||
|
||||
fd=freopen(newfname, "w", stderr);
|
||||
|
||||
if (fd == NULL) {
|
||||
prnt("ERROR: stderr redir to %s error %s",strerror(errno));
|
||||
prnt("ERROR: stderr redir to %s error %s\n", strerror(errno));
|
||||
} else {
|
||||
prnt("stderr redirected to %s\n", newfname);
|
||||
}
|
||||
}
|
||||
|
||||
int wsetoutput(char *buffer, int debug, telnet_printfunc_t prnt, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
|
||||
char *logfname;
|
||||
char stdout_str[64];
|
||||
#define LOGFILE "logfile.log"
|
||||
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
|
||||
|
||||
@@ -265,10 +279,10 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
|
||||
if (strncasecmp(cmds[0],"file",4) == 0) {
|
||||
if (cmds[1][0] == 0)
|
||||
logfname=LOGFILE;
|
||||
logfname = telnetparams.logfile;
|
||||
else
|
||||
logfname=cmds[1];
|
||||
|
||||
prnt("Log output redirected to (%s)\n", logfname);
|
||||
fflush(stdout);
|
||||
redirstd(logfname,prnt);
|
||||
}
|
||||
@@ -281,6 +295,11 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
return CMDSTATUS_FOUND;
|
||||
} /* setoutput */
|
||||
|
||||
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setparam(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
|
||||
memset(cmds,0,sizeof(cmds));
|
||||
@@ -344,94 +363,120 @@ int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
|
||||
/*
|
||||
generic commands available for all modules loaded by the server
|
||||
*/
|
||||
char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex)
|
||||
{
|
||||
char *val;
|
||||
switch (var[varindex].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
val = malloc(64);
|
||||
snprintf(val, 64, "%i", *(int32_t *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
int setgetvar(int moduleindex,char getorset,char *params) {
|
||||
int n,i;
|
||||
case TELNET_VARTYPE_INT64:
|
||||
val = malloc(128);
|
||||
snprintf(val, 128, "%lli", (long long)*(int64_t *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
val = malloc(16);
|
||||
snprintf(val, 16, "%hi", *(short *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
val = malloc(16);
|
||||
snprintf(val, 16, "%i", (int)(*(int8_t *)(var[varindex].varvalptr)));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
val = malloc(64);
|
||||
snprintf(val, 64, "%u", *(unsigned int *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
val = malloc(32);
|
||||
snprintf(val, 32, "%g\n", *(double *)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
val = strdup(*(char **)(var[varindex].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
val = malloc(64);
|
||||
snprintf(val, 64, "ERR:var %i unknown type", varindex);
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
int telnet_setvarvalue(telnetshell_vardef_t *var, char *strval, telnet_printfunc_t prnt)
|
||||
{
|
||||
int st = 0;
|
||||
switch (var->vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
*(int *)(var->varvalptr) = (int)strtol(strval, NULL, 0);
|
||||
if (prnt != NULL)
|
||||
prnt("%i\n", *(int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
*(short *)(var->varvalptr) = (short)strtol(strval, NULL, 0);
|
||||
if (prnt != NULL)
|
||||
prnt("%hi\n", *(short *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
*(char *)(var->varvalptr) = (char)strtol(strval, NULL, 0);
|
||||
if (prnt != NULL)
|
||||
prnt("%i\n", *(int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
*(unsigned int *)(var->varvalptr) = (unsigned int)strtol(strval, NULL, 0);
|
||||
if (prnt != NULL)
|
||||
prnt("%u\n", *(unsigned int *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
*(double *)(var->varvalptr) = strtod(strval, NULL);
|
||||
if (prnt != NULL)
|
||||
prnt("%g\n", *(double *)(var->varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
sprintf(*(char **)(var->varvalptr), "%s", strval);
|
||||
if (prnt != NULL)
|
||||
prnt("\"%s\"\n", *(char **)(var->varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (prnt != NULL)
|
||||
prnt("unknown type\n");
|
||||
st = -1;
|
||||
break;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
int setgetvar(int moduleindex, char getorset, char *params)
|
||||
{
|
||||
int n, i;
|
||||
char varname[TELNET_CMD_MAXSIZE];
|
||||
char *varval=NULL;
|
||||
memset(varname,0,sizeof(varname));
|
||||
n = sscanf(params,"%9s %ms",varname,&varval);
|
||||
char *varval = NULL;
|
||||
memset(varname, 0, sizeof(varname));
|
||||
n = sscanf(params, "%9s %ms", varname, &varval);
|
||||
|
||||
for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) {
|
||||
if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) {
|
||||
for (i = 0; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL; i++) {
|
||||
if (strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname, varname, strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) {
|
||||
if (n > 0 && (getorset == 'g' || getorset == 'G')) {
|
||||
client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module,
|
||||
telnetparams.CmdParsers[moduleindex].var[i].varname );
|
||||
|
||||
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT64:
|
||||
client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
break;
|
||||
}
|
||||
client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module, telnetparams.CmdParsers[moduleindex].var[i].varname);
|
||||
char *strval = telnet_getvarvalue(telnetparams.CmdParsers[moduleindex].var, i);
|
||||
client_printf("%s\n", strval);
|
||||
free(strval);
|
||||
}
|
||||
|
||||
if (n > 1 && (getorset == 's' || getorset == 'S')) {
|
||||
client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module,
|
||||
telnetparams.CmdParsers[moduleindex].var[i].varname);
|
||||
|
||||
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
|
||||
case TELNET_VARTYPE_INT32:
|
||||
*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (int)strtol(varval,NULL,0);
|
||||
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT16:
|
||||
*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
|
||||
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_INT8:
|
||||
*(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0);
|
||||
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_UINT:
|
||||
*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0);
|
||||
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_DOUBLE:
|
||||
*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
|
||||
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
case TELNET_VARTYPE_STRING:
|
||||
sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval);
|
||||
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
|
||||
break;
|
||||
|
||||
default:
|
||||
client_printf("unknown type\n");
|
||||
break;
|
||||
}
|
||||
client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module, telnetparams.CmdParsers[moduleindex].var[i].varname);
|
||||
telnet_setvarvalue(&(telnetparams.CmdParsers[moduleindex].var[i]), varval, client_printf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,6 +487,14 @@ int setgetvar(int moduleindex,char getorset,char *params) {
|
||||
|
||||
return CMDSTATUS_VARNOTFOUND;
|
||||
}
|
||||
|
||||
void telnetsrv_freetbldata(webdatadef_t *wdata)
|
||||
{
|
||||
for (int i = 0; i < wdata->numlines; i++)
|
||||
for (int j = 0; j < wdata->numcols; j++)
|
||||
if (wdata->columns[j].coltype & TELNET_VAR_NEEDFREE)
|
||||
free(wdata->lines[i].val[j]);
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------*/
|
||||
char *get_time(char *buff,int bufflen) {
|
||||
struct tm tmstruct;
|
||||
@@ -449,17 +502,28 @@ char *get_time(char *buff,int bufflen) {
|
||||
strftime (buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now,&tmstruct));
|
||||
return buff;
|
||||
}
|
||||
void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt)
|
||||
{
|
||||
notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t), 0, NULL, NULL);
|
||||
telnetsrv_qmsg_t *cmddata = NotifiedFifoData(msg);
|
||||
cmddata->cmdfunc = (qcmdfunc_t)cmd->cmdfunc;
|
||||
cmddata->prnt = prnt;
|
||||
cmddata->debug = telnetparams.telnetdbg;
|
||||
if (cmdbuff != NULL)
|
||||
cmddata->cmdbuff = strdup(cmdbuff);
|
||||
pushNotifiedFIFO(cmd->qptr, msg);
|
||||
}
|
||||
|
||||
int process_command(char *buf) {
|
||||
int process_command(char *buf, int iteration)
|
||||
{
|
||||
int i,j,k;
|
||||
char modulename[TELNET_CMD_MAXSIZE];
|
||||
char cmd[TELNET_CMD_MAXSIZE];
|
||||
char *cmdb=NULL;
|
||||
char *bufbck;
|
||||
int rt;
|
||||
memset(modulename,0,sizeof(modulename));
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
|
||||
|
||||
|
||||
if (strncasecmp(buf,"ex",2) == 0)
|
||||
return CMDSTATUS_EXIT;
|
||||
@@ -474,6 +538,8 @@ int process_command(char *buf) {
|
||||
}
|
||||
|
||||
for(j=0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL ; j++) {
|
||||
if (telnetparams.CmdParsers[i].cmd[j].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY)
|
||||
continue;
|
||||
client_printf(" %s %s %s\n",
|
||||
telnetparams.CmdParsers[i].module,telnetparams.CmdParsers[i].cmd[j].cmdname,
|
||||
telnetparams.CmdParsers[i].cmd[j].helpstr);
|
||||
@@ -483,13 +549,11 @@ int process_command(char *buf) {
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
|
||||
|
||||
bufbck=strdup(buf);
|
||||
rt=CMDSTATUS_NOTFOUND;
|
||||
j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
|
||||
|
||||
if (telnetparams.telnetdbg > 0)
|
||||
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
|
||||
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n", j, modulename, cmd, (cmdb == NULL) ? "" : cmdb);
|
||||
|
||||
for (i=0; j>=2 && telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) {
|
||||
if ( (strncasecmp(telnetparams.CmdParsers[i].module,modulename,strlen(telnetparams.CmdParsers[i].module)) == 0)) {
|
||||
@@ -504,15 +568,11 @@ int process_command(char *buf) {
|
||||
} else {
|
||||
for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) {
|
||||
if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) {
|
||||
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
|
||||
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
|
||||
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
|
||||
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
|
||||
cmddata->prnt=client_printf;
|
||||
cmddata->debug=telnetparams.telnetdbg;
|
||||
cmddata->cmdbuff=cmdb ? strdup(cmdb) : NULL;
|
||||
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
|
||||
} else {
|
||||
if (telnetparams.CmdParsers[i].cmd[k].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY)
|
||||
continue;
|
||||
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
|
||||
telnet_pushcmd(&(telnetparams.CmdParsers[i].cmd[k]), (cmdb != NULL) ? strdup(cmdb) : NULL, client_printf);
|
||||
} else {
|
||||
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
|
||||
}
|
||||
rt= CMDSTATUS_FOUND;
|
||||
@@ -533,7 +593,7 @@ int process_command(char *buf) {
|
||||
char tbuff[64];
|
||||
client_printf(CSI "1J" CSI "1;10H " STDFMT "%s %i/%i\n",
|
||||
get_time(tbuff,sizeof(tbuff)),lc,telnetparams.loopcount );
|
||||
process_command(bufbck+strlen("loop")+1);
|
||||
process_command(buf + strlen("loop") + 1, lc);
|
||||
errno=0;
|
||||
int rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff));
|
||||
|
||||
@@ -554,7 +614,6 @@ int process_command(char *buf) {
|
||||
} /* loop */
|
||||
} /* for i */
|
||||
free(cmdb);
|
||||
free(bufbck);
|
||||
return rt;
|
||||
}
|
||||
|
||||
@@ -645,7 +704,7 @@ void run_telnetsrv(void) {
|
||||
}
|
||||
|
||||
if (strlen(buf) > 2 ) {
|
||||
status=process_command(buf);
|
||||
status = process_command(buf, 0);
|
||||
} else
|
||||
status=CMDSTATUS_NOCMD;
|
||||
|
||||
@@ -847,44 +906,35 @@ int telnetsrv_autoinit(void) {
|
||||
*/
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
|
||||
{
|
||||
notifiedFIFO_t *afifo = NULL;
|
||||
|
||||
if( modulename == NULL || var == NULL || cmd == NULL) {
|
||||
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i=0; i<TELNET_MAXCMD ; i++) {
|
||||
cmdparser_t *CmdParser = &telnetparams.CmdParsers[i];
|
||||
if (CmdParser->var == NULL) {
|
||||
strncpy(CmdParser->module, modulename, sizeof(CmdParser->module) - 1);
|
||||
CmdParser->cmd = cmd;
|
||||
CmdParser->var = var;
|
||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
|
||||
i, CmdParser->module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == TELNET_MAXCMD) {
|
||||
fprintf(stderr, "[TELNETSRV] TELNET_MAXCMD reached, cannot add new module %s\n", modulename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
notifiedFIFO_t *afifo = NULL;
|
||||
for (int k = 0; cmd[k].cmdfunc != NULL ; k++) {
|
||||
if (cmd[k].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(afifo);
|
||||
for (int i = 0; i < TELNET_MAXCMD; i++) {
|
||||
if (telnetparams.CmdParsers[i].var == NULL) {
|
||||
strncpy(telnetparams.CmdParsers[i].module, modulename, sizeof(telnetparams.CmdParsers[i].module) - 1);
|
||||
telnetparams.CmdParsers[i].cmd = cmd;
|
||||
telnetparams.CmdParsers[i].var = var;
|
||||
for (int j = 0; cmd[j].cmdfunc != NULL; j++) {
|
||||
if (cmd[j].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
|
||||
if (afifo == NULL) {
|
||||
afifo = malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(afifo);
|
||||
}
|
||||
cmd[j].qptr = afifo;
|
||||
}
|
||||
}
|
||||
cmd[k].qptr = afifo;
|
||||
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* function which will be called by the shared lib loader, to check shared lib version
|
||||
against main exec version. version mismatch not considered as fatal (interfaces not supposed to change)
|
||||
*/
|
||||
@@ -903,10 +953,18 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers
|
||||
}
|
||||
|
||||
int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
|
||||
*farray=malloc(sizeof(loader_shlibfunc_t)*2);
|
||||
int const num_func_tln_srv = 3;
|
||||
*farray = malloc(sizeof(loader_shlibfunc_t) * num_func_tln_srv);
|
||||
(*farray)[0].fname=TELNET_ADDCMD_FNAME;
|
||||
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
|
||||
(*farray)[1].fname=TELNET_POLLCMDQ_FNAME;
|
||||
(*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq;
|
||||
return ( 2);
|
||||
(*farray)[1].fptr = (int (*)(void))poll_telnetcmdq;
|
||||
(*farray)[2].fname = TELNET_PUSHCMD_FNAME;
|
||||
(*farray)[2].fptr = (int (*)(void))telnet_pushcmd;
|
||||
return (3);
|
||||
}
|
||||
/* for webserver interface, needs access to some telnet server paramaters */
|
||||
telnetsrv_params_t *get_telnetsrv_params(void)
|
||||
{
|
||||
return &telnetparams;
|
||||
}
|
||||
|
||||
@@ -48,19 +48,54 @@
|
||||
#define CMDSTATUS_VARNOTFOUND 3
|
||||
#define CMDSTATUS_NOTFOUND 4
|
||||
|
||||
/* definitions to store 2 dim table, used to store command results before */
|
||||
/* displaying them either on console or web page */
|
||||
#define TELNET_MAXLINE_NUM 100
|
||||
#define TELNET_MAXCOL_NUM 10
|
||||
|
||||
typedef struct col {
|
||||
char coltitle[TELNET_CMD_MAXSIZE];
|
||||
unsigned int coltype;
|
||||
} acol_t;
|
||||
|
||||
typedef struct line {
|
||||
char *val[TELNET_MAXCOL_NUM];
|
||||
} aline_t;
|
||||
|
||||
typedef struct webdatadef {
|
||||
char tblname[TELNET_HELPSTR_SIZE];
|
||||
int numlines;
|
||||
int numcols;
|
||||
acol_t columns[TELNET_MAXCOL_NUM];
|
||||
aline_t lines[TELNET_MAXLINE_NUM];
|
||||
} webdatadef_t;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* structure to be used when adding a module to the telnet server */
|
||||
/* This is the second parameter of the add_telnetcmd function, which can be used */
|
||||
/* to add a set of new command to the telnet server shell */
|
||||
typedef void(*telnet_printfunc_t)(const char* format, ...);
|
||||
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
|
||||
typedef int (*webfunc_t)(char *cmdbuff, int debug, telnet_printfunc_t prnt, ...);
|
||||
typedef int (*webfunc_getdata_t)(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt);
|
||||
typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg);
|
||||
|
||||
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
|
||||
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1 << 0) // ask the telnet server to push the command in a thread pool queue
|
||||
#define TELNETSRV_CMDFLAG_GETWEBDATA (1 << 1) // When called from web server, use the getdata variant of the function
|
||||
#define TELNETSRV_CMDFLAG_TELNETONLY (1 << 2) // Command only for telnet client connections
|
||||
#define TELNETSRV_CMDFLAG_WEBSRVONLY (1 << 3) // Command only for web server connections
|
||||
#define TELNETSRV_CMDFLAG_CONFEXEC (1 << 4) // Ask for confirm before exec
|
||||
#define TELNETSRV_CMDFLAG_GETWEBTBLDATA (1 << 8) // When called from web server, use the get table data variant of the function
|
||||
#define TELNETSRV_CMDFLAG_NEEDPARAM (1 << 10) // websrv: The command needs a parameter
|
||||
#define TELNETSRV_CMDFLAG_WEBSRV_SETRETURNTBL (1 << 11) // websrv: set callback returns a new table
|
||||
#define TELNETSRV_CMDFLAG_AUTOUPDATE (1 << 12) // command can be re-submitted automatically for result update
|
||||
typedef struct cmddef {
|
||||
char cmdname[TELNET_CMD_MAXSIZE];
|
||||
char helpstr[TELNET_HELPSTR_SIZE];
|
||||
cmdfunc_t cmdfunc;
|
||||
cmdfunc_t cmdfunc;
|
||||
union {
|
||||
webfunc_t webfunc;
|
||||
webfunc_getdata_t webfunc_getdata;
|
||||
};
|
||||
unsigned int cmdflags;
|
||||
void *qptr;
|
||||
} telnetshell_cmddef_t;
|
||||
@@ -78,6 +113,8 @@ typedef struct telnetsrv_qmsg {
|
||||
/*structure to be used when adding a module to the telnet server */
|
||||
/* This is the first parameter of the add_telnetcmd function, which can be used */
|
||||
/* to add a set of new variables which can be got/set from the telnet server shell */
|
||||
/* var type: bits 0-3, type value (1 to 15)
|
||||
* type modifier, bits 4-31 */
|
||||
#define TELNET_VARTYPE_INT32 1
|
||||
#define TELNET_VARTYPE_INT16 2
|
||||
#define TELNET_VARTYPE_INT64 3
|
||||
@@ -85,9 +122,16 @@ typedef struct telnetsrv_qmsg {
|
||||
#define TELNET_VARTYPE_DOUBLE 5
|
||||
#define TELNET_VARTYPE_INT8 6
|
||||
#define TELNET_VARTYPE_UINT 7
|
||||
|
||||
#define TELNET_CHECKVAL_RDONLY 16
|
||||
#define TELNET_CHECKVAL_BOOL 32
|
||||
#define TELNET_VAR_NEEDFREE 64
|
||||
#define TELNET_CHECKVAL_LOGLVL 128
|
||||
#define TELNET_CHECKVAL_SIMALGO 256
|
||||
typedef struct variabledef {
|
||||
char varname[TELNET_CMD_MAXSIZE];
|
||||
char vartype;
|
||||
char checkval;
|
||||
void *varvalptr;
|
||||
} telnetshell_vardef_t;
|
||||
|
||||
@@ -113,6 +157,7 @@ typedef struct {
|
||||
int priority; // server running priority
|
||||
char *histfile; // command history
|
||||
int histsize; // command history length
|
||||
char *logfile; // filename to use when redirecting output to file
|
||||
int new_socket; // socket of the client connection
|
||||
int logfilefd; // file id of the log file when log output is redirected to a file
|
||||
int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout
|
||||
@@ -145,14 +190,25 @@ VT escape sequence definition, for smarter display....
|
||||
#define STDFMT "\x1b[0m"
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*/
|
||||
#define NICE_MAX 19
|
||||
#define NICE_MIN -20
|
||||
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
|
||||
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
|
||||
#define TELNET_PUSHCMD_FNAME "telnet_pushcmd"
|
||||
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
|
||||
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
|
||||
typedef void (*push_telnetcmd_func_t)(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
|
||||
#ifdef TELNETSERVERCODE
|
||||
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
|
||||
void set_sched(pthread_t tid, int pid,int priority);
|
||||
void set_affinity(pthread_t tid, int pid, int coreid);
|
||||
extern int get_phybsize(void);
|
||||
#endif
|
||||
#ifdef WEBSERVERCODE
|
||||
extern void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
|
||||
extern telnetsrv_params_t *get_telnetsrv_params(void);
|
||||
extern char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex);
|
||||
extern int telnet_setvarvalue(telnetshell_vardef_t *var, char *strval, telnet_printfunc_t prnt);
|
||||
extern void telnetsrv_freetbldata(webdatadef_t *wdata);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -32,6 +32,6 @@ endforeach()
|
||||
|
||||
install(TARGETS telnetsrv DESTINATION bin)
|
||||
|
||||
if (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/ran_build/build)
|
||||
endif (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")
|
||||
if (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
install(TARGETS telnetsrv DESTINATION ${OPENAIR_CMAKE}/ran_build/build)
|
||||
endif (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
|
||||
|
||||
@@ -42,14 +42,17 @@
|
||||
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
telnetshell_cmddef_t loader_cmdarray[] = {
|
||||
{"show","[params,modules]",loader_show_cmd},
|
||||
{"","",NULL},
|
||||
{"show", "[params,modules]", loader_show_cmd, {(webfunc_t)loader_show_cmd}, 0, NULL},
|
||||
{"", "", NULL, {NULL}, 0, NULL},
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buff == NULL) {
|
||||
prnt("ERROR wrong loader SHOW command...\n");
|
||||
return 0;
|
||||
}
|
||||
if (debug > 0)
|
||||
prnt( "loader_show_cmd received %s\n",buff);
|
||||
|
||||
@@ -58,21 +61,19 @@ int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
|
||||
prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion);
|
||||
prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath);
|
||||
prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs);
|
||||
}
|
||||
else if (strcasestr(buff,"modules") != NULL) {
|
||||
prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
|
||||
for (int i=0 ; i<loader_data.numshlibs ; i++) {
|
||||
prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name);
|
||||
prnt( " Shared library build version: \"%s\"\n",((loader_data.shlibs[i].shlib_buildversion == NULL )?"":loader_data.shlibs[i].shlib_buildversion));
|
||||
prnt( " Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
|
||||
prnt( " %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
|
||||
for(int j=0 ; j<loader_data.shlibs[i].numfunc;j++) {
|
||||
prnt( " function %i %s at %p\n",j,
|
||||
loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr);
|
||||
}
|
||||
} else if (strcasestr(buff, "modules") != NULL || buff[0] == 0 || strcasestr(buff, "show") != NULL) {
|
||||
prnt("%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
|
||||
for (int i = 0; i < loader_data.numshlibs; i++) {
|
||||
prnt(" Module %i: %s\n", i, loader_data.shlibs[i].name);
|
||||
prnt(" Shared library build version: \"%s\"\n", ((loader_data.shlibs[i].shlib_buildversion == NULL) ? "" : loader_data.shlibs[i].shlib_buildversion));
|
||||
prnt(" Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path);
|
||||
prnt(" %i function pointers registered:\n", loader_data.shlibs[i].numfunc);
|
||||
for (int j = 0; j < loader_data.shlibs[i].numfunc; j++) {
|
||||
prnt(" function %i %s at %p\n", j, loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prnt("%s: wrong loader command...\n",buff);
|
||||
prnt("%s: wrong loader command...\n", buff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -37,14 +37,11 @@
|
||||
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
|
||||
|
||||
telnetshell_vardef_t loader_globalvardef[] = {
|
||||
{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)},
|
||||
{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)},
|
||||
{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)},
|
||||
{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)},
|
||||
{"",0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t loader_globalvardef[] = {{"mainversion", TELNET_VARTYPE_STRING, TELNET_CHECKVAL_RDONLY, &(loader_data.mainexec_buildversion)},
|
||||
{"defpath", TELNET_VARTYPE_STRING, TELNET_CHECKVAL_RDONLY, &(loader_data.shlibpath)},
|
||||
{"maxshlibs", TELNET_VARTYPE_INT32, TELNET_CHECKVAL_RDONLY, &(loader_data.maxshlibs)},
|
||||
{"numshlibs", TELNET_VARTYPE_INT32, TELNET_CHECKVAL_RDONLY, &(loader_data.numshlibs)},
|
||||
{"", 0, 0, NULL}};
|
||||
telnetshell_vardef_t *loader_modulesvardef;
|
||||
|
||||
extern void add_loader_cmds(void);
|
||||
|
||||
@@ -91,9 +91,7 @@ telnetshell_cmddef_t measur_cmdarray[] = {
|
||||
{"","",NULL}
|
||||
};
|
||||
|
||||
telnetshell_vardef_t measur_vardef[] = {
|
||||
{"",0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t measur_vardef[] = {{"", 0, 0, NULL}};
|
||||
/* function to be implemented in any telnetsrv_xxx_measurements.c sources
|
||||
to allow common measurment code to access measurments data */
|
||||
extern int get_measurgroups(telnet_measurgroupdef_t **measurgroups);
|
||||
|
||||
@@ -44,17 +44,7 @@
|
||||
#define TELNETVAR_PHYCC0 0
|
||||
#define TELNETVAR_PHYCC1 1
|
||||
|
||||
telnetshell_vardef_t phy_vardef[] = {
|
||||
//{"iqmax",TELNET_VARTYPE_INT16,NULL},
|
||||
//{"iqmin",TELNET_VARTYPE_INT16,NULL},
|
||||
//{"loglvl",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"sndslp",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"rxrescale",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"txshift",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"rachemin",TELNET_VARTYPE_INT32,NULL},
|
||||
//{"rachdmax",TELNET_VARTYPE_INT32,NULL},
|
||||
{"",0,NULL}
|
||||
};
|
||||
telnetshell_vardef_t phy_vardef[] = {{"", 0, 0, NULL}};
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@@ -57,84 +57,119 @@
|
||||
#include "openair1/PHY/phy_extern.h"
|
||||
#include "telnetsrv_proccmd.h"
|
||||
|
||||
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt)
|
||||
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
|
||||
{
|
||||
char prntline[160];
|
||||
char *procfile_fiels;
|
||||
char *procfile_fields;
|
||||
char *strtokptr;
|
||||
char *lptr;
|
||||
int fieldcnt;
|
||||
char toksep[2];
|
||||
|
||||
fieldcnt=0;
|
||||
procfile_fiels =strtok_r(record," ",&strtokptr);
|
||||
lptr= prntline;
|
||||
fieldcnt = 0;
|
||||
procfile_fields = strtok_r(record, " ", &strtokptr);
|
||||
lptr = prntline;
|
||||
/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
|
||||
|
||||
while( procfile_fiels != NULL && fieldcnt < 42) {
|
||||
long int policy;
|
||||
if (strlen(procfile_fiels) == 0)
|
||||
continue;
|
||||
fieldcnt++;
|
||||
sprintf(toksep," ");
|
||||
switch(fieldcnt) {
|
||||
case 1: /* id */
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
sprintf(toksep,")");
|
||||
break;
|
||||
case 2: /* name */
|
||||
lptr+=sprintf(lptr,"%20.20s ",procfile_fiels+1);
|
||||
break;
|
||||
case 3: //thread state
|
||||
lptr+=sprintf(lptr," %c ",procfile_fiels[0]);
|
||||
break;
|
||||
case 14: //time in user mode
|
||||
case 15: //time in kernel mode
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
break;
|
||||
case 18: //priority
|
||||
case 19: //nice
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
|
||||
break;
|
||||
case 23: //vsize
|
||||
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
|
||||
break;
|
||||
case 39: //processor
|
||||
lptr+=sprintf(lptr," %2.2s ",procfile_fiels);
|
||||
break;
|
||||
case 41: //policy
|
||||
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
|
||||
policy=strtol(procfile_fiels,NULL,0);
|
||||
switch(policy) {
|
||||
case SCHED_FIFO:
|
||||
lptr+=sprintf(lptr,"%s ","rt: fifo");
|
||||
break;
|
||||
case SCHED_OTHER:
|
||||
lptr+=sprintf(lptr,"%s ","other");
|
||||
break;
|
||||
case SCHED_IDLE:
|
||||
lptr+=sprintf(lptr,"%s ","idle");
|
||||
break;
|
||||
case SCHED_BATCH:
|
||||
lptr+=sprintf(lptr,"%s ","batch");
|
||||
break;
|
||||
case SCHED_RR:
|
||||
lptr+=sprintf(lptr,"%s ","rt: rr");
|
||||
break;
|
||||
default:
|
||||
lptr+=sprintf(lptr,"%s ","????");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}/* switch on fieldcnr */
|
||||
procfile_fiels =strtok_r(NULL,toksep,&strtokptr);
|
||||
} /* while on proc_fields != NULL */
|
||||
prnt("%s\n",prntline);
|
||||
int priority = 0;
|
||||
int nice = 0;
|
||||
while (procfile_fields != NULL && fieldcnt < 42) {
|
||||
long int policy;
|
||||
if (strlen(procfile_fields) == 0)
|
||||
continue;
|
||||
fieldcnt++;
|
||||
sprintf(toksep, " ");
|
||||
switch (fieldcnt) {
|
||||
case 1: /* id */
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[0] = strdup(procfile_fields);
|
||||
}
|
||||
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
||||
sprintf(toksep, ")");
|
||||
break;
|
||||
case 2: /* name */
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[1] = strdup(procfile_fields);
|
||||
}
|
||||
lptr += sprintf(lptr, "%20.20s ", procfile_fields + 1);
|
||||
break;
|
||||
case 3: // thread state
|
||||
lptr += sprintf(lptr, " %c ", procfile_fields[0]);
|
||||
break;
|
||||
case 14: // time in user mode
|
||||
case 15: // time in kernel mode
|
||||
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
||||
break;
|
||||
case 18: // priority column index 2 in tdata, -2 to -100 (1, min to 99, highest prio)
|
||||
priority = strtol(procfile_fields, NULL, 0);
|
||||
case 19: // nice column index 3 in tdata 0 to 39 (-20, highest prio, to 19)
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[fieldcnt - 16] = strdup(procfile_fields);
|
||||
}
|
||||
lptr += sprintf(lptr, "%3.3s ", procfile_fields);
|
||||
nice = strtol(procfile_fields, NULL, 0);
|
||||
break;
|
||||
case 23: // vsize
|
||||
lptr += sprintf(lptr, "%9.9s ", procfile_fields);
|
||||
break;
|
||||
case 39: // processor
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[4] = strdup(procfile_fields);
|
||||
}
|
||||
lptr += sprintf(lptr, " %2.2s ", procfile_fields);
|
||||
break;
|
||||
case 41: // policy
|
||||
lptr += sprintf(lptr, "%3.3s ", procfile_fields);
|
||||
policy = strtol(procfile_fields, NULL, 0);
|
||||
char strschedp[64];
|
||||
switch (policy) {
|
||||
case SCHED_FIFO:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:fifo");
|
||||
priority = priority + 1; // in /proc file system priority 1 to 99 mapped to -2 to -100
|
||||
break;
|
||||
case SCHED_OTHER:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "other");
|
||||
priority = nice - NICE_MIN; // linux nice is -20 to 19
|
||||
break;
|
||||
case SCHED_IDLE:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "idle");
|
||||
priority = 2 * (NICE_MAX - NICE_MIN + 1);
|
||||
break;
|
||||
case SCHED_BATCH:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "batch");
|
||||
priority = (NICE_MAX - NICE_MIN + 1) + nice - NICE_MIN;
|
||||
break;
|
||||
case SCHED_RR:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:rr");
|
||||
priority = priority - 99;
|
||||
break;
|
||||
#ifdef SCHED_DEADLINE
|
||||
case SCHED_DEADLINE:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "rt:deadline");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
snprintf(strschedp, sizeof(strschedp), "%s ", "????");
|
||||
break;
|
||||
}
|
||||
lptr += sprintf(lptr, "%s ", strschedp);
|
||||
if (tdata != NULL) {
|
||||
tdata->lines[tdata->numlines].val[5] = strdup(strschedp);
|
||||
tdata->lines[tdata->numlines].val[6] = malloc(10);
|
||||
snprintf(tdata->lines[tdata->numlines].val[6], 9, "%i", priority);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} /* switch on fieldcnr */
|
||||
procfile_fields = strtok_r(NULL, toksep, &strtokptr);
|
||||
} /* while on proc_fields != NULL */
|
||||
prnt("%s\n", prntline);
|
||||
if (tdata != NULL) {
|
||||
tdata->numlines++;
|
||||
}
|
||||
} /*decode_procstat */
|
||||
|
||||
void read_statfile(char *fname,int debug, telnet_printfunc_t prnt)
|
||||
void read_statfile(char *fname, int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
|
||||
{
|
||||
FILE *procfile;
|
||||
char arecord[1024];
|
||||
@@ -152,44 +187,207 @@ char arecord[1024];
|
||||
return;
|
||||
}
|
||||
fclose(procfile);
|
||||
decode_procstat(arecord, debug, prnt);
|
||||
decode_procstat(arecord, debug, prnt, tdata);
|
||||
}
|
||||
|
||||
void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
int nullprnt(char *fmt, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void proccmd_get_threaddata(char *buf, int debug, telnet_printfunc_t fprnt, webdatadef_t *tdata)
|
||||
{
|
||||
char aname[256];
|
||||
|
||||
DIR *proc_dir;
|
||||
struct dirent *entry;
|
||||
DIR *proc_dir;
|
||||
struct dirent *entry;
|
||||
telnet_printfunc_t prnt = (fprnt != NULL) ? fprnt : (telnet_printfunc_t)nullprnt;
|
||||
if (tdata != NULL) {
|
||||
tdata->numcols = 7;
|
||||
snprintf(tdata->columns[0].coltitle, sizeof(tdata->columns[0].coltitle), "thread id");
|
||||
tdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[1].coltitle, sizeof(tdata->columns[1].coltitle), "thread name");
|
||||
tdata->columns[1].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[2].coltitle, sizeof(tdata->columns[2].coltitle), "priority");
|
||||
tdata->columns[2].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[3].coltitle, sizeof(tdata->columns[3].coltitle), "nice");
|
||||
tdata->columns[3].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[4].coltitle, sizeof(tdata->columns[4].coltitle), "core");
|
||||
tdata->columns[4].coltype = TELNET_VARTYPE_STRING | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[5].coltitle, sizeof(tdata->columns[5].coltitle), "sched policy");
|
||||
tdata->columns[5].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[5].coltitle, sizeof(tdata->columns[5].coltitle), "sched policy");
|
||||
tdata->columns[6].coltype = TELNET_VARTYPE_STRING | TELNET_VAR_NEEDFREE;
|
||||
snprintf(tdata->columns[6].coltitle, sizeof(tdata->columns[6].coltitle), "oai priority");
|
||||
tdata->numlines = 0;
|
||||
}
|
||||
|
||||
unsigned int eax = 11, ebx = 0, ecx = 1, edx = 0;
|
||||
|
||||
asm volatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "0"(eax), "2"(ecx) :);
|
||||
|
||||
prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
|
||||
read_statfile(aname,debug,prnt);
|
||||
prnt("\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task", getpid());
|
||||
proc_dir = opendir(aname);
|
||||
if (proc_dir == NULL)
|
||||
{
|
||||
prnt("Error: Couldn't open %s %i %s\n",aname,errno,strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(proc_dir)) != NULL)
|
||||
{
|
||||
if(entry->d_name[0] == '.')
|
||||
continue;
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
|
||||
read_statfile(aname,debug,prnt);
|
||||
} /* while entry != NULL */
|
||||
closedir(proc_dir);
|
||||
} /* print_threads */
|
||||
prnt("System has %d cores %d threads %d Actual threads", eax, ebx, edx);
|
||||
|
||||
prnt("\n id name state USRmod KRNmod prio nice vsize proc pol \n\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
|
||||
read_statfile(aname, debug, prnt, NULL);
|
||||
prnt("\n");
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task", getpid());
|
||||
proc_dir = opendir(aname);
|
||||
if (proc_dir == NULL) {
|
||||
prnt("Error: Couldn't open %s %i %s\n", aname, errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(proc_dir)) != NULL) {
|
||||
if (entry->d_name[0] != '.') {
|
||||
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(), (int)(sizeof(aname) - 24), entry->d_name);
|
||||
read_statfile(aname, debug, prnt, tdata);
|
||||
}
|
||||
} /* while entry != NULL */
|
||||
closedir(proc_dir);
|
||||
} /* proccmd_get_threaddata */
|
||||
|
||||
void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
proccmd_get_threaddata(buf, debug, prnt, NULL);
|
||||
}
|
||||
|
||||
int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt)
|
||||
{
|
||||
webdatadef_t *logsdata = (webdatadef_t *)data;
|
||||
if (strncmp(cmdbuff, "set", 3) == 0) {
|
||||
telnet_printfunc_t printfunc = (prnt != NULL) ? prnt : (telnet_printfunc_t)printf;
|
||||
if (strcasestr(cmdbuff, "loglvl") != NULL) {
|
||||
int level = map_str_to_int(log_level_names, logsdata->lines[0].val[1]);
|
||||
int enabled = (strcmp(logsdata->lines[0].val[2], "true") == 0) ? 1 : 0;
|
||||
int loginfile = (strcmp(logsdata->lines[0].val[3], "true") == 0) ? 1 : 0;
|
||||
set_log(logsdata->numlines, level);
|
||||
if (enabled == 0)
|
||||
set_log(logsdata->numlines, OAILOG_DISABLE);
|
||||
if (loginfile == 1) {
|
||||
set_component_filelog(logsdata->numlines);
|
||||
} else {
|
||||
close_component_filelog(logsdata->numlines);
|
||||
}
|
||||
printfunc("%s log level %s is %s, output to %s\n",
|
||||
logsdata->lines[0].val[0],
|
||||
logsdata->lines[0].val[1],
|
||||
enabled ? "enabled" : "disabled",
|
||||
loginfile ? g_log->log_component[logsdata->numlines].filelog_name : "stdout");
|
||||
}
|
||||
if (strcasestr(cmdbuff, "logopt") != NULL) {
|
||||
int optbit = map_str_to_int(log_options, logsdata->lines[0].val[0]);
|
||||
if (optbit < 0) {
|
||||
printfunc("option %s unknown\n", logsdata->lines[0].val[0]);
|
||||
} else {
|
||||
if (strcmp(logsdata->lines[0].val[1], "true") == 0) {
|
||||
SET_LOG_OPTION(optbit);
|
||||
} else {
|
||||
CLEAR_LOG_OPTION(optbit);
|
||||
}
|
||||
printfunc("%s log option %s\n", logsdata->lines[0].val[0], (strcmp(logsdata->lines[0].val[1], "true") == 0) ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff, "dbgopt") != NULL) {
|
||||
int optbit = map_str_to_int(log_maskmap, logsdata->lines[0].val[0]);
|
||||
if (optbit < 0) {
|
||||
printfunc("debug option %s unknown\n", logsdata->lines[0].val[0]);
|
||||
} else {
|
||||
if (strcmp(logsdata->lines[0].val[1], "true") == 0)
|
||||
SET_LOG_DEBUG(optbit);
|
||||
else
|
||||
CLEAR_LOG_DEBUG(optbit);
|
||||
if (strcmp(logsdata->lines[0].val[2], "true") == 0)
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
printfunc("%s debug %s dump %s\n",
|
||||
logsdata->lines[0].val[0],
|
||||
(strcmp(logsdata->lines[0].val[1], "true") == 0) ? "enabled" : "disabled",
|
||||
(strcmp(logsdata->lines[0].val[2], "true") == 0) ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff, "threadsched") != NULL) {
|
||||
unsigned int tid = strtoll(logsdata->lines[0].val[0], NULL, 0);
|
||||
unsigned int core = strtoll(logsdata->lines[0].val[4], NULL, 0);
|
||||
int priority = strtoll(logsdata->lines[0].val[6], NULL, 0);
|
||||
printfunc("Thread %s id %u set affinity to core %u\n", logsdata->lines[0].val[0], tid, core);
|
||||
set_affinity(0, (pid_t)tid, core);
|
||||
set_sched(0, (pid_t)tid, priority);
|
||||
}
|
||||
} else { /* end of set, => show */
|
||||
if (strcasestr(cmdbuff, "loglvl") != NULL) {
|
||||
logsdata->numcols = 4;
|
||||
logsdata->numlines = 0;
|
||||
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "component");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "level");
|
||||
logsdata->columns[1].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_LOGLVL;
|
||||
snprintf(logsdata->columns[2].coltitle, TELNET_CMD_MAXSIZE, "enabled");
|
||||
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
||||
snprintf(logsdata->columns[3].coltitle, TELNET_CMD_MAXSIZE, "in file");
|
||||
logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i = MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
|
||||
if (g_log->log_component[i].name != NULL) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = (char *)(g_log->log_component[i].name);
|
||||
|
||||
logsdata->lines[i].val[1] = map_int_to_str(log_level_names, (g_log->log_component[i].level >= 0) ? g_log->log_component[i].level : g_log->log_component[i].savedlevel);
|
||||
logsdata->lines[i].val[2] = (g_log->log_component[i].level >= 0) ? "true" : "false";
|
||||
logsdata->lines[i].val[3] = (g_log->log_component[i].filelog > 0) ? "true" : "false";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff, "dbgopt") != NULL) {
|
||||
webdatadef_t *logsdata = (webdatadef_t *)data;
|
||||
logsdata->numcols = 3;
|
||||
logsdata->numlines = 0;
|
||||
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "module");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "debug");
|
||||
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
||||
snprintf(logsdata->columns[2].coltitle, TELNET_CMD_MAXSIZE, "dump");
|
||||
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i = 0; log_maskmap[i].name != NULL; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = log_maskmap[i].name;
|
||||
logsdata->lines[i].val[1] = (g_log->debug_mask & log_maskmap[i].value) ? "true" : "false";
|
||||
logsdata->lines[i].val[2] = (g_log->dump_mask & log_maskmap[i].value) ? "true" : "false";
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasestr(cmdbuff, "logopt") != NULL) {
|
||||
webdatadef_t *logsdata = (webdatadef_t *)data;
|
||||
logsdata->numcols = 2;
|
||||
logsdata->numlines = 0;
|
||||
snprintf(logsdata->columns[0].coltitle, TELNET_CMD_MAXSIZE, "option");
|
||||
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
|
||||
snprintf(logsdata->columns[1].coltitle, TELNET_CMD_MAXSIZE, "enabled");
|
||||
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
|
||||
|
||||
for (int i = 0; log_options[i].name != NULL; i++) {
|
||||
logsdata->numlines++;
|
||||
logsdata->lines[i].val[0] = log_options[i].name;
|
||||
logsdata->lines[i].val[1] = (g_log->flag & log_options[i].value) ? "true" : "false";
|
||||
}
|
||||
}
|
||||
if (strcasestr(cmdbuff, "threadsched") != NULL) {
|
||||
proccmd_get_threaddata(cmdbuff, debug, prnt, (webdatadef_t *)data);
|
||||
}
|
||||
} // show
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
|
||||
if (buf == NULL) {
|
||||
prnt("ERROR wrong softmodem SHOW command...\n");
|
||||
return 0;
|
||||
}
|
||||
if (debug > 0)
|
||||
prnt(" proccmd_show received %s\n",buf);
|
||||
if (strcasestr(buf,"thread") != NULL) {
|
||||
@@ -263,8 +461,12 @@ int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
int bv1,bv2;
|
||||
int res;
|
||||
char sv1[64];
|
||||
|
||||
char sv1[64];
|
||||
|
||||
if (buf == NULL) {
|
||||
prnt("ERROR wrong thread command...\n");
|
||||
return 0;
|
||||
}
|
||||
bv1=0;
|
||||
bv2=0;
|
||||
sv1[0]=0;
|
||||
@@ -279,7 +481,7 @@ char sv1[64];
|
||||
prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);
|
||||
if(res != 3)
|
||||
{
|
||||
prnt("softmodem thread needs 3 params, %i received\n",res);
|
||||
print_threads(buf, debug, prnt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -302,11 +504,20 @@ int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (debug > 0)
|
||||
prnt("process module received %s\n",buf);
|
||||
|
||||
end_configmodule();
|
||||
exit_fun("telnet server received exit command\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (debug > 0)
|
||||
prnt("process module received %s\n", buf);
|
||||
end_configmodule();
|
||||
configmodule_interface_t *cfg = config_get_if();
|
||||
execvpe(cfg->argv[0], cfg->argv, environ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
|
||||
{
|
||||
@@ -391,7 +602,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
SET_LOG_DUMP(optbit);
|
||||
else
|
||||
CLEAR_LOG_DUMP(optbit);
|
||||
proccmd_show("dbgopt",debug,prnt);
|
||||
proccmd_show("dump", debug, prnt);
|
||||
}
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
@@ -431,7 +642,8 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
|
||||
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
|
||||
}
|
||||
} else {
|
||||
prnt("%s unknown log sub command \n",logsubcmd);
|
||||
level = map_str_to_int(log_level_names, tmpstr);
|
||||
prnt("%s unknown log sub command \n", logsubcmd);
|
||||
}
|
||||
if (logparam != NULL) free(logparam);
|
||||
if (tmpstr != NULL) free(tmpstr);
|
||||
|
||||
@@ -44,11 +44,12 @@
|
||||
extern int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
|
||||
telnetshell_vardef_t proc_vardef[] = {
|
||||
{"",0,NULL}
|
||||
};
|
||||
#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\
|
||||
extern int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt);
|
||||
telnetshell_vardef_t proc_vardef[] = {{"", 0, 0, NULL}};
|
||||
#define PROCCMD_LOG_HELP_STRING \
|
||||
" log sub commands: \n\
|
||||
show: display current log configuration \n\
|
||||
online, noonline: enable or disable console logs \n\
|
||||
enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\
|
||||
@@ -60,24 +61,32 @@ telnetshell_vardef_t proc_vardef[] = {
|
||||
print_<opt> <0|1> disable or enable the \"opt\" log option, use the show command to get \
|
||||
the available options\n\
|
||||
dump_<mod> debug_<mod > disable or enable the debug file generation or debug code\
|
||||
for \"mod\" module. use the show command to get the available modules\n"
|
||||
for \"mod\" module. use the show command to get the available modules\n"
|
||||
|
||||
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
|
||||
#define PROCCMD_THREAD_HELP_STRING \
|
||||
" thread sub commands: \n\
|
||||
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\
|
||||
<thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\
|
||||
if prio < -20: linux scheduling policy set to FIFO, \n\
|
||||
with priority = -20 - prio \n\
|
||||
if prio > 19: linux scheduling policy set to OTHER, \n\
|
||||
with priority (nice value) = prio \n\
|
||||
-100 < prio < 0: linux scheduling policy set to FIFO, priority -prio, \n\
|
||||
-200 < prio < -100: linux scheduling policy set to RR, priority -(prio+100), \n\
|
||||
0 <= prio < 40: linux scheduling policy set to NORMAL, nice value prio-20 \n\
|
||||
40 <= prio < 80: linux scheduling policy set to BATCH, nice value prio-60 \n\
|
||||
prio >=80: linux scheduling policy set to IDLE \n\
|
||||
use \"softmodem show thread\" to get <thread id> \n"
|
||||
|
||||
|
||||
telnetshell_cmddef_t proc_cmdarray[] = {
|
||||
{"show","loglvl|thread|config", proccmd_show},
|
||||
{"log","(enter help for details)", proccmd_log},
|
||||
{"thread","(enter help for details)", proccmd_thread},
|
||||
{"exit","", proccmd_exit},
|
||||
{"","",NULL},
|
||||
{"show", "loglvl|thread|config", proccmd_show, {(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_TELNETONLY, NULL},
|
||||
{"log", "(enter help for details)", proccmd_log, {NULL}, TELNETSRV_CMDFLAG_TELNETONLY, NULL},
|
||||
{"show loglvl", "", proccmd_log, {(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_GETWEBTBLDATA, NULL},
|
||||
{"show logopt", "", proccmd_log, {(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_GETWEBTBLDATA, NULL},
|
||||
{"show dbgopt", "", proccmd_log, {(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_GETWEBTBLDATA, NULL},
|
||||
{"show config", "", proccmd_show, {(webfunc_t)proccmd_show}, TELNETSRV_CMDFLAG_WEBSRVONLY, NULL},
|
||||
{"show thread", "", proccmd_thread, {(webfunc_t)proccmd_show}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_AUTOUPDATE, NULL},
|
||||
{"thread", "(enter help for details)", proccmd_thread, {NULL}, TELNETSRV_CMDFLAG_TELNETONLY, NULL},
|
||||
{"show threadsched", "", proccmd_show, {(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY | TELNETSRV_CMDFLAG_GETWEBTBLDATA, NULL},
|
||||
{"exit", "", proccmd_exit, {NULL}, TELNETSRV_CMDFLAG_CONFEXEC, NULL},
|
||||
{"restart", "", proccmd_restart, {NULL}, TELNETSRV_CMDFLAG_CONFEXEC, NULL},
|
||||
{"", "", NULL},
|
||||
};
|
||||
#else
|
||||
extern void add_proccmd_cmds(void);
|
||||
|
||||
Reference in New Issue
Block a user