Almost done now
[ntk/apt.git] / apt-pkg / acquire-method.cc
CommitLineData
93bf083d
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b98f2859 3// $Id: acquire-method.cc,v 1.6 1998/11/11 06:54:15 jgg Exp $
93bf083d
AL
4/* ######################################################################
5
6 Acquire Method
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
11#ifdef __GNUG__
12#pragma implementation "apt-pkg/acquire-method.h"
13#endif
14#include <apt-pkg/acquire-method.h>
15#include <apt-pkg/error.h>
16#include <apt-pkg/configuration.h>
17#include <strutl.h>
18#include <apt-pkg/fileutl.h>
19
20#include <stdio.h>
21 /*}}}*/
22
23// AcqMethod::pkgAcqMethod - Constructor /*{{{*/
24// ---------------------------------------------------------------------
25/* This constructs the initialization text */
26pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags)
27{
28 char S[300] = "";
29 char *End = S;
30 strcat(End,"100 Capabilities\n");
31 sprintf(End+strlen(End),"Version: %s\n",Ver);
32
33 if ((Flags & SingleInstance) == SingleInstance)
34 strcat(End,"Single-Instance: true\n");
35
36 if ((Flags & PreScan) == PreScan)
37 strcat(End,"Pre-Scan: true\n");
38
39 if ((Flags & Pipeline) == Pipeline)
40 strcat(End,"Pipeline: true\n");
41
42 if ((Flags & SendConfig) == SendConfig)
43 strcat(End,"Send-Config: true\n");
44 strcat(End,"\n");
45
46 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
47 exit(100);
be4401bf
AL
48
49 SetNonBlock(STDIN_FILENO,true);
92e889c8
AL
50
51 Queue = 0;
93bf083d
AL
52}
53 /*}}}*/
54// AcqMethod::Fail - A fetch has failed /*{{{*/
55// ---------------------------------------------------------------------
56/* */
57void pkgAcqMethod::Fail()
58{
59 string Err = "Undetermined Error";
60 if (_error->empty() == false)
61 _error->PopMessage(Err);
62 _error->Discard();
63 Fail(Err);
64}
65 /*}}}*/
66// AcqMethod::Fail - A fetch has failed /*{{{*/
67// ---------------------------------------------------------------------
68/* */
69void pkgAcqMethod::Fail(string Err)
70{
71 char S[1024];
be4401bf
AL
72 if (Queue != 0)
73 {
74 snprintf(S,sizeof(S),"400 URI Failure\nURI: %s\n"
75 "Message: %s\n\n",Queue->Uri.c_str(),Err.c_str());
76
77 // Dequeue
78 FetchItem *Tmp = Queue;
79 Queue = Queue->Next;
80 delete Tmp;
81 }
82 else
83 snprintf(S,sizeof(S),"400 URI Failure\nURI: <UNKNOWN>\n"
84 "Message: %s\n\n",Err.c_str());
85
93bf083d
AL
86 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
87 exit(100);
88}
89 /*}}}*/
90// AcqMethod::URIStart - Indicate a download is starting /*{{{*/
91// ---------------------------------------------------------------------
92/* */
be4401bf 93void pkgAcqMethod::URIStart(FetchResult &Res)
93bf083d 94{
be4401bf
AL
95 if (Queue == 0)
96 abort();
97
93bf083d
AL
98 char S[1024] = "";
99 char *End = S;
100
be4401bf 101 End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",Queue->Uri.c_str());
93bf083d
AL
102 if (Res.Size != 0)
103 End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size);
104
105 if (Res.LastModified != 0)
106 End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n",
107 TimeRFC1123(Res.LastModified).c_str());
108
be4401bf 109 if (Res.ResumePoint != 0)
93bf083d 110 End += snprintf(End,sizeof(S) - (End - S),"Resume-Point: %u\n",
be4401bf 111 Res.ResumePoint);
93bf083d
AL
112
113 strcat(End,"\n");
114 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
115 exit(100);
116}
117 /*}}}*/
118// AcqMethod::URIDone - A URI is finished /*{{{*/
119// ---------------------------------------------------------------------
120/* */
121void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
122{
be4401bf
AL
123 if (Queue == 0)
124 abort();
125
93bf083d
AL
126 char S[1024] = "";
127 char *End = S;
128
be4401bf 129 End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",Queue->Uri.c_str());
93bf083d
AL
130
131 if (Res.Filename.empty() == false)
132 End += snprintf(End,sizeof(S) - (End - S),"Filename: %s\n",Res.Filename.c_str());
133
134 if (Res.Size != 0)
135 End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size);
136
137 if (Res.LastModified != 0)
138 End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n",
139 TimeRFC1123(Res.LastModified).c_str());
140
141 if (Res.MD5Sum.empty() == false)
142 End += snprintf(End,sizeof(S) - (End - S),"MD5Sum: %s\n",Res.MD5Sum.c_str());
143
b98f2859
AL
144 if (Res.ResumePoint != 0)
145 End += snprintf(End,sizeof(S) - (End - S),"Resume-Point: %u\n",
146 Res.ResumePoint);
147
93bf083d
AL
148 if (Res.IMSHit == true)
149 strcat(End,"IMS-Hit: true\n");
150 End = S + strlen(S);
151
152 if (Alt != 0)
153 {
154 if (Alt->Filename.empty() == false)
155 End += snprintf(End,sizeof(S) - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str());
156
157 if (Alt->Size != 0)
158 End += snprintf(End,sizeof(S) - (End - S),"Alt-Size: %u\n",Alt->Size);
159
160 if (Alt->LastModified != 0)
161 End += snprintf(End,sizeof(S) - (End - S),"Alt-Last-Modified: %s\n",
162 TimeRFC1123(Alt->LastModified).c_str());
163
164 if (Alt->MD5Sum.empty() == false)
165 End += snprintf(End,sizeof(S) - (End - S),"Alt-MD5Sum: %s\n",
166 Alt->MD5Sum.c_str());
167
168 if (Alt->IMSHit == true)
169 strcat(End,"Alt-IMS-Hit: true\n");
170 }
171
172 strcat(End,"\n");
173 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
174 exit(100);
be4401bf
AL
175
176 // Dequeue
177 FetchItem *Tmp = Queue;
178 Queue = Queue->Next;
179 delete Tmp;
93bf083d
AL
180}
181 /*}}}*/
182// AcqMethod::Configuration - Handle the configuration message /*{{{*/
183// ---------------------------------------------------------------------
184/* This parses each configuration entry and puts it into the _config
185 Configuration class. */
186bool pkgAcqMethod::Configuration(string Message)
187{
188 ::Configuration &Cnf = *_config;
189
190 const char *I = Message.begin();
191
192 unsigned int Length = strlen("Config-Item");
193 for (; I + Length < Message.end(); I++)
194 {
195 // Not a config item
196 if (I[Length] != ':' || stringcasecmp(I,I+Length,"Config-Item") != 0)
197 continue;
198
199 I += Length + 1;
200
201 for (; I < Message.end() && *I == ' '; I++);
202 const char *Equals = I;
203 for (; Equals < Message.end() && *Equals != '='; Equals++);
204 const char *End = Equals;
205 for (; End < Message.end() && *End != '\n'; End++);
206 if (End == Equals)
207 return false;
208
209 Cnf.Set(string(I,Equals-I),string(Equals+1,End-Equals-1));
210 I = End;
211 }
212
213 return true;
214}
215 /*}}}*/
216// AcqMethod::Run - Run the message engine /*{{{*/
217// ---------------------------------------------------------------------
218/* */
be4401bf 219int pkgAcqMethod::Run(bool Single)
93bf083d 220{
93bf083d
AL
221 while (1)
222 {
be4401bf 223 // Block if the message queue is empty
93bf083d 224 if (Messages.empty() == true)
be4401bf
AL
225 {
226 if (Single == false)
227 if (WaitFd(STDIN_FILENO) == false)
228 return 0;
be4401bf 229
92e889c8
AL
230 if (ReadMessages(STDIN_FILENO,Messages) == false)
231 return 0;
232 }
233
be4401bf
AL
234 // Single mode exits if the message queue is empty
235 if (Single == true && Messages.empty() == true)
236 return 0;
237
93bf083d
AL
238 string Message = Messages.front();
239 Messages.erase(Messages.begin());
240
241 // Fetch the message number
242 char *End;
243 int Number = strtol(Message.c_str(),&End,10);
244 if (End == Message.c_str())
245 {
246 cerr << "Malformed message!" << endl;
247 return 100;
248 }
249
250 switch (Number)
251 {
252 case 601:
253 if (Configuration(Message) == false)
254 return 100;
255 break;
256
257 case 600:
be4401bf
AL
258 {
259 FetchItem *Tmp = new FetchItem;
260
261 Tmp->Uri = LookupTag(Message,"URI");
262 Tmp->DestFile = LookupTag(Message,"FileName");
b98f2859
AL
263 if (StrToTime(LookupTag(Message,"Last-Modified"),Tmp->LastModified) == false)
264 Tmp->LastModified = 0;
265
be4401bf
AL
266 Tmp->Next = 0;
267
268 // Append it to the list
269 FetchItem **I = &Queue;
92e889c8 270 for (; *I != 0; I = &(*I)->Next);
be4401bf 271 *I = Tmp;
bfd22fc0
AL
272
273 // Notify that this item is to be fetched.
be4401bf 274 if (Fetch(Tmp) == false)
93bf083d 275 Fail();
bfd22fc0 276
93bf083d
AL
277 break;
278 }
279 }
280 }
281
282 return 0;
283}
284 /*}}}*/
be4401bf
AL
285// AcqMethod::Log - Send a log message /*{{{*/
286// ---------------------------------------------------------------------
287/* */
288void pkgAcqMethod::Log(const char *Format,...)
289{
290 string CurrentURI = "<UNKNOWN>";
291 if (Queue != 0)
292 CurrentURI = Queue->Uri;
293
294 va_list args;
295 va_start(args,Format);
296
297 // sprintf the description
298 char S[1024];
299 unsigned int Len = snprintf(S,sizeof(S),"101 Log\nURI: %s\n"
300 "Message: ",CurrentURI.c_str());
301
302 vsnprintf(S+Len,sizeof(S)-Len,Format,args);
303 strcat(S,"\n\n");
304
305 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
306 exit(100);
307}
308 /*}}}*/
309// AcqMethod::Status - Send a status message /*{{{*/
310// ---------------------------------------------------------------------
311/* */
312void pkgAcqMethod::Status(const char *Format,...)
313{
314 string CurrentURI = "<UNKNOWN>";
315 if (Queue != 0)
316 CurrentURI = Queue->Uri;
317
318 va_list args;
319 va_start(args,Format);
320
321 // sprintf the description
322 char S[1024];
8267fe24 323 unsigned int Len = snprintf(S,sizeof(S),"102 Status\nURI: %s\n"
be4401bf
AL
324 "Message: ",CurrentURI.c_str());
325
326 vsnprintf(S+Len,sizeof(S)-Len,Format,args);
327 strcat(S,"\n\n");
328
329 if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
330 exit(100);
331}
332 /*}}}*/
333
93bf083d
AL
334// AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/
335// ---------------------------------------------------------------------
336/* */
337pkgAcqMethod::FetchResult::FetchResult() : LastModified(0),
338 IMSHit(false), Size(0)
339{
340}
341 /*}}}*/
342