when copying large files (around a gig), rcp will choke.
herre is the fix and a function for printing status when running as a sink.
license is public domain. no attribution.
diff -wBrNU3 inetutils-1.9/src/rcp.c inetutils-1.9-1/src/rcp.c
--- inetutils-1.9/src/rcp.c 2011-12-31 15:02:32.000000000 +0000
+++ inetutils-1.9-1/src/rcp.c 2012-01-02 07:08:08.120789750 +0000
@@ -708,6 +708,141 @@
response ();
}
+ int
+precision(value)
+ double value;
+{
+ if(1 > value)
+ return 4;
+ if(10 > value)
+ return 3;
+ if(100 > value)
+ return 2;
+ return 1;
+}
+void printstatus(double current,double total);
+ void
+printstatus(current,total)
+ double current,total;
+{
+ static char output[60];
+ static double lastupdate = 0,lastcurrent = 0,startupdate = 0
+ ,_avgrate = 0;
+ struct timeval _now;
+ double now,rate,avgrate;
+ unsigned eta,sizeorder,rateorder;
+ char* outputcc[2];
+ gettimeofday(&_now,NULL);
+ now = _now.tv_sec + (((double) _now.tv_usec) / 1e6);
+ if( ! current )
+ {
+ startupdate = now;
+ lastupdate = now;
+ lastcurrent = 0;
+ return;
+ }
+ if(( ! (total == current) ) && (1 > (now - lastupdate)))
+ return;
+ if(( ! lastcurrent ) && ( ! (total == current) ))
+ printf("\n");
+ rate = (current - lastcurrent) / (now - lastupdate);
+ if(total == current)
+ {
+ if( ! lastcurrent )
+ return;
+ avgrate = total / (now - startupdate);
+ eta = now - startupdate;
+ }
+ else
+ {
+ if( ! _avgrate )
+ _avgrate = rate;
+ else
+ _avgrate = (0.1 * rate) + (0.9 * _avgrate);
+ eta = (total - current) / _avgrate;
+ lastupdate = now;
+ lastcurrent = current;
+ avgrate = _avgrate;
+ }
+ rateorder = 0;
+ for(;;)
+ {
+#define max(A,B) (((A) < (B)) ? (B) : (A))
+ if(1000 > max(rate,avgrate))
+#undef max
+ break;
+ rate /= 1024;
+ avgrate /= 1024;
+ ++rateorder;
+ }
+ sizeorder = 0;
+ for(;;)
+ {
+ if(1000 > total)
+ break;
+ current /= 1024;
+ total /= 1024;
+ ++sizeorder;
+ }
+ outputcc[0] = output;
+ outputcc[1]
+ = &outputcc[0][
+ sprintf(outputcc[0],"%4.*f/",precision(current),current)
+ ];
+ if(4 == precision(current))
+ {
+ --outputcc[1];
+ memmove(outputcc[0],&outputcc[0][1],outputcc[1] - outputcc[0]);
+ }
+ outputcc[0] = outputcc[1];
+ outputcc[1]
+ = &outputcc[0][
+ sprintf(
+ outputcc[0]
+ ,"%4.*f %cb @ "
+ ,precision(total),total
+ ," KMGTP"[sizeorder]
+ )
+ ];
+ if(4 == precision(total))
+ {
+ --outputcc[1];
+ memmove(outputcc[0],&outputcc[0][1],outputcc[1] - outputcc[0]);
+ }
+ outputcc[0] = outputcc[1];
+ outputcc[1]
+ = &outputcc[0][
+ sprintf(
+ outputcc[0]
+ ,"%4.*f ["
+ ,precision(rate),rate," KMGTP"[rateorder]
+ )
+ ];
+ if(4 == precision(rate))
+ {
+ --outputcc[1];
+ memmove(outputcc[0],&outputcc[0][1],outputcc[1] - outputcc[0]);
+ }
+ outputcc[0] = outputcc[1];
+ outputcc[1]
+ = &outputcc[0][
+ sprintf(
+ outputcc[0]
+ ,"%4.*f] %cb/s (%02u:%02u:%02u)"
+ ,precision(avgrate),avgrate," KMGTP"[rateorder]
+ ,eta / (60 * 60),(eta / 60) % 60,eta % 60
+ )
+ ];
+ if(4 == precision(avgrate))
+ {
+ --outputcc[1];
+ memmove(outputcc[0],&outputcc[0][1],outputcc[1] - outputcc[0]);
+ }
+ setbuf(stdout,NULL);
+ printf("\033[2K\033[0G %s",output);
+ setlinebuf(stdout);
+}
+
void
sink (int argc, char *argv[])
{
@@ -717,9 +852,9 @@
enum
{ YES, NO, DISPLAYED } wrerr;
BUF *bp;
- off_t i, j;
+ off_t i, j, size;
int amt, count, exists, first, mask, mode, ofd, omode;
- int setimes, size, targisdir, wrerrno;
+ int setimes, targisdir, wrerrno;
char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ];
const char *why;
@@ -727,6 +862,7 @@
#define mtime tv[1]
#define SCREWUP(str) { why = str; goto screwup; }
+ setbuf(stdout,NULL);
setimes = targisdir = 0;
mask = umask (0);
if (!preserve_option)
@@ -902,6 +1038,8 @@
}
cp = bp->buf;
wrerr = NO;
+ printf("%s",np);
+ printstatus(i,size);
for (count = i = 0; i < size; i += BUFSIZ)
{
amt = BUFSIZ;
@@ -935,7 +1073,10 @@
count = 0;
cp = bp->buf;
}
+ printstatus(i,size);
}
+ printstatus(size,size);
+ printf("\n");
if (count != 0 && wrerr == NO
&& (j = write (ofd, bp->buf, count)) != count)
{