~ubuntu-branches/debian/experimental/apt/experimental

« back to all changes in this revision

Viewing changes to apt-pkg/depcache.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2010-02-18 22:07:23 UTC
  • mfrom: (9.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100218220723-zb7zdh6fmsmp30tr
Tags: 0.7.26~exp2
fix crash when LANGUAGE is not set

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
// Include Files                                                        /*{{{*/
11
11
#include <apt-pkg/depcache.h>
12
12
#include <apt-pkg/version.h>
13
 
#include <apt-pkg/contrib/error.h>
14
 
#include <apt-pkg/contrib/sptr.h>
 
13
#include <apt-pkg/error.h>
 
14
#include <apt-pkg/sptr.h>
15
15
#include <apt-pkg/algorithms.h>
16
16
 
17
 
#include <apt-pkg/contrib/fileutl.h>
18
 
#include <apt-pkg/contrib/configuration.h>
 
17
#include <apt-pkg/fileutl.h>
 
18
#include <apt-pkg/strutl.h>
 
19
#include <apt-pkg/configuration.h>
19
20
#include <apt-pkg/pkgsystem.h>
20
21
#include <apt-pkg/tagfile.h>
21
22
 
26
27
#include <sys/stat.h>
27
28
 
28
29
#include <apti18n.h>    
29
 
 
30
 
// helper for Install-Recommends-Sections and Never-MarkAuto-Sections
 
30
                                                                        /*}}}*/
 
31
// helper for Install-Recommends-Sections and Never-MarkAuto-Sections   /*{{{*/
31
32
static bool 
32
33
ConfigValueInSubTree(const char* SubTree, const char *needle)
33
34
{
46
47
   }
47
48
   return false;
48
49
}
49
 
 
50
 
 
51
 
pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :
 
50
                                                                        /*}}}*/
 
51
pkgDepCache::ActionGroup::ActionGroup(pkgDepCache &cache) :             /*{{{*/
52
52
  cache(cache), released(false)
53
53
{
54
54
  ++cache.group_level;
76
76
{
77
77
  release();
78
78
}
79
 
 
 
79
                                                                        /*}}}*/
80
80
// DepCache::pkgDepCache - Constructors                                 /*{{{*/
81
81
// ---------------------------------------------------------------------
82
82
/* */
83
83
pkgDepCache::pkgDepCache(pkgCache *pCache,Policy *Plcy) :
84
84
  group_level(0), Cache(pCache), PkgState(0), DepState(0)
85
85
{
 
86
   DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false);
 
87
   DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false);
86
88
   delLocalPolicy = 0;
87
89
   LocalPolicy = Plcy;
88
90
   if (LocalPolicy == 0)
127
129
   int Done = 0;
128
130
   for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++)
129
131
   {
130
 
      if (Prog != 0)
 
132
      if (Prog != 0 && Done%20 == 0)
131
133
         Prog->Progress(Done);
132
134
      
133
135
      // Find the proper cache slot
159
161
   return true;
160
162
161
163
                                                                        /*}}}*/
162
 
 
163
 
bool pkgDepCache::readStateFile(OpProgress *Prog)
 
164
bool pkgDepCache::readStateFile(OpProgress *Prog)                       /*{{{*/
164
165
{
165
166
   FileFd state_file;
166
167
   string state = _config->FindDir("Dir::State") + "extended_states";
174
175
      pkgTagFile tagfile(&state_file);
175
176
      pkgTagSection section;
176
177
      int amt=0;
 
178
      bool debug_autoremove=_config->FindB("Debug::pkgAutoRemove",false);
177
179
      while(tagfile.Step(section)) {
178
180
         string pkgname = section.FindS("Package");
179
181
         pkgCache::PkgIterator pkg=Cache->FindPkg(pkgname);
183
185
            short reason = section.FindI("Auto-Installed", 0);
184
186
            if(reason > 0)
185
187
               PkgState[pkg->ID].Flags  |= Flag::Auto;
186
 
            if(_config->FindB("Debug::pkgAutoRemove",false))
 
188
            if(debug_autoremove)
187
189
               std::cout << "Auto-Installed : " << pkgname << std::endl;
188
190
            amt+=section.size();
189
191
            if(Prog != NULL)
190
192
               Prog->OverallProgress(amt, file_size, 1, 
191
193
                                     _("Reading state information"));
192
194
         }
193
 
         if(Prog != NULL)
194
 
            Prog->OverallProgress(file_size, file_size, 1, 
195
 
                                  _("Reading state information"));
196
195
      }
 
196
      if(Prog != NULL)
 
197
         Prog->OverallProgress(file_size, file_size, 1,
 
198
                               _("Reading state information"));
197
199
   }
198
200
 
199
201
   return true;
200
202
}
201
 
 
202
 
bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)
 
203
                                                                        /*}}}*/
 
204
bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)  /*{{{*/
203
205
{
204
 
   if(_config->FindB("Debug::pkgAutoRemove",false))
 
206
   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
 
207
   
 
208
   if(debug_autoremove)
205
209
      std::clog << "pkgDepCache::writeStateFile()" << std::endl;
206
210
 
207
211
   FileFd StateFile;
239
243
            continue;
240
244
         bool newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
241
245
         if(_config->FindB("Debug::pkgAutoRemove",false))
242
 
            std::clog << "Update exisiting AutoInstall info: " 
 
246
            std::clog << "Update existing AutoInstall info: " 
243
247
                      << pkg.Name() << std::endl;
244
248
         TFRewriteData rewrite[2];
245
249
         rewrite[0].Tag = "Auto-Installed";
256
260
   for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
257
261
      if(PkgState[pkg->ID].Flags & Flag::Auto) {
258
262
         if (pkgs_seen.find(pkg.Name()) != pkgs_seen.end()) {
259
 
            if(_config->FindB("Debug::pkgAutoRemove",false))
 
263
            if(debug_autoremove)
260
264
               std::clog << "Skipping already written " << pkg.Name() << std::endl;
261
265
            continue;
262
266
         }
263
267
         // skip not installed ones if requested
264
268
         if(InstalledOnly && pkg->CurrentVer == 0)
265
269
            continue;
266
 
         if(_config->FindB("Debug::pkgAutoRemove",false))
 
270
         if(debug_autoremove)
267
271
            std::clog << "Writing new AutoInstall: " 
268
272
                      << pkg.Name() << std::endl;
269
273
         ostr.str(string(""));
281
285
 
282
286
   return true;
283
287
}
284
 
 
 
288
                                                                        /*}}}*/
285
289
// DepCache::CheckDep - Checks a single dependency                      /*{{{*/
286
290
// ---------------------------------------------------------------------
287
291
/* This first checks the dependency against the main target package and
699
703
           P.end() != true; P++)
700
704
         Update(P.ParentPkg().RevDependsList());
701
705
}
702
 
 
703
706
                                                                        /*}}}*/
704
 
 
705
707
// DepCache::MarkKeep - Put the package in the keep state               /*{{{*/
706
708
// ---------------------------------------------------------------------
707
709
/* */
708
 
void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser)
 
710
void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 
711
                           unsigned long Depth)
709
712
{
710
713
   // Simplifies other routines.
711
714
   if (Pkg.end() == true)
746
749
     P.Flags &= ~Flag::Auto;
747
750
#endif
748
751
 
 
752
   if (DebugMarker == true)
 
753
      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << " FU=" << FromUser << std::endl;
 
754
 
749
755
   RemoveSizes(Pkg);
750
756
   RemoveStates(Pkg);
751
757
 
765
771
// DepCache::MarkDelete - Put the package in the delete state           /*{{{*/
766
772
// ---------------------------------------------------------------------
767
773
/* */
768
 
void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
 
774
void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
 
775
                             unsigned long Depth, bool FromUser)
769
776
{
770
777
   // Simplifies other routines.
771
778
   if (Pkg.end() == true)
787
794
   if (Pkg->VersionList == 0)
788
795
      return;
789
796
 
 
797
   // check if we are allowed to install the package
 
798
   if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false)
 
799
      return;
 
800
 
 
801
   if (DebugMarker == true)
 
802
      std::clog << OutputInDepth(Depth) << "MarkDelete " << Pkg << " FU=" << FromUser << std::endl;
 
803
 
790
804
   RemoveSizes(Pkg);
791
805
   RemoveStates(Pkg);
792
806
   
801
815
   AddSizes(Pkg);
802
816
}
803
817
                                                                        /*}}}*/
 
818
// DepCache::IsDeleteOk - check if it is ok to remove this package      /*{{{*/
 
819
// ---------------------------------------------------------------------
 
820
/* The default implementation just honors dpkg hold
 
821
   But an application using this library can override this method
 
822
   to control the MarkDelete behaviour */
 
823
bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge,
 
824
                              unsigned long Depth, bool FromUser)
 
825
{
 
826
   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
 
827
   {
 
828
      if (DebugMarker == true)
 
829
         std::clog << OutputInDepth(Depth) << "Hold prevents MarkDelete of " << Pkg << " FU=" << FromUser << std::endl;
 
830
      return false;
 
831
   }
 
832
   return true;
 
833
}
 
834
                                                                        /*}}}*/
804
835
// DepCache::MarkInstall - Put the package in the install state         /*{{{*/
805
836
// ---------------------------------------------------------------------
806
837
/* */
826
857
        P.CandidateVer == (Version *)Pkg.CurrentVer()))
827
858
   {
828
859
      if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
829
 
         MarkKeep(Pkg, false, FromUser);
 
860
         MarkKeep(Pkg, false, FromUser, Depth+1);
830
861
      return;
831
862
   }
832
863
 
836
867
   // We dont even try to install virtual packages..
837
868
   if (Pkg->VersionList == 0)
838
869
      return;
 
870
 
 
871
   // check if we are allowed to install the package
 
872
   if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false)
 
873
      return;
 
874
 
839
875
   /* Target the candidate version and remove the autoflag. We reset the
840
876
      autoflag below if this was called recursively. Otherwise the user
841
877
      should have the ability to de-auto a package by changing its state */
864
900
   AddStates(Pkg);
865
901
   Update(Pkg);
866
902
   AddSizes(Pkg);
867
 
   
 
903
 
868
904
   if (AutoInst == false)
869
905
      return;
870
906
 
 
907
   if (DebugMarker == true)
 
908
      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
 
909
 
871
910
   DepIterator Dep = P.InstVerIter(*this).DependsList();
872
911
   for (; Dep.end() != true;)
873
912
   {
937
976
         }
938
977
      }
939
978
      if(isNewImportantDep)
940
 
         if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
941
 
            std::clog << "new important dependency: " 
 
979
         if(DebugAutoInstall == true)
 
980
            std::clog << OutputInDepth(Depth) << "new important dependency: "
942
981
                      << Start.TargetPkg().Name() << std::endl;
943
982
      if(isPreviouslySatisfiedImportantDep)
944
 
        if(_config->FindB("Debug::pkgDepCache::AutoInstall", false) == true)
945
 
          std::clog << "previously satisfied important dependency on "
 
983
        if(DebugAutoInstall == true)
 
984
          std::clog << OutputInDepth(Depth) << "previously satisfied important dependency on "
946
985
                    << Start.TargetPkg().Name() << std::endl;
947
986
 
948
987
      // skip important deps if the package is already installed
991
1030
            }
992
1031
         }
993
1032
         
994
 
         if (InstPkg.end() == false) 
 
1033
         if (InstPkg.end() == false)
995
1034
         {
996
 
            if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
997
 
               std::clog << "Installing " << InstPkg.Name() 
998
 
                         << " as dep of " << Pkg.Name() 
 
1035
            if(DebugAutoInstall == true)
 
1036
               std::clog << OutputInDepth(Depth) << "Installing " << InstPkg.Name()
 
1037
                         << " as " << Start.DepType() << " of " << Pkg.Name()
999
1038
                         << std::endl;
1000
1039
            // now check if we should consider it a automatic dependency or not
1001
1040
            if(Pkg.Section() && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section()))
1002
1041
            {
1003
 
               if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
1004
 
                  std::clog << "Setting NOT as auto-installed (direct dep of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
 
1042
               if(DebugAutoInstall == true)
 
1043
                  std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct "
 
1044
                            << Start.DepType() << " of pkg in APT::Never-MarkAuto-Sections)" << std::endl;
1005
1045
               MarkInstall(InstPkg,true,Depth + 1, true);
1006
1046
            }
1007
1047
            else 
1028
1068
            PkgIterator Pkg = Ver.ParentPkg();
1029
1069
 
1030
1070
            if (Start->Type != Dep::DpkgBreaks)
1031
 
               MarkDelete(Pkg);
1032
 
            else
1033
 
               if (PkgState[Pkg->ID].CandidateVer != *I)
1034
 
                  MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
 
1071
               MarkDelete(Pkg,false,Depth + 1, false);
 
1072
            else if (PkgState[Pkg->ID].CandidateVer != *I)
 
1073
               MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps);
1035
1074
         }
1036
1075
         continue;
1037
1076
      }      
1038
1077
   }
1039
1078
}
1040
1079
                                                                        /*}}}*/
 
1080
// DepCache::IsInstallOk - check if it is ok to install this package    /*{{{*/
 
1081
// ---------------------------------------------------------------------
 
1082
/* The default implementation just honors dpkg hold
 
1083
   But an application using this library can override this method
 
1084
   to control the MarkInstall behaviour */
 
1085
bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
 
1086
                              unsigned long Depth, bool FromUser)
 
1087
{
 
1088
   if (FromUser == false && Pkg->SelectedState == pkgCache::State::Hold && _config->FindB("APT::Ignore-Hold",false) == false)
 
1089
   {
 
1090
      if (DebugMarker == true)
 
1091
         std::clog << OutputInDepth(Depth) << "Hold prevents MarkInstall of " << Pkg << " FU=" << FromUser << std::endl;
 
1092
      return false;
 
1093
   }
 
1094
   return true;
 
1095
}
 
1096
                                                                        /*}}}*/
1041
1097
// DepCache::SetReInstall - Set the reinstallation flag                 /*{{{*/
1042
1098
// ---------------------------------------------------------------------
1043
1099
/* */
1137
1193
   return Ver;
1138
1194
}
1139
1195
                                                                        /*}}}*/
1140
 
 
1141
1196
// Policy::GetCandidateVer - Returns the Candidate install version      /*{{{*/
1142
1197
// ---------------------------------------------------------------------
1143
1198
/* The default just returns the highest available version that is not
1174
1229
   return Last;
1175
1230
}
1176
1231
                                                                        /*}}}*/
1177
 
 
1178
1232
// Policy::IsImportantDep - True if the dependency is important         /*{{{*/
1179
1233
// ---------------------------------------------------------------------
1180
1234
/* */
1200
1254
   return false;
1201
1255
}
1202
1256
                                                                        /*}}}*/
1203
 
 
1204
 
pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()
 
1257
pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc()                   /*{{{*/
1205
1258
  : constructedSuccessfully(false)
1206
1259
{
1207
1260
  Configuration::Item const *Opts;
1230
1283
 
1231
1284
  constructedSuccessfully = true;
1232
1285
}
1233
 
 
1234
 
pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()
 
1286
                                                                        /*}}}*/
 
1287
pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc()                  /*{{{*/
1235
1288
{
1236
1289
  for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
1237
1290
    {
1239
1292
      delete rootSetRegexp[i];
1240
1293
    }
1241
1294
}
1242
 
 
1243
 
 
1244
 
bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg)
 
1295
                                                                        /*}}}*/
 
1296
bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) /*{{{*/
1245
1297
{
1246
1298
   for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
1247
1299
      if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
1249
1301
 
1250
1302
   return false;
1251
1303
}
1252
 
 
1253
 
pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()
 
1304
                                                                        /*}}}*/
 
1305
pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc()               /*{{{*/
1254
1306
{
1255
1307
  DefaultRootSetFunc *f = new DefaultRootSetFunc;
1256
1308
  if(f->wasConstructedSuccessfully())
1261
1313
      return NULL;
1262
1314
    }
1263
1315
}
1264
 
 
 
1316
                                                                        /*}}}*/
1265
1317
bool pkgDepCache::MarkFollowsRecommends()
1266
1318
{
1267
1319
  return _config->FindB("APT::AutoRemove::RecommendsImportant", true);
1272
1324
  return _config->FindB("APT::AutoRemove::SuggestsImportant", false);
1273
1325
}
1274
1326
 
1275
 
// the main mark algorithm
 
1327
// pkgDepCache::MarkRequired - the main mark algorithm                  /*{{{*/
1276
1328
bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
1277
1329
{
1278
1330
   bool follow_recommends;
1279
1331
   bool follow_suggests;
 
1332
   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
1280
1333
 
1281
1334
   // init the states
1282
1335
   for(PkgIterator p = PkgBegin(); !p.end(); ++p)
1285
1338
      PkgState[p->ID].Garbage = false;
1286
1339
 
1287
1340
      // debug output
1288
 
      if(_config->FindB("Debug::pkgAutoRemove",false) 
1289
 
         && PkgState[p->ID].Flags & Flag::Auto)
 
1341
      if(debug_autoremove && PkgState[p->ID].Flags & Flag::Auto)
1290
1342
         std::clog << "AutoDep: " << p.Name() << std::endl;
1291
1343
   }
1292
1344
 
1317
1369
 
1318
1370
   return true;
1319
1371
}
1320
 
 
1321
 
// mark a single package in Mark-and-Sweep
 
1372
                                                                        /*}}}*/
 
1373
// MarkPackage - mark a single package in Mark-and-Sweep                /*{{{*/
1322
1374
void pkgDepCache::MarkPackage(const pkgCache::PkgIterator &pkg,
1323
1375
                              const pkgCache::VerIterator &ver,
1324
1376
                              bool follow_recommends,
1357
1409
   if(state.Marked)
1358
1410
      return;
1359
1411
 
1360
 
   if(_config->FindB("Debug::pkgAutoRemove",false))
 
1412
   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove", false);
 
1413
   
 
1414
   if(debug_autoremove)
1361
1415
     {
1362
1416
       std::clog << "Marking: " << pkg.Name();
1363
1417
       if(!ver.end())
1388
1442
           {
1389
1443
              if(_system->VS->CheckDep(V.VerStr(), d->CompareOp, d.TargetVer()))
1390
1444
              {
1391
 
                if(_config->FindB("Debug::pkgAutoRemove",false))
 
1445
                if(debug_autoremove)
1392
1446
                  {
1393
1447
                    std::clog << "Following dep: " << d.ParentPkg().Name()
1394
1448
                              << " " << d.ParentVer().VerStr() << " "
1412
1466
              if(_system->VS->CheckDep(prv.ProvideVersion(), d->CompareOp, 
1413
1467
                                       d.TargetVer()))
1414
1468
              {
1415
 
                if(_config->FindB("Debug::pkgAutoRemove",false))
 
1469
                if(debug_autoremove)
1416
1470
                  {
1417
1471
                    std::clog << "Following dep: " << d.ParentPkg().Name()
1418
1472
                              << " " << d.ParentVer().VerStr() << " "
1437
1491
     }
1438
1492
   }
1439
1493
}
 
1494
                                                                        /*}}}*/
 
1495
bool pkgDepCache::Sweep()                                               /*{{{*/
 
1496
{
 
1497
   bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false);
1440
1498
 
1441
 
bool pkgDepCache::Sweep()
1442
 
{
1443
1499
   // do the sweep
1444
1500
   for(PkgIterator p=PkgBegin(); !p.end(); ++p)
1445
 
  {
 
1501
   {
1446
1502
     StateCache &state=PkgState[p->ID];
1447
1503
 
1448
1504
     // skip required packages
1454
1510
     if(!state.Marked && (!p.CurrentVer().end() || state.Install()))
1455
1511
     {
1456
1512
        state.Garbage=true;
1457
 
        if(_config->FindB("Debug::pkgAutoRemove",false))
 
1513
        if(debug_autoremove)
1458
1514
           std::cout << "Garbage: " << p.Name() << std::endl;
1459
1515
     }
1460
1516
  }   
1461
1517
 
1462
1518
   return true;
1463
1519
}
 
1520
                                                                        /*}}}*/