// Execute the eLua "shell" in an infinite loop void shell_start() { char cmd[ SHELL_MAXSIZE + 1 ]; const SHELL_COMMAND *pcmd; #ifdef BUILD_UIP int i; #endif printf( SHELL_WELCOMEMSG, ELUA_STR_VERSION ); while( 1 ) { while( linenoise_getline( LINENOISE_ID_SHELL, cmd, SHELL_MAXSIZE - 1, SHELL_PROMPT ) == -1 ) { printf( "\n" ); clearerr( stdin ); } if( strlen( cmd ) == 0 ) continue; linenoise_addhistory( LINENOISE_ID_SHELL, cmd ); pcmd = shellh_execute_command( cmd, 1 ); // Check for 'exit' command if( pcmd && pcmd->cmd && !pcmd->handler_func ) #ifdef BUILD_UIP { if( ( i = elua_net_get_telnet_socket() ) != -1 ) elua_net_close( i ); } #else break; #endif } // Shell exit point if( shell_prog ) free( shell_prog ); }
// 'write' static _ssize_t std_write( struct _reent *r, int fd, const void* vptr, size_t len, void *pdata ) { int sock; // Check file number if( ( fd != DM_STDOUT_NUM ) && ( fd != DM_STDERR_NUM ) ) { r->_errno = EINVAL; return -1; } // Get (and wait for) socket while( ( sock = elua_net_get_telnet_socket() ) == - 1 ); // Send data elua_net_send( sock, vptr, len ); return len; }
// 'read' static _ssize_t std_read( struct _reent *r, int fd, void* vptr, size_t len, void *pdata ) { int sock; elua_net_size pktsize; size_t actsize, j; char* lptr = ( char* )vptr; // Check file number if( fd != DM_STDIN_NUM ) { r->_errno = EINVAL; return -1; } // Get (and wait for) socket while( ( sock = elua_net_get_telnet_socket() ) == - 1 ); // Read data actsize = 0; while( 1 ) { pktsize = elua_net_recv( sock, lptr, len, -1, 0, 0 ); // Check EOF for( j = 0; j < pktsize; j ++ ) if( lptr[ j ] == STD_CTRLZ_CODE ) return 0; actsize += pktsize; if( actsize >= len ) { actsize = len; break; } // Is this the final packet? if( pktsize >= 2 && lptr[ pktsize - 2 ] == '\r' && lptr[ pktsize - 1 ] == '\n' ) // final packet break; lptr += pktsize; len -= pktsize; } return actsize; }
// Execute the eLua "shell" in an infinite loop void shell_start() { char cmd[ SHELL_MAXSIZE + 1 ]; char *p, *temp; const SHELL_COMMAND* pcmd; int i, inside_quotes; char quote_char; printf( SHELL_WELCOMEMSG, ELUA_STR_VERSION ); while( 1 ) { while( linenoise_getline( LINENOISE_ID_SHELL, cmd, SHELL_MAXSIZE, SHELL_PROMPT ) == -1 ) { printf( "\n" ); clearerr( stdin ); } if( strlen( cmd ) == 0 ) continue; linenoise_addhistory( LINENOISE_ID_SHELL, cmd ); if( cmd[ strlen( cmd ) - 1 ] != '\n' ) strcat( cmd, "\n" ); // Change '\r' and '\n' chars to ' ' to ease processing p = cmd; while( *p ) { if( *p == '\r' || *p == '\n' ) *p = ' '; p ++; } // Transform ' ' characters inside a '' or "" quoted string in // a 'special' char. We do this to let the user execute something // like "lua -e 'quoted string'" without disturbing the quoted // string in any way. for( i = 0, inside_quotes = 0, quote_char = '\0'; i < strlen( cmd ); i ++ ) if( ( cmd[ i ] == '\'' ) || ( cmd[ i ] == '"' ) ) { if( !inside_quotes ) { inside_quotes = 1; quote_char = cmd[ i ]; } else { if( cmd[ i ] == quote_char ) { inside_quotes = 0; quote_char = '\0'; } } } else if( ( cmd[ i ] == ' ' ) && inside_quotes ) cmd[ i ] = SHELL_ALT_SPACE; if( inside_quotes ) { printf( "Invalid quoted string\n" ); continue; } // Transform consecutive sequences of spaces into a single space p = strchr( cmd, ' ' ); while( p ) { temp = p + 1; while( *temp && *temp == ' ' ) memmove( temp, temp + 1, strlen( temp ) ); p = strchr( p + 1, ' ' ); } if( strlen( cmd ) == 1 ) continue; // Look for the first ' ' to separate the command from its args temp = cmd; if( *temp == ' ' ) temp ++; if( ( p = strchr( temp, ' ' ) ) == NULL ) { printf( SHELL_ERRMSG ); continue; } *p = 0; i = 0; while( 1 ) { pcmd = shell_commands + i; if( pcmd->cmd == NULL ) { printf( SHELL_ERRMSG ); break; } if( !strcasecmp( pcmd->cmd, temp ) ) { // Special case: the "exit" command has a NULL handler if( pcmd->handler_func ) pcmd->handler_func( p + 1 ); break; } i ++; } // Check for 'exit' command if( pcmd->cmd && !pcmd->handler_func ) #ifdef BUILD_UIP { if( ( i = elua_net_get_telnet_socket() ) != -1 ) elua_net_close( i ); } #else break; #endif } // Shell exit point if( shell_prog ) free( shell_prog ); }
// Execute the eLua "shell" in an infinite loop void shell_start() { char cmd[ SHELL_MAXSIZE + 1 ]; char *p, *temp; const SHELL_COMMAND* pcmd; int i, inside_quotes; char quote_char; int argc; char *argv[ SHELL_MAX_ARGS ]; printf( SHELL_WELCOMEMSG, ELUA_STR_VERSION ); while( 1 ) { while( linenoise_getline( LINENOISE_ID_SHELL, cmd, SHELL_MAXSIZE - 1, SHELL_PROMPT ) == -1 ) { printf( "\n" ); clearerr( stdin ); } if( strlen( cmd ) == 0 ) continue; linenoise_addhistory( LINENOISE_ID_SHELL, cmd ); if( cmd[ strlen( cmd ) - 1 ] != '\n' ) strcat( cmd, "\n" ); // Change '\r', '\n' and '\t' chars to ' ' to ease processing p = cmd; while( *p ) { if( *p == '\r' || *p == '\n' || *p == '\t' ) *p = ' '; p ++; } // Transform ' ' characters inside a '' or "" quoted string in // a 'special' char. We do this to let the user execute something // like "lua -e 'quoted string'" without disturbing the quoted // string in any way. for( i = 0, inside_quotes = 0, quote_char = '\0'; i < strlen( cmd ); i ++ ) if( ( cmd[ i ] == '\'' ) || ( cmd[ i ] == '"' ) ) { if( !inside_quotes ) { inside_quotes = 1; quote_char = cmd[ i ]; } else { if( cmd[ i ] == quote_char ) { inside_quotes = 0; quote_char = '\0'; } } } else if( ( cmd[ i ] == ' ' ) && inside_quotes ) cmd[ i ] = SHELL_ALT_SPACE; if( inside_quotes ) { printf( "Invalid quoted string\n" ); continue; } // Transform consecutive sequences of spaces into a single space p = strchr( cmd, ' ' ); while( p ) { temp = p + 1; while( *temp && *temp == ' ' ) memmove( temp, temp + 1, strlen( temp ) ); p = strchr( p + 1, ' ' ); } if( !strcmp( cmd, " " ) ) continue; // Skip over the initial space char if it exists p = cmd; if( *p == ' ' ) p ++; // Add a final space if it does not exist if( p[ strlen( p ) - 1 ] != ' ' ) strcat( p, " " ); // Compute argc/argv for( argc = 0; argc < SHELL_MAX_ARGS; argc ++ ) argv[ argc ] = NULL; argc = 0; while( ( temp = strchr( p, ' ' ) ) != NULL ) { *temp = 0; if( argc == SHELL_MAX_ARGS ) { printf( "Error: too many arguments\n" ); argc = -1; break; } argv[ argc ++ ] = p; p = temp + 1; } if( argc == -1 ) continue; // Additional argument processing happens here for( i = 0; i < argc; i ++ ) { p = argv[ i ]; // Put back spaces if needed for( inside_quotes = 0; inside_quotes < strlen( argv[ i ] ); inside_quotes ++ ) { if( p[ inside_quotes ] == SHELL_ALT_SPACE ) argv[ i ][ inside_quotes ] = ' '; } // Remove quotes if( ( p[ 0 ] == '\'' || p [ 0 ] == '"' ) && ( p[ 0 ] == p[ strlen( p ) - 1 ] ) ) { argv[ i ] = p + 1; p[ strlen( p ) - 1 ] = '\0'; } } // Match user command with shell's commands i = 0; while( 1 ) { pcmd = shell_commands + i; if( pcmd->cmd == NULL ) { printf( SHELL_ERRMSG ); break; } if( !strcasecmp( pcmd->cmd, argv[ 0 ] ) ) { // Special case: the "exit" command has a NULL handler if( pcmd->handler_func ) pcmd->handler_func( argc, argv ); break; } i ++; } // Check for 'exit' command if( pcmd->cmd && !pcmd->handler_func ) #ifdef BUILD_UIP { if( ( i = elua_net_get_telnet_socket() ) != -1 ) elua_net_close( i ); } #else break; #endif } // Shell exit point if( shell_prog ) free( shell_prog ); }