]>
git.saurik.com Git - apt.git/blob - apt-pkg/packagemanager.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: packagemanager.cc,v 1.4 1998/07/12 23:58:30 jgg Exp $
4 /* ######################################################################
6 Package Manager - Abstacts the package manager
8 More work is needed in the area of transitioning provides, ie exim
9 replacing smail. This can cause interesing side effects.
11 Other cases involving conflicts+replaces should be tested.
13 ##################################################################### */
15 // Include Files /*{{{*/
17 #pragma implementation "apt-pkg/packagemanager.h"
19 #include <apt-pkg/packagemanager.h>
20 #include <apt-pkg/orderlist.h>
21 #include <apt-pkg/depcache.h>
22 #include <apt-pkg/error.h>
23 #include <apt-pkg/version.h>
26 // PM::PackageManager - Constructor /*{{{*/
27 // ---------------------------------------------------------------------
29 pkgPackageManager::pkgPackageManager(pkgDepCache
&Cache
) : Cache(Cache
)
31 FileNames
= new string
[Cache
.Head().PackageCount
];
35 // PM::PackageManager - Destructor /*{{{*/
36 // ---------------------------------------------------------------------
38 pkgPackageManager::~pkgPackageManager()
44 // PM::FixMissing - Keep all missing packages /*{{{*/
45 // ---------------------------------------------------------------------
46 /* This is called to correct the installation when packages could not
48 bool pkgPackageManager::FixMissing()
50 unsigned char *Touch
= new unsigned char[Cache
.Head().PackageCount
];
51 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
53 // Create the status list that ResolveConflicts needs
54 if ((Cache
[I
].DepState
& pkgDepCache::DepNowMin
) == pkgDepCache::DepNowMin
)
55 Touch
[I
->ID
] = (1 << 0) | (1 << 1);
57 Touch
[I
->ID
] = 1 << 1;
59 if (Cache
[I
].Keep() == true)
61 if (FileNames
[I
->ID
].empty() == false || Cache
[I
].Delete() == true)
66 // Now downgrade everything that is broken
67 // Cache.ResolveConflicts(Touch);
70 return Cache
.BrokenCount() == 0;
74 // PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
75 // ---------------------------------------------------------------------
76 /* The restriction on provides is to eliminate the case when provides
77 are transitioning between valid states [ie exim to smail] */
78 bool pkgPackageManager::DepAlwaysTrue(DepIterator D
)
80 if (D
.TargetPkg()->ProvidesList
!= 0)
83 if ((Cache
[D
] & pkgDepCache::DepInstall
) != 0 &&
84 (Cache
[D
] & pkgDepCache::DepNow
) != 0)
89 // PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
90 // ---------------------------------------------------------------------
91 /* This looks over the reverses for a conflicts line that needs early
93 bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg
,DepIterator D
,
96 for (;D
.end() == false; D
++)
98 if (D
->Type
!= pkgCache::Dep::Conflicts
)
101 if (D
.ParentPkg() == Pkg
)
104 if (pkgCheckDep(D
.TargetVer(),Ver
,D
->CompareOp
) == false)
107 if (List
->IsNow(Pkg
) == false)
110 if (EarlyRemove(D
.ParentPkg()) == false)
116 // PM::ConfigureAll - Run the all out configuration /*{{{*/
117 // ---------------------------------------------------------------------
118 /* This configures every package. It is assumed they are all unpacked and
119 that the final configuration is valid. */
120 bool pkgPackageManager::ConfigureAll()
122 pkgOrderList
OList(Cache
);
124 // Populate the order list
125 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
126 if (List
->IsFlag(pkgCache::PkgIterator(Cache
,*I
),
127 pkgOrderList::UnPacked
) == true)
130 if (OList
.OrderConfigure() == false)
133 // Perform the configuring
134 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); I
++)
136 PkgIterator
Pkg(Cache
,*I
);
138 if (Configure(Pkg
) == false)
141 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
147 // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
148 // ---------------------------------------------------------------------
149 /* This routine scheduals the configuration of the given package and all
150 of it's dependents. */
151 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg
)
153 pkgOrderList
OList(Cache
);
155 if (DepAdd(OList
,Pkg
) == false)
158 if (OList
.OrderConfigure() == false)
161 // Perform the configuring
162 for (pkgOrderList::iterator I
= OList
.begin(); I
!= OList
.end(); I
++)
164 PkgIterator
Pkg(Cache
,*I
);
166 if (Configure(Pkg
) == false)
169 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
173 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == false)
174 return _error
->Error("Internal error, could not immediate configure %s",Pkg
.Name());
179 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
180 // ---------------------------------------------------------------------
181 /* This recursively adds all dependents to the order list */
182 bool pkgPackageManager::DepAdd(pkgOrderList
&OList
,PkgIterator Pkg
,int Depth
)
184 if (OList
.IsFlag(Pkg
,pkgOrderList::Added
) == true)
186 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
188 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == false)
192 // Put the package on the list
193 OList
.push_back(Pkg
);
194 OList
.Flag(Pkg
,pkgOrderList::Added
);
197 // Check the dependencies to see if they are all satisfied.
199 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); D
.end() == false;)
201 if (D
->Type
!= pkgCache::Dep::Depends
&& D
->Type
!= pkgCache::Dep::PreDepends
)
209 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
211 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
216 Version
**VList
= D
.AllTargets();
217 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
219 VerIterator
Ver(Cache
,*I
);
220 PkgIterator Pkg
= Ver
.ParentPkg();
222 // See if the current version is ok
223 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
224 Pkg
.State() == PkgIterator::NeedsNothing
)
230 // Not the install version
231 if (Cache
[Pkg
].InstallVer
!= *I
||
232 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
234 if (List
->IsFlag(Pkg
,pkgOrderList::UnPacked
) == true)
235 Bad
= !DepAdd(OList
,Pkg
,Depth
);
236 if (List
->IsFlag(Pkg
,pkgOrderList::Configured
) == true)
244 OList
.Flag(Pkg
,0,pkgOrderList::Added
);
255 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
256 // ---------------------------------------------------------------------
257 /* This is called to deal with conflicts arising from unpacking */
258 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg
)
260 if (List
->IsNow(Pkg
) == false)
263 // Already removed it
264 if (List
->IsFlag(Pkg
,pkgOrderList::Removed
) == true)
267 // Woops, it will not be re-installed!
268 if (List
->IsFlag(Pkg
,pkgOrderList::InList
) == false)
271 bool Res
= SmartRemove(Pkg
);
272 if (Cache
[Pkg
].Delete() == false)
273 List
->Flag(Pkg
,pkgOrderList::Removed
,pkgOrderList::States
);
278 // PM::SmartRemove - Removal Helper /*{{{*/
279 // ---------------------------------------------------------------------
281 bool pkgPackageManager::SmartRemove(PkgIterator Pkg
)
283 if (List
->IsNow(Pkg
) == false)
286 List
->Flag(Pkg
,pkgOrderList::Configured
,pkgOrderList::States
);
290 // PM::SmartUnPack - Install helper /*{{{*/
291 // ---------------------------------------------------------------------
292 /* This performs the task of handling pre-depends. */
293 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg
)
295 // Check if it is already unpacked
296 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
297 Cache
[Pkg
].Keep() == true)
299 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
300 if (List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
301 if (SmartConfigure(Pkg
) == false)
302 return _error
->Error("Internal Error, Could not perform immediate configuraton");
306 /* See if this packages install version has any predependencies
307 that are not met by 'now' packages. */
308 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
309 D
.end() == false; D
++)
311 if (D
->Type
== pkgCache::Dep::PreDepends
)
313 // Look for possible ok targets.
314 Version
**VList
= D
.AllTargets();
316 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
318 VerIterator
Ver(Cache
,*I
);
319 PkgIterator Pkg
= Ver
.ParentPkg();
321 // See if the current version is ok
322 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true &&
323 Pkg
.State() == PkgIterator::NeedsNothing
)
330 // Look for something that could be configured.
331 for (Version
**I
= VList
; *I
!= 0 && Bad
== true; I
++)
333 VerIterator
Ver(Cache
,*I
);
334 PkgIterator Pkg
= Ver
.ParentPkg();
336 // Not the install version
337 if (Cache
[Pkg
].InstallVer
!= *I
||
338 (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
))
341 Bad
= !SmartConfigure(Pkg
);
347 return _error
->Error("Internal Error, Couldn't configure a pre-depend");
352 if (D
->Type
== pkgCache::Dep::Conflicts
)
354 /* Look for conflicts. Two packages that are both in the install
355 state cannot conflict so we don't check.. */
356 Version
**VList
= D
.AllTargets();
357 for (Version
**I
= VList
; *I
!= 0; I
++)
359 VerIterator
Ver(Cache
,*I
);
360 PkgIterator Pkg
= Ver
.ParentPkg();
362 // See if the current version is conflicting
363 if (Pkg
.CurrentVer() == Ver
&& List
->IsNow(Pkg
) == true)
365 if (EarlyRemove(Pkg
) == false)
366 return _error
->Error("Internal Error, Could not early remove %s",Pkg
.Name());
373 // Check for reverse conflicts.
374 CheckRConflicts(Pkg
,Pkg
.RevDependsList(),
375 Cache
[Pkg
].InstVerIter(Cache
).VerStr());
376 for (PrvIterator P
= Cache
[Pkg
].InstVerIter(Cache
).ProvidesList();
377 P
.end() == false; P
++)
378 CheckRConflicts(Pkg
,P
.ParentPkg().RevDependsList(),P
.ProvideVersion());
380 if (Install(Pkg
,FileNames
[Pkg
->ID
]) == false)
383 List
->Flag(Pkg
,pkgOrderList::UnPacked
,pkgOrderList::States
);
385 // Perform immedate configuration of the package.
386 if (List
->IsFlag(Pkg
,pkgOrderList::Immediate
) == true)
387 if (SmartConfigure(Pkg
) == false)
388 return _error
->Error("Internal Error, Could not perform immediate configuraton");
393 // PM::OrderInstall - Installation ordering routine /*{{{*/
394 // ---------------------------------------------------------------------
396 bool pkgPackageManager::OrderInstall()
399 List
= new pkgOrderList(Cache
);
401 // Generate the list of affected packages and sort it
402 for (PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; I
++)
404 // Consider all depends
405 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
407 List
->Flag(I
,pkgOrderList::Immediate
);
408 if (Cache
[I
].InstallVer
!= 0)
409 for (DepIterator D
= Cache
[I
].InstVerIter(Cache
).DependsList();
410 D
.end() == false; D
++)
411 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
412 List
->Flag(D
.TargetPkg(),pkgOrderList::Immediate
);
413 if (I
->CurrentVer
!= 0)
414 for (DepIterator D
= I
.CurrentVer().DependsList();
415 D
.end() == false; D
++)
416 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
417 List
->Flag(D
.TargetPkg(),pkgOrderList::Immediate
);
421 if ((Cache
[I
].Keep() == true ||
422 Cache
[I
].InstVerIter(Cache
) == I
.CurrentVer()) &&
423 I
.State() == pkgCache::PkgIterator::NeedsNothing
)
426 // Append it to the list
429 if ((I
->Flags
& pkgCache::Flag::ImmediateConf
) == pkgCache::Flag::ImmediateConf
)
430 List
->Flag(I
,pkgOrderList::Immediate
);
433 if (List
->OrderUnpack() == false)
434 return _error
->Error("Internal ordering error");
436 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
438 PkgIterator
Pkg(Cache
,*I
);
441 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
)
442 return _error
->Error("Internal Error, trying to manipulate a kept package");
444 // Perform a delete or an install
445 if (Cache
[Pkg
].Delete() == true)
447 if (SmartRemove(Pkg
) == false)
451 if (SmartUnPack(Pkg
) == false)
455 // Final run through the configure phase
456 if (ConfigureAll() == false)
460 for (pkgOrderList::iterator I
= List
->begin(); I
!= List
->end(); I
++)
461 if (List
->IsFlag(*I
,pkgOrderList::Configured
) == false)
462 return _error
->Error("Internal error, packages left unconfigured. %s",
463 PkgIterator(Cache
,*I
).Name());
468 // PM::DoInstall - Does the installation /*{{{*/
469 // ---------------------------------------------------------------------
470 /* This uses the filenames in FileNames and the information in the
471 DepCache to perform the installation of packages.*/
472 bool pkgPackageManager::DoInstall()
474 return OrderInstall() && Go();