Join with aliencode
[ntk/apt.git] / apt-pkg / packagemanager.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: packagemanager.cc,v 1.26 2001/02/20 07:03:17 jgg Exp $
4 /* ######################################################################
5
6 Package Manager - Abstacts the package manager
7
8 More work is needed in the area of transitioning provides, ie exim
9 replacing smail. This can cause interesing side effects.
10
11 Other cases involving conflicts+replaces should be tested.
12
13 ##################################################################### */
14 /*}}}*/
15 // Include Files /*{{{*/
16 #ifdef __GNUG__
17 #pragma implementation "apt-pkg/packagemanager.h"
18 #endif
19
20 #include <apt-pkg/packagemanager.h>
21 #include <apt-pkg/orderlist.h>
22 #include <apt-pkg/depcache.h>
23 #include <apt-pkg/error.h>
24 #include <apt-pkg/version.h>
25 #include <apt-pkg/acquire-item.h>
26 #include <apt-pkg/algorithms.h>
27 #include <apt-pkg/configuration.h>
28 #include <apt-pkg/sptr.h>
29
30 #include <apti18n.h>
31 /*}}}*/
32
33 // PM::PackageManager - Constructor /*{{{*/
34 // ---------------------------------------------------------------------
35 /* */
36 pkgPackageManager::pkgPackageManager(pkgDepCache *pCache) : Cache(*pCache)
37 {
38 FileNames = new string[Cache.Head().PackageCount];
39 List = 0;
40 Debug = _config->FindB("Debug::pkgPackageManager",false);
41 }
42 /*}}}*/
43 // PM::PackageManager - Destructor /*{{{*/
44 // ---------------------------------------------------------------------
45 /* */
46 pkgPackageManager::~pkgPackageManager()
47 {
48 delete List;
49 delete [] FileNames;
50 }
51 /*}}}*/
52 // PM::GetArchives - Queue the archives for download /*{{{*/
53 // ---------------------------------------------------------------------
54 /* */
55 bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources,
56 pkgRecords *Recs)
57 {
58 if (CreateOrderList() == false)
59 return false;
60
61 if (List->OrderUnpack() == false)
62 return _error->Error("Internal ordering error");
63
64 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
65 {
66 PkgIterator Pkg(Cache,*I);
67 FileNames[Pkg->ID] = string();
68
69 // Skip packages to erase
70 if (Cache[Pkg].Delete() == true)
71 continue;
72
73 // Skip Packages that need configure only.
74 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
75 Cache[Pkg].Keep() == true)
76 continue;
77
78 // Skip already processed packages
79 if (List->IsNow(Pkg) == false)
80 continue;
81
82 new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache),
83 FileNames[Pkg->ID]);
84 }
85
86 return true;
87 }
88 /*}}}*/
89 // PM::FixMissing - Keep all missing packages /*{{{*/
90 // ---------------------------------------------------------------------
91 /* This is called to correct the installation when packages could not
92 be downloaded. */
93 bool pkgPackageManager::FixMissing()
94 {
95 pkgProblemResolver Resolve(&Cache);
96 List->SetFileList(FileNames);
97
98 bool Bad = false;
99 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
100 {
101 if (List->IsMissing(I) == false)
102 continue;
103
104 // Okay, this file is missing and we need it. Mark it for keep
105 Bad = true;
106 Cache.MarkKeep(I);
107 }
108
109 // We have to empty the list otherwise it will not have the new changes
110 delete List;
111 List = 0;
112
113 if (Bad == false)
114 return true;
115
116 // Now downgrade everything that is broken
117 return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0;
118 }
119 /*}}}*/
120
121 // PM::CreateOrderList - Create the ordering class /*{{{*/
122 // ---------------------------------------------------------------------
123 /* This populates the ordering list with all the packages that are
124 going to change. */
125 bool pkgPackageManager::CreateOrderList()
126 {
127 if (List != 0)
128 return true;
129
130 delete List;
131 List = new pkgOrderList(&Cache);
132
133 bool NoImmConfigure = _config->FindB("APT::Immediate-Configure",false);
134
135 // Generate the list of affected packages and sort it
136 for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
137 {
138 // Mark the package and its dependends for immediate configuration
139 if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential ||
140 (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) &&
141 NoImmConfigure == false)
142 {
143 List->Flag(I,pkgOrderList::Immediate);
144
145 // Look for other packages to make immediate configurea
146 if (Cache[I].InstallVer != 0)
147 for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
148 D.end() == false; D++)
149 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
150 List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
151
152 // And again with the current version.
153 if (I->CurrentVer != 0)
154 for (DepIterator D = I.CurrentVer().DependsList();
155 D.end() == false; D++)
156 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
157 List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
158 }
159
160 // Not interesting
161 if ((Cache[I].Keep() == true ||
162 Cache[I].InstVerIter(Cache) == I.CurrentVer()) &&
163 I.State() == pkgCache::PkgIterator::NeedsNothing &&
164 (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall &&
165 (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete ||
166 (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge))
167 continue;
168
169 // Append it to the list
170 List->push_back(I);
171 }
172
173 return true;
174 }
175 /*}}}*/
176 // PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/
177 // ---------------------------------------------------------------------
178 /* The restriction on provides is to eliminate the case when provides
179 are transitioning between valid states [ie exim to smail] */
180 bool pkgPackageManager::DepAlwaysTrue(DepIterator D)
181 {
182 if (D.TargetPkg()->ProvidesList != 0)
183 return false;
184
185 if ((Cache[D] & pkgDepCache::DepInstall) != 0 &&
186 (Cache[D] & pkgDepCache::DepNow) != 0)
187 return true;
188 return false;
189 }
190 /*}}}*/
191 // PM::CheckRConflicts - Look for reverse conflicts /*{{{*/
192 // ---------------------------------------------------------------------
193 /* This looks over the reverses for a conflicts line that needs early
194 removal. */
195 bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D,
196 const char *Ver)
197 {
198 for (;D.end() == false; D++)
199 {
200 if (D->Type != pkgCache::Dep::Conflicts &&
201 D->Type != pkgCache::Dep::Obsoletes)
202 continue;
203
204 // The package hasnt been changed
205 if (List->IsNow(Pkg) == false)
206 continue;
207
208 // Ignore self conflicts, ignore conflicts from irrelevent versions
209 if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer())
210 continue;
211
212 if (Cache.VS().CheckDep(Ver,D->CompareOp,D.TargetVer()) == false)
213 continue;
214
215 if (EarlyRemove(D.ParentPkg()) == false)
216 return _error->Error("Reverse conflicts early remove for package '%s' failed",
217 Pkg.Name());
218 }
219 return true;
220 }
221 /*}}}*/
222 // PM::ConfigureAll - Run the all out configuration /*{{{*/
223 // ---------------------------------------------------------------------
224 /* This configures every package. It is assumed they are all unpacked and
225 that the final configuration is valid. */
226 bool pkgPackageManager::ConfigureAll()
227 {
228 pkgOrderList OList(&Cache);
229
230 // Populate the order list
231 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
232 if (List->IsFlag(pkgCache::PkgIterator(Cache,*I),
233 pkgOrderList::UnPacked) == true)
234 OList.push_back(*I);
235
236 if (OList.OrderConfigure() == false)
237 return false;
238
239 // Perform the configuring
240 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
241 {
242 PkgIterator Pkg(Cache,*I);
243
244 if (Configure(Pkg) == false)
245 return false;
246
247 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
248 }
249
250 return true;
251 }
252 /*}}}*/
253 // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/
254 // ---------------------------------------------------------------------
255 /* This routine scheduals the configuration of the given package and all
256 of it's dependents. */
257 bool pkgPackageManager::SmartConfigure(PkgIterator Pkg)
258 {
259 pkgOrderList OList(&Cache);
260
261 if (DepAdd(OList,Pkg) == false)
262 return false;
263
264 if (OList.OrderConfigure() == false)
265 return false;
266
267 // Perform the configuring
268 for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++)
269 {
270 PkgIterator Pkg(Cache,*I);
271
272 if (Configure(Pkg) == false)
273 return false;
274
275 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
276 }
277
278 // Sanity Check
279 if (List->IsFlag(Pkg,pkgOrderList::Configured) == false)
280 return _error->Error("Internal error, could not immediate configure %s",Pkg.Name());
281
282 return true;
283 }
284 /*}}}*/
285 // PM::DepAdd - Add all dependents to the oder list /*{{{*/
286 // ---------------------------------------------------------------------
287 /* This recursively adds all dependents to the order list */
288 bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth)
289 {
290 if (OList.IsFlag(Pkg,pkgOrderList::Added) == true)
291 return true;
292 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
293 return true;
294 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false)
295 return false;
296
297 // Put the package on the list
298 OList.push_back(Pkg);
299 OList.Flag(Pkg,pkgOrderList::Added);
300 Depth++;
301
302 // Check the dependencies to see if they are all satisfied.
303 bool Bad = false;
304 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;)
305 {
306 if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)
307 {
308 D++;
309 continue;
310 }
311
312 // Grok or groups
313 Bad = true;
314 for (bool LastOR = true; D.end() == false && LastOR == true; D++)
315 {
316 LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
317
318 if (Bad == false)
319 continue;
320
321 SPtrArray<Version *> VList = D.AllTargets();
322 for (Version **I = VList; *I != 0 && Bad == true; I++)
323 {
324 VerIterator Ver(Cache,*I);
325 PkgIterator Pkg = Ver.ParentPkg();
326
327 // See if the current version is ok
328 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
329 Pkg.State() == PkgIterator::NeedsNothing)
330 {
331 Bad = false;
332 continue;
333 }
334
335 // Not the install version
336 if (Cache[Pkg].InstallVer != *I ||
337 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
338 continue;
339
340 if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true)
341 Bad = !DepAdd(OList,Pkg,Depth);
342 if (List->IsFlag(Pkg,pkgOrderList::Configured) == true)
343 Bad = false;
344 }
345 }
346
347 if (Bad == true)
348 {
349 OList.Flag(Pkg,0,pkgOrderList::Added);
350 OList.pop_back();
351 Depth--;
352 return false;
353 }
354 }
355
356 Depth--;
357 return true;
358 }
359 /*}}}*/
360 // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/
361 // ---------------------------------------------------------------------
362 /* This is called to deal with conflicts arising from unpacking */
363 bool pkgPackageManager::EarlyRemove(PkgIterator Pkg)
364 {
365 if (List->IsNow(Pkg) == false)
366 return true;
367
368 // Already removed it
369 if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
370 return true;
371
372 // Woops, it will not be re-installed!
373 if (List->IsFlag(Pkg,pkgOrderList::InList) == false)
374 return false;
375
376 // Essential packages get special treatment
377 bool IsEssential = false;
378 if ((Pkg->Flags & pkgCache::Flag::Essential) != 0)
379 IsEssential = true;
380
381 /* Check for packages that are the dependents of essential packages and
382 promote them too */
383 if (Pkg->CurrentVer != 0)
384 {
385 for (DepIterator D = Pkg.RevDependsList(); D.end() == false &&
386 IsEssential == false; D++)
387 if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends)
388 if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0)
389 IsEssential = true;
390 }
391
392 if (IsEssential == true)
393 {
394 if (_config->FindB("APT::Force-LoopBreak",false) == false)
395 return _error->Error(_("This installation run will require temporarily "
396 "removing the essential package %s due to a "
397 "Conflicts/Pre-Depends loop. This is often bad, "
398 "but if you really want to do it, activate the "
399 "APT::Force-LoopBreak option."),Pkg.Name());
400 }
401
402 bool Res = SmartRemove(Pkg);
403 if (Cache[Pkg].Delete() == false)
404 List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States);
405
406 return Res;
407 }
408 /*}}}*/
409 // PM::SmartRemove - Removal Helper /*{{{*/
410 // ---------------------------------------------------------------------
411 /* */
412 bool pkgPackageManager::SmartRemove(PkgIterator Pkg)
413 {
414 if (List->IsNow(Pkg) == false)
415 return true;
416
417 List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States);
418 return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge);
419 }
420 /*}}}*/
421 // PM::SmartUnPack - Install helper /*{{{*/
422 // ---------------------------------------------------------------------
423 /* This performs the task of handling pre-depends. */
424 bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
425 {
426 // Check if it is already unpacked
427 if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
428 Cache[Pkg].Keep() == true)
429 {
430 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
431 if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
432 if (SmartConfigure(Pkg) == false)
433 return _error->Error("Internal Error, Could not perform immediate configuration (1) on %s",Pkg.Name());
434 return true;
435 }
436
437 /* See if this packages install version has any predependencies
438 that are not met by 'now' packages. */
439 for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList();
440 D.end() == false; )
441 {
442 // Compute a single dependency element (glob or)
443 pkgCache::DepIterator Start;
444 pkgCache::DepIterator End;
445 D.GlobOr(Start,End);
446
447 while (End->Type == pkgCache::Dep::PreDepends)
448 {
449 // Look for possible ok targets.
450 SPtrArray<Version *> VList = Start.AllTargets();
451 bool Bad = true;
452 for (Version **I = VList; *I != 0 && Bad == true; I++)
453 {
454 VerIterator Ver(Cache,*I);
455 PkgIterator Pkg = Ver.ParentPkg();
456
457 // See if the current version is ok
458 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true &&
459 Pkg.State() == PkgIterator::NeedsNothing)
460 {
461 Bad = false;
462 continue;
463 }
464 }
465
466 // Look for something that could be configured.
467 for (Version **I = VList; *I != 0 && Bad == true; I++)
468 {
469 VerIterator Ver(Cache,*I);
470 PkgIterator Pkg = Ver.ParentPkg();
471
472 // Not the install version
473 if (Cache[Pkg].InstallVer != *I ||
474 (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing))
475 continue;
476
477 Bad = !SmartConfigure(Pkg);
478 }
479
480 /* If this or element did not match then continue on to the
481 next or element until a matching element is found*/
482 if (Bad == true)
483 {
484 if (Start == End)
485 return _error->Error("Internal Error, Couldn't configure a pre-depend");
486 Start++;
487 }
488 else
489 break;
490 }
491
492 if (End->Type == pkgCache::Dep::Conflicts ||
493 End->Type == pkgCache::Dep::Obsoletes)
494 {
495 /* Look for conflicts. Two packages that are both in the install
496 state cannot conflict so we don't check.. */
497 SPtrArray<Version *> VList = End.AllTargets();
498 for (Version **I = VList; *I != 0; I++)
499 {
500 VerIterator Ver(Cache,*I);
501 PkgIterator Pkg = Ver.ParentPkg();
502
503 // See if the current version is conflicting
504 if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true)
505 {
506 if (EarlyRemove(Pkg) == false)
507 return _error->Error("Internal Error, Could not early remove %s",Pkg.Name());
508 }
509 }
510 }
511 }
512
513 // Check for reverse conflicts.
514 if (CheckRConflicts(Pkg,Pkg.RevDependsList(),
515 Cache[Pkg].InstVerIter(Cache).VerStr()) == false)
516 return false;
517
518 for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList();
519 P.end() == false; P++)
520 CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion());
521
522 if (Install(Pkg,FileNames[Pkg->ID]) == false)
523 return false;
524
525 List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States);
526
527 // Perform immedate configuration of the package.
528 if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true)
529 if (SmartConfigure(Pkg) == false)
530 return _error->Error("Internal Error, Could not perform immediate configuration (2) on %s",Pkg.Name());
531
532 return true;
533 }
534 /*}}}*/
535 // PM::OrderInstall - Installation ordering routine /*{{{*/
536 // ---------------------------------------------------------------------
537 /* */
538 pkgPackageManager::OrderResult pkgPackageManager::OrderInstall()
539 {
540 if (CreateOrderList() == false)
541 return Failed;
542
543 Reset();
544
545 if (Debug == true)
546 clog << "Begining to order" << endl;
547
548 if (List->OrderUnpack(FileNames) == false)
549 {
550 _error->Error("Internal ordering error");
551 return Failed;
552 }
553
554 if (Debug == true)
555 clog << "Done ordering" << endl;
556
557 bool DoneSomething = false;
558 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
559 {
560 PkgIterator Pkg(Cache,*I);
561
562 if (List->IsNow(Pkg) == false)
563 {
564 if (Debug == true)
565 clog << "Skipping already done " << Pkg.Name() << endl;
566 continue;
567 }
568
569 if (List->IsMissing(Pkg) == true)
570 {
571 if (Debug == true)
572 clog << "Sequence completed at " << Pkg.Name() << endl;
573 if (DoneSomething == false)
574 {
575 _error->Error("Internal Error, ordering was unable to handle the media swap");
576 return Failed;
577 }
578 return Incomplete;
579 }
580
581 // Sanity check
582 if (Cache[Pkg].Keep() == true &&
583 Pkg.State() == pkgCache::PkgIterator::NeedsNothing &&
584 (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)
585 {
586 _error->Error("Internal Error, trying to manipulate a kept package");
587 return Failed;
588 }
589
590 // Perform a delete or an install
591 if (Cache[Pkg].Delete() == true)
592 {
593 if (SmartRemove(Pkg) == false)
594 return Failed;
595 }
596 else
597 if (SmartUnPack(Pkg) == false)
598 return Failed;
599 DoneSomething = true;
600 }
601
602 // Final run through the configure phase
603 if (ConfigureAll() == false)
604 return Failed;
605
606 // Sanity check
607 for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++)
608 {
609 if (List->IsFlag(*I,pkgOrderList::Configured) == false)
610 {
611 _error->Error("Internal error, packages left unconfigured. %s",
612 PkgIterator(Cache,*I).Name());
613 return Failed;
614 }
615 }
616
617 return Completed;
618 }
619 /*}}}*/
620 // PM::DoInstall - Does the installation /*{{{*/
621 // ---------------------------------------------------------------------
622 /* This uses the filenames in FileNames and the information in the
623 DepCache to perform the installation of packages.*/
624 pkgPackageManager::OrderResult pkgPackageManager::DoInstall()
625 {
626 OrderResult Res = OrderInstall();
627 if (Res != Failed)
628 if (Go() == false)
629 return Failed;
630 return Res;
631 }
632 /*}}}*/