summaryrefslogtreecommitdiff
path: root/src/biruda.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2014-11-21 19:07:58 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2014-11-21 19:07:58 +0100
commit5da03da44b1c2d7693857bda1ce01c644c9aa5f4 (patch)
treeb7e0e89af64bb498d70ab1629f1c9aeb351fc454 /src/biruda.c
parent36a9558737abb4fc6440903361a6c175a4140f35 (diff)
downloadbiruda-5da03da44b1c2d7693857bda1ce01c644c9aa5f4.tar.gz
biruda-5da03da44b1c2d7693857bda1ce01c644c9aa5f4.tar.bz2
added completion for worker names
Diffstat (limited to 'src/biruda.c')
-rw-r--r--src/biruda.c181
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;