]> git.saurik.com Git - apt.git/blame - apt-pkg/acquire-item.cc
Working acquire code
[apt.git] / apt-pkg / acquire-item.cc
CommitLineData
0118833a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
bfd22fc0 3// $Id: acquire-item.cc,v 1.7 1998/11/05 07:21:35 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/* */
33pkgAcquire::Item::Item(pkgAcquire *Owner) : Owner(Owner), QueueCounter(0)
34{
35 Owner->Add(this);
c88edf1d 36 Status = StatIdle;
0118833a
AL
37}
38 /*}}}*/
39// Acquire::Item::~Item - Destructor /*{{{*/
40// ---------------------------------------------------------------------
41/* */
42pkgAcquire::Item::~Item()
43{
44 Owner->Remove(this);
45}
46 /*}}}*/
c88edf1d
AL
47// Acquire::Item::Failed - Item failed to download /*{{{*/
48// ---------------------------------------------------------------------
93bf083d
AL
49/* We return to an idle state if there are still other queues that could
50 fetch this object */
c88edf1d
AL
51void pkgAcquire::Item::Failed(string Message)
52{
93bf083d 53 Status = StatIdle;
c88edf1d 54 if (QueueCounter <= 1)
93bf083d
AL
55 {
56 ErrorText = LookupTag(Message,"Message");
57 Status = StatError;
c88edf1d 58 Owner->Dequeue(this);
93bf083d 59 }
c88edf1d
AL
60}
61 /*}}}*/
62// Acquire::Item::Done - Item downloaded OK /*{{{*/
63// ---------------------------------------------------------------------
64/* */
65void pkgAcquire::Item::Done(string,unsigned long,string)
66{
67 Status = StatDone;
68 ErrorText = string();
69 Owner->Dequeue(this);
70}
71 /*}}}*/
8b89e57f
AL
72// Acquire::Item::Rename - Rename a file /*{{{*/
73// ---------------------------------------------------------------------
74/* This helper function is used by alot of item methods as thier final
75 step */
76void pkgAcquire::Item::Rename(string From,string To)
77{
78 if (rename(From.c_str(),To.c_str()) != 0)
79 {
80 char S[300];
81 sprintf(S,"rename failed, %s (%s -> %s).",strerror(errno),
82 From.c_str(),To.c_str());
83 Status = StatError;
84 ErrorText = S;
85 }
86}
87 /*}}}*/
0118833a
AL
88
89// AcqIndex::AcqIndex - Constructor /*{{{*/
90// ---------------------------------------------------------------------
91/* The package file is added to the queue and a second class is
92 instantiated to fetch the revision file */
93pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,const pkgSourceList::Item *Location) :
94 Item(Owner), Location(Location)
95{
8b89e57f 96 Decompression = false;
bfd22fc0 97 Erase = false;
8b89e57f 98
0a8a80e5
AL
99 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
100 DestFile += URItoFileName(Location->PackagesURI());
101
102 QueueURI(Location->PackagesURI() + ".gz",Location->PackagesInfo());
0118833a 103
0a8a80e5 104 // Create the Release fetch class
0118833a
AL
105 new pkgAcqIndexRel(Owner,Location);
106}
107 /*}}}*/
0a8a80e5 108// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/
0118833a 109// ---------------------------------------------------------------------
0a8a80e5
AL
110/* The only header we use is the last-modified header. */
111string pkgAcqIndex::Custom600Headers()
0118833a 112{
0a8a80e5
AL
113 string Final = _config->FindDir("Dir::State::lists");
114 Final += URItoFileName(Location->PackagesURI());
115
116 struct stat Buf;
117 if (stat(Final.c_str(),&Buf) != 0)
118 return string();
0118833a 119
0a8a80e5 120 return "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
0118833a
AL
121}
122 /*}}}*/
8b89e57f
AL
123// AcqIndex::Done - Finished a fetch /*{{{*/
124// ---------------------------------------------------------------------
125/* This goes through a number of states.. On the initial fetch the
126 method could possibly return an alternate filename which points
127 to the uncompressed version of the file. If this is so the file
128 is copied into the partial directory. In all other cases the file
129 is decompressed with a gzip uri. */
130void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5)
131{
132 Item::Done(Message,Size,MD5);
133
134 if (Decompression == true)
135 {
136 // Done, move it into position
137 string FinalFile = _config->FindDir("Dir::State::lists");
138 FinalFile += URItoFileName(Location->PackagesURI());
139 Rename(DestFile,FinalFile);
bfd22fc0
AL
140
141 // Remove the compressed version.
142 if (Erase == true)
143 {
144 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
145 DestFile += URItoFileName(Location->PackagesURI());
146 unlink(DestFile.c_str());
147 }
8b89e57f
AL
148 return;
149 }
bfd22fc0
AL
150
151 Erase = false;
152
8b89e57f
AL
153 // Handle the unzipd case
154 string FileName = LookupTag(Message,"Alt-Filename");
155 if (FileName.empty() == false)
156 {
157 // The files timestamp matches
158 if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true)
159 return;
160
161 Decompression = true;
162 DestFile += ".decomp";
163 QueueURI("copy:" + FileName,string());
164 return;
165 }
166
167 FileName = LookupTag(Message,"Filename");
168 if (FileName.empty() == true)
169 {
170 Status = StatError;
171 ErrorText = "Method gave a blank filename";
172 }
173
174 // The files timestamp matches
175 if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
176 return;
bfd22fc0
AL
177
178 if (FileName == DestFile)
179 Erase = true;
8b89e57f
AL
180
181 Decompression = true;
182 DestFile += ".decomp";
183 QueueURI("gzip:" + FileName,string());
184}
185 /*}}}*/
186
0118833a
AL
187// AcqIndexRel::pkgAcqIndexRel - Constructor /*{{{*/
188// ---------------------------------------------------------------------
189/* The Release file is added to the queue */
190pkgAcqIndexRel::pkgAcqIndexRel(pkgAcquire *Owner,
191 const pkgSourceList::Item *Location) :
192 Item(Owner), Location(Location)
193{
0a8a80e5
AL
194 DestFile = _config->FindDir("Dir::State::lists") + "partial/";
195 DestFile += URItoFileName(Location->ReleaseURI());
196
197 QueueURI(Location->ReleaseURI(),Location->ReleaseInfo());
0118833a
AL
198}
199 /*}}}*/
0a8a80e5 200// AcqIndexRel::Custom600Headers - Insert custom request headers /*{{{*/
0118833a 201// ---------------------------------------------------------------------
0a8a80e5
AL
202/* The only header we use is the last-modified header. */
203string pkgAcqIndexRel::Custom600Headers()
0118833a 204{
0a8a80e5
AL
205 string Final = _config->FindDir("Dir::State::lists");
206 Final += URItoFileName(Location->ReleaseURI());
207
208 struct stat Buf;
209 if (stat(Final.c_str(),&Buf) != 0)
210 return string();
0118833a 211
0a8a80e5 212 return "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
0118833a
AL
213}
214 /*}}}*/
c88edf1d
AL
215// AcqIndexRel::Done - Item downloaded OK /*{{{*/
216// ---------------------------------------------------------------------
217/* The release file was not placed into the download directory then
218 a copy URI is generated and it is copied there otherwise the file
219 in the partial directory is moved into .. and the URI is finished. */
220void pkgAcqIndexRel::Done(string Message,unsigned long Size,string MD5)
221{
222 Item::Done(Message,Size,MD5);
223
224 string FileName = LookupTag(Message,"Filename");
225 if (FileName.empty() == true)
226 {
227 Status = StatError;
228 ErrorText = "Method gave a blank filename";
8b89e57f 229 return;
c88edf1d 230 }
8b89e57f
AL
231
232 // The files timestamp matches
233 if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true)
234 return;
c88edf1d
AL
235
236 // We have to copy it into place
237 if (FileName != DestFile)
238 {
239 QueueURI("copy:" + FileName,string());
240 return;
241 }
242
243 // Done, move it into position
244 string FinalFile = _config->FindDir("Dir::State::lists");
245 FinalFile += URItoFileName(Location->ReleaseURI());
8b89e57f 246 Rename(DestFile,FinalFile);
c88edf1d
AL
247}
248 /*}}}*/