]>
git.saurik.com Git - apt.git/blob - apt-pkg/acquire-method.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: acquire-method.cc,v 1.18 1999/03/15 08:10:39 jgg Exp $
4 /* ######################################################################
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "apt-pkg/acquire-method.h"
14 #include <apt-pkg/acquire-method.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/strutl.h>
18 #include <apt-pkg/fileutl.h>
24 // AcqMethod::pkgAcqMethod - Constructor /*{{{*/
25 // ---------------------------------------------------------------------
26 /* This constructs the initialization text */
27 pkgAcqMethod::pkgAcqMethod(const char *Ver
,unsigned long Flags
)
31 strcat(End
,"100 Capabilities\n");
32 sprintf(End
+strlen(End
),"Version: %s\n",Ver
);
34 if ((Flags
& SingleInstance
) == SingleInstance
)
35 strcat(End
,"Single-Instance: true\n");
37 if ((Flags
& Pipeline
) == Pipeline
)
38 strcat(End
,"Pipeline: true\n");
40 if ((Flags
& SendConfig
) == SendConfig
)
41 strcat(End
,"Send-Config: true\n");
43 if ((Flags
& LocalOnly
) == LocalOnly
)
44 strcat(End
,"Local-Only: true\n");
47 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
50 SetNonBlock(STDIN_FILENO
,true);
56 // AcqMethod::Fail - A fetch has failed /*{{{*/
57 // ---------------------------------------------------------------------
59 void pkgAcqMethod::Fail(bool Transient
)
61 string Err
= "Undetermined Error";
62 if (_error
->empty() == false)
63 _error
->PopMessage(Err
);
68 // AcqMethod::Fail - A fetch has failed /*{{{*/
69 // ---------------------------------------------------------------------
71 void pkgAcqMethod::Fail(string Err
,bool Transient
)
73 // Strip out junk from the error messages
74 for (char *I
= Err
.begin(); I
!= Err
.end(); I
++)
85 snprintf(S
,sizeof(S
),"400 URI Failure\nURI: %s\n"
86 "Message: %s\n",Queue
->Uri
.c_str(),Err
.c_str());
89 FetchItem
*Tmp
= Queue
;
96 snprintf(S
,sizeof(S
),"400 URI Failure\nURI: <UNKNOWN>\n"
97 "Message: %s\n",Err
.c_str());
99 // Set the transient flag
100 if (Transient
== true)
101 strcat(S
,"Transient-Failure: true\n\n");
105 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
109 // AcqMethod::URIStart - Indicate a download is starting /*{{{*/
110 // ---------------------------------------------------------------------
112 void pkgAcqMethod::URIStart(FetchResult
&Res
)
120 End
+= snprintf(S
,sizeof(S
),"200 URI Start\nURI: %s\n",Queue
->Uri
.c_str());
122 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Size: %u\n",Res
.Size
);
124 if (Res
.LastModified
!= 0)
125 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Last-Modified: %s\n",
126 TimeRFC1123(Res
.LastModified
).c_str());
128 if (Res
.ResumePoint
!= 0)
129 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Resume-Point: %u\n",
133 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
137 // AcqMethod::URIDone - A URI is finished /*{{{*/
138 // ---------------------------------------------------------------------
140 void pkgAcqMethod::URIDone(FetchResult
&Res
, FetchResult
*Alt
)
148 End
+= snprintf(S
,sizeof(S
),"201 URI Done\nURI: %s\n",Queue
->Uri
.c_str());
150 if (Res
.Filename
.empty() == false)
151 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Filename: %s\n",Res
.Filename
.c_str());
154 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Size: %u\n",Res
.Size
);
156 if (Res
.LastModified
!= 0)
157 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Last-Modified: %s\n",
158 TimeRFC1123(Res
.LastModified
).c_str());
160 if (Res
.MD5Sum
.empty() == false)
161 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"MD5-Hash: %s\n",Res
.MD5Sum
.c_str());
163 if (Res
.ResumePoint
!= 0)
164 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Resume-Point: %u\n",
167 if (Res
.IMSHit
== true)
168 strcat(End
,"IMS-Hit: true\n");
173 if (Alt
->Filename
.empty() == false)
174 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Alt-Filename: %s\n",Alt
->Filename
.c_str());
177 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Alt-Size: %u\n",Alt
->Size
);
179 if (Alt
->LastModified
!= 0)
180 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Alt-Last-Modified: %s\n",
181 TimeRFC1123(Alt
->LastModified
).c_str());
183 if (Alt
->MD5Sum
.empty() == false)
184 End
+= snprintf(End
,sizeof(S
) - (End
- S
),"Alt-MD5-Hash: %s\n",
185 Alt
->MD5Sum
.c_str());
187 if (Alt
->IMSHit
== true)
188 strcat(End
,"Alt-IMS-Hit: true\n");
192 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
196 FetchItem
*Tmp
= Queue
;
199 if (Tmp
== QueueBack
)
203 // AcqMethod::MediaFail - Syncronous request for new media /*{{{*/
204 // ---------------------------------------------------------------------
205 /* This sends a 403 Media Failure message to the APT and waits for it
207 bool pkgAcqMethod::MediaFail(string Required
,string Drive
)
210 snprintf(S
,sizeof(S
),"403 Media Failure\nMedia: %s\nDrive: %s\n\n",
211 Required
.c_str(),Drive
.c_str());
213 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
216 vector
<string
> MyMessages
;
218 /* Here we read messages until we find a 603, each non 603 message is
219 appended to the main message list for later processing */
222 if (WaitFd(STDIN_FILENO
) == false)
225 if (ReadMessages(STDIN_FILENO
,MyMessages
) == false)
228 string Message
= MyMessages
.front();
229 MyMessages
.erase(MyMessages
.begin());
231 // Fetch the message number
233 int Number
= strtol(Message
.c_str(),&End
,10);
234 if (End
== Message
.c_str())
236 cerr
<< "Malformed message!" << endl
;
243 while (MyMessages
.empty() == false)
245 Messages
.push_back(MyMessages
.front());
246 MyMessages
.erase(MyMessages
.begin());
249 return !StringToBool(LookupTag(Message
,"Fail"),false);
252 Messages
.push_back(Message
);
256 // AcqMethod::Configuration - Handle the configuration message /*{{{*/
257 // ---------------------------------------------------------------------
258 /* This parses each configuration entry and puts it into the _config
259 Configuration class. */
260 bool pkgAcqMethod::Configuration(string Message
)
262 ::Configuration
&Cnf
= *_config
;
264 const char *I
= Message
.begin();
266 unsigned int Length
= strlen("Config-Item");
267 for (; I
+ Length
< Message
.end(); I
++)
270 if (I
[Length
] != ':' || stringcasecmp(I
,I
+Length
,"Config-Item") != 0)
275 for (; I
< Message
.end() && *I
== ' '; I
++);
276 const char *Equals
= I
;
277 for (; Equals
< Message
.end() && *Equals
!= '='; Equals
++);
278 const char *End
= Equals
;
279 for (; End
< Message
.end() && *End
!= '\n'; End
++);
283 Cnf
.Set(DeQuoteString(string(I
,Equals
-I
)),
284 DeQuoteString(string(Equals
+1,End
-Equals
-1)));
291 // AcqMethod::Run - Run the message engine /*{{{*/
292 // ---------------------------------------------------------------------
294 int pkgAcqMethod::Run(bool Single
)
298 // Block if the message queue is empty
299 if (Messages
.empty() == true)
302 if (WaitFd(STDIN_FILENO
) == false)
305 if (ReadMessages(STDIN_FILENO
,Messages
) == false)
309 // Single mode exits if the message queue is empty
310 if (Single
== true && Messages
.empty() == true)
313 string Message
= Messages
.front();
314 Messages
.erase(Messages
.begin());
316 // Fetch the message number
318 int Number
= strtol(Message
.c_str(),&End
,10);
319 if (End
== Message
.c_str())
321 cerr
<< "Malformed message!" << endl
;
328 if (Configuration(Message
) == false)
334 FetchItem
*Tmp
= new FetchItem
;
336 Tmp
->Uri
= LookupTag(Message
,"URI");
337 Tmp
->DestFile
= LookupTag(Message
,"FileName");
338 if (StrToTime(LookupTag(Message
,"Last-Modified"),Tmp
->LastModified
) == false)
339 Tmp
->LastModified
= 0;
340 Tmp
->IndexFile
= StringToBool(LookupTag(Message
,"Index-File"),false);
343 // Append it to the list
344 FetchItem
**I
= &Queue
;
345 for (; *I
!= 0; I
= &(*I
)->Next
);
350 // Notify that this item is to be fetched.
351 if (Fetch(Tmp
) == false)
362 // AcqMethod::Log - Send a log message /*{{{*/
363 // ---------------------------------------------------------------------
365 void pkgAcqMethod::Log(const char *Format
,...)
367 string CurrentURI
= "<UNKNOWN>";
369 CurrentURI
= Queue
->Uri
;
372 va_start(args
,Format
);
374 // sprintf the description
376 unsigned int Len
= snprintf(S
,sizeof(S
),"101 Log\nURI: %s\n"
377 "Message: ",CurrentURI
.c_str());
379 vsnprintf(S
+Len
,sizeof(S
)-Len
,Format
,args
);
382 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
386 // AcqMethod::Status - Send a status message /*{{{*/
387 // ---------------------------------------------------------------------
389 void pkgAcqMethod::Status(const char *Format
,...)
391 string CurrentURI
= "<UNKNOWN>";
393 CurrentURI
= Queue
->Uri
;
396 va_start(args
,Format
);
398 // sprintf the description
400 unsigned int Len
= snprintf(S
,sizeof(S
),"102 Status\nURI: %s\n"
401 "Message: ",CurrentURI
.c_str());
403 vsnprintf(S
+Len
,sizeof(S
)-Len
,Format
,args
);
406 if (write(STDOUT_FILENO
,S
,strlen(S
)) != (signed)strlen(S
))
411 // AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/
412 // ---------------------------------------------------------------------
414 pkgAcqMethod::FetchResult::FetchResult() : LastModified(0),
415 IMSHit(false), Size(0), ResumePoint(0)