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