--- client.c Mon Sep 8 18:04:35 2003 +++ /home/rodin/programmeren/samba/client.c Fri Nov 7 21:54:32 2003 @@ -28,6 +28,9 @@ #define REGISTER 0 #endif +/* Used for correctly displaying the progress bar */ +#include + struct cli_state *cli; extern BOOL in_client; static int port = 0; @@ -635,6 +638,116 @@ return rc; } + +#define BAR_OVERHEAD 30 +static int progress = 0; +static int oldlen = 0; +static long lasttime = 0; +static int ttywidth = 80; + +/**************************************************************************** + Toggle the progress bar +****************************************************************************/ +static int cmd_progress(void) +{ + if(progress) { + progress = 0; + printf("Progress bar OFF\n"); + } else { + progress = 1; + printf("Progress bar ON\n"); + } + + return(0); + +} + +/**************************************************************************** + Set the global ttywidth variable +****************************************************************************/ +static void setttywidth(int dummy) +{ + struct winsize winsize; + if(ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1 && winsize.ws_col != 0) + ttywidth = winsize.ws_col; + else + d_printf("Couldn't determine ttywidth, using default value of 80\n"); + + /* Update the progressbar immediately */ + lasttime = 0; +} + +/**************************************************************************** + Catch window_resize events +****************************************************************************/ +static void init_signalhandler(void) +{ + struct sigaction sig, old; + memset(&sig, 0, sizeof(sig)); + sig.sa_handler = setttywidth; + sigaction(SIGWINCH, &sig, &old); +} + +/**************************************************************************** + Display a progress bar - by Marijn van Vliet - +nread: number of bytes read this transfer +start: number of bytes read previous transfer (used for download completion) +size: filesize in bytes +tp_start: starttime of transfer +****************************************************************************/ +static void progressbar(off_t nread, off_t start, size_t size, struct timeval tp_start) +{ + int barlen, curlen, i, j; + struct timeval tp_now, tp_elapsed; + float speed, prefixspeed; + int eta = 0; + off_t totalread = nread + start; + size_t prefixnread; + char* prefixes = " kmgtp"; + + barlen = ttywidth-BAR_OVERHEAD; + curlen = ((double)totalread) / (double)size *(double)barlen; + GetTimeOfDay(&tp_now); + + /* See if we need to update the bar */ + if(curlen == oldlen && lasttime == tp_now.tv_sec) return; + + oldlen = curlen; + lasttime = tp_now.tv_sec; + + fprintf(stderr, "\r|"); + for(i=0; i= 1024 && i>=10; + } + + prefixspeed = speed; + for(j=0; prefixspeed >= 1024 && j 0) { + fprintf(stderr, "| %d%cb %.2f%cb/s %02d:%02d ETA", (int)prefixnread, + prefixes[i], prefixspeed, prefixes[j], eta/60, eta%60); + } else { + fprintf(stderr, "| %d%cb --:-- ETA", (int)prefixnread, prefixes[i]); + } + + fflush(stdout); +} + /**************************************************************************** Get a file from rname to lname ****************************************************************************/ @@ -705,12 +818,28 @@ return 1; } + if(progress) { + /* Calculate ttywidth for use with progressbar */ + setttywidth(0); + + /* Init the signal handler to catch window_resize events */ + init_signalhandler(); + + /* Display filename */ + fprintf(stderr, "getting file %s of size %.0f as %s\n", + rname, (double)size, lname); + } + while (1) { int n = cli_read(cli, fnum, data, nread + start, read_size); if (n <= 0) break; - + + /* Progress bar */ + if(progress) progressbar(nread, start, size, tp_start); + + if (writefile(handle,data, n) != n) { d_printf("Error writing local file\n"); rc = 1; @@ -720,6 +849,12 @@ nread += n; } + /* For neat formatting */ + if(progress) { + progressbar(size, start, size, tp_start); + fprintf(stderr, "\n"); + } + if (nread + start < size) { DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n", rname, (long)nread)); @@ -2101,6 +2236,7 @@ {"print",cmd_print," print a file",{COMPL_NONE,COMPL_NONE}}, {"printmode",cmd_printmode," set the print mode",{COMPL_NONE,COMPL_NONE}}, {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}}, + {"progress",cmd_progress,"toggle the progress bar",{COMPL_NONE,COMPL_NONE}}, {"put",cmd_put," [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}}, {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}}, {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},