Package: apt-move
Version: 4.2.23
Followup-For: Bug #74784
Hi
I wrote a patch for fetch.cc to get a download progress indicator.
It can be switch of with the "-q" option from apt-move.
acqprogress.cc and acqprogress.h come from the apt source.
Robert
*** apt-move-4.2.23-download-progress.patch
diff -Naur apt-move-4.2.23/acqprogress.cc
apt-move-4.2.23-download-progress/acqprogress.cc
--- apt-move-4.2.23/acqprogress.cc 1970-01-01 01:00:00.000000000 +0100
+++ apt-move-4.2.23-download-progress/acqprogress.cc 2005-05-31
00:21:02.000000000 +0200
@@ -0,0 +1,283 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: acqprogress.cc,v 1.24 2003/04/27 01:56:48 doogie Exp $
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+// Include files /*{{{*/
+#include "acqprogress.h"
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/acquire-worker.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/error.h>
+
+//#include <apti18n.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <iostream>
+ /*}}}*/
+
+using namespace std;
+
+// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) :
+ ScreenWidth(ScreenWidth), Quiet(Quiet)
+{
+}
+ /*}}}*/
+// AcqTextStatus::Start - Downloading has started /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::Start()
+{
+ pkgAcquireStatus::Start();
+ BlankLine[0] = 0;
+ ID = 1;
+};
+ /*}}}*/
+// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << "Hit " << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fetch - An item has started to download /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the short description and the expected size */
+void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+ if (Itm.Owner->Complete == true)
+ return;
+
+ Itm.Owner->ID = ID++;
+
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ cout << "Get:" << Itm.Owner->ID << ' ' << Itm.Description;
+ if (Itm.Owner->FileSize != 0)
+ cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]";
+ cout << endl;
+};
+ /*}}}*/
+// AcqTextStatus::Done - Completed a download /*{{{*/
+// ---------------------------------------------------------------------
+/* We don't display anything... */
+void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm)
+{
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/
+// ---------------------------------------------------------------------
+/* We print out the error text */
+void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm)
+{
+ if (Quiet > 1)
+ return;
+
+ // Ignore certain kinds of transient failures (bad code)
+ if (Itm.Owner->Status == pkgAcquire::Item::StatIdle)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+
+ if (Itm.Owner->Status == pkgAcquire::Item::StatDone)
+ {
+ cout << "Ign " << Itm.Description << endl;
+ }
+ else
+ {
+ cout << "Err " << Itm.Description << endl;
+ cout << " " << Itm.Owner->ErrorText << endl;
+ }
+
+ Update = true;
+};
+ /*}}}*/
+// AcqTextStatus::Stop - Finished downloading /*{{{*/
+// ---------------------------------------------------------------------
+/* This prints out the bytes downloaded and the overall average line
+ speed */
+void AcqTextStatus::Stop()
+{
+ pkgAcquireStatus::Stop();
+ if (Quiet > 1)
+ return;
+
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r' << flush;
+
+ if (FetchedBytes != 0 && _error->PendingError() == false)
+ ioprintf(cout,"Fetched %sB in %s (%sB/s)\n",
+ SizeToStr(FetchedBytes).c_str(),
+ TimeToStr(ElapsedTime).c_str(),
+ SizeToStr(CurrentCPS).c_str());
+}
+ /*}}}*/
+// AcqTextStatus::Pulse - Regular event pulse /*{{{*/
+// ---------------------------------------------------------------------
+/* This draws the current progress. Each line has an overall percent
+ meter and a per active item status meter along with an overall
+ bandwidth and ETA indicator. */
+bool AcqTextStatus::Pulse(pkgAcquire *Owner)
+{
+ if (Quiet > 0)
+ return true;
+
+ pkgAcquireStatus::Pulse(Owner);
+
+ enum {Long = 0,Medium,Short} Mode = Long;
+
+ char Buffer[sizeof(BlankLine)];
+ char *End = Buffer + sizeof(Buffer);
+ char *S = Buffer;
+ if (ScreenWidth >= sizeof(Buffer))
+ ScreenWidth = sizeof(Buffer)-1;
+
+ // Put in the percent done
+ sprintf(S,"%ld%%",long(double((CurrentBytes +
CurrentItems)*100.0)/double(TotalBytes+TotalItems)));
+
+ bool Shown = false;
+ for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0;
+ I = Owner->WorkerStep(I))
+ {
+ S += strlen(S);
+
+ // There is no item running
+ if (I->CurrentItem == 0)
+ {
+ if (I->Status.empty() == false)
+ {
+ snprintf(S,End-S," [%s]",I->Status.c_str());
+ Shown = true;
+ }
+
+ continue;
+ }
+
+ Shown = true;
+
+ // Add in the short description
+ if (I->CurrentItem->Owner->ID != 0)
+ snprintf(S,End-S," [%lu %s",I->CurrentItem->Owner->ID,
+ I->CurrentItem->ShortDesc.c_str());
+ else
+ snprintf(S,End-S," [%s",I->CurrentItem->ShortDesc.c_str());
+ S += strlen(S);
+
+ // Show the short mode string
+ if (I->CurrentItem->Owner->Mode != 0)
+ {
+ snprintf(S,End-S," %s",I->CurrentItem->Owner->Mode);
+ S += strlen(S);
+ }
+
+ // Add the current progress
+ if (Mode == Long)
+ snprintf(S,End-S," %lu",I->CurrentSize);
+ else
+ {
+ if (Mode == Medium || I->TotalSize == 0)
+ snprintf(S,End-S," %sB",SizeToStr(I->CurrentSize).c_str());
+ }
+ S += strlen(S);
+
+ // Add the total size and percent
+ if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false)
+ {
+ if (Mode == Short)
+ snprintf(S,End-S," %lu%%",
+ long(double(I->CurrentSize*100.0)/double(I->TotalSize)));
+ else
+ snprintf(S,End-S,"/%sB %lu%%",SizeToStr(I->TotalSize).c_str(),
+ long(double(I->CurrentSize*100.0)/double(I->TotalSize)));
+ }
+ S += strlen(S);
+ snprintf(S,End-S,"]");
+ }
+
+ // Show something..
+ if (Shown == false)
+ snprintf(S,End-S," [Working]");
+
+ /* Put in the ETA and cps meter, block off signals to prevent strangeness
+ during resizing */
+ sigset_t Sigs,OldSigs;
+ sigemptyset(&Sigs);
+ sigaddset(&Sigs,SIGWINCH);
+ sigprocmask(SIG_BLOCK,&Sigs,&OldSigs);
+
+ if (CurrentCPS != 0)
+ {
+ char Tmp[300];
+ unsigned long ETA = (unsigned long)((TotalBytes -
CurrentBytes)/CurrentCPS);
+ sprintf(Tmp," %sB/s
%s",SizeToStr(CurrentCPS).c_str(),TimeToStr(ETA).c_str());
+ unsigned int Len = strlen(Buffer);
+ unsigned int LenT = strlen(Tmp);
+ if (Len + LenT < ScreenWidth)
+ {
+ memset(Buffer + Len,' ',ScreenWidth - Len);
+ strcpy(Buffer + ScreenWidth - LenT,Tmp);
+ }
+ }
+ Buffer[ScreenWidth] = 0;
+ BlankLine[ScreenWidth] = 0;
+ sigprocmask(SIG_SETMASK,&OldSigs,0);
+
+ // Draw the current status
+ if (strlen(Buffer) == strlen(BlankLine))
+ cout << '\r' << Buffer << flush;
+ else
+ cout << '\r' << BlankLine << '\r' << Buffer << flush;
+ memset(BlankLine,' ',strlen(Buffer));
+ BlankLine[strlen(Buffer)] = 0;
+
+ Update = false;
+
+ return true;
+}
+ /*}}}*/
+// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/
+// ---------------------------------------------------------------------
+/* Prompt for a media swap */
+bool AcqTextStatus::MediaChange(string Media,string Drive)
+{
+ if (Quiet <= 0)
+ cout << '\r' << BlankLine << '\r';
+ ioprintf(cout,"Media Change: Please insert the disc labeled\n"
+ " '%s'\n"
+ "in the drive '%s' and press enter\n",
+ Media.c_str(),Drive.c_str());
+
+ char C = 0;
+ while (C != '\n' && C != '\r')
+ read(STDIN_FILENO,&C,1);
+
+ Update = true;
+ return true;
+}
+ /*}}}*/
diff -Naur apt-move-4.2.23/acqprogress.h
apt-move-4.2.23-download-progress/acqprogress.h
--- apt-move-4.2.23/acqprogress.h 1970-01-01 01:00:00.000000000 +0100
+++ apt-move-4.2.23-download-progress/acqprogress.h 2005-05-31
00:05:38.000000000 +0200
@@ -0,0 +1,37 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: acqprogress.h,v 1.5 2003/02/02 22:24:11 jgg Exp $
+/* ######################################################################
+
+ Acquire Progress - Command line progress meter
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef ACQPROGRESS_H
+#define ACQPROGRESS_H
+
+#include <apt-pkg/acquire.h>
+
+class AcqTextStatus : public pkgAcquireStatus
+{
+ unsigned int &ScreenWidth;
+ char BlankLine[1024];
+ unsigned long ID;
+ unsigned long Quiet;
+
+ public:
+
+ virtual bool MediaChange(string Media,string Drive);
+ virtual void IMSHit(pkgAcquire::ItemDesc &Itm);
+ virtual void Fetch(pkgAcquire::ItemDesc &Itm);
+ virtual void Done(pkgAcquire::ItemDesc &Itm);
+ virtual void Fail(pkgAcquire::ItemDesc &Itm);
+ virtual void Start();
+ virtual void Stop();
+
+ bool Pulse(pkgAcquire *Owner);
+
+ AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet);
+};
+
+#endif
diff -Naur apt-move-4.2.23/apt-move apt-move-4.2.23-download-progress/apt-move
--- apt-move-4.2.23/apt-move 2004-11-22 00:04:26.000000000 +0100
+++ apt-move-4.2.23-download-progress/apt-move 2005-06-02 00:03:55.000000000
+0200
@@ -1433,7 +1433,11 @@
xargs -r $FETCH -t
return 0
fi
- xargs -r $FETCH
+ if [ $QUIET ]; then
+ xargs -r $FETCH -q
+ else
+ xargs -r $FETCH
+ fi
}
domove
}
diff -Naur apt-move-4.2.23/fetch.cc apt-move-4.2.23-download-progress/fetch.cc
--- apt-move-4.2.23/fetch.cc 2004-11-21 23:23:15.000000000 +0100
+++ apt-move-4.2.23-download-progress/fetch.cc 2005-06-02 00:08:39.000000000
+0200
@@ -10,6 +10,11 @@
#include <stdlib.h>
#include <unistd.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <apt-pkg/strutl.h>
+#include "acqprogress.h"
+
using std::cerr;
using std::cout;
using std::endl;
@@ -19,6 +24,20 @@
#define NotSource pkgCache::Flag::NotSource
#define NotAutomatic pkgCache::Flag::NotAutomatic
+unsigned int ScreenWidth=80;
+
+// SigWinch - window size change signal handler
+void SigWinch(int)
+{
+ // riped from GNU ls
+#ifdef TIOCGWINSZ
+ struct winsize ws;
+
+ if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
+ ScreenWidth = ws.ws_col - 1;
+#endif
+}
+
VerIterator getHighestVersion(pkgCache &cache, pkgCache::PkgIterator pkg) {
VerIterator last(cache, 0);
@@ -59,7 +78,9 @@
"Unable to lock the download directory");
}
- pkgAcquire fetcher;
+ // Create the download object
+ AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
+ pkgAcquire fetcher(&Stat);
pkgSourceList list;
if (!list.ReadMainList())
@@ -89,6 +110,18 @@
return true;
}
+ // Display statistics
+ double FetchBytes = fetcher.FetchNeeded();
+ double DebBytes = fetcher.TotalNeeded();
+
+ // Number of bytes
+ if (DebBytes != FetchBytes)
+ ioprintf(cout,"Need to get %sB/%sB of archives.\n",
+ SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
+ else
+ ioprintf(cout,"Need to get %sB of archives.\n",
+ SizeToStr(DebBytes).c_str());
+
if (fetcher.Run() == pkgAcquire::Failed)
return false;
@@ -96,20 +129,24 @@
}
static void usage(const char *name) {
- cerr << "usage: " << name << " [-t] pkg..." << endl;
+ cerr << "usage: " << name << " [-t] [-q] pkg..." << endl;
exit(1);
}
int main(int argc, char **argv) {
int test = 0;
+ int quiet = 0;
const char *progname = argv[0];
int c;
- while ((c = getopt(argc, argv, "t")) != -1) {
+ while ((c = getopt(argc, argv, "tq")) != -1) {
switch (c) {
case 't':
test = 1;
break;
+ case 'q':
+ quiet = 1;
+ break;
default:
usage(progname);
}
@@ -125,6 +162,13 @@
if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
_config->Set("quiet","1");
+ if (quiet)
+ _config->Set("quiet","2");
+
+ // setup the signals
+ signal(SIGWINCH,SigWinch);
+ SigWinch(0);
+
downloadPackages(test, argc, argv);
if (!_error->empty()) {
diff -Naur apt-move-4.2.23/Makefile apt-move-4.2.23-download-progress/Makefile
--- apt-move-4.2.23/Makefile 2004-11-21 23:23:15.000000000 +0100
+++ apt-move-4.2.23-download-progress/Makefile 2005-05-31 00:37:03.000000000
+0200
@@ -14,7 +14,7 @@
all: fetch
-fetch: fetch.o
+fetch: fetch.o acqprogress.o
$(CXX) -o $@ $(LDFLAGS) $^ $(LOADLIBS) $(LDLIBS)
clean:
-- System Information:
Debian Release: 3.1
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Locale: LANG=de_CH, LC_CTYPE=de_CH (charmap=ISO-8859-1) (ignored: LC_ALL set to
de_CH)
Versions of packages apt-move depends on:
ii apt [libapt-pkg-libc6.3-5-3 0.5.28.6 Advanced front-end for dpkg
ii bc 1.06-17 The GNU bc arbitrary precision cal
ii coreutils 5.2.1-2 The GNU core utilities
ii dash 0.5.2-2 The Debian Almquist Shell
ii libc6 2.3.2.ds1-21 GNU C Library: Shared libraries an
ii libgcc1 1:3.4.3-12 GCC support library
ii libstdc++5 1:3.3.5-12 The GNU Standard C++ Library v3
ii mawk 1.3.3-11 a pattern scanning and text proces
-- no debconf information
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]