diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2014-11-21 19:07:58 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2014-11-21 19:07:58 +0100 |
commit | 5da03da44b1c2d7693857bda1ce01c644c9aa5f4 (patch) | |
tree | b7e0e89af64bb498d70ab1629f1c9aeb351fc454 /src/biruda.c | |
parent | 36a9558737abb4fc6440903361a6c175a4140f35 (diff) | |
download | biruda-5da03da44b1c2d7693857bda1ce01c644c9aa5f4.tar.gz biruda-5da03da44b1c2d7693857bda1ce01c644c9aa5f4.tar.bz2 |
added completion for worker names
Diffstat (limited to 'src/biruda.c')
-rw-r--r-- | src/biruda.c | 181 |
1 files changed, 148 insertions, 33 deletions
diff --git a/src/biruda.c b/src/biruda.c index 28725bc..ea76b09 100644 --- a/src/biruda.c +++ b/src/biruda.c @@ -256,34 +256,109 @@ static void terminate_foreground_func( int sig ) #define HISTORY_FILE ".biruda_history" +typedef enum { + COMMAND, // command parsing + WORKER_PARAM // worker command expecting a worker parameter +} command_state_t; + static char *commands[] = { - "help", "quit", "status", NULL + "help", "quit", "status", "start", "stop", NULL }; static bool print_colors = false; static bool is_interactive = false; +static command_state_t command_state = COMMAND; + +static char *worker_names[MAX_WORKERS]; + +static int nof_worker_names = 0; + +static void cleanup_worker_names( ) +{ + for( int i = 0; i < nof_worker_names; i++ ) { + free( worker_names[i] ); + } +} + +static void print_error( const char *fmt, ... ); + +static void get_workers( ) +{ + char *url = "status"; + char *data = NULL; + int len; + http_retcode ret = http_get( url, &data, &len, NULL ); + if( ret == 200 ) { + cleanup_worker_names( ); + + char *line = strtok( data, "\n" ); + while( line != NULL ) { + char *p = strchr( line, ' ' ); + if( p == NULL ) { + line = strtok( NULL, "\n" ); + continue; + } + if( strncmp( line, "worker", p - line ) != 0 ) { + line = strtok( NULL, "\n" ); + continue; + } + char *pp = strchr( p+1, ' ' ); + if( pp == NULL ) { + line = strtok( NULL, "\n" ); + continue; + } + char s = *pp; + *pp = '\0'; + if( nof_worker_names >= MAX_WORKERS ) { + fprintf( stderr, "ERROR: Too many workers seen, ignoring rest!\n" ); + free( data ); + return; + } + worker_names[nof_worker_names++] = strdup( p + 1 ); + *pp = s; + line = strtok( NULL, "\n" ); + } + } else { + print_error( "ERROR: HTTP error %d", ret ); + } + free( data ); +} + static void completion_func( const char *buf, linenoiseCompletions *lc ) { unsigned int i; size_t len = strlen( buf ); - for (i = 0; commands[i]; ++i) { - char *cmd = commands[i]; - if( strlen( cmd ) < len ) continue; - if( strncasecmp( buf, cmd, len ) == 0 ) { - linenoiseAddCompletion( lc, cmd ); - } - } + switch( command_state ) { + case COMMAND: + for (i = 0; commands[i]; ++i) { + char *cmd = commands[i]; + if( strlen( cmd ) < len ) continue; + if( strncasecmp( buf, cmd, len ) == 0 ) { + linenoiseAddCompletion( lc, cmd ); + } + } + break; + + case WORKER_PARAM: + get_workers( ); + for( int i = 0; i < nof_worker_names; i++ ) { + linenoiseAddCompletion( lc, worker_names[i] ); + } + break; + } } static void print_help( ) { puts( "\n" - " help - show this help page\n" - " quit - quit the client\n" - " status - status of the biruda network\n" + " help - show this help page\n" + " quit - quit the client\n" + " status - status of the biruda network\n" + " start - start a worker manually\n" + " stop - stop a worker manually\n" ); } @@ -318,18 +393,17 @@ static void print_answer( const char *fmt, ... ) static void print_status( ) { - http_server = "localhost"; - http_port = 8080; char *url = "status"; char *data = NULL; int len; http_retcode ret = http_get( url, &data, &len, NULL ); if( ret == 200 ) { - if( strlen( data ) > 0 && data[strlen( data )-1] == '\n' ) { - data[strlen( data )-1] = '\0'; + if( strlen( data ) > 0 && data[len-1] == '\n' ) { + data[len-1] = '\0'; + len--; } - if( strlen( data ) > 0 && data[strlen( data )-1] == '\r' ) { - data[strlen( data )-1] = '\0'; + if( strlen( data ) > 0 && data[len-1] == '\r' ) { + data[len-1] = '\0'; } print_answer( data ); } else { @@ -341,6 +415,10 @@ static void print_status( ) static int start_interactive( bool colors ) { char history_filename[1024]; + + // for http_tidy, tell it where to issue requests to + http_server = "localhost"; + http_port = 8080; is_interactive = isatty( fileno( stdin ) ); print_colors = is_interactive ? colors : false; @@ -356,16 +434,41 @@ static int start_interactive( bool colors ) char *context = "biruda"; for( ;; ) { - char buf[4096]; + char prompt[128]; + char buf[1024]; char *line; + + switch( command_state ) { + case COMMAND: + context = "biruda"; + break; + + case WORKER_PARAM: + context = "worker"; + break; + } if( is_interactive ) { - snprintf( buf, sizeof( buf ), "%s> ", context ); - if( ( line = linenoise( buf ) ) == NULL ) { + snprintf( prompt, sizeof( prompt ), "%s> ", context ); + if( ( line = linenoise( prompt ) ) == NULL ) { + switch( command_state ) { + case COMMAND: + cleanup_worker_names( ); + free( line ); + return EXIT_SUCCESS; + + case WORKER_PARAM: + command_state = COMMAND; + continue; + } break; } + strncpy( buf, line, sizeof( buf ) ); + free( line ); + line = buf; } else { if( fgets( buf, sizeof( buf ), stdin ) == NULL ) { + cleanup_worker_names( ); return EXIT_SUCCESS; } line = buf; @@ -380,19 +483,31 @@ static int start_interactive( bool colors ) if( is_interactive ) { linenoiseHistoryAdd( line ); } - - if( strncasecmp( line, "quit", 4 ) == 0 ) { - if( is_interactive ) { - linenoiseHistorySave( history_filename ); - } - return EXIT_SUCCESS; - } else if( strncasecmp( line, "help", 4 ) == 0 ) { - print_help( ); - } else if( strncasecmp( line, "status", 6 ) == 0 ) { - print_status( ); - } else { - print_error( "Bad command '%s'.", line ); - } + + switch( command_state ) { + case COMMAND: + if( strncasecmp( line, "quit", 4 ) == 0 ) { + if( is_interactive ) { + linenoiseHistorySave( history_filename ); + } + cleanup_worker_names( ); + return EXIT_SUCCESS; + } else if( strncasecmp( line, "help", 4 ) == 0 ) { + print_help( ); + } else if( strncasecmp( line, "status", 6 ) == 0 ) { + print_status( ); + } else if( strncasecmp( line, "start", 5 ) == 0 ) { + command_state = WORKER_PARAM; + } else { + print_error( "Bad command '%s'.", line ); + } + break; + + case WORKER_PARAM: + printf( "starting worker '%s'\n", line ); + command_state = COMMAND; + break; + } } return EXIT_SUCCESS; |