11/* *******************************************************************
22* Description: schedrmt.cc
3- * Extended telnet based scheduler interface
3+ * Extended Telnet- based scheduler interface.
44*
5- * Derived from a work by Fred Proctor & Will Shackleford
6- * Further derived from work by jmkasunich
5+ * Derived from a work by Fred Proctor & Will Shackleford.
6+ * Further derived from work by jmkasunich.
77*
88* Author: Eric H. Johnson
99* License: GPL Version 2
2020#include < string.h>
2121#include < stdlib.h>
2222#include < signal.h>
23+ #include < errno.h>
24+ #include < getopt.h>
2325#include < unistd.h>
2426#include < ctype.h>
2527#include < math.h>
2830#include < sys/uio.h>
2931#include < netinet/in.h>
3032#include < pthread.h>
31- #include < errno.h>
32-
33- #include < getopt.h>
33+ #include < atomic> // for sessions counter
3434
3535#include " rcs.hh"
3636#include " posemath.h" // PM_POSE, TO_RAD
4545#include " emcsched.hh"
4646#include < rtapi_string.h>
4747
48- #include < atomic> // for sessions counter
49-
5048/*
5149 Using schedrmt:
5250
@@ -273,8 +271,10 @@ const char *setCommands[] = {
273271 " QMODE" , " QSTATUS" , " AUTOTAGID" , " PGMADD" , " PGMBYID" , " PGMBYINDEX" , " PGMALL" , " PRIORITYBYID" ,
274272 " PRIORITYBYINDEX" , " DELETEBYID" , " DELETEBYINDEX" , " POLLRATE" ,
275273 " " };
274+ const unsigned char setCommands_max_length = 16 ;
276275
277276const char *commands[] = {" HELLO" , " SET" , " GET" , " QUIT" , " SHUTDOWN" , " HELP" , " " };
277+ const unsigned char command_max_length = 8 ;
278278
279279struct option longopts[] = {
280280 {" port" , 1 , NULL , ' p' },
@@ -287,7 +287,7 @@ struct option longopts[] = {
287287 };
288288
289289
290- static void thisQuit ()
290+ static void freeAllBuffers ()
291291{
292292 EMC_NULL emc_null_msg;
293293
@@ -313,7 +313,11 @@ static void thisQuit()
313313 delete emcCommandBuffer;
314314 emcCommandBuffer = 0 ;
315315 }
316+ }
316317
318+ static void thisQuit ()
319+ {
320+ freeAllBuffers ();
317321 exit (0 );
318322}
319323
@@ -330,6 +334,7 @@ static int initSockets()
330334 return 0 ;
331335}
332336
337+ // attached to signal SIGINT in main()
333338static void sigQuit (int /* sig*/ )
334339{
335340 thisQuit ();
@@ -347,7 +352,7 @@ static setCommandType lookupSetCommand(char *s)
347352 int temp;
348353
349354 while (i < scUnknown) {
350- if (strcmp (setCommands[i], s) == 0 ) return i;
355+ if (strncmp (setCommands[i], s, setCommand_max_length ) == 0 ) return i;
351356// (int)i += 1;
352357 temp = i;
353358 temp++;
@@ -400,10 +405,10 @@ static int checkBinaryASCII(char *s)
400405
401406static queueStatusType checkMode (char *s)
402407{
403- static const char *runStr = " RUN" ;
404- static const char *stopStr = " STOP" ;
405- static const char *pauseStr = " PAUSE" ;
406- static const char *resumeStr = " RESUME" ;
408+ static const char * const runStr = " RUN" ;
409+ static const char * const stopStr = " STOP" ;
410+ static const char * const pauseStr = " PAUSE" ;
411+ static const char * const resumeStr = " RESUME" ;
407412
408413 if (s == NULL ) return qsError;
409414 strupr (s);
@@ -942,7 +947,7 @@ int commandShutdown(connectionRecType *context)
942947{
943948 if (context->cliSock == enabledConn) {
944949 printf (" Shutting down\n " );
945- thisQuit ();
950+ freeAllBuffers ();
946951 return -1 ;
947952 }
948953 else
@@ -1034,7 +1039,7 @@ static int helpQuit(connectionRecType *context)
10341039 snprintf (context->outBuf , sizeof (context->outBuf ), " Usage:\n\r " );
10351040 rtapi_strxcat (context->outBuf , " The quit command has the server initiate a disconnect from the client,\n\r " );
10361041 rtapi_strxcat (context->outBuf , " the command has no parameters and no requirements to have negotiated\n\r " );
1037- rtapi_strxcat (context->outBuf , " a hello, or be in control." );
1042+ rtapi_strxcat (context->outBuf , " a hello, or to be in control." );
10381043 sockWrite (context);
10391044 return 0 ;
10401045}
@@ -1080,7 +1085,9 @@ commandTokenType lookupToken(char *s)
10801085 int temp;
10811086
10821087 while (i < cmdUnknown) {
1083- if (strcmp (commands[i], s) == 0 ) return i;
1088+ if (strncmp (commands[i], s, command_max_length+1 ) == 0 ) {
1089+ return i;
1090+ }
10841091// (int)i += 1;
10851092 temp = i;
10861093 temp++;
@@ -1094,10 +1101,10 @@ int parseCommand(connectionRecType *context)
10941101 int ret = 0 ;
10951102 char *pch;
10961103 char s[64 ];
1097- static const char *helloNakStr = " HELLO NAK\r\n " ;
1098- static const char *shutdownNakStr = " SHUTDOWN NAK\r\n " ;
1099- static const char *helloAckStr = " HELLO ACK %s 1.1\r\n " ;
1100- static const char *setNakStr = " SET NAK\r\n " ;
1104+ static const char * const helloNakStr = " HELLO NAK\r\n " ;
1105+ static const char * const shutdownNakStr = " SHUTDOWN NAK\r\n " ;
1106+ static const char * const helloAckStr = " HELLO ACK %s 1.1\r\n " ;
1107+ static const char * const setNakStr = " SET NAK\r\n " ;
11011108
11021109 pch = strtok (context->inBuf , delims);
11031110 snprintf (s, sizeof (s), helloAckStr, serverName);
@@ -1192,16 +1199,14 @@ void *readClient(void *arg)
11921199
11931200void sockMain ()
11941201{
1195- pthread_t thrd;
1196-
11971202 while (1 ) {
11981203 int res = -1 ;
11991204 struct sockaddr_in client_address;
12001205 socklen_t client_len = sizeof (client_address);
12011206 int client_sockfd = accept (server_sockfd, (struct sockaddr *)&client_address, &client_len);
12021207 if (client_sockfd < 0 ) {
12031208 perror (" sockMain: accept failed\n " );
1204- exit (0 );
1209+ exit (EXIT_FAILURE );
12051210 }
12061211 ++sessions;
12071212 if ((maxSessions == -1 ) || (sessions <= maxSessions)) {
@@ -1212,10 +1217,11 @@ void sockMain()
12121217 rtapi_strxcpy (context->hostName , " Default" );
12131218 rtapi_strxcpy (context->version , " 1.0" );
12141219 context->echo = true ;
1220+ pthread_t thrd;
12151221 res = pthread_create (&thrd, NULL , readClient, context);
12161222 if (pthread_detach (thrd)) {
12171223 // no errno set by pthread_detach
1218- fprintf (stderr, " sockMain: error by pthread_detach - ignored\n " );
1224+ rcs_print_error ( " sockMain: error by pthread_detach - ignored\n " );
12191225 }
12201226 if (res != 0 ) {
12211227 free (context);
@@ -1251,12 +1257,9 @@ static void initMain()
12511257
12521258int main (int argc, char *argv[])
12531259{
1254- int opt;
1255- pthread_t updateThread;
1256- int res;
1257-
12581260 initMain ();
12591261 // process local command line args
1262+ int opt;
12601263 while ((opt = getopt_long (argc, argv, " e:n:p:s:w:" , longopts, NULL )) != -1 ) {
12611264 switch (opt) {
12621265 case ' e' : snprintf (enablePWD, sizeof (enablePWD), " %s" , optarg); break ;
@@ -1270,17 +1273,17 @@ int main(int argc, char *argv[])
12701273
12711274 // process emc command line args
12721275 if (emcGetArgs (argc, argv) != 0 ) {
1273- rcs_print_error (" error in argument list\n " );
1274- exit (1 );
1276+ rcs_print_error (" Error in argument list\n " );
1277+ exit (EXIT_FAILURE );
12751278 }
12761279 // get configuration information
12771280 iniLoad (emc_inifile);
12781281 initSockets ();
12791282 // init NML
12801283 if (tryNml () != 0 ) {
1281- rcs_print_error (" can't connect to emc \n " );
1282- thisQuit ();
1283- exit (1 );
1284+ rcs_print_error (" Cannot connect to EMC \n " );
1285+ freeAllBuffers ();
1286+ exit (EXIT_FAILURE );
12841287 }
12851288 // get current serial number, and save it for restoring when we quit
12861289 // so as not to interfere with real operator interface
@@ -1291,10 +1294,16 @@ int main(int argc, char *argv[])
12911294 signal (SIGINT, sigQuit);
12921295
12931296 schedInit ();
1294- res = pthread_create (&updateThread, NULL , checkQueue, (void *)NULL );
1297+ pthread_t updateThread;
1298+ int res = pthread_create (&updateThread, NULL , checkQueue, (void *)NULL );
12951299 pthread_detach (updateThread);
1296- if (res != 0 ) { perror (" pthread_create" ); return 1 ; }
1300+ if (res != 0 ) {
1301+ perror (" pthread_create" );
1302+ freeAllBuffers ();
1303+ return EXIT_FAILURE;
1304+ }
12971305 if (useSockets) sockMain ();
12981306
1299- return 0 ;
1307+ freeAllBuffers ();
1308+ return EXIT_SUCCESS;
13001309}
0 commit comments