=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/progressmeter.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- src/usr.bin/ssh/progressmeter.c 2016/03/02 22:42:40 1.42 +++ src/usr.bin/ssh/progressmeter.c 2016/05/25 23:48:45 1.43 @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.42 2016/03/02 22:42:40 dtucker Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.43 2016/05/25 23:48:45 schwarze Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "progressmeter.h" #include "atomicio.h" #include "misc.h" +#include "utf8.h" #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 @@ -117,14 +119,14 @@ void refresh_progress_meter(void) { - char buf[MAX_WINSIZE + 1]; + char buf[MAX_WINSIZE * 4 + 1]; off_t transferred; double elapsed, now; int percent; off_t bytes_left; int cur_speed; int hours, minutes, seconds; - int i, len; + size_t i; int file_len; transferred = *counter - (cur_pos ? cur_pos : start_pos); @@ -155,17 +157,16 @@ bytes_per_second = cur_speed; /* filename */ - buf[0] = '\0'; + buf[0] = '\r'; + buf[1] = '\0'; file_len = win_size - 35; if (file_len > 0) { - len = snprintf(buf, file_len + 1, "\r%s", file); - if (len < 0) - len = 0; - if (len >= file_len + 1) - len = file_len; - for (i = len; i < file_len; i++) - buf[i] = ' '; - buf[file_len] = '\0'; + (void) snmprintf(buf + 1, sizeof(buf) - 1 - 35, + &file_len, "%s", file); + i = strlen(buf); + while (++file_len < win_size - 35 && i + 1 < sizeof(buf)) + buf[i++] = ' '; + buf[i] = '\0'; } /* percent of transfer done */ @@ -173,18 +174,18 @@ percent = ((float)cur_pos / end_pos) * 100; else percent = 100; - snprintf(buf + strlen(buf), win_size - strlen(buf), + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %3d%% ", percent); /* amount transferred */ - format_size(buf + strlen(buf), win_size - strlen(buf), + format_size(buf + strlen(buf), sizeof(buf) - strlen(buf), cur_pos); - strlcat(buf, " ", win_size); + strlcat(buf, " ", sizeof(buf)); /* bandwidth usage */ - format_rate(buf + strlen(buf), win_size - strlen(buf), + format_rate(buf + strlen(buf), sizeof(buf) - strlen(buf), (off_t)bytes_per_second); - strlcat(buf, "/s ", win_size); + strlcat(buf, "/s ", sizeof(buf)); /* ETA */ if (!transferred) @@ -193,9 +194,9 @@ stalled = 0; if (stalled >= STALL_TIME) - strlcat(buf, "- stalled -", win_size); + strlcat(buf, "- stalled -", sizeof(buf)); else if (bytes_per_second == 0 && bytes_left) - strlcat(buf, " --:-- ETA", win_size); + strlcat(buf, " --:-- ETA", sizeof(buf)); else { if (bytes_left > 0) seconds = bytes_left / bytes_per_second; @@ -208,19 +209,21 @@ seconds -= minutes * 60; if (hours != 0) - snprintf(buf + strlen(buf), win_size - strlen(buf), + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%d:%02d:%02d", hours, minutes, seconds); else - snprintf(buf + strlen(buf), win_size - strlen(buf), + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %02d:%02d", minutes, seconds); if (bytes_left > 0) - strlcat(buf, " ETA", win_size); + strlcat(buf, " ETA", sizeof(buf)); else - strlcat(buf, " ", win_size); + strlcat(buf, " ", sizeof(buf)); } + if (win_size < 35) + buf[win_size] = '\0'; - atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); + atomicio(vwrite, STDOUT_FILENO, buf, strlen(buf)); last_update = now; }