summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2015-09-06 21:31:56 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2015-09-06 21:31:56 +0200
commit69a0fdd630b13d8864d7dfe494205139d5ecb079 (patch)
tree910a81f57ccd0f9da04e3592b40c2a393982f1ba
parentc69a497ce13d0054d29256e91044878341deed00 (diff)
downloadcssh-69a0fdd630b13d8864d7dfe494205139d5ecb079.tar.gz
cssh-69a0fdd630b13d8864d7dfe494205139d5ecb079.tar.bz2
some empty libary for multi-line progress bar, hooked up to SCP download code
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/cssh.c32
-rw-r--r--src/msleep.h6
-rw-r--r--src/port.c (renamed from src/msleep.c)2
-rw-r--r--src/port.h6
-rw-r--r--src/progressbar.c91
-rw-r--r--src/progressbar.h37
7 files changed, 165 insertions, 12 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c8acde1..65e457e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,7 +2,8 @@ include_directories(${LIBSSH_PUBLIC_INCLUDE_DIRS})
set(SRC
cssh.c
- msleep.c
+ port.c
+ progressbar.c
)
ADD_GENGETOPT_FILES(SRC options.ggo)
diff --git a/src/cssh.c b/src/cssh.c
index e989677..2b3663a 100644
--- a/src/cssh.c
+++ b/src/cssh.c
@@ -17,7 +17,8 @@
#include <unistd.h>
#include <netdb.h>
-#include "msleep.h"
+#include "port.h"
+#include "progressbar.h"
#include "options.h"
#include "version.h"
@@ -73,6 +74,7 @@ typedef struct scp_data_t {
char *buf;
uint64_t size;
uint64_t bytesReceived;
+ cssh_progressbar_t progressbar;
} scp_data_t;
static int push_dir_stack( scp_dir_stack_t *stack, const char *dir )
@@ -419,6 +421,7 @@ static int read_hosts_file( const char *hosts_file, unsigned short default_port,
return 0;
}
+// TODO: cleanup also progressbarpool
static void cleanup_sessions( ssh_session **session, ssh_channel **channel, scp_data_t **scp_data, char **host, unsigned short *port, const int nof_sessions, bool verbose )
{
for( unsigned int i = 0; i < nof_sessions; i++ ) {
@@ -1086,6 +1089,14 @@ int main( int argc, char *argv[] )
exit( EXIT_FAILURE );
}
}
+
+ cssh_progressbar_pool_t progressbars;
+ rc = create_progressbar_pool( &progressbars, nof_sessions );
+ if( rc < 0 ) {
+ fprintf( stderr, "ERROR: Creation of a pool of progress bars failed\n" );
+ cleanup_sessions( &session, NULL, &scp_data, host, port, nof_sessions, args_info.verbose_given > 0 );
+ exit( EXIT_FAILURE );
+ }
bool all_eof = false;
@@ -1268,7 +1279,19 @@ int main( int argc, char *argv[] )
scp_data[i].fd = fd;
scp_data[i].filename = full_path;
scp_data[i].bytesReceived = 0;
- scp_data[i].read_state = CSSH_SCP_READ_STATE_READING;
+ scp_data[i].read_state = CSSH_SCP_READ_STATE_READING;
+
+ len = strlen( host[i] ) + strlen( full_path ) + 5;
+ rc = create_progressbar( &scp_data[i].progressbar, 0, scp_data[i].size, len,
+ "[%s:%s]", host[i], full_path );
+ if( rc < 0 ) {
+ fprintf( stderr, "ERROR: Unable to create progress bar for host '%s' and file '%s'\n",
+ host[i], full_path );
+ cleanup_sessions( &session, NULL, &scp_data, host, port, nof_sessions, args_info.verbose_given > 0 );
+ exit( EXIT_FAILURE );
+ }
+ rc = append_progressbar_to_pool( &progressbars, &scp_data[i].progressbar );
+
} break;
case SSH_SCP_REQUEST_EOF:
@@ -1318,8 +1341,7 @@ int main( int argc, char *argv[] )
}
}
if( args_info.verbose_given > 0 ) {
- printf( "[%s:%s] %"PRIu64"/%"PRIu64"\r",
- host[i], scp_data[i].filename, scp_data[i].bytesReceived, scp_data[i].size );
+ set_value_of_progressbar( &scp_data[i].progressbar, scp_data[i].bytesReceived );
}
} else {
rc = close( scp_data[i].fd );
@@ -1333,6 +1355,8 @@ int main( int argc, char *argv[] )
scp_data[i].fd = 0;
free( scp_data[i].filename );
scp_data[i].filename = NULL;
+ remvove_progressbar_from_pool( &progressbars, &scp_data[i].progressbar );
+ free_progressbar( &scp_data[i].progressbar );
}
break;
diff --git a/src/msleep.h b/src/msleep.h
deleted file mode 100644
index bfe8c7a..0000000
--- a/src/msleep.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _USLEEP_HEADER_INCLUDED
-#define _USLEEP_HEADER_INCLUDED
-
-void cssh_msleep( unsigned int msec );
-
-#endif
diff --git a/src/msleep.c b/src/port.c
index 607cd02..d6b947e 100644
--- a/src/msleep.c
+++ b/src/port.c
@@ -1,4 +1,4 @@
-#include "msleep.h"
+#include "port.h"
#include <time.h>
diff --git a/src/port.h b/src/port.h
new file mode 100644
index 0000000..49295b9
--- /dev/null
+++ b/src/port.h
@@ -0,0 +1,6 @@
+#ifndef _PORT_HEADER_INCLUDED
+#define _PORT_HEADER_INCLUDED
+
+void cssh_msleep( unsigned int msec );
+
+#endif
diff --git a/src/progressbar.c b/src/progressbar.c
new file mode 100644
index 0000000..f8a4121
--- /dev/null
+++ b/src/progressbar.c
@@ -0,0 +1,91 @@
+#include "progressbar.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+int create_progressbar( cssh_progressbar_t *progressbar, uint64_t min_value, uint64_t max_value, size_t size, const char *label_fmt, ... )
+{
+ progressbar->min_value = min_value;
+ progressbar->max_value = max_value;
+
+ va_list va;
+ va_start( va, label_fmt );
+
+ progressbar->label = (char *)malloc( size );
+ if( progressbar->label == NULL ) {
+ return -1;
+ }
+
+ (void)vsnprintf( progressbar->label, size, label_fmt, va );
+
+ va_end( va );
+
+ return 0;
+}
+
+void free_progressbar( cssh_progressbar_t *progressbar )
+{
+ free( progressbar->label );
+}
+
+void set_value_of_progressbar( cssh_progressbar_t *progressbar, uint64_t value )
+{
+ fprintf( stderr, "%s %"PRIu64"\n", progressbar->label, value );
+}
+
+int create_progressbar_pool( cssh_progressbar_pool_t *pool, size_t initial_size )
+{
+ pool->N = 0;
+ pool->capacity = initial_size;
+ pool->progressbar = (cssh_progressbar_t **)malloc( pool->capacity * sizeof( cssh_progressbar_t * ) );
+ if( pool->progressbar == NULL ) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void free_progressbar_pool( cssh_progressbar_pool_t *pool )
+{
+ for( size_t i = 0; i < pool->N; i++ ) {
+ free_progressbar( pool->progressbar[i] );
+ }
+
+ free( pool->progressbar );
+}
+
+int append_progressbar_to_pool( cssh_progressbar_pool_t *pool, cssh_progressbar_t *progressbar )
+{
+ if( pool->N + 1 > pool->capacity ) {
+ return -1;
+ }
+
+ pool->progressbar[pool->N] = progressbar;
+ pool->N++;
+
+ return 0;
+}
+
+int remvove_progressbar_from_pool( cssh_progressbar_pool_t *pool, cssh_progressbar_t *progressbar )
+{
+ if( pool->N == 0 ) {
+ return -1;
+ }
+
+ for( size_t i = 0; i < pool->N; i++ ) {
+ if( pool->progressbar[i] ) {
+ if( i < pool->N - 1 ) {
+ memmove( &pool->progressbar[i], &pool->progressbar[i+1],
+ ( pool->N - i ) * sizeof( cssh_progressbar_t * ) );
+ }
+ pool->N--;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+
diff --git a/src/progressbar.h b/src/progressbar.h
new file mode 100644
index 0000000..70e93f8
--- /dev/null
+++ b/src/progressbar.h
@@ -0,0 +1,37 @@
+// rougly based on https://github.com/doches/progressbar
+// but changed in API, multi-line support and some interna
+// also simplified to exactly what we need for cssh
+
+#ifndef _PROGRESSBAR_HEADER_INCLUDED
+#define _PROGRESSBAR_HEADER_INCLUDED
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+typedef struct cssh_progressbar_t {
+ uint64_t min_value;
+ uint64_t max_value;
+ char *label;
+} cssh_progressbar_t;
+
+typedef struct cssh_progressbar_pool_t {
+ size_t capacity;
+ size_t N;
+ cssh_progressbar_t **progressbar;
+} cssh_progressbar_pool_t;
+
+int create_progressbar( cssh_progressbar_t *progressbar, uint64_t min_value, uint64_t max_value, size_t size, const char *label_fmt, ... );
+
+void free_progressbar( cssh_progressbar_t *progressbar );
+
+void set_value_of_progressbar( cssh_progressbar_t *progressbar, uint64_t value );
+
+int create_progressbar_pool( cssh_progressbar_pool_t *pool, size_t initial_size );
+
+void free_progressbar_pool( cssh_progressbar_pool_t *pool );
+
+int append_progressbar_to_pool( cssh_progressbar_pool_t *pool, cssh_progressbar_t *progressbar );
+
+int remvove_progressbar_from_pool( cssh_progressbar_pool_t *pool, cssh_progressbar_t *progressbar );
+
+#endif