// -*- 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 #include #include #include #include #include /*}}}*/ // 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) { } /*}}}*/