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]

Reply via email to