X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/bdae53f1bf6710404235bbbd071c55f4ec1a9330..76fcbe5c97849dcbbe67434d08e0a22c02fedd51:/apt-pkg/acquire-worker.cc diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index d5b4541a3..4f0b52af9 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: acquire-worker.cc,v 1.26 1999/08/03 05:19:41 jgg Exp $ +// $Id: acquire-worker.cc,v 1.34 2001/05/22 04:42:54 jgg Exp $ /* ###################################################################### Acquire Worker @@ -12,9 +12,6 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/acquire-worker.h" -#endif #include #include #include @@ -22,6 +19,12 @@ #include #include +#include + +#include +#include +#include + #include #include #include @@ -30,6 +33,8 @@ #include /*}}}*/ +using namespace std; + // Worker::Worker - Constructor for Queue startup /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -86,7 +91,10 @@ pkgAcquire::Worker::~Worker() if (Process > 0) { - kill(Process,SIGINT); + /* Closing of stdin is the signal to exit and die when the process + indicates it needs cleanup */ + if (Config->NeedsCleanup == false) + kill(Process,SIGINT); ExecWait(Process,Access.c_str(),true); } } @@ -99,7 +107,7 @@ bool pkgAcquire::Worker::Start() // Get the method path string Method = _config->FindDir("Dir::Bin::Methods") + Access; if (FileExists(Method) == false) - return _error->Error("The method driver %s could not be found.",Method.c_str()); + return _error->Error(_("The method driver %s could not be found."),Method.c_str()); if (Debug == true) clog << "Starting method '" << Method << '\'' << endl; @@ -114,18 +122,15 @@ bool pkgAcquire::Worker::Start() return false; } for (int I = 0; I != 4; I++) - SetCloseExec(Pipes[0],true); + SetCloseExec(Pipes[I],true); // Fork off the process Process = ExecFork(); - - // Spawn the subprocess if (Process == 0) { // Setup the FDs dup2(Pipes[1],STDOUT_FILENO); dup2(Pipes[2],STDIN_FILENO); - dup2(((filebuf *)clog.rdbuf())->fd(),STDERR_FILENO); SetCloseExec(STDOUT_FILENO,false); SetCloseExec(STDIN_FILENO,false); SetCloseExec(STDERR_FILENO,false); @@ -151,7 +156,7 @@ bool pkgAcquire::Worker::Start() // Read the configuration data if (WaitFd(InFd) == false || ReadMessages() == false) - return _error->Error("Method %s did not start correctly",Method.c_str()); + return _error->Error(_("Method %s did not start correctly"),Method.c_str()); RunMessages(); if (OwnerQ != 0) @@ -215,6 +220,20 @@ bool pkgAcquire::Worker::RunMessages() Status = LookupTag(Message,"Message"); break; + // 103 Redirect + case 103: + { + if (Itm == 0) + { + _error->Error("Method gave invalid 103 Redirect message"); + break; + } + + string NewURI = LookupTag(Message,"New-URI",URI.c_str()); + Itm->URI = NewURI; + break; + } + // 200 URI Start case 200: { @@ -230,6 +249,10 @@ bool pkgAcquire::Worker::RunMessages() ResumePoint = atoi(LookupTag(Message,"Resume-Point","0").c_str()); Itm->Owner->Start(Message,atoi(LookupTag(Message,"Size","0").c_str())); + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Itm->Owner->GetOwner()); + if (Log != 0) Log->Fetch(*Itm); @@ -244,17 +267,39 @@ bool pkgAcquire::Worker::RunMessages() _error->Error("Method gave invalid 201 URI Done message"); break; } - + pkgAcquire::Item *Owner = Itm->Owner; pkgAcquire::ItemDesc Desc = *Itm; + + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Owner->GetOwner()); + OwnerQ->ItemDone(Itm); - if (TotalSize != 0 && - atoi(LookupTag(Message,"Size","0").c_str()) != TotalSize) - _error->Warning("Bizzar Error - File size is not what the server reported %s %u", + if (TotalSize != 0 && + (unsigned)atoi(LookupTag(Message,"Size","0").c_str()) != TotalSize) + _error->Warning("Bizarre Error - File size is not what the server reported %s %lu", LookupTag(Message,"Size","0").c_str(),TotalSize); + // see if there is a hash to verify + string RecivedHash; + HashString expectedHash(Owner->HashSum()); + if(!expectedHash.empty()) + { + string hashTag = expectedHash.HashType()+"-Hash"; + string hashSum = LookupTag(Message, hashTag.c_str()); + if(!hashSum.empty()) + RecivedHash = expectedHash.HashType() + ":" + hashSum; + if(_config->FindB("Debug::pkgAcquire::Auth", false) == true) + { + clog << "201 URI Done: " << Owner->DescURI() << endl + << "RecivedHash: " << RecivedHash << endl + << "ExpectedHash: " << expectedHash.toStr() + << endl << endl; + } + } Owner->Done(Message,atoi(LookupTag(Message,"Size","0").c_str()), - LookupTag(Message,"MD5-Hash")); + RecivedHash.c_str(), Config); ItemDone(); // Log that we are done @@ -283,9 +328,21 @@ bool pkgAcquire::Worker::RunMessages() break; } + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Itm->Owner->GetOwner()); + pkgAcquire::Item *Owner = Itm->Owner; pkgAcquire::ItemDesc Desc = *Itm; OwnerQ->ItemDone(Itm); + + // set some status + if(LookupTag(Message,"FailReason") == "Timeout" || + LookupTag(Message,"FailReason") == "TmpResolveFailure" || + LookupTag(Message,"FailReason") == "ResolveFailure" || + LookupTag(Message,"FailReason") == "ConnectionRefused") + Owner->Status = pkgAcquire::Item::StatTransientNetworkError; + Owner->Failed(Message,Config); ItemDone(); @@ -297,7 +354,7 @@ bool pkgAcquire::Worker::RunMessages() // 401 General Failure case 401: - _error->Error("Method %s General failure: %s",LookupTag(Message,"Message").c_str()); + _error->Error("Method %s General failure: %s",Access.c_str(),LookupTag(Message,"Message").c_str()); break; // 403 Media Change @@ -323,15 +380,20 @@ bool pkgAcquire::Worker::Capabilities(string Message) Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false); Config->SendConfig = StringToBool(LookupTag(Message,"Send-Config"),false); Config->LocalOnly = StringToBool(LookupTag(Message,"Local-Only"),false); + Config->NeedsCleanup = StringToBool(LookupTag(Message,"Needs-Cleanup"),false); + Config->Removable = StringToBool(LookupTag(Message,"Removable"),false); // Some debug text if (Debug == true) { clog << "Configured access method " << Config->Access << endl; - clog << "Version:" << Config->Version << " SingleInstance:" << - Config->SingleInstance << - " Pipeline:" << Config->Pipeline << " SendConfig:" << - Config->SendConfig << endl; + clog << "Version:" << Config->Version << + " SingleInstance:" << Config->SingleInstance << + " Pipeline:" << Config->Pipeline << + " SendConfig:" << Config->SendConfig << + " LocalOnly: " << Config->LocalOnly << + " NeedsCleanup: " << Config->NeedsCleanup << + " Removable: " << Config->Removable << endl; } return true; @@ -342,11 +404,29 @@ bool pkgAcquire::Worker::Capabilities(string Message) /* */ bool pkgAcquire::Worker::MediaChange(string Message) { + int status_fd = _config->FindI("APT::Status-Fd",-1); + if(status_fd > 0) + { + string Media = LookupTag(Message,"Media"); + string Drive = LookupTag(Message,"Drive"); + ostringstream msg,status; + ioprintf(msg,_("Please insert the disc labeled: " + "'%s' " + "in the drive '%s' and press enter."), + Media.c_str(),Drive.c_str()); + status << "media-change: " // message + << Media << ":" // media + << Drive << ":" // drive + << msg.str() // l10n message + << endl; + write(status_fd, status.str().c_str(), status.str().size()); + } + if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"), LookupTag(Message,"Drive")) == false) { char S[300]; - sprintf(S,"603 Media Changed\nFailed: true\n\n"); + snprintf(S,sizeof(S),"603 Media Changed\nFailed: true\n\n"); if (Debug == true) clog << " -> " << Access << ':' << QuoteString(S,"\n") << endl; OutQueue += S; @@ -355,7 +435,7 @@ bool pkgAcquire::Worker::MediaChange(string Message) } char S[300]; - sprintf(S,"603 Media Changed\n\n"); + snprintf(S,sizeof(S),"603 Media Changed\n\n"); if (Debug == true) clog << " -> " << Access << ':' << QuoteString(S,"\n") << endl; OutQueue += S; @@ -384,7 +464,7 @@ bool pkgAcquire::Worker::SendConfiguration() { if (Top->Value.empty() == false) { - string Line = "Config-Item: " + Top->FullTag() + "="; + string Line = "Config-Item: " + QuoteString(Top->FullTag(),"=\"\n") + "="; Line += QuoteString(Top->Value,"\n") + '\n'; Message += Line; } @@ -441,16 +521,12 @@ bool pkgAcquire::Worker::OutFdReady() int Res; do { - Res = write(OutFd,OutQueue.begin(),OutQueue.length()); + Res = write(OutFd,OutQueue.c_str(),OutQueue.length()); } while (Res < 0 && errno == EINTR); if (Res <= 0) return MethodFailure(); - - // Hmm.. this should never happen. - if (Res < 0) - return true; OutQueue.erase(0,Res); if (OutQueue.empty() == true) @@ -478,7 +554,8 @@ bool pkgAcquire::Worker::MethodFailure() { _error->Error("Method %s has died unexpectedly!",Access.c_str()); - ExecWait(Process,Access.c_str(),true); + // do not reap the child here to show meaningfull error to the user + ExecWait(Process,Access.c_str(),false); Process = -1; close(InFd); close(OutFd);