~l3on/ubuntu/lucid/apt/fix-917845

« back to all changes in this revision

Viewing changes to apt-pkg/policy.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jason Gunthorpe
  • Date: 2001-08-18 17:21:59 UTC
  • Revision ID: james.westby@ubuntu.com-20010818172159-85f7g43wdzi9dwb5
Tags: 0.5.4
* M68k config.guess patch. Closes: #88913
* Bi-yearly test on OpenBSD and Solaris
* Doc updates. Closes: #89121, #89854, #99671, #98353, #95823, #93057,
        #97520, #102867, #101071, #102421, #101565, #98272, #106914,
        #105606, #105377
* Various cosmetic code updates. Closes: #89066, #89066, #89152
* Add "pre-auto" as an option for DSelect::Clean (run autoclean after
  update).
* More patches from Alfredo for Vendors and more SHA-1 stuff
* Fix for AJ's 'desire to remove perl-5.005' and possibly other
  similar situations. Closes: #56708, #59432
* no_proxy and ftp. Closes: #89671
* Philippe Batailler's man page patches.
* Fix for display bug. Closes: #92033, #93652, #98468
* Use more than 16bits for the dep ID. Some people ran out..
  Closes: #103020, #97809, #102951, #99974, #107362, #107395, #107362,
          #106911, #107395, #108968
* Reordered some things to make dante and FTP happier. Closes: #92757
* James R. Van Zandt's guide.sgml updates. Closes: #90027
* apt-ftparchive copes with no uncompressed package files + contents.
* French man pages from philippe batailler - well sort of. They 
  don't build yet..
* run-parts. Closes: #94286
* 'apt-cache policy' preferences debug tool.
* Whatever. Closes: #89762
* libstdc++ and HURD. Closes: #92025
* More apt-utils verbage. Closes: #86954
* Fliped comparision operator. Closes: #94618
* Used the right copyright file. Closes: #65691
* Randolph's G++3 patches. 
* Fixed no_proxy tokanizing. Closes: #100046
* Strip Config-Version when copying status to available. Closes: #97520
* Segfault with missing source files. Closes: #100325
* EINTR check. Closes: #102293
* Various changes to the locking metholodgy for --print-uris. 
  Closes: #100590
* Lame LD_LIBRARY_PATH thing. Closes: #98928
* apt-cache search searchs provide names too now. Closes: #98695
* Checksum and long lines problem. Closes: #106591
* .aptignr and empty files are just a warning. Closes: #97364  

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: cpp; mode: fold -*-
 
2
// Description                                                          /*{{{*/
 
3
// $Id: policy.cc,v 1.8 2001/05/27 23:40:56 jgg Exp $
 
4
/* ######################################################################
 
5
 
 
6
   Package Version Policy implementation
 
7
   
 
8
   This is just a really simple wrapper around pkgVersionMatch with
 
9
   some added goodies to manage the list of things..
 
10
   
 
11
   Priority Table:
 
12
   
 
13
   1000 -> inf = Downgradeable priorities
 
14
   1000        = The 'no downgrade' pseduo-status file
 
15
   100 -> 1000 = Standard priorities
 
16
   990         = Config file override package files
 
17
   989         = Start for preference auto-priorities
 
18
   500         = Default package files
 
19
   100         = The status file
 
20
   0 -> 100    = NotAutomatic sources like experimental
 
21
   -inf -> 0   = Never selected   
 
22
   
 
23
   ##################################################################### */
 
24
                                                                        /*}}}*/
 
25
// Include Files                                                        /*{{{*/
 
26
#ifdef __GNUG__
 
27
#pragma implementation "apt-pkg/policy.h"
 
28
#endif
 
29
#include <apt-pkg/policy.h>
 
30
#include <apt-pkg/configuration.h>
 
31
#include <apt-pkg/tagfile.h>
 
32
#include <apt-pkg/strutl.h>
 
33
#include <apt-pkg/error.h>
 
34
#include <apt-pkg/sptr.h>
 
35
    
 
36
#include <apti18n.h>
 
37
 
 
38
#include <iostream>
 
39
                                                                        /*}}}*/
 
40
 
 
41
using namespace std;
 
42
 
 
43
// Policy::Init - Startup and bind to a cache                           /*{{{*/
 
44
// ---------------------------------------------------------------------
 
45
/* Set the defaults for operation. The default mode with no loaded policy
 
46
   file matches the V0 policy engine. */
 
47
pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
 
48
{
 
49
   PFPriority = new signed short[Owner->Head().PackageFileCount];
 
50
   Pins = new Pin[Owner->Head().PackageCount];
 
51
 
 
52
   for (unsigned long I = 0; I != Owner->Head().PackageCount; I++)
 
53
      Pins[I].Type = pkgVersionMatch::None;
 
54
 
 
55
   // The config file has a master override.
 
56
   string DefRel = _config->Find("APT::Default-Release");
 
57
   if (DefRel.empty() == false)
 
58
      CreatePin(pkgVersionMatch::Release,"",DefRel,990);
 
59
      
 
60
   InitDefaults();
 
61
}
 
62
                                                                        /*}}}*/
 
63
// Policy::InitDefaults - Compute the default selections                /*{{{*/
 
64
// ---------------------------------------------------------------------
 
65
/* */
 
66
bool pkgPolicy::InitDefaults()
 
67
{   
 
68
   // Initialize the priorities based on the status of the package file
 
69
   for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I != Cache->FileEnd(); I++)
 
70
   {
 
71
      PFPriority[I->ID] = 500;
 
72
      if ((I->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
 
73
         PFPriority[I->ID] = 100;
 
74
      else
 
75
         if ((I->Flags & pkgCache::Flag::NotAutomatic) == pkgCache::Flag::NotAutomatic)
 
76
            PFPriority[I->ID] = 1;
 
77
   }
 
78
 
 
79
   // Apply the defaults..
 
80
   SPtrArray<bool> Fixed = new bool[Cache->HeaderP->PackageFileCount];
 
81
   memset(Fixed,0,sizeof(*Fixed)*Cache->HeaderP->PackageFileCount);
 
82
   signed Cur = 989;
 
83
   StatusOverride = false;
 
84
   for (vector<Pin>::const_iterator I = Defaults.begin(); I != Defaults.end();
 
85
        I++, Cur--)
 
86
   {
 
87
      pkgVersionMatch Match(I->Data,I->Type);
 
88
      for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); F++)
 
89
      {
 
90
         if (Match.FileMatch(F) == true && Fixed[F->ID] == false)
 
91
         {
 
92
            if (I->Priority != 0 && I->Priority > 0)
 
93
               Cur = I->Priority;
 
94
            
 
95
            if (I->Priority < 0)
 
96
               PFPriority[F->ID] =  I->Priority;
 
97
            else
 
98
               PFPriority[F->ID] = Cur;
 
99
            
 
100
            if (PFPriority[F->ID] > 1000)
 
101
               StatusOverride = true;
 
102
            
 
103
            Fixed[F->ID] = true;
 
104
         }      
 
105
      }      
 
106
   }
 
107
 
 
108
   if (_config->FindB("Debug::pkgPolicy",false) == true)
 
109
      for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); F++)
 
110
         cout << "Prio of " << F.FileName() << ' ' << PFPriority[F->ID] << endl; 
 
111
   
 
112
   return true;   
 
113
}
 
114
                                                                        /*}}}*/
 
115
// Policy::GetCandidateVer - Get the candidate install version          /*{{{*/
 
116
// ---------------------------------------------------------------------
 
117
/* Evaluate the package pins and the default list to deteremine what the
 
118
   best package is. */
 
119
pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator Pkg)
 
120
{
 
121
   // Look for a package pin and evaluate it.
 
122
   signed Max = GetPriority(Pkg);
 
123
   pkgCache::VerIterator Pref = GetMatch(Pkg);
 
124
 
 
125
   /* Falling through to the default version.. Setting Max to zero
 
126
      effectively excludes everything <= 0 which are the non-automatic
 
127
      priorities.. The status file is given a prio of 100 which will exclude
 
128
      not-automatic sources, except in a single shot not-installed mode.
 
129
      The second pseduo-status file is at prio 1000, above which will permit
 
130
      the user to force-downgrade things.
 
131
      
 
132
      The user pin is subject to the same priority rules as default 
 
133
      selections. Thus there are two ways to create a pin - a pin that
 
134
      tracks the default when the default is taken away, and a permanent
 
135
      pin that stays at that setting.
 
136
    */
 
137
   for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; Ver++)
 
138
   {
 
139
      for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; VF++)
 
140
      {
 
141
         /* If this is the status file, and the current version is not the
 
142
            version in the status file (ie it is not installed, or somesuch)
 
143
            then it is not a candidate for installation, ever. This weeds
 
144
            out bogus entries that may be due to config-file states, or
 
145
            other. */
 
146
         if ((VF.File()->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource &&
 
147
             Pkg.CurrentVer() != Ver)
 
148
            continue;
 
149
                         
 
150
         signed Prio = PFPriority[VF.File()->ID];
 
151
         if (Prio > Max)
 
152
         {
 
153
            Pref = Ver;
 
154
            Max = Prio;
 
155
         }       
 
156
      }      
 
157
      
 
158
      if (Pkg.CurrentVer() == Ver && Max < 1000)
 
159
      {
 
160
         /* Elevate our current selection (or the status file itself)
 
161
            to the Pseudo-status priority. */
 
162
         if (Pref.end() == true)
 
163
            Pref = Ver;
 
164
         Max = 1000;
 
165
         
 
166
         // Fast path optimize.
 
167
         if (StatusOverride == false)
 
168
            break;
 
169
      }            
 
170
   }
 
171
   return Pref;
 
172
}
 
173
                                                                        /*}}}*/
 
174
// Policy::CreatePin - Create an entry in the pin table..               /*{{{*/
 
175
// ---------------------------------------------------------------------
 
176
/* For performance we have 3 tables, the default table, the main cache
 
177
   table (hashed to the cache). A blank package name indicates the pin
 
178
   belongs to the default table. Order of insertion matters here, the
 
179
   earlier defaults override later ones. */
 
180
void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
 
181
                          string Data,signed short Priority)
 
182
{
 
183
   Pin *P = 0;
 
184
   
 
185
   if (Name.empty() == true)
 
186
      P = &*Defaults.insert(Defaults.end());
 
187
   else
 
188
   {
 
189
      // Get a spot to put the pin
 
190
      pkgCache::PkgIterator Pkg = Cache->FindPkg(Name);
 
191
      if (Pkg.end() == true)
 
192
      {
 
193
         // Check the unmatched table
 
194
         for (vector<PkgPin>::iterator I = Unmatched.begin(); 
 
195
              I != Unmatched.end() && P == 0; I++)
 
196
            if (I->Pkg == Name)
 
197
               P = &*I;
 
198
         
 
199
         if (P == 0)
 
200
            P = &*Unmatched.insert(Unmatched.end());      
 
201
      }
 
202
      else
 
203
      {
 
204
         P = Pins + Pkg->ID;
 
205
      }      
 
206
   }
 
207
   
 
208
   // Set..
 
209
   P->Type = Type;
 
210
   P->Priority = Priority;
 
211
   P->Data = Data;
 
212
}
 
213
                                                                        /*}}}*/
 
214
// Policy::GetMatch - Get the matching version for a package pin        /*{{{*/
 
215
// ---------------------------------------------------------------------
 
216
/* */
 
217
pkgCache::VerIterator pkgPolicy::GetMatch(pkgCache::PkgIterator Pkg)
 
218
{
 
219
   const Pin &PPkg = Pins[Pkg->ID];
 
220
   if (PPkg.Type != pkgVersionMatch::None)
 
221
   {
 
222
      pkgVersionMatch Match(PPkg.Data,PPkg.Type);
 
223
      return Match.Find(Pkg);
 
224
   }
 
225
   return pkgCache::VerIterator(*Pkg.Cache());
 
226
}
 
227
                                                                        /*}}}*/
 
228
// Policy::GetPriority - Get the priority of the package pin            /*{{{*/
 
229
// ---------------------------------------------------------------------
 
230
/* */
 
231
signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
 
232
{
 
233
   if (Pins[Pkg->ID].Type != pkgVersionMatch::None)
 
234
   {
 
235
      // In this case 0 means default priority
 
236
      if (Pins[Pkg->ID].Priority == 0)
 
237
         return 989;
 
238
      return Pins[Pkg->ID].Priority;
 
239
   }
 
240
   
 
241
   return 0;
 
242
}
 
243
                                                                        /*}}}*/
 
244
 
 
245
// ReadPinFile - Load the pin file into a Policy                        /*{{{*/
 
246
// ---------------------------------------------------------------------
 
247
/* I'd like to see the preferences file store more than just pin information
 
248
   but right now that is the only stuff I have to store. Later there will
 
249
   have to be some kind of combined super parser to get the data into all
 
250
   the right classes.. */
 
251
bool ReadPinFile(pkgPolicy &Plcy,string File)
 
252
{
 
253
   if (File.empty() == true)
 
254
      File = _config->FindFile("Dir::Etc::Preferences");
 
255
 
 
256
   if (FileExists(File) == false)
 
257
      return true;
 
258
   
 
259
   FileFd Fd(File,FileFd::ReadOnly);
 
260
   pkgTagFile TF(&Fd);
 
261
   if (_error->PendingError() == true)
 
262
      return false;
 
263
   
 
264
   pkgTagSection Tags;
 
265
   while (TF.Step(Tags) == true)
 
266
   {
 
267
      string Name = Tags.FindS("Package");
 
268
      if (Name.empty() == true)
 
269
         return _error->Error(_("Invalid record in the preferences file, no Package header"));
 
270
      if (Name == "*")
 
271
         Name = string();
 
272
      
 
273
      const char *Start;
 
274
      const char *End;
 
275
      if (Tags.Find("Pin",Start,End) == false)
 
276
         continue;
 
277
         
 
278
      const char *Word = Start;
 
279
      for (; Word != End && isspace(*Word) == 0; Word++);
 
280
 
 
281
      // Parse the type..
 
282
      pkgVersionMatch::MatchType Type;
 
283
      if (stringcasecmp(Start,Word,"version") == 0 && Name.empty() == false)
 
284
         Type = pkgVersionMatch::Version;
 
285
      else if (stringcasecmp(Start,Word,"release") == 0)
 
286
         Type = pkgVersionMatch::Release;
 
287
      else if (stringcasecmp(Start,Word,"origin") == 0)
 
288
         Type = pkgVersionMatch::Origin;
 
289
      else
 
290
      {
 
291
         _error->Warning(_("Did not understand pin type %s"),string(Start,Word).c_str());
 
292
         continue;
 
293
      }
 
294
      for (; Word != End && isspace(*Word) != 0; Word++);
 
295
 
 
296
      Plcy.CreatePin(Type,Name,string(Word,End),
 
297
                     Tags.FindI("Pin-Priority"));
 
298
   }
 
299
 
 
300
   Plcy.InitDefaults();
 
301
   return true;
 
302
}
 
303
                                                                        /*}}}*/