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)
 	{

Reply via email to