+ // Normalize the figures and account for unknown size downloads
+ if (TotalBytes <= 0)
+ TotalBytes = 1;
+ if (Unknown == Count)
+ TotalBytes = Unknown;
+
+ // Wha?! Is not supposed to happen.
+ if (CurrentBytes > TotalBytes)
+ CurrentBytes = TotalBytes;
+
+ // Compute the CPS
+ struct timeval NewTime;
+ gettimeofday(&NewTime,0);
+ if (NewTime.tv_sec - Time.tv_sec == 6 && NewTime.tv_usec > Time.tv_usec ||
+ NewTime.tv_sec - Time.tv_sec > 6)
+ {
+ double Delta = NewTime.tv_sec - Time.tv_sec +
+ (NewTime.tv_usec - Time.tv_usec)/1000000.0;
+
+ // Compute the CPS value
+ if (Delta < 0.01)
+ CurrentCPS = 0;
+ else
+ CurrentCPS = ((CurrentBytes - ResumeSize) - LastBytes)/Delta;
+ LastBytes = CurrentBytes - ResumeSize;
+ ElapsedTime = (unsigned long)Delta;
+ Time = NewTime;
+ }
+
+ int fd = _config->FindI("APT::Status-Fd",-1);
+ if(fd > 0)
+ {
+ ostringstream status;
+
+ char msg[200];
+ long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems;
+ unsigned long ETA =
+ (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS);
+
+ // only show the ETA if it makes sense
+ if (ETA > 0 && ETA < 172800 /* two days */ )
+ snprintf(msg,sizeof(msg), _("Retrieving file %li of %li (%s remaining)"), i, TotalItems, TimeToStr(ETA).c_str());
+ else
+ snprintf(msg,sizeof(msg), _("Retrieving file %li of %li"), i, TotalItems);
+
+
+
+ // build the status str
+ status << "dlstatus:" << i
+ << ":" << (CurrentBytes/float(TotalBytes)*100.0)
+ << ":" << msg
+ << endl;
+ write(fd, status.str().c_str(), status.str().size());
+ }
+
+ return true;
+}
+ /*}}}*/
+// AcquireStatus::Start - Called when the download is started /*{{{*/
+// ---------------------------------------------------------------------
+/* We just reset the counters */
+void pkgAcquireStatus::Start()
+{
+ gettimeofday(&Time,0);
+ gettimeofday(&StartTime,0);
+ LastBytes = 0;
+ CurrentCPS = 0;
+ CurrentBytes = 0;
+ TotalBytes = 0;
+ FetchedBytes = 0;
+ ElapsedTime = 0;
+ TotalItems = 0;
+ CurrentItems = 0;
+}
+ /*}}}*/
+// AcquireStatus::Stop - Finished downloading /*{{{*/
+// ---------------------------------------------------------------------
+/* This accurately computes the elapsed time and the total overall CPS. */
+void pkgAcquireStatus::Stop()
+{
+ // Compute the CPS and elapsed time
+ struct timeval NewTime;
+ gettimeofday(&NewTime,0);
+
+ double Delta = NewTime.tv_sec - StartTime.tv_sec +
+ (NewTime.tv_usec - StartTime.tv_usec)/1000000.0;
+
+ // Compute the CPS value
+ if (Delta < 0.01)
+ CurrentCPS = 0;
+ else
+ CurrentCPS = FetchedBytes/Delta;
+ LastBytes = CurrentBytes;
+ ElapsedTime = (unsigned int)Delta;
+}
+ /*}}}*/
+// AcquireStatus::Fetched - Called when a byte set has been fetched /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to get accurate final transfer rate reporting. */
+void pkgAcquireStatus::Fetched(unsigned long Size,unsigned long Resume)
+{
+ FetchedBytes += Size - Resume;