add APT::FTPArchive::AlwaysStat to disable the too aggressive
[ntk/apt.git] / ftparchive / override.cc
CommitLineData
b2e465d6
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
dc738e7a 3// $Id: override.cc,v 1.4 2003/02/10 07:34:41 doogie Exp $
b2e465d6
AL
4/* ######################################################################
5
6 Override
7
8 Store the override file.
9
10 ##################################################################### */
11 /*}}}*/
12// Include Files /*{{{*/
b2e465d6
AL
13#include "override.h"
14
dc738e7a 15#include <apti18n.h>
b2e465d6
AL
16#include <apt-pkg/strutl.h>
17#include <apt-pkg/error.h>
18
19#include <stdio.h>
20
21#include "override.h"
22 /*}}}*/
23
24// Override::ReadOverride - Read the override file /*{{{*/
25// ---------------------------------------------------------------------
26/* This parses the override file and reads it into the map */
27bool Override::ReadOverride(string File,bool Source)
28{
29 if (File.empty() == true)
30 return true;
31
32 FILE *F = fopen(File.c_str(),"r");
33 if (F == 0)
dc738e7a 34 return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
b2e465d6
AL
35
36 char Line[500];
37 unsigned long Counter = 0;
38 while (fgets(Line,sizeof(Line),F) != 0)
39 {
40 Counter++;
41 Item Itm;
42
43 // Silence
44 for (char *I = Line; *I != 0; I++)
45 if (*I == '#')
46 *I = 0;
47
48 // Strip space leading up to the package name, skip blank lines
49 char *Pkg = Line;
50 for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
51 if (Pkg == 0)
52 continue;
53
54 // Find the package and zero..
55 char *Start = Pkg;
56 char *End = Pkg;
57 for (; isspace(*End) == 0 && *End != 0; End++);
58 if (*End == 0)
59 {
dc738e7a 60 _error->Warning(_("Malformed override %s line %lu #1"),File.c_str(),
b2e465d6
AL
61 Counter);
62 continue;
63 }
64 *End = 0;
65
66 // Find the priority
67 if (Source == false)
68 {
69 for (End++; isspace(*End) != 0 && *End != 0; End++);
70 Start = End;
71 for (; isspace(*End) == 0 && *End != 0; End++);
72 if (*End == 0)
73 {
dc738e7a 74 _error->Warning(_("Malformed override %s line %lu #2"),File.c_str(),
b2e465d6
AL
75 Counter);
76 continue;
77 }
78 *End = 0;
79 Itm.Priority = Start;
80 }
81
82 // Find the Section
83 for (End++; isspace(*End) != 0 && *End != 0; End++);
84 Start = End;
85 for (; isspace(*End) == 0 && *End != 0; End++);
86 if (*End == 0)
87 {
dc738e7a 88 _error->Warning(_("Malformed override %s line %lu #3"),File.c_str(),
b2e465d6
AL
89 Counter);
90 continue;
91 }
92 *End = 0;
64177f17 93 Itm.FieldOverride["Section"] = Start;
b2e465d6
AL
94
95 // Source override files only have the two columns
96 if (Source == true)
97 {
98 Mapping[Pkg] = Itm;
99 continue;
100 }
101
102 // Find the =>
103 for (End++; isspace(*End) != 0 && *End != 0; End++);
104 if (*End != 0)
105 {
106 Start = End;
107 for (; *End != 0 && (End[0] != '=' || End[1] != '>'); End++);
108 if (*End == 0 || strlen(End) < 4)
109 {
110 Itm.OldMaint = "*";
111 Itm.NewMaint = _strstrip(Start);
112 }
113 else
114 {
115 *End = 0;
116 Itm.OldMaint = _strstrip(Start);
117
118 End += 3;
119 Itm.NewMaint = _strstrip(End);
120 }
121 }
122
123 Mapping[Pkg] = Itm;
124 }
125
64177f17 126 if (ferror(F))
dc738e7a 127 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
64177f17
AL
128 fclose(F);
129 return true;
130}
131 /*}}}*/
132// Override::ReadExtraOverride - Read the extra override file /*{{{*/
133// ---------------------------------------------------------------------
134/* This parses the extra override file and reads it into the map */
135bool Override::ReadExtraOverride(string File,bool Source)
136{
137 if (File.empty() == true)
138 return true;
139
140 FILE *F = fopen(File.c_str(),"r");
141 if (F == 0)
dc738e7a 142 return _error->Errno("fopen",_("Unable to open %s"),File.c_str());
64177f17
AL
143
144 char Line[500];
145 unsigned long Counter = 0;
146 while (fgets(Line,sizeof(Line),F) != 0)
147 {
148 Counter++;
149
150 // Silence
151 for (char *I = Line; *I != 0; I++)
152 if (*I == '#')
153 *I = 0;
154
155 // Strip space leading up to the package name, skip blank lines
156 char *Pkg = Line;
157 for (; isspace(*Pkg) && *Pkg != 0;Pkg++);
158 if (Pkg == 0)
159 continue;
160
161 // Find the package and zero..
162 char *End = Pkg;
163 for (; isspace(*End) == 0 && *End != 0; End++);
164 if (*End == 0)
165 {
dc738e7a 166 _error->Warning(_("Malformed override %s line %lu #1"),File.c_str(),
64177f17
AL
167 Counter);
168 continue;
169 }
170 *End = 0;
171
172 // Find the field
173 for (End++; isspace(*End) != 0 && *End != 0; End++);
174 char *Field = End;
175 for (; isspace(*End) == 0 && *End != 0; End++);
176 if (*End == 0)
177 {
dc738e7a 178 _error->Warning(_("Malformed override %s line %lu #2"),File.c_str(),
64177f17
AL
179 Counter);
180 continue;
181 }
182 *End = 0;
183
184 // Find the field value
185 for (End++; isspace(*End) != 0 && *End != 0; End++);
186 char *Value = End;
187 for (; *End != 0; End++);
188 for (; isspace(*(End-1)) && End > Value; End--);
189 if (End == Value)
190 {
dc738e7a 191 _error->Warning(_("Malformed override %s line %lu #3"),File.c_str(),
64177f17
AL
192 Counter);
193 continue;
194 }
195 *End = 0;
196
197 Mapping[Pkg].FieldOverride[Field] = Value;
198 }
199
b2e465d6 200 if (ferror(F))
dc738e7a 201 _error->Errno("fgets",_("Failed to read the override file %s"),File.c_str());
b2e465d6
AL
202 fclose(F);
203 return true;
204}
205 /*}}}*/
0b41e0e7
MV
206
207// Override::GetItem - Get a architecture specific item /*{{{*/
208// ---------------------------------------------------------------------
209/* Returns a override item for the given package and the given architecture.
210 * Treats "all" special
211 */
212Override::Item* Override::GetItem(string Package, string Architecture)
213{
214 map<string,Item>::iterator I = Mapping.find(Package);
215 map<string,Item>::iterator J = Mapping.find(Package + "/" + Architecture);
216
217 if (I == Mapping.end() && J == Mapping.end())
218 {
219 return 0;
220 }
221
222 Item *result = new Item;
223 if (I == Mapping.end()) *result = J->second;
224 else
225 {
226 *result = I->second;
227 if (J != Mapping.end())
228 {
229 Item *R = &J->second;
230 if (R->Priority != "") result->Priority = R->Priority;
231 if (R->OldMaint != "") result->OldMaint = R->OldMaint;
232 if (R->NewMaint != "") result->NewMaint = R->NewMaint;
233 for (map<string,string>::iterator foI = R->FieldOverride.begin();
234 foI != R->FieldOverride.end(); foI++)
235 {
236 result->FieldOverride[foI->first] = foI->second;
237 }
238 }
239 }
240 return result;
241};
242
243
b2e465d6
AL
244// Override::Item::SwapMaint - Swap the maintainer field if necessary /*{{{*/
245// ---------------------------------------------------------------------
246/* Returns the new maintainer string after evaluating the rewriting rule. If
247 there is a rule but it does not match then the empty string is returned,
248 also if there was no rewrite rule the empty string is returned. Failed
249 indicates if there was some kind of problem while rewriting. */
250string Override::Item::SwapMaint(string Orig,bool &Failed)
251{
252 Failed = false;
253
254 // Degenerate case..
255 if (NewMaint.empty() == true)
256 return OldMaint;
257
258 if (OldMaint == "*")
259 return NewMaint;
260
261 /* James: ancient, eliminate it, however it is still being used in the main
262 override file. Thus it persists.*/
263#if 1
264 // Break OldMaint up into little bits on double slash boundaries.
265 string::iterator End = OldMaint.begin();
266 while (1)
267 {
268 string::iterator Start = End;
269 for (; End < OldMaint.end() &&
270 (End + 3 >= OldMaint.end() || End[0] != ' ' ||
271 End[1] != '/' || End[2] != '/'); End++);
272 if (stringcasecmp(Start,End,Orig.begin(),Orig.end()) == 0)
273 return NewMaint;
274
275 if (End >= OldMaint.end())
276 break;
277
278 // Skip the divider and white space
279 for (; End < OldMaint.end() && (*End == '/' || *End == ' '); End++);
280 }
281#else
282 if (stringcasecmp(OldMaint.begin(),OldMaint.end(),Orig.begin(),Orig.end()) == 0)
283 return NewMaint;
284#endif
285
286 Failed = true;
287 return string();
288}
289 /*}}}*/