diff options
Diffstat (limited to 'apt-pkg/acquire-method.cc')
-rw-r--r-- | apt-pkg/acquire-method.cc | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc new file mode 100644 index 000000000..bd7dd6779 --- /dev/null +++ b/apt-pkg/acquire-method.cc @@ -0,0 +1,245 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-method.cc,v 1.1 1998/10/30 07:53:35 jgg Exp $ +/* ###################################################################### + + Acquire Method + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/acquire-method.h" +#endif +#include <apt-pkg/acquire-method.h> +#include <apt-pkg/error.h> +#include <apt-pkg/configuration.h> +#include <strutl.h> +#include <apt-pkg/fileutl.h> + +#include <stdio.h> + /*}}}*/ + +// AcqMethod::pkgAcqMethod - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* This constructs the initialization text */ +pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags) +{ + char S[300] = ""; + char *End = S; + strcat(End,"100 Capabilities\n"); + sprintf(End+strlen(End),"Version: %s\n",Ver); + + if ((Flags & SingleInstance) == SingleInstance) + strcat(End,"Single-Instance: true\n"); + + if ((Flags & PreScan) == PreScan) + strcat(End,"Pre-Scan: true\n"); + + if ((Flags & Pipeline) == Pipeline) + strcat(End,"Pipeline: true\n"); + + if ((Flags & SendConfig) == SendConfig) + strcat(End,"Send-Config: true\n"); + strcat(End,"\n"); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::Fail - A fetch has failed /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Fail() +{ + string Err = "Undetermined Error"; + if (_error->empty() == false) + _error->PopMessage(Err); + _error->Discard(); + Fail(Err); +} + /*}}}*/ +// AcqMethod::Fail - A fetch has failed /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Fail(string Err) +{ + char S[1024]; + snprintf(S,sizeof(S),"400 URI Failure\nURI: %s\n" + "Message %s\n\n",CurrentURI.c_str(),Err.c_str()); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::URIStart - Indicate a download is starting /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::URIStart(FetchResult &Res,unsigned long Resume = 0) +{ + char S[1024] = ""; + char *End = S; + + End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",CurrentURI.c_str()); + if (Res.Size != 0) + End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size); + + if (Res.LastModified != 0) + End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n", + TimeRFC1123(Res.LastModified).c_str()); + + if (Resume != 0) + End += snprintf(End,sizeof(S) - (End - S),"Resume-Point: %u\n", + Resume); + + strcat(End,"\n"); + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::URIDone - A URI is finished /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt) +{ + char S[1024] = ""; + char *End = S; + + End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",CurrentURI.c_str()); + + if (Res.Filename.empty() == false) + End += snprintf(End,sizeof(S) - (End - S),"Filename: %s\n",Res.Filename.c_str()); + + if (Res.Size != 0) + End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size); + + if (Res.LastModified != 0) + End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n", + TimeRFC1123(Res.LastModified).c_str()); + + if (Res.MD5Sum.empty() == false) + End += snprintf(End,sizeof(S) - (End - S),"MD5Sum: %s\n",Res.MD5Sum.c_str()); + + if (Res.IMSHit == true) + strcat(End,"IMS-Hit: true\n"); + End = S + strlen(S); + + if (Alt != 0) + { + if (Alt->Filename.empty() == false) + End += snprintf(End,sizeof(S) - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str()); + + if (Alt->Size != 0) + End += snprintf(End,sizeof(S) - (End - S),"Alt-Size: %u\n",Alt->Size); + + if (Alt->LastModified != 0) + End += snprintf(End,sizeof(S) - (End - S),"Alt-Last-Modified: %s\n", + TimeRFC1123(Alt->LastModified).c_str()); + + if (Alt->MD5Sum.empty() == false) + End += snprintf(End,sizeof(S) - (End - S),"Alt-MD5Sum: %s\n", + Alt->MD5Sum.c_str()); + + if (Alt->IMSHit == true) + strcat(End,"Alt-IMS-Hit: true\n"); + } + + strcat(End,"\n"); + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::Configuration - Handle the configuration message /*{{{*/ +// --------------------------------------------------------------------- +/* This parses each configuration entry and puts it into the _config + Configuration class. */ +bool pkgAcqMethod::Configuration(string Message) +{ + ::Configuration &Cnf = *_config; + + const char *I = Message.begin(); + + unsigned int Length = strlen("Config-Item"); + for (; I + Length < Message.end(); I++) + { + // Not a config item + if (I[Length] != ':' || stringcasecmp(I,I+Length,"Config-Item") != 0) + continue; + + I += Length + 1; + + for (; I < Message.end() && *I == ' '; I++); + const char *Equals = I; + for (; Equals < Message.end() && *Equals != '='; Equals++); + const char *End = Equals; + for (; End < Message.end() && *End != '\n'; End++); + if (End == Equals) + return false; + + Cnf.Set(string(I,Equals-I),string(Equals+1,End-Equals-1)); + I = End; + } + + return true; +} + /*}}}*/ +// AcqMethod::Run - Run the message engine /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int pkgAcqMethod::Run() +{ + SetNonBlock(STDIN_FILENO,true); + + while (1) + { + if (Messages.empty() == true) + if (WaitFd(STDIN_FILENO) == false) + return 0; + + if (ReadMessages(STDIN_FILENO,Messages) == false) + return 0; + + string Message = Messages.front(); + Messages.erase(Messages.begin()); + + // Fetch the message number + char *End; + int Number = strtol(Message.c_str(),&End,10); + if (End == Message.c_str()) + { + cerr << "Malformed message!" << endl; + return 100; + } + + switch (Number) + { + case 601: + if (Configuration(Message) == false) + return 100; + break; + + case 600: + { + CurrentURI = LookupTag(Message,"URI"); + DestFile = LookupTag(Message,"FileName"); + StrToTime(LookupTag(Message,"Last-Modified"),LastModified); + + if (Fetch(Message,CurrentURI) == false) + Fail(); + break; + } + } + } + + return 0; +} + /*}}}*/ +// AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcqMethod::FetchResult::FetchResult() : LastModified(0), + IMSHit(false), Size(0) +{ +} + /*}}}*/ + |