reorder includes: add <config.h> if needed and include it at first
[ntk/apt.git] / apt-pkg / indexrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: indexrecords.cc,v 1.1.2.4 2003/12/30 02:11:43 mdz Exp $
4 /*}}}*/
5 // Include Files /*{{{*/
6 #include<config.h>
7
8 #include <apt-pkg/indexrecords.h>
9 #include <apt-pkg/tagfile.h>
10 #include <apt-pkg/error.h>
11 #include <apt-pkg/strutl.h>
12 #include <apt-pkg/configuration.h>
13 #include <sys/stat.h>
14 #include <clocale>
15
16 #include <apti18n.h>
17 /*}}}*/
18 string indexRecords::GetDist() const
19 {
20 return this->Dist;
21 }
22
23 bool indexRecords::CheckDist(const string MaybeDist) const
24 {
25 return (this->Dist == MaybeDist
26 || this->Suite == MaybeDist);
27 }
28
29 string indexRecords::GetExpectedDist() const
30 {
31 return this->ExpectedDist;
32 }
33
34 time_t indexRecords::GetValidUntil() const
35 {
36 return this->ValidUntil;
37 }
38
39 const indexRecords::checkSum *indexRecords::Lookup(const string MetaKey)
40 {
41 return Entries[MetaKey];
42 }
43
44 bool indexRecords::Exists(string const &MetaKey) const
45 {
46 return Entries.count(MetaKey) == 1;
47 }
48
49 bool indexRecords::Load(const string Filename) /*{{{*/
50 {
51 FileFd Fd(Filename, FileFd::ReadOnly);
52 pkgTagFile TagFile(&Fd, Fd.Size() + 256); // XXX
53 if (_error->PendingError() == true)
54 {
55 strprintf(ErrorText, _("Unable to parse Release file %s"),Filename.c_str());
56 return false;
57 }
58
59 pkgTagSection Section;
60 const char *Start, *End;
61 // Skip over sections beginning with ----- as this is an idicator for clearsigns
62 do {
63 if (TagFile.Step(Section) == false)
64 {
65 strprintf(ErrorText, _("No sections in Release file %s"), Filename.c_str());
66 return false;
67 }
68
69 Section.Get (Start, End, 0);
70 } while (End - Start > 5 && strncmp(Start, "-----", 5) == 0);
71
72 Suite = Section.FindS("Suite");
73 Dist = Section.FindS("Codename");
74
75 int i;
76 for (i=0;HashString::SupportedHashes()[i] != NULL; i++)
77 {
78 if (!Section.Find(HashString::SupportedHashes()[i], Start, End))
79 continue;
80
81 string Name;
82 string Hash;
83 size_t Size;
84 while (Start < End)
85 {
86 if (!parseSumData(Start, End, Name, Hash, Size))
87 return false;
88 indexRecords::checkSum *Sum = new indexRecords::checkSum;
89 Sum->MetaKeyFilename = Name;
90 Sum->Hash = HashString(HashString::SupportedHashes()[i],Hash);
91 Sum->Size = Size;
92 Entries[Name] = Sum;
93 }
94 break;
95 }
96
97 if(HashString::SupportedHashes()[i] == NULL)
98 {
99 strprintf(ErrorText, _("No Hash entry in Release file %s"), Filename.c_str());
100 return false;
101 }
102
103 string Label = Section.FindS("Label");
104 string StrDate = Section.FindS("Date");
105 string StrValidUntil = Section.FindS("Valid-Until");
106
107 // if we have a Valid-Until header in the Release file, use it as default
108 if (StrValidUntil.empty() == false)
109 {
110 if(RFC1123StrToTime(StrValidUntil.c_str(), ValidUntil) == false)
111 {
112 strprintf(ErrorText, _("Invalid 'Valid-Until' entry in Release file %s"), Filename.c_str());
113 return false;
114 }
115 }
116 // get the user settings for this archive and use what expires earlier
117 int MaxAge = _config->FindI("Acquire::Max-ValidTime", 0);
118 if (Label.empty() == true)
119 MaxAge = _config->FindI(string("Acquire::Max-ValidTime::" + Label).c_str(), MaxAge);
120
121 if(MaxAge == 0) // No user settings, use the one from the Release file
122 return true;
123
124 time_t date;
125 if (RFC1123StrToTime(StrDate.c_str(), date) == false)
126 {
127 strprintf(ErrorText, _("Invalid 'Date' entry in Release file %s"), Filename.c_str());
128 return false;
129 }
130 date += 24*60*60*MaxAge;
131
132 if (ValidUntil == 0 || ValidUntil > date)
133 ValidUntil = date;
134
135 return true;
136 }
137 /*}}}*/
138 vector<string> indexRecords::MetaKeys() /*{{{*/
139 {
140 std::vector<std::string> keys;
141 std::map<string,checkSum *>::iterator I = Entries.begin();
142 while(I != Entries.end()) {
143 keys.push_back((*I).first);
144 ++I;
145 }
146 return keys;
147 }
148 /*}}}*/
149 bool indexRecords::parseSumData(const char *&Start, const char *End, /*{{{*/
150 string &Name, string &Hash, size_t &Size)
151 {
152 Name = "";
153 Hash = "";
154 Size = 0;
155 /* Skip over the first blank */
156 while ((*Start == '\t' || *Start == ' ' || *Start == '\n')
157 && Start < End)
158 Start++;
159 if (Start >= End)
160 return false;
161
162 /* Move EntryEnd to the end of the first entry (the hash) */
163 const char *EntryEnd = Start;
164 while ((*EntryEnd != '\t' && *EntryEnd != ' ')
165 && EntryEnd < End)
166 EntryEnd++;
167 if (EntryEnd == End)
168 return false;
169
170 Hash.append(Start, EntryEnd-Start);
171
172 /* Skip over intermediate blanks */
173 Start = EntryEnd;
174 while (*Start == '\t' || *Start == ' ')
175 Start++;
176 if (Start >= End)
177 return false;
178
179 EntryEnd = Start;
180 /* Find the end of the second entry (the size) */
181 while ((*EntryEnd != '\t' && *EntryEnd != ' ' )
182 && EntryEnd < End)
183 EntryEnd++;
184 if (EntryEnd == End)
185 return false;
186
187 Size = strtol (Start, NULL, 10);
188
189 /* Skip over intermediate blanks */
190 Start = EntryEnd;
191 while (*Start == '\t' || *Start == ' ')
192 Start++;
193 if (Start >= End)
194 return false;
195
196 EntryEnd = Start;
197 /* Find the end of the third entry (the filename) */
198 while ((*EntryEnd != '\t' && *EntryEnd != ' ' && *EntryEnd != '\n')
199 && EntryEnd < End)
200 EntryEnd++;
201
202 Name.append(Start, EntryEnd-Start);
203 Start = EntryEnd; //prepare for the next round
204 return true;
205 }
206 /*}}}*/
207 indexRecords::indexRecords()
208 {
209 }
210
211 indexRecords::indexRecords(const string ExpectedDist) :
212 ExpectedDist(ExpectedDist), ValidUntil(0)
213 {
214 }