]> git.saurik.com Git - apt.git/blame - apt-pkg/acquire-item.cc
Almost done now
[apt.git] / apt-pkg / acquire-item.cc
CommitLineData
0118833a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b98f2859 3// $Id: acquire-item.cc,v 1.9 1998/11/11 06:54:13 jgg Exp $
0118833a
AL
4/* ######################################################################
5
6 Acquire Item - Item to acquire
7
8 Each item can download to exactly one file at a time. This means you
9 cannot create an item that fetches two uri's to two files at the same
10 time. The pkgAcqIndex class creates a second class upon instantiation
11 to fetch the other index files because of this.
12
13 ##################################################################### */
14 /*}}}*/
15// Include Files /*{{{*/
16#ifdef __GNUG__
17#pragma implementation "apt-pkg/acquire-item.h"
18#endif
19#include <apt-pkg/acquire-item.h>
20#include <apt-pkg/configuration.h>
21#include <strutl.h>
0a8a80e5
AL
22
23#include <sys/stat.h>
24#include <unistd.h>
c88edf1d
AL
25#include <errno.h>
26#include <string.h>
27#include <stdio.h>
0118833a
AL
28 /*}}}*/
29
30// Acquire::Item::Item - Constructor /*{{{*/
31// ---------------------------------------------------------------------
32/* */
8267fe24 33pkgAcquire::Item::Item(pkgAcquire *Owner) : Owner(Owner), FileSize(0),
b98f2859 34 Mode(0), ID(0), Complete(false), QueueCounter(0)
0118833a
AL
35{
36 Owner->Add(this);
c88edf1d 37 Status = StatIdle;
0118833a
AL
38}
39 /*}}}*/
40// Acquire::Item::~Item - Destructor /*{{{*/
41// ---------------------------------------------------------------------
42/* */
43pkgAcquire::Item::~Item()
44{
45 Owner->Remove(this);
46}
47 /*}}}*/
c88edf1d
AL
48// Acquire::Item::Failed - Item failed to download /*{{{*/
49// ---------------------------------------------------------------------
93bf083d
AL
50/* We return to an idle state if there are still other queues that could
51 fetch this object */
c88edf1d
AL
52void pkgAcquire::Item::Failed(string Message)
53{
93bf083d 54 Status = StatIdle;
c88edf1d 55 if (QueueCounter <= 1)
93bf083d
AL
56 {
57 ErrorText = LookupTag(Message,"Message");
58 Status = StatError;
c88edf1d 59 Owner->Dequeue(this);
93bf083d 60 }
c88edf1d
AL
61}
62 /*}}}*/
8267fe24
AL
63// Acquire::Item::Start - Item has begun to download /*{{{*/
64// ---------------------------------------------------------------------
65/* */
66void pkgAcquire::Item::Start(string Message,unsigned long Size)
67{
68 Status = StatFetching;
69 if (FileSize == 0 && Complete == false)
70 FileSize = Size;
71}
72 /*}}}*/
c88edf1d
AL
73// Acquire::Item::Done - Item downloaded OK /*{{{*/
74// ---------------------------------------------------------------------
75/* */
b98f2859 76void pkgAcquire::Item::Done(string Message,unsigned long Size,string)
c88edf1d 77{
b98f2859
AL
78 // We just downloaded something..
79 string FileName = LookupTag(Message,"Filename");
80 if (Complete == false && FileName == DestFile)
81 {
82 if (Owner->Log != 0)
83 Owner->Log->Fetched(Size,atoi(LookupTag(Message,"Resume-Point","0").c_str()));
84 }
85
c88edf1d
AL
86 Status = StatDone;
87 ErrorText = string();
88 Owner->Dequeue(this);
89}
90 /*}}}*/
8b89e57f
AL
91// Acquire::Item::Rename - Rename a file /*{{{*/
92// ---------------------------------------------------------------------
93/* This helper function is used by alot of item methods as thier final
94 step */
95void pkgAcquire::Item::Rename(string From,string To)
96{
97 if (rename(From.c_str(),To.c_str()) != 0)
98 {
99 char S[300];
100 sprintf(S,"rename failed, %s (%s -> %s).",strerror(errno),
101 From.c_str(),To.c_str());
102 Status = StatError;
103 ErrorText = S;
104 }
105}
106 /*}}}*/
0118833a
AL
107
108// AcqIndex::AcqIndex - Constructor /*{{{*/
109// ---------------------------------------------------------------------
110/* The package file is added to the queue and a second class is
111 instantiated to fetch the revision file */
112pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,const pkgSourceList::Item *Location) :
113 Item(Owner), Location(Location)
114{
8b89e57f 115 Decompression = false;
bfd22fc0 116 Erase = false;
8b89e57f 117
0a8a80e5
AL
118 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
119 DestFile += URItoFileName(Location->PackagesURI());
8267fe24
AL
120
121 // Create the item
122 Desc.URI = Location->PackagesURI() + ".gz";
123 Desc.Description = Location->PackagesInfo();
124 Desc.Owner = this;
125
126 // Set the short description to the archive component
127 if (Location->Dist[Location->Dist.size() - 1] == '/')
128 Desc.ShortDesc = Location->Dist;
129 else
130 Desc.ShortDesc = Location->Dist + '/' + Location->Section;
131
132 QueueURI(Desc);
0118833a 133
0a8a80e5 134 // Create the Release fetch class
0118833a
AL
135 new pkgAcqIndexRel(Owner,Location);
136}
137 /*}}}*/
0a8a80e5 138// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
0118833a 139// ---------------------------------------------------------------------
0a8a80e5
AL
140/* The only header we use is the last-modified header. */
141string pkgAcqIndex::Custom600Headers()
0118833a 142{
0a8a80e5
AL
143 string Final = _config->FindDir("Dir::State::lists");
144 Final += URItoFileName(Location->PackagesURI());
145
146 struct stat Buf;
147 if (stat(Final.c_str(),&Buf) != 0)
148 return string();
0118833a 149
0a8a80e5 150 return "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
0118833a
AL
151}
152 /*}}}*/
8b89e57f
AL
153// AcqIndex::Done - Finished a fetch /*{{{*/
154// ---------------------------------------------------------------------
155/* This goes through a number of states.. On the initial fetch the
156 method could possibly return an alternate filename which points
157 to the uncompressed version of the file. If this is so the file
158 is copied into the partial directory. In all other cases the file
159 is decompressed with a gzip uri. */
160void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5)
161{
162 Item::Done(Message,Size,MD5);
163
164 if (Decompression == true)
165 {
166 // Done, move it into position
167 string FinalFile = _config->FindDir("Dir::State::lists");
168 FinalFile += URItoFileName(Location->PackagesURI());
169 Rename(DestFile,FinalFile);
bfd22fc0
AL
170
171 // Remove the compressed version.
172 if (Erase == true)
173 {
174 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
175 DestFile += URItoFileName(Location->PackagesURI());
176 unlink(DestFile.c_str());
177 }
8b89e57f
AL
178 return;
179 }
bfd22fc0
AL
180
181 Erase = false;
8267fe24 182 Complete = true;
bfd22fc0 183
8b89e57f
AL
184 // Handle the unzipd case
185 string FileName = LookupTag(Message,"Alt-Filename");
186 if (FileName.empty() == false)
187 {
188 // The files timestamp matches
189 if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
190 return;
191
192 Decompression = true;
8267fe24 193 FileSize = 0;
8b89e57f 194 DestFile += ".decomp";
8267fe24
AL
195 Desc.URI = "copy:" + FileName;
196 QueueURI(Desc);
b98f2859 197 Mode = "copy";
8b89e57f
AL
198 return;
199 }
200
201 FileName = LookupTag(Message,"Filename");
202 if (FileName.empty() == true)
203 {
204 Status = StatError;
205 ErrorText = "Method gave a blank filename";
206 }
207
208 // The files timestamp matches
209 if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
210 return;
bfd22fc0
AL
211
212 if (FileName == DestFile)
213 Erase = true;
8267fe24
AL
214 else
215 FileSize = 0;
8b89e57f
AL
216
217 Decompression = true;
218 DestFile += ".decomp";
8267fe24
AL
219 Desc.URI = "gzip:" + FileName,Location->PackagesInfo();
220 QueueURI(Desc);
b98f2859 221 Mode = "gzip";
8b89e57f
AL
222}
223 /*}}}*/
224
0118833a
AL
225// AcqIndexRel::pkgAcqIndexRel - Constructor /*{{{*/
226// ---------------------------------------------------------------------
227/* The Release file is added to the queue */
228pkgAcqIndexRel::pkgAcqIndexRel(pkgAcquire *Owner,
229 const pkgSourceList::Item *Location) :
230 Item(Owner), Location(Location)
231{
0a8a80e5
AL
232 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
233 DestFile += URItoFileName(Location->ReleaseURI());
234
8267fe24
AL
235 // Create the item
236 Desc.URI = Location->ReleaseURI();
237 Desc.Description = Location->ReleaseInfo();
238 Desc.Owner = this;
239
240 // Set the short description to the archive component
241 if (Location->Dist[Location->Dist.size() - 1] == '/')
242 Desc.ShortDesc = Location->Dist;
243 else
244 Desc.ShortDesc = Location->Dist + '/' + Location->Section;
245
246 QueueURI(Desc);
0118833a
AL
247}
248 /*}}}*/
0a8a80e5 249// AcqIndexRel::Custom600Headers - Insert custom request headers /*{{{*/
0118833a 250// ---------------------------------------------------------------------
0a8a80e5
AL
251/* The only header we use is the last-modified header. */
252string pkgAcqIndexRel::Custom600Headers()
0118833a 253{
0a8a80e5
AL
254 string Final = _config->FindDir("Dir::State::lists");
255 Final += URItoFileName(Location->ReleaseURI());
256
257 struct stat Buf;
258 if (stat(Final.c_str(),&Buf) != 0)
259 return string();
0118833a 260
0a8a80e5 261 return "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
0118833a
AL
262}
263 /*}}}*/
c88edf1d
AL
264// AcqIndexRel::Done - Item downloaded OK /*{{{*/
265// ---------------------------------------------------------------------
266/* The release file was not placed into the download directory then
267 a copy URI is generated and it is copied there otherwise the file
268 in the partial directory is moved into .. and the URI is finished. */
269void pkgAcqIndexRel::Done(string Message,unsigned long Size,string MD5)
270{
271 Item::Done(Message,Size,MD5);
272
273 string FileName = LookupTag(Message,"Filename");
274 if (FileName.empty() == true)
275 {
276 Status = StatError;
277 ErrorText = "Method gave a blank filename";
8b89e57f 278 return;
c88edf1d 279 }
8b89e57f 280
8267fe24
AL
281 Complete = true;
282
8b89e57f
AL
283 // The files timestamp matches
284 if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
285 return;
c88edf1d
AL
286
287 // We have to copy it into place
288 if (FileName != DestFile)
289 {
8267fe24
AL
290 FileSize = 0;
291 Desc.URI = "copy:" + FileName;
292 QueueURI(Desc);
c88edf1d
AL
293 return;
294 }
295
296 // Done, move it into position
297 string FinalFile = _config->FindDir("Dir::State::lists");
298 FinalFile += URItoFileName(Location->ReleaseURI());
8b89e57f 299 Rename(DestFile,FinalFile);
c88edf1d
AL
300}
301 /*}}}*/