]> git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
ab069ddc25043cc798f1ef17df598b25cde94392
[apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.136 2003/08/08 23:48:48 mdz Exp $
4 /* ######################################################################
5
6 apt-get - Cover for dpkg
7
8 This is an allout cover for dpkg implementing a safer front end. It is
9 based largely on libapt-pkg.
10
11 The syntax is different,
12 apt-get [opt] command [things]
13 Where command is:
14 update - Resyncronize the package files from their sources
15 upgrade - Smart-Download the newest versions of all packages
16 dselect-upgrade - Follows dselect's changes to the Status: field
17 and installes new and removes old packages
18 dist-upgrade - Powerfull upgrader designed to handle the issues with
19 a new distribution.
20 install - Download and install a given package (by name, not by .deb)
21 check - Update the package cache and check for broken packages
22 clean - Erase the .debs downloaded to /var/cache/apt/archives and
23 the partial dir too
24
25 ##################################################################### */
26 /*}}}*/
27 // Include Files /*{{{*/
28 #include <apt-pkg/error.h>
29 #include <apt-pkg/cmndline.h>
30 #include <apt-pkg/init.h>
31 #include <apt-pkg/depcache.h>
32 #include <apt-pkg/sourcelist.h>
33 #include <apt-pkg/algorithms.h>
34 #include <apt-pkg/acquire-item.h>
35 #include <apt-pkg/strutl.h>
36 #include <apt-pkg/clean.h>
37 #include <apt-pkg/srcrecords.h>
38 #include <apt-pkg/version.h>
39 #include <apt-pkg/cachefile.h>
40 #include <apt-pkg/sptr.h>
41 #include <apt-pkg/versionmatch.h>
42
43 #include <config.h>
44 #include <apti18n.h>
45
46 #include "acqprogress.h"
47
48 #include <locale.h>
49 #include <fstream>
50 #include <termios.h>
51 #include <sys/ioctl.h>
52 #include <sys/stat.h>
53 #include <sys/statvfs.h>
54 #include <signal.h>
55 #include <unistd.h>
56 #include <stdio.h>
57 #include <errno.h>
58 #include <regex.h>
59 #include <sys/wait.h>
60 /*}}}*/
61
62 using namespace std;
63
64 ostream c0out(0);
65 ostream c1out(0);
66 ostream c2out(0);
67 ofstream devnull("/dev/null");
68 unsigned int ScreenWidth = 80;
69
70 // class CacheFile - Cover class for some dependency cache functions /*{{{*/
71 // ---------------------------------------------------------------------
72 /* */
73 class CacheFile : public pkgCacheFile
74 {
75 static pkgCache *SortCache;
76 static int NameComp(const void *a,const void *b);
77
78 public:
79 pkgCache::Package **List;
80
81 void Sort();
82 bool CheckDeps(bool AllowBroken = false);
83 bool BuildCaches(bool WithLock = true)
84 {
85 OpTextProgress Prog(*_config);
86 if (pkgCacheFile::BuildCaches(Prog,WithLock) == false)
87 return false;
88 return true;
89 }
90 bool Open(bool WithLock = true)
91 {
92 OpTextProgress Prog(*_config);
93 if (pkgCacheFile::Open(Prog,WithLock) == false)
94 return false;
95 Sort();
96
97 return true;
98 };
99 bool OpenForInstall()
100 {
101 if (_config->FindB("APT::Get::Print-URIs") == true)
102 return Open(false);
103 else
104 return Open(true);
105 }
106 CacheFile() : List(0) {};
107 };
108 /*}}}*/
109
110 // YnPrompt - Yes No Prompt. /*{{{*/
111 // ---------------------------------------------------------------------
112 /* Returns true on a Yes.*/
113 bool YnPrompt()
114 {
115 // This needs to be a capital
116 const char *Yes = _("Y");
117
118 if (_config->FindB("APT::Get::Assume-Yes",false) == true)
119 {
120 c1out << Yes << endl;
121 return true;
122 }
123
124 char C = 0;
125 char Jnk = 0;
126 if (read(STDIN_FILENO,&C,1) != 1)
127 return false;
128 while (C != '\n' && Jnk != '\n')
129 if (read(STDIN_FILENO,&Jnk,1) != 1)
130 return false;
131
132 if (!(toupper(C) == *Yes || C == '\n' || C == '\r'))
133 return false;
134 return true;
135 }
136 /*}}}*/
137 // AnalPrompt - Annoying Yes No Prompt. /*{{{*/
138 // ---------------------------------------------------------------------
139 /* Returns true on a Yes.*/
140 bool AnalPrompt(const char *Text)
141 {
142 char Buf[1024];
143 cin.getline(Buf,sizeof(Buf));
144 if (strcmp(Buf,Text) == 0)
145 return true;
146 return false;
147 }
148 /*}}}*/
149 // ShowList - Show a list /*{{{*/
150 // ---------------------------------------------------------------------
151 /* This prints out a string of space separated words with a title and
152 a two space indent line wraped to the current screen width. */
153 bool ShowList(ostream &out,string Title,string List,string VersionsList)
154 {
155 if (List.empty() == true)
156 return true;
157 // trim trailing space
158 int NonSpace = List.find_last_not_of(' ');
159 if (NonSpace != -1)
160 {
161 List = List.erase(NonSpace + 1);
162 if (List.empty() == true)
163 return true;
164 }
165
166 // Acount for the leading space
167 int ScreenWidth = ::ScreenWidth - 3;
168
169 out << Title << endl;
170 string::size_type Start = 0;
171 string::size_type VersionsStart = 0;
172 while (Start < List.size())
173 {
174 if(_config->FindB("APT::Get::Show-Versions",false) == true &&
175 VersionsList.size() > 0) {
176 string::size_type End;
177 string::size_type VersionsEnd;
178
179 End = List.find(' ',Start);
180 VersionsEnd = VersionsList.find('\n', VersionsStart);
181
182 out << " " << string(List,Start,End - Start) << " (" <<
183 string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) <<
184 ")" << endl;
185
186 if (End == string::npos || End < Start)
187 End = Start + ScreenWidth;
188
189 Start = End + 1;
190 VersionsStart = VersionsEnd + 1;
191 } else {
192 string::size_type End;
193
194 if (Start + ScreenWidth >= List.size())
195 End = List.size();
196 else
197 End = List.rfind(' ',Start+ScreenWidth);
198
199 if (End == string::npos || End < Start)
200 End = Start + ScreenWidth;
201 out << " " << string(List,Start,End - Start) << endl;
202 Start = End + 1;
203 }
204 }
205
206 return false;
207 }
208 /*}}}*/
209 // ShowBroken - Debugging aide /*{{{*/
210 // ---------------------------------------------------------------------
211 /* This prints out the names of all the packages that are broken along
212 with the name of each each broken dependency and a quite version
213 description.
214
215 The output looks like:
216 The following packages have unmet dependencies:
217 exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed
218 Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
219 Depends: libsasl7 but it is not going to be installed
220 */
221 void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
222 {
223 out << _("The following packages have unmet dependencies:") << endl;
224 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
225 {
226 pkgCache::PkgIterator I(Cache,Cache.List[J]);
227
228 if (Now == true)
229 {
230 if (Cache[I].NowBroken() == false)
231 continue;
232 }
233 else
234 {
235 if (Cache[I].InstBroken() == false)
236 continue;
237 }
238
239 // Print out each package and the failed dependencies
240 out <<" " << I.Name() << ":";
241 unsigned Indent = strlen(I.Name()) + 3;
242 bool First = true;
243 pkgCache::VerIterator Ver;
244
245 if (Now == true)
246 Ver = I.CurrentVer();
247 else
248 Ver = Cache[I].InstVerIter(Cache);
249
250 if (Ver.end() == true)
251 {
252 out << endl;
253 continue;
254 }
255
256 for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
257 {
258 // Compute a single dependency element (glob or)
259 pkgCache::DepIterator Start;
260 pkgCache::DepIterator End;
261 D.GlobOr(Start,End);
262
263 if (Cache->IsImportantDep(End) == false)
264 continue;
265
266 if (Now == true)
267 {
268 if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
269 continue;
270 }
271 else
272 {
273 if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
274 continue;
275 }
276
277 bool FirstOr = true;
278 while (1)
279 {
280 if (First == false)
281 for (unsigned J = 0; J != Indent; J++)
282 out << ' ';
283 First = false;
284
285 if (FirstOr == false)
286 {
287 for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
288 out << ' ';
289 }
290 else
291 out << ' ' << End.DepType() << ": ";
292 FirstOr = false;
293
294 out << Start.TargetPkg().Name();
295
296 // Show a quick summary of the version requirements
297 if (Start.TargetVer() != 0)
298 out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
299
300 /* Show a summary of the target package if possible. In the case
301 of virtual packages we show nothing */
302 pkgCache::PkgIterator Targ = Start.TargetPkg();
303 if (Targ->ProvidesList == 0)
304 {
305 out << ' ';
306 pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
307 if (Now == true)
308 Ver = Targ.CurrentVer();
309
310 if (Ver.end() == false)
311 {
312 if (Now == true)
313 ioprintf(out,_("but %s is installed"),Ver.VerStr());
314 else
315 ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
316 }
317 else
318 {
319 if (Cache[Targ].CandidateVerIter(Cache).end() == true)
320 {
321 if (Targ->ProvidesList == 0)
322 out << _("but it is not installable");
323 else
324 out << _("but it is a virtual package");
325 }
326 else
327 out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
328 }
329 }
330
331 if (Start != End)
332 out << _(" or");
333 out << endl;
334
335 if (Start == End)
336 break;
337 Start++;
338 }
339 }
340 }
341 }
342 /*}}}*/
343 // ShowNew - Show packages to newly install /*{{{*/
344 // ---------------------------------------------------------------------
345 /* */
346 void ShowNew(ostream &out,CacheFile &Cache)
347 {
348 /* Print out a list of packages that are going to be removed extra
349 to what the user asked */
350 string List;
351 string VersionsList;
352 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
353 {
354 pkgCache::PkgIterator I(Cache,Cache.List[J]);
355 if (Cache[I].NewInstall() == true) {
356 List += string(I.Name()) + " ";
357 VersionsList += string(Cache[I].CandVersion) + "\n";
358 }
359 }
360
361 ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
362 }
363 /*}}}*/
364 // ShowDel - Show packages to delete /*{{{*/
365 // ---------------------------------------------------------------------
366 /* */
367 void ShowDel(ostream &out,CacheFile &Cache)
368 {
369 /* Print out a list of packages that are going to be removed extra
370 to what the user asked */
371 string List;
372 string VersionsList;
373 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
374 {
375 pkgCache::PkgIterator I(Cache,Cache.List[J]);
376 if (Cache[I].Delete() == true)
377 {
378 if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
379 List += string(I.Name()) + "* ";
380 else
381 List += string(I.Name()) + " ";
382
383 VersionsList += string(Cache[I].CandVersion)+ "\n";
384 }
385 }
386
387 ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
388 }
389 /*}}}*/
390 // ShowKept - Show kept packages /*{{{*/
391 // ---------------------------------------------------------------------
392 /* */
393 void ShowKept(ostream &out,CacheFile &Cache)
394 {
395 string List;
396 string VersionsList;
397 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
398 {
399 pkgCache::PkgIterator I(Cache,Cache.List[J]);
400
401 // Not interesting
402 if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
403 I->CurrentVer == 0 || Cache[I].Delete() == true)
404 continue;
405
406 List += string(I.Name()) + " ";
407 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
408 }
409 ShowList(out,_("The following packages have been kept back"),List,VersionsList);
410 }
411 /*}}}*/
412 // ShowUpgraded - Show upgraded packages /*{{{*/
413 // ---------------------------------------------------------------------
414 /* */
415 void ShowUpgraded(ostream &out,CacheFile &Cache)
416 {
417 string List;
418 string VersionsList;
419 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
420 {
421 pkgCache::PkgIterator I(Cache,Cache.List[J]);
422
423 // Not interesting
424 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
425 continue;
426
427 List += string(I.Name()) + " ";
428 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
429 }
430 ShowList(out,_("The following packages will be upgraded"),List,VersionsList);
431 }
432 /*}}}*/
433 // ShowDowngraded - Show downgraded packages /*{{{*/
434 // ---------------------------------------------------------------------
435 /* */
436 bool ShowDowngraded(ostream &out,CacheFile &Cache)
437 {
438 string List;
439 string VersionsList;
440 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
441 {
442 pkgCache::PkgIterator I(Cache,Cache.List[J]);
443
444 // Not interesting
445 if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
446 continue;
447
448 List += string(I.Name()) + " ";
449 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
450 }
451 return ShowList(out,_("The following packages will be DOWNGRADED"),List,VersionsList);
452 }
453 /*}}}*/
454 // ShowHold - Show held but changed packages /*{{{*/
455 // ---------------------------------------------------------------------
456 /* */
457 bool ShowHold(ostream &out,CacheFile &Cache)
458 {
459 string List;
460 string VersionsList;
461 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
462 {
463 pkgCache::PkgIterator I(Cache,Cache.List[J]);
464 if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
465 I->SelectedState == pkgCache::State::Hold) {
466 List += string(I.Name()) + " ";
467 VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
468 }
469 }
470
471 return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
472 }
473 /*}}}*/
474 // ShowEssential - Show an essential package warning /*{{{*/
475 // ---------------------------------------------------------------------
476 /* This prints out a warning message that is not to be ignored. It shows
477 all essential packages and their dependents that are to be removed.
478 It is insanely risky to remove the dependents of an essential package! */
479 bool ShowEssential(ostream &out,CacheFile &Cache)
480 {
481 string List;
482 string VersionsList;
483 bool *Added = new bool[Cache->Head().PackageCount];
484 for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
485 Added[I] = false;
486
487 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
488 {
489 pkgCache::PkgIterator I(Cache,Cache.List[J]);
490 if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
491 (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
492 continue;
493
494 // The essential package is being removed
495 if (Cache[I].Delete() == true)
496 {
497 if (Added[I->ID] == false)
498 {
499 Added[I->ID] = true;
500 List += string(I.Name()) + " ";
501 //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
502 }
503 }
504
505 if (I->CurrentVer == 0)
506 continue;
507
508 // Print out any essential package depenendents that are to be removed
509 for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++)
510 {
511 // Skip everything but depends
512 if (D->Type != pkgCache::Dep::PreDepends &&
513 D->Type != pkgCache::Dep::Depends)
514 continue;
515
516 pkgCache::PkgIterator P = D.SmartTargetPkg();
517 if (Cache[P].Delete() == true)
518 {
519 if (Added[P->ID] == true)
520 continue;
521 Added[P->ID] = true;
522
523 char S[300];
524 snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name());
525 List += S;
526 //VersionsList += "\n"; ???
527 }
528 }
529 }
530
531 delete [] Added;
532 return ShowList(out,_("WARNING: The following essential packages will be removed\n"
533 "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
534 }
535 /*}}}*/
536 // Stats - Show some statistics /*{{{*/
537 // ---------------------------------------------------------------------
538 /* */
539 void Stats(ostream &out,pkgDepCache &Dep)
540 {
541 unsigned long Upgrade = 0;
542 unsigned long Downgrade = 0;
543 unsigned long Install = 0;
544 unsigned long ReInstall = 0;
545 for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++)
546 {
547 if (Dep[I].NewInstall() == true)
548 Install++;
549 else
550 {
551 if (Dep[I].Upgrade() == true)
552 Upgrade++;
553 else
554 if (Dep[I].Downgrade() == true)
555 Downgrade++;
556 }
557
558 if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall)
559 ReInstall++;
560 }
561
562 ioprintf(out,_("%lu packages upgraded, %lu newly installed, "),
563 Upgrade,Install);
564
565 if (ReInstall != 0)
566 ioprintf(out,_("%lu reinstalled, "),ReInstall);
567 if (Downgrade != 0)
568 ioprintf(out,_("%lu downgraded, "),Downgrade);
569
570 ioprintf(out,_("%lu to remove and %lu not upgraded.\n"),
571 Dep.DelCount(),Dep.KeepCount());
572
573 if (Dep.BadCount() != 0)
574 ioprintf(out,_("%lu packages not fully installed or removed.\n"),
575 Dep.BadCount());
576 }
577 /*}}}*/
578
579 // CacheFile::NameComp - QSort compare by name /*{{{*/
580 // ---------------------------------------------------------------------
581 /* */
582 pkgCache *CacheFile::SortCache = 0;
583 int CacheFile::NameComp(const void *a,const void *b)
584 {
585 if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
586 return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
587
588 const pkgCache::Package &A = **(pkgCache::Package **)a;
589 const pkgCache::Package &B = **(pkgCache::Package **)b;
590
591 return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name);
592 }
593 /*}}}*/
594 // CacheFile::Sort - Sort by name /*{{{*/
595 // ---------------------------------------------------------------------
596 /* */
597 void CacheFile::Sort()
598 {
599 delete [] List;
600 List = new pkgCache::Package *[Cache->Head().PackageCount];
601 memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
602 pkgCache::PkgIterator I = Cache->PkgBegin();
603 for (;I.end() != true; I++)
604 List[I->ID] = I;
605
606 SortCache = *this;
607 qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
608 }
609 /*}}}*/
610 // CacheFile::CheckDeps - Open the cache file /*{{{*/
611 // ---------------------------------------------------------------------
612 /* This routine generates the caches and then opens the dependency cache
613 and verifies that the system is OK. */
614 bool CacheFile::CheckDeps(bool AllowBroken)
615 {
616 if (_error->PendingError() == true)
617 return false;
618
619 // Check that the system is OK
620 if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
621 return _error->Error("Internal Error, non-zero counts");
622
623 // Apply corrections for half-installed packages
624 if (pkgApplyStatus(*DCache) == false)
625 return false;
626
627 // Nothing is broken
628 if (DCache->BrokenCount() == 0 || AllowBroken == true)
629 return true;
630
631 // Attempt to fix broken things
632 if (_config->FindB("APT::Get::Fix-Broken",false) == true)
633 {
634 c1out << _("Correcting dependencies...") << flush;
635 if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
636 {
637 c1out << _(" failed.") << endl;
638 ShowBroken(c1out,*this,true);
639
640 return _error->Error(_("Unable to correct dependencies"));
641 }
642 if (pkgMinimizeUpgrade(*DCache) == false)
643 return _error->Error(_("Unable to minimize the upgrade set"));
644
645 c1out << _(" Done") << endl;
646 }
647 else
648 {
649 c1out << _("You might want to run `apt-get -f install' to correct these.") << endl;
650 ShowBroken(c1out,*this,true);
651
652 return _error->Error(_("Unmet dependencies. Try using -f."));
653 }
654
655 return true;
656 }
657 /*}}}*/
658
659 // InstallPackages - Actually download and install the packages /*{{{*/
660 // ---------------------------------------------------------------------
661 /* This displays the informative messages describing what is going to
662 happen and then calls the download routines */
663 bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
664 bool Saftey = true)
665 {
666 if (_config->FindB("APT::Get::Purge",false) == true)
667 {
668 pkgCache::PkgIterator I = Cache->PkgBegin();
669 for (; I.end() == false; I++)
670 {
671 if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
672 Cache->MarkDelete(I,true);
673 }
674 }
675
676 bool Fail = false;
677 bool Essential = false;
678
679 // Show all the various warning indicators
680 ShowDel(c1out,Cache);
681 ShowNew(c1out,Cache);
682 if (ShwKept == true)
683 ShowKept(c1out,Cache);
684 Fail |= !ShowHold(c1out,Cache);
685 if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
686 ShowUpgraded(c1out,Cache);
687 Fail |= !ShowDowngraded(c1out,Cache);
688 if (_config->FindB("APT::Get::Download-Only",false) == false)
689 Essential = !ShowEssential(c1out,Cache);
690 Fail |= Essential;
691 Stats(c1out,Cache);
692
693 // Sanity check
694 if (Cache->BrokenCount() != 0)
695 {
696 ShowBroken(c1out,Cache,false);
697 return _error->Error("Internal Error, InstallPackages was called with broken packages!");
698 }
699
700 if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
701 Cache->BadCount() == 0)
702 return true;
703
704 // No remove flag
705 if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
706 return _error->Error(_("Packages need to be removed but Remove is disabled."));
707
708 // Run the simulator ..
709 if (_config->FindB("APT::Get::Simulate") == true)
710 {
711 pkgSimulate PM(Cache);
712 pkgPackageManager::OrderResult Res = PM.DoInstall();
713 if (Res == pkgPackageManager::Failed)
714 return false;
715 if (Res != pkgPackageManager::Completed)
716 return _error->Error("Internal Error, Ordering didn't finish");
717 return true;
718 }
719
720 // Create the text record parser
721 pkgRecords Recs(Cache);
722 if (_error->PendingError() == true)
723 return false;
724
725 // Lock the archive directory
726 FileFd Lock;
727 if (_config->FindB("Debug::NoLocking",false) == false &&
728 _config->FindB("APT::Get::Print-URIs") == false)
729 {
730 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
731 if (_error->PendingError() == true)
732 return _error->Error(_("Unable to lock the download directory"));
733 }
734
735 // Create the download object
736 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
737 pkgAcquire Fetcher(&Stat);
738
739 // Read the source list
740 pkgSourceList List;
741 if (List.ReadMainList() == false)
742 return _error->Error(_("The list of sources could not be read."));
743
744 // Create the package manager and prepare to download
745 SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
746 if (PM->GetArchives(&Fetcher,&List,&Recs) == false ||
747 _error->PendingError() == true)
748 return false;
749
750 // Display statistics
751 double FetchBytes = Fetcher.FetchNeeded();
752 double FetchPBytes = Fetcher.PartialPresent();
753 double DebBytes = Fetcher.TotalNeeded();
754 if (DebBytes != Cache->DebSize())
755 {
756 c0out << DebBytes << ',' << Cache->DebSize() << endl;
757 c0out << "How odd.. The sizes didn't match, email apt@packages.debian.org" << endl;
758 }
759
760 // Number of bytes
761 if (DebBytes != FetchBytes)
762 ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"),
763 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
764 else
765 ioprintf(c1out,_("Need to get %sB of archives.\n"),
766 SizeToStr(DebBytes).c_str());
767
768 // Size delta
769 if (Cache->UsrSize() >= 0)
770 ioprintf(c1out,_("After unpacking %sB of additional disk space will be used.\n"),
771 SizeToStr(Cache->UsrSize()).c_str());
772 else
773 ioprintf(c1out,_("After unpacking %sB disk space will be freed.\n"),
774 SizeToStr(-1*Cache->UsrSize()).c_str());
775
776 if (_error->PendingError() == true)
777 return false;
778
779 /* Check for enough free space, but only if we are actually going to
780 download */
781 if (_config->FindB("APT::Get::Print-URIs") == false &&
782 _config->FindB("APT::Get::Download",true) == true)
783 {
784 struct statvfs Buf;
785 string OutputDir = _config->FindDir("Dir::Cache::Archives");
786 if (statvfs(OutputDir.c_str(),&Buf) != 0)
787 return _error->Errno("statvfs","Couldn't determine free space in %s",
788 OutputDir.c_str());
789 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
790 return _error->Error(_("You don't have enough free space in %s."),
791 OutputDir.c_str());
792 }
793
794 // Fail safe check
795 if (_config->FindI("quiet",0) >= 2 ||
796 _config->FindB("APT::Get::Assume-Yes",false) == true)
797 {
798 if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
799 return _error->Error(_("There are problems and -y was used without --force-yes"));
800 }
801
802 if (Essential == true && Saftey == true)
803 {
804 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
805 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
806
807 const char *Prompt = _("Yes, do as I say!");
808 ioprintf(c2out,
809 _("You are about to do something potentially harmful\n"
810 "To continue type in the phrase '%s'\n"
811 " ?] "),Prompt);
812 c2out << flush;
813 if (AnalPrompt(Prompt) == false)
814 {
815 c2out << _("Abort.") << endl;
816 exit(1);
817 }
818 }
819 else
820 {
821 // Prompt to continue
822 if (Ask == true || Fail == true)
823 {
824 if (_config->FindB("APT::Get::Trivial-Only",false) == true)
825 return _error->Error(_("Trivial Only specified but this is not a trivial operation."));
826
827 if (_config->FindI("quiet",0) < 2 &&
828 _config->FindB("APT::Get::Assume-Yes",false) == false)
829 {
830 c2out << _("Do you want to continue? [Y/n] ") << flush;
831
832 if (YnPrompt() == false)
833 {
834 c2out << _("Abort.") << endl;
835 exit(1);
836 }
837 }
838 }
839 }
840
841 // Just print out the uris an exit if the --print-uris flag was used
842 if (_config->FindB("APT::Get::Print-URIs") == true)
843 {
844 pkgAcquire::UriIterator I = Fetcher.UriBegin();
845 for (; I != Fetcher.UriEnd(); I++)
846 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
847 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
848 return true;
849 }
850
851 /* Unlock the dpkg lock if we are not going to be doing an install
852 after. */
853 if (_config->FindB("APT::Get::Download-Only",false) == true)
854 _system->UnLock();
855
856 // Run it
857 while (1)
858 {
859 bool Transient = false;
860 if (_config->FindB("APT::Get::Download",true) == false)
861 {
862 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
863 {
864 if ((*I)->Local == true)
865 {
866 I++;
867 continue;
868 }
869
870 // Close the item and check if it was found in cache
871 (*I)->Finished();
872 if ((*I)->Complete == false)
873 Transient = true;
874
875 // Clear it out of the fetch list
876 delete *I;
877 I = Fetcher.ItemsBegin();
878 }
879 }
880
881 if (Fetcher.Run() == pkgAcquire::Failed)
882 return false;
883
884 // Print out errors
885 bool Failed = false;
886 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
887 {
888 if ((*I)->Status == pkgAcquire::Item::StatDone &&
889 (*I)->Complete == true)
890 continue;
891
892 if ((*I)->Status == pkgAcquire::Item::StatIdle)
893 {
894 Transient = true;
895 // Failed = true;
896 continue;
897 }
898
899 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
900 (*I)->ErrorText.c_str());
901 Failed = true;
902 }
903
904 /* If we are in no download mode and missing files and there were
905 'failures' then the user must specify -m. Furthermore, there
906 is no such thing as a transient error in no-download mode! */
907 if (Transient == true &&
908 _config->FindB("APT::Get::Download",true) == false)
909 {
910 Transient = false;
911 Failed = true;
912 }
913
914 if (_config->FindB("APT::Get::Download-Only",false) == true)
915 {
916 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
917 return _error->Error(_("Some files failed to download"));
918 c1out << _("Download complete and in download only mode") << endl;
919 return true;
920 }
921
922 if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
923 {
924 return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
925 }
926
927 if (Transient == true && Failed == true)
928 return _error->Error(_("--fix-missing and media swapping is not currently supported"));
929
930 // Try to deal with missing package files
931 if (Failed == true && PM->FixMissing() == false)
932 {
933 cerr << _("Unable to correct missing packages.") << endl;
934 return _error->Error(_("Aborting Install."));
935 }
936
937 _system->UnLock();
938 pkgPackageManager::OrderResult Res = PM->DoInstall();
939 if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
940 return false;
941 if (Res == pkgPackageManager::Completed)
942 return true;
943
944 // Reload the fetcher object and loop again for media swapping
945 Fetcher.Shutdown();
946 if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
947 return false;
948
949 _system->Lock();
950 }
951 }
952 /*}}}*/
953 // TryToInstall - Try to install a single package /*{{{*/
954 // ---------------------------------------------------------------------
955 /* This used to be inlined in DoInstall, but with the advent of regex package
956 name matching it was split out.. */
957 bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
958 pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
959 unsigned int &ExpectedInst,bool AllowFail = true)
960 {
961 /* This is a pure virtual package and there is a single available
962 provides */
963 if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 &&
964 Pkg.ProvidesList()->NextProvides == 0)
965 {
966 pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
967 ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
968 Tmp.Name(),Pkg.Name());
969 Pkg = Tmp;
970 }
971
972 // Handle the no-upgrade case
973 if (_config->FindB("APT::Get::upgrade",true) == false &&
974 Pkg->CurrentVer != 0)
975 {
976 if (AllowFail == true)
977 ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
978 Pkg.Name());
979 return true;
980 }
981
982 // Check if there is something at all to install
983 pkgDepCache::StateCache &State = Cache[Pkg];
984 if (Remove == true && Pkg->CurrentVer == 0)
985 {
986 Fix.Clear(Pkg);
987 Fix.Protect(Pkg);
988 Fix.Remove(Pkg);
989
990 /* We want to continue searching for regex hits, so we return false here
991 otherwise this is not really an error. */
992 if (AllowFail == false)
993 return false;
994
995 ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name());
996 return true;
997 }
998
999 if (State.CandidateVer == 0 && Remove == false)
1000 {
1001 if (AllowFail == false)
1002 return false;
1003
1004 if (Pkg->ProvidesList != 0)
1005 {
1006 ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
1007 Pkg.Name());
1008
1009 pkgCache::PrvIterator I = Pkg.ProvidesList();
1010 for (; I.end() == false; I++)
1011 {
1012 pkgCache::PkgIterator Pkg = I.OwnerPkg();
1013
1014 if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
1015 {
1016 if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
1017 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() <<
1018 _(" [Installed]") << endl;
1019 else
1020 c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl;
1021 }
1022 }
1023 c1out << _("You should explicitly select one to install.") << endl;
1024 }
1025 else
1026 {
1027 ioprintf(c1out,
1028 _("Package %s has no available version, but exists in the database.\n"
1029 "This typically means that the package was mentioned in a dependency and\n"
1030 "never uploaded, has been obsoleted or is not available with the contents\n"
1031 "of sources.list\n"),Pkg.Name());
1032
1033 string List;
1034 string VersionsList;
1035 SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
1036 memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
1037 pkgCache::DepIterator Dep = Pkg.RevDependsList();
1038 for (; Dep.end() == false; Dep++)
1039 {
1040 if (Dep->Type != pkgCache::Dep::Replaces)
1041 continue;
1042 if (Seen[Dep.ParentPkg()->ID] == true)
1043 continue;
1044 Seen[Dep.ParentPkg()->ID] = true;
1045 List += string(Dep.ParentPkg().Name()) + " ";
1046 //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
1047 }
1048 ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
1049 }
1050
1051 _error->Error(_("Package %s has no installation candidate"),Pkg.Name());
1052 return false;
1053 }
1054
1055 Fix.Clear(Pkg);
1056 Fix.Protect(Pkg);
1057 if (Remove == true)
1058 {
1059 Fix.Remove(Pkg);
1060 Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
1061 return true;
1062 }
1063
1064 // Install it
1065 Cache.MarkInstall(Pkg,false);
1066 if (State.Install() == false)
1067 {
1068 if (_config->FindB("APT::Get::ReInstall",false) == true)
1069 {
1070 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
1071 ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
1072 Pkg.Name());
1073 else
1074 Cache.SetReInstall(Pkg,true);
1075 }
1076 else
1077 {
1078 if (AllowFail == true)
1079 ioprintf(c1out,_("%s is already the newest version.\n"),
1080 Pkg.Name());
1081 }
1082 }
1083 else
1084 ExpectedInst++;
1085
1086 // Install it with autoinstalling enabled.
1087 if (State.InstBroken() == true && BrokenFix == false)
1088 Cache.MarkInstall(Pkg,true);
1089 return true;
1090 }
1091 /*}}}*/
1092 // TryToChangeVer - Try to change a candidate version /*{{{*/
1093 // ---------------------------------------------------------------------
1094 /* */
1095 bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
1096 const char *VerTag,bool IsRel)
1097 {
1098 pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
1099 pkgVersionMatch::Version));
1100
1101 pkgCache::VerIterator Ver = Match.Find(Pkg);
1102
1103 if (Ver.end() == true)
1104 {
1105 if (IsRel == true)
1106 return _error->Error(_("Release '%s' for '%s' was not found"),
1107 VerTag,Pkg.Name());
1108 return _error->Error(_("Version '%s' for '%s' was not found"),
1109 VerTag,Pkg.Name());
1110 }
1111
1112 if (strcmp(VerTag,Ver.VerStr()) != 0)
1113 {
1114 ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
1115 Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name());
1116 }
1117
1118 Cache.SetCandidateVersion(Ver);
1119 return true;
1120 }
1121 /*}}}*/
1122 // FindSrc - Find a source record /*{{{*/
1123 // ---------------------------------------------------------------------
1124 /* */
1125 pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
1126 pkgSrcRecords &SrcRecs,string &Src,
1127 pkgDepCache &Cache)
1128 {
1129 // We want to pull the version off the package specification..
1130 string VerTag;
1131 string TmpSrc = Name;
1132 string::size_type Slash = TmpSrc.rfind('=');
1133 if (Slash != string::npos)
1134 {
1135 VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end());
1136 TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash);
1137 }
1138
1139 /* Lookup the version of the package we would install if we were to
1140 install a version and determine the source package name, then look
1141 in the archive for a source package of the same name. In theory
1142 we could stash the version string as well and match that too but
1143 today there aren't multi source versions in the archive. */
1144 if (_config->FindB("APT::Get::Only-Source") == false &&
1145 VerTag.empty() == true)
1146 {
1147 pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc);
1148 if (Pkg.end() == false)
1149 {
1150 pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg);
1151 if (Ver.end() == false)
1152 {
1153 pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList());
1154 Src = Parse.SourcePkg();
1155 }
1156 }
1157 }
1158
1159 // No source package name..
1160 if (Src.empty() == true)
1161 Src = TmpSrc;
1162
1163 // The best hit
1164 pkgSrcRecords::Parser *Last = 0;
1165 unsigned long Offset = 0;
1166 string Version;
1167 bool IsMatch = false;
1168
1169 // If we are matching by version then we need exact matches to be happy
1170 if (VerTag.empty() == false)
1171 IsMatch = true;
1172
1173 /* Iterate over all of the hits, which includes the resulting
1174 binary packages in the search */
1175 pkgSrcRecords::Parser *Parse;
1176 SrcRecs.Restart();
1177 while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0)
1178 {
1179 string Ver = Parse->Version();
1180
1181 // Skip name mismatches
1182 if (IsMatch == true && Parse->Package() != Src)
1183 continue;
1184
1185 if (VerTag.empty() == false)
1186 {
1187 /* Don't want to fall through because we are doing exact version
1188 matching. */
1189 if (Cache.VS().CmpVersion(VerTag,Ver) != 0)
1190 continue;
1191
1192 Last = Parse;
1193 Offset = Parse->Offset();
1194 break;
1195 }
1196
1197 // Newer version or an exact match
1198 if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 ||
1199 (Parse->Package() == Src && IsMatch == false))
1200 {
1201 IsMatch = Parse->Package() == Src;
1202 Last = Parse;
1203 Offset = Parse->Offset();
1204 Version = Ver;
1205 }
1206 }
1207
1208 if (Last == 0)
1209 return 0;
1210
1211 if (Last->Jump(Offset) == false)
1212 return 0;
1213
1214 return Last;
1215 }
1216 /*}}}*/
1217
1218 // DoUpdate - Update the package lists /*{{{*/
1219 // ---------------------------------------------------------------------
1220 /* */
1221 bool DoUpdate(CommandLine &CmdL)
1222 {
1223 if (CmdL.FileSize() != 1)
1224 return _error->Error(_("The update command takes no arguments"));
1225
1226 // Get the source list
1227 pkgSourceList List;
1228 if (List.ReadMainList() == false)
1229 return false;
1230
1231 // Lock the list directory
1232 FileFd Lock;
1233 if (_config->FindB("Debug::NoLocking",false) == false)
1234 {
1235 Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
1236 if (_error->PendingError() == true)
1237 return _error->Error(_("Unable to lock the list directory"));
1238 }
1239
1240 // Create the download object
1241 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1242 pkgAcquire Fetcher(&Stat);
1243
1244 // Populate it with the source selection
1245 if (List.GetIndexes(&Fetcher) == false)
1246 return false;
1247
1248 // Just print out the uris an exit if the --print-uris flag was used
1249 if (_config->FindB("APT::Get::Print-URIs") == true)
1250 {
1251 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1252 for (; I != Fetcher.UriEnd(); I++)
1253 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1254 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1255 return true;
1256 }
1257
1258 // Run it
1259 if (Fetcher.Run() == pkgAcquire::Failed)
1260 return false;
1261
1262 bool Failed = false;
1263 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1264 {
1265 if ((*I)->Status == pkgAcquire::Item::StatDone)
1266 continue;
1267
1268 (*I)->Finished();
1269
1270 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1271 (*I)->ErrorText.c_str());
1272 Failed = true;
1273 }
1274
1275 // Clean out any old list files
1276 if (_config->FindB("APT::Get::List-Cleanup",true) == true)
1277 {
1278 if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
1279 Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
1280 return false;
1281 }
1282
1283 // Prepare the cache.
1284 CacheFile Cache;
1285 if (Cache.BuildCaches() == false)
1286 return false;
1287
1288 if (Failed == true)
1289 return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
1290
1291 return true;
1292 }
1293 /*}}}*/
1294 // DoUpgrade - Upgrade all packages /*{{{*/
1295 // ---------------------------------------------------------------------
1296 /* Upgrade all packages without installing new packages or erasing old
1297 packages */
1298 bool DoUpgrade(CommandLine &CmdL)
1299 {
1300 CacheFile Cache;
1301 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1302 return false;
1303
1304 // Do the upgrade
1305 if (pkgAllUpgrade(Cache) == false)
1306 {
1307 ShowBroken(c1out,Cache,false);
1308 return _error->Error(_("Internal Error, AllUpgrade broke stuff"));
1309 }
1310
1311 return InstallPackages(Cache,true);
1312 }
1313 /*}}}*/
1314 // DoInstall - Install packages from the command line /*{{{*/
1315 // ---------------------------------------------------------------------
1316 /* Install named packages */
1317 bool DoInstall(CommandLine &CmdL)
1318 {
1319 CacheFile Cache;
1320 if (Cache.OpenForInstall() == false ||
1321 Cache.CheckDeps(CmdL.FileSize() != 1) == false)
1322 return false;
1323
1324 // Enter the special broken fixing mode if the user specified arguments
1325 bool BrokenFix = false;
1326 if (Cache->BrokenCount() != 0)
1327 BrokenFix = true;
1328
1329 unsigned int ExpectedInst = 0;
1330 unsigned int Packages = 0;
1331 pkgProblemResolver Fix(Cache);
1332
1333 bool DefRemove = false;
1334 if (strcasecmp(CmdL.FileList[0],"remove") == 0)
1335 DefRemove = true;
1336
1337 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1338 {
1339 // Duplicate the string
1340 unsigned int Length = strlen(*I);
1341 char S[300];
1342 if (Length >= sizeof(S))
1343 continue;
1344 strcpy(S,*I);
1345
1346 // See if we are removing and special indicators..
1347 bool Remove = DefRemove;
1348 char *VerTag = 0;
1349 bool VerIsRel = false;
1350 while (Cache->FindPkg(S).end() == true)
1351 {
1352 // Handle an optional end tag indicating what to do
1353 if (Length >= 1 && S[Length - 1] == '-')
1354 {
1355 Remove = true;
1356 S[--Length] = 0;
1357 continue;
1358 }
1359
1360 if (Length >= 1 && S[Length - 1] == '+')
1361 {
1362 Remove = false;
1363 S[--Length] = 0;
1364 continue;
1365 }
1366
1367 char *Slash = strchr(S,'=');
1368 if (Slash != 0)
1369 {
1370 VerIsRel = false;
1371 *Slash = 0;
1372 VerTag = Slash + 1;
1373 }
1374
1375 Slash = strchr(S,'/');
1376 if (Slash != 0)
1377 {
1378 VerIsRel = true;
1379 *Slash = 0;
1380 VerTag = Slash + 1;
1381 }
1382
1383 break;
1384 }
1385
1386 // Locate the package
1387 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
1388 Packages++;
1389 if (Pkg.end() == true)
1390 {
1391 // Check if the name is a regex
1392 const char *I;
1393 for (I = S; *I != 0; I++)
1394 if (*I == '?' || *I == '*' || *I == '|' ||
1395 *I == '[' || *I == '^' || *I == '$')
1396 break;
1397 if (*I == 0)
1398 return _error->Error(_("Couldn't find package %s"),S);
1399
1400 // Regexs must always be confirmed
1401 ExpectedInst += 1000;
1402
1403 // Compile the regex pattern
1404 regex_t Pattern;
1405 int Res;
1406 if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
1407 REG_NOSUB)) != 0)
1408 {
1409 char Error[300];
1410 regerror(Res,&Pattern,Error,sizeof(Error));
1411 return _error->Error(_("Regex compilation error - %s"),Error);
1412 }
1413
1414 // Run over the matches
1415 bool Hit = false;
1416 for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++)
1417 {
1418 if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0)
1419 continue;
1420
1421 ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
1422 Pkg.Name(),S);
1423
1424 if (VerTag != 0)
1425 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1426 return false;
1427
1428 Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
1429 ExpectedInst,false);
1430 }
1431 regfree(&Pattern);
1432
1433 if (Hit == false)
1434 return _error->Error(_("Couldn't find package %s"),S);
1435 }
1436 else
1437 {
1438 if (VerTag != 0)
1439 if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
1440 return false;
1441 if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
1442 return false;
1443 }
1444 }
1445
1446 /* If we are in the Broken fixing mode we do not attempt to fix the
1447 problems. This is if the user invoked install without -f and gave
1448 packages */
1449 if (BrokenFix == true && Cache->BrokenCount() != 0)
1450 {
1451 c1out << _("You might want to run `apt-get -f install' to correct these:") << endl;
1452 ShowBroken(c1out,Cache,false);
1453
1454 return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution)."));
1455 }
1456
1457 // Call the scored problem resolver
1458 Fix.InstallProtect();
1459 if (Fix.Resolve(true) == false)
1460 _error->Discard();
1461
1462 // Now we check the state of the packages,
1463 if (Cache->BrokenCount() != 0)
1464 {
1465 c1out <<
1466 _("Some packages could not be installed. This may mean that you have\n"
1467 "requested an impossible situation or if you are using the unstable\n"
1468 "distribution that some required packages have not yet been created\n"
1469 "or been moved out of Incoming.") << endl;
1470 if (Packages == 1)
1471 {
1472 c1out << endl;
1473 c1out <<
1474 _("Since you only requested a single operation it is extremely likely that\n"
1475 "the package is simply not installable and a bug report against\n"
1476 "that package should be filed.") << endl;
1477 }
1478
1479 c1out << _("The following information may help to resolve the situation:") << endl;
1480 c1out << endl;
1481 ShowBroken(c1out,Cache,false);
1482 return _error->Error(_("Broken packages"));
1483 }
1484
1485 /* Print out a list of packages that are going to be installed extra
1486 to what the user asked */
1487 if (Cache->InstCount() != ExpectedInst)
1488 {
1489 string List;
1490 string VersionsList;
1491 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1492 {
1493 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1494 if ((*Cache)[I].Install() == false)
1495 continue;
1496
1497 const char **J;
1498 for (J = CmdL.FileList + 1; *J != 0; J++)
1499 if (strcmp(*J,I.Name()) == 0)
1500 break;
1501
1502 if (*J == 0) {
1503 List += string(I.Name()) + " ";
1504 VersionsList += string(Cache[I].CandVersion) + "\n";
1505 }
1506 }
1507
1508 ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
1509 }
1510
1511 /* Print out a list of suggested and recommended packages */
1512 {
1513 string SuggestsList, RecommendsList, List;
1514 string SuggestsVersions, RecommendsVersions;
1515 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1516 {
1517 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1518
1519 /* Just look at the ones we want to install */
1520 if ((*Cache)[I].Install() == false)
1521 continue;
1522
1523 for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
1524 {
1525 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
1526 {
1527 pkgCache::DepIterator Start;
1528 pkgCache::DepIterator End;
1529 D.GlobOr(Start,End);
1530
1531 /*
1532 * If this is a virtual package, we need to check the list of
1533 * packages that provide it and see if any of those are
1534 * installed
1535 */
1536 pkgCache::PrvIterator Prv = Start.TargetPkg().ProvidesList();
1537 bool providedBySomething = false;
1538 for (; Prv.end() != true; Prv++)
1539 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) {
1540 providedBySomething = true;
1541 break;
1542 }
1543
1544 if (providedBySomething) continue;
1545
1546 do
1547 {
1548 if (Start->Type == pkgCache::Dep::Suggests) {
1549
1550 /* A suggests relations, let's see if we have it
1551 installed already */
1552
1553 string target = string(Start.TargetPkg().Name()) + " ";
1554 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install || Cache[Start.TargetPkg()].Install())
1555 break;
1556 /* Does another package suggest it as well? If so,
1557 don't print it twice */
1558 if (int(SuggestsList.find(target)) > -1)
1559 break;
1560 SuggestsList += target;
1561 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1562 }
1563
1564 if (Start->Type == pkgCache::Dep::Recommends) {
1565
1566 /* A recommends relation, let's see if we have it
1567 installed already */
1568
1569 string target = string(Start.TargetPkg().Name()) + " ";
1570 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install || Cache[Start.TargetPkg()].Install())
1571 break;
1572
1573 /* Does another package recommend it as well? If so,
1574 don't print it twice */
1575
1576 if (int(RecommendsList.find(target)) > -1)
1577 break;
1578 RecommendsList += target;
1579 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1580 }
1581 if (Start == End)
1582 break;
1583 Start++;
1584 } while (1);
1585 }
1586 }
1587 }
1588 ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
1589 ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
1590
1591 }
1592
1593 // See if we need to prompt
1594 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
1595 return InstallPackages(Cache,false,false);
1596
1597 return InstallPackages(Cache,false);
1598 }
1599 /*}}}*/
1600 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1601 // ---------------------------------------------------------------------
1602 /* Intelligent upgrader that will install and remove packages at will */
1603 bool DoDistUpgrade(CommandLine &CmdL)
1604 {
1605 CacheFile Cache;
1606 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1607 return false;
1608
1609 c0out << _("Calculating Upgrade... ") << flush;
1610 if (pkgDistUpgrade(*Cache) == false)
1611 {
1612 c0out << _("Failed") << endl;
1613 ShowBroken(c1out,Cache,false);
1614 return false;
1615 }
1616
1617 c0out << _("Done") << endl;
1618
1619 return InstallPackages(Cache,true);
1620 }
1621 /*}}}*/
1622 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1623 // ---------------------------------------------------------------------
1624 /* Follows dselect's selections */
1625 bool DoDSelectUpgrade(CommandLine &CmdL)
1626 {
1627 CacheFile Cache;
1628 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1629 return false;
1630
1631 // Install everything with the install flag set
1632 pkgCache::PkgIterator I = Cache->PkgBegin();
1633 for (;I.end() != true; I++)
1634 {
1635 /* Install the package only if it is a new install, the autoupgrader
1636 will deal with the rest */
1637 if (I->SelectedState == pkgCache::State::Install)
1638 Cache->MarkInstall(I,false);
1639 }
1640
1641 /* Now install their deps too, if we do this above then order of
1642 the status file is significant for | groups */
1643 for (I = Cache->PkgBegin();I.end() != true; I++)
1644 {
1645 /* Install the package only if it is a new install, the autoupgrader
1646 will deal with the rest */
1647 if (I->SelectedState == pkgCache::State::Install)
1648 Cache->MarkInstall(I,true);
1649 }
1650
1651 // Apply erasures now, they override everything else.
1652 for (I = Cache->PkgBegin();I.end() != true; I++)
1653 {
1654 // Remove packages
1655 if (I->SelectedState == pkgCache::State::DeInstall ||
1656 I->SelectedState == pkgCache::State::Purge)
1657 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
1658 }
1659
1660 /* Resolve any problems that dselect created, allupgrade cannot handle
1661 such things. We do so quite agressively too.. */
1662 if (Cache->BrokenCount() != 0)
1663 {
1664 pkgProblemResolver Fix(Cache);
1665
1666 // Hold back held packages.
1667 if (_config->FindB("APT::Ignore-Hold",false) == false)
1668 {
1669 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1670 {
1671 if (I->SelectedState == pkgCache::State::Hold)
1672 {
1673 Fix.Protect(I);
1674 Cache->MarkKeep(I);
1675 }
1676 }
1677 }
1678
1679 if (Fix.Resolve() == false)
1680 {
1681 ShowBroken(c1out,Cache,false);
1682 return _error->Error("Internal Error, problem resolver broke stuff");
1683 }
1684 }
1685
1686 // Now upgrade everything
1687 if (pkgAllUpgrade(Cache) == false)
1688 {
1689 ShowBroken(c1out,Cache,false);
1690 return _error->Error("Internal Error, problem resolver broke stuff");
1691 }
1692
1693 return InstallPackages(Cache,false);
1694 }
1695 /*}}}*/
1696 // DoClean - Remove download archives /*{{{*/
1697 // ---------------------------------------------------------------------
1698 /* */
1699 bool DoClean(CommandLine &CmdL)
1700 {
1701 if (_config->FindB("APT::Get::Simulate") == true)
1702 {
1703 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1704 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1705 return true;
1706 }
1707
1708 // Lock the archive directory
1709 FileFd Lock;
1710 if (_config->FindB("Debug::NoLocking",false) == false)
1711 {
1712 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1713 if (_error->PendingError() == true)
1714 return _error->Error(_("Unable to lock the download directory"));
1715 }
1716
1717 pkgAcquire Fetcher;
1718 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1719 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
1720 return true;
1721 }
1722 /*}}}*/
1723 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1724 // ---------------------------------------------------------------------
1725 /* This is similar to clean but it only purges things that cannot be
1726 downloaded, that is old versions of cached packages. */
1727 class LogCleaner : public pkgArchiveCleaner
1728 {
1729 protected:
1730 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1731 {
1732 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
1733
1734 if (_config->FindB("APT::Get::Simulate") == false)
1735 unlink(File);
1736 };
1737 };
1738
1739 bool DoAutoClean(CommandLine &CmdL)
1740 {
1741 // Lock the archive directory
1742 FileFd Lock;
1743 if (_config->FindB("Debug::NoLocking",false) == false)
1744 {
1745 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1746 if (_error->PendingError() == true)
1747 return _error->Error(_("Unable to lock the download directory"));
1748 }
1749
1750 CacheFile Cache;
1751 if (Cache.Open() == false)
1752 return false;
1753
1754 LogCleaner Cleaner;
1755
1756 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1757 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1758 }
1759 /*}}}*/
1760 // DoCheck - Perform the check operation /*{{{*/
1761 // ---------------------------------------------------------------------
1762 /* Opening automatically checks the system, this command is mostly used
1763 for debugging */
1764 bool DoCheck(CommandLine &CmdL)
1765 {
1766 CacheFile Cache;
1767 Cache.Open();
1768 Cache.CheckDeps();
1769
1770 return true;
1771 }
1772 /*}}}*/
1773 // DoSource - Fetch a source archive /*{{{*/
1774 // ---------------------------------------------------------------------
1775 /* Fetch souce packages */
1776 struct DscFile
1777 {
1778 string Package;
1779 string Version;
1780 string Dsc;
1781 };
1782
1783 bool DoSource(CommandLine &CmdL)
1784 {
1785 CacheFile Cache;
1786 if (Cache.Open(false) == false)
1787 return false;
1788
1789 if (CmdL.FileSize() <= 1)
1790 return _error->Error(_("Must specify at least one package to fetch source for"));
1791
1792 // Read the source list
1793 pkgSourceList List;
1794 if (List.ReadMainList() == false)
1795 return _error->Error(_("The list of sources could not be read."));
1796
1797 // Create the text record parsers
1798 pkgRecords Recs(Cache);
1799 pkgSrcRecords SrcRecs(List);
1800 if (_error->PendingError() == true)
1801 return false;
1802
1803 // Create the download object
1804 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1805 pkgAcquire Fetcher(&Stat);
1806
1807 DscFile *Dsc = new DscFile[CmdL.FileSize()];
1808
1809 // Load the requestd sources into the fetcher
1810 unsigned J = 0;
1811 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1812 {
1813 string Src;
1814 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1815
1816 if (Last == 0)
1817 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1818
1819 // Back track
1820 vector<pkgSrcRecords::File> Lst;
1821 if (Last->Files(Lst) == false)
1822 return false;
1823
1824 // Load them into the fetcher
1825 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1826 I != Lst.end(); I++)
1827 {
1828 // Try to guess what sort of file it is we are getting.
1829 if (I->Type == "dsc")
1830 {
1831 Dsc[J].Package = Last->Package();
1832 Dsc[J].Version = Last->Version();
1833 Dsc[J].Dsc = flNotDir(I->Path);
1834 }
1835
1836 // Diff only mode only fetches .diff files
1837 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
1838 I->Type != "diff")
1839 continue;
1840
1841 // Tar only mode only fetches .tar files
1842 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
1843 I->Type != "tar")
1844 continue;
1845
1846 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1847 I->MD5Hash,I->Size,
1848 Last->Index().SourceInfo(*Last,*I),Src);
1849 }
1850 }
1851
1852 // Display statistics
1853 double FetchBytes = Fetcher.FetchNeeded();
1854 double FetchPBytes = Fetcher.PartialPresent();
1855 double DebBytes = Fetcher.TotalNeeded();
1856
1857 // Check for enough free space
1858 struct statvfs Buf;
1859 string OutputDir = ".";
1860 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1861 return _error->Errno("statvfs","Couldn't determine free space in %s",
1862 OutputDir.c_str());
1863 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1864 return _error->Error(_("You don't have enough free space in %s"),
1865 OutputDir.c_str());
1866
1867 // Number of bytes
1868 if (DebBytes != FetchBytes)
1869 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1870 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1871 else
1872 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1873 SizeToStr(DebBytes).c_str());
1874
1875 if (_config->FindB("APT::Get::Simulate",false) == true)
1876 {
1877 for (unsigned I = 0; I != J; I++)
1878 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
1879 return true;
1880 }
1881
1882 // Just print out the uris an exit if the --print-uris flag was used
1883 if (_config->FindB("APT::Get::Print-URIs") == true)
1884 {
1885 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1886 for (; I != Fetcher.UriEnd(); I++)
1887 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1888 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1889 return true;
1890 }
1891
1892 // Run it
1893 if (Fetcher.Run() == pkgAcquire::Failed)
1894 return false;
1895
1896 // Print error messages
1897 bool Failed = false;
1898 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1899 {
1900 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1901 (*I)->Complete == true)
1902 continue;
1903
1904 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1905 (*I)->ErrorText.c_str());
1906 Failed = true;
1907 }
1908 if (Failed == true)
1909 return _error->Error(_("Failed to fetch some archives."));
1910
1911 if (_config->FindB("APT::Get::Download-only",false) == true)
1912 {
1913 c1out << _("Download complete and in download only mode") << endl;
1914 return true;
1915 }
1916
1917 // Unpack the sources
1918 pid_t Process = ExecFork();
1919
1920 if (Process == 0)
1921 {
1922 for (unsigned I = 0; I != J; I++)
1923 {
1924 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
1925
1926 // Diff only mode only fetches .diff files
1927 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
1928 _config->FindB("APT::Get::Tar-Only",false) == true ||
1929 Dsc[I].Dsc.empty() == true)
1930 continue;
1931
1932 // See if the package is already unpacked
1933 struct stat Stat;
1934 if (stat(Dir.c_str(),&Stat) == 0 &&
1935 S_ISDIR(Stat.st_mode) != 0)
1936 {
1937 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1938 Dir.c_str());
1939 }
1940 else
1941 {
1942 // Call dpkg-source
1943 char S[500];
1944 snprintf(S,sizeof(S),"%s -x %s",
1945 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1946 Dsc[I].Dsc.c_str());
1947 if (system(S) != 0)
1948 {
1949 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
1950 _exit(1);
1951 }
1952 }
1953
1954 // Try to compile it with dpkg-buildpackage
1955 if (_config->FindB("APT::Get::Compile",false) == true)
1956 {
1957 // Call dpkg-buildpackage
1958 char S[500];
1959 snprintf(S,sizeof(S),"cd %s && %s %s",
1960 Dir.c_str(),
1961 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1962 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1963
1964 if (system(S) != 0)
1965 {
1966 fprintf(stderr,_("Build command '%s' failed.\n"),S);
1967 _exit(1);
1968 }
1969 }
1970 }
1971
1972 _exit(0);
1973 }
1974
1975 // Wait for the subprocess
1976 int Status = 0;
1977 while (waitpid(Process,&Status,0) != Process)
1978 {
1979 if (errno == EINTR)
1980 continue;
1981 return _error->Errno("waitpid","Couldn't wait for subprocess");
1982 }
1983
1984 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1985 return _error->Error(_("Child process failed"));
1986
1987 return true;
1988 }
1989 /*}}}*/
1990 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1991 // ---------------------------------------------------------------------
1992 /* This function will look at the build depends list of the given source
1993 package and install the necessary packages to make it true, or fail. */
1994 bool DoBuildDep(CommandLine &CmdL)
1995 {
1996 CacheFile Cache;
1997 if (Cache.Open(true) == false)
1998 return false;
1999
2000 if (CmdL.FileSize() <= 1)
2001 return _error->Error(_("Must specify at least one package to check builddeps for"));
2002
2003 // Read the source list
2004 pkgSourceList List;
2005 if (List.ReadMainList() == false)
2006 return _error->Error(_("The list of sources could not be read."));
2007
2008 // Create the text record parsers
2009 pkgRecords Recs(Cache);
2010 pkgSrcRecords SrcRecs(List);
2011 if (_error->PendingError() == true)
2012 return false;
2013
2014 // Create the download object
2015 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
2016 pkgAcquire Fetcher(&Stat);
2017
2018 unsigned J = 0;
2019 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
2020 {
2021 string Src;
2022 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
2023 if (Last == 0)
2024 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
2025
2026 // Process the build-dependencies
2027 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
2028 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
2029 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
2030
2031 // Also ensure that build-essential packages are present
2032 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
2033 if (Opts)
2034 Opts = Opts->Child;
2035 for (; Opts; Opts = Opts->Next)
2036 {
2037 if (Opts->Value.empty() == true)
2038 continue;
2039
2040 pkgSrcRecords::Parser::BuildDepRec rec;
2041 rec.Package = Opts->Value;
2042 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
2043 rec.Op = 0;
2044 BuildDeps.insert(BuildDeps.begin(), rec);
2045 }
2046
2047 if (BuildDeps.size() == 0)
2048 {
2049 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
2050 continue;
2051 }
2052
2053 // Install the requested packages
2054 unsigned int ExpectedInst = 0;
2055 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
2056 pkgProblemResolver Fix(Cache);
2057 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
2058 {
2059 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
2060 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
2061 {
2062 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2063 // Build-conflicts on unknown packages are silently ignored
2064 if (Pkg.end() == true)
2065 continue;
2066
2067 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2068
2069 /*
2070 * Remove if we have an installed version that satisfies the
2071 * version criteria
2072 */
2073 if (IV.end() == false &&
2074 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2075 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
2076 }
2077 else // BuildDep || BuildDepIndep
2078 {
2079 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2080 if (Pkg.end() == true)
2081 {
2082 // Check if there are any alternatives
2083 if (((*D).Op & pkgCache::Dep::Or) != pkgCache::Dep::Or)
2084 return _error->Error(_("%s dependency for %s cannot be satisfied "
2085 "because the package %s cannot be found"),
2086 Last->BuildDepType((*D).Type),Src.c_str(),
2087 (*D).Package.c_str());
2088 // Try the next alternative
2089 continue;
2090 }
2091
2092 /*
2093 * if there are alternatives, we've already picked one, so skip
2094 * the rest
2095 *
2096 * TODO: this means that if there's a build-dep on A|B and B is
2097 * installed, we'll still try to install A; more importantly,
2098 * if A is currently broken, we cannot go back and try B. To fix
2099 * this would require we do a Resolve cycle for each package we
2100 * add to the install list. Ugh
2101 */
2102 while (D != BuildDeps.end() &&
2103 (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or))
2104 D++;
2105
2106 /*
2107 * If this is a virtual package, we need to check the list of
2108 * packages that provide it and see if any of those are
2109 * installed
2110 */
2111 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
2112 bool providedBySomething = !Prv.end();
2113 for (; Prv.end() != true; Prv++)
2114 {
2115 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
2116 break;
2117 }
2118
2119 // Get installed version and version we are going to install
2120 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2121
2122 if (!providedBySomething || (*D).Version[0] != '\0') {
2123 /* We either have a versioned dependency (so a provides won't do)
2124 or nothing is providing this package */
2125
2126 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
2127
2128 for (; CV.end() != true; CV++)
2129 {
2130 if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2131 break;
2132 }
2133 if (CV.end() == true)
2134 return _error->Error(_("%s dependency for %s cannot be satisfied "
2135 "because no available versions of package %s "
2136 "can satisfy version requirements"),
2137 Last->BuildDepType((*D).Type),Src.c_str(),
2138 (*D).Package.c_str());
2139 }
2140
2141 /*
2142 * TODO: if we depend on a version lower than what we already have
2143 * installed it is not clear what should be done; in practice
2144 * this case should be rare, and right now nothing is
2145 * done about it :-(
2146 */
2147 if (Prv.end() == true && // Nothing provides it; and
2148 (IV.end() == true || // It is not installed, or
2149 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false))
2150 // the version installed doesn't
2151 // satisfy constraints
2152 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
2153 }
2154 }
2155
2156 Fix.InstallProtect();
2157 if (Fix.Resolve(true) == false)
2158 _error->Discard();
2159
2160 // Now we check the state of the packages,
2161 if (Cache->BrokenCount() != 0)
2162 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
2163 "You might want to run `apt-get -f install' to correct these."));
2164 }
2165
2166 if (InstallPackages(Cache, false, true) == false)
2167 return _error->Error(_("Failed to process build dependencies"));
2168 return true;
2169 }
2170 /*}}}*/
2171
2172 // DoMoo - Never Ask, Never Tell /*{{{*/
2173 // ---------------------------------------------------------------------
2174 /* */
2175 bool DoMoo(CommandLine &CmdL)
2176 {
2177 cout <<
2178 " (__) \n"
2179 " (oo) \n"
2180 " /------\\/ \n"
2181 " / | || \n"
2182 " * /\\---/\\ \n"
2183 " ~~ ~~ \n"
2184 "....\"Have you mooed today?\"...\n";
2185
2186 return true;
2187 }
2188 /*}}}*/
2189 // ShowHelp - Show a help screen /*{{{*/
2190 // ---------------------------------------------------------------------
2191 /* */
2192 bool ShowHelp(CommandLine &CmdL)
2193 {
2194 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
2195 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
2196
2197 if (_config->FindB("version") == true)
2198 {
2199 cout << _("Supported Modules:") << endl;
2200
2201 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
2202 {
2203 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
2204 if (_system != 0 && _system->VS == VS)
2205 cout << '*';
2206 else
2207 cout << ' ';
2208 cout << "Ver: " << VS->Label << endl;
2209
2210 /* Print out all the packaging systems that will work with
2211 this VS */
2212 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2213 {
2214 pkgSystem *Sys = pkgSystem::GlobalList[J];
2215 if (_system == Sys)
2216 cout << '*';
2217 else
2218 cout << ' ';
2219 if (Sys->VS->TestCompatibility(*VS) == true)
2220 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2221 }
2222 }
2223
2224 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2225 {
2226 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2227 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2228 }
2229
2230 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2231 {
2232 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2233 cout << " Idx: " << Type->Label << endl;
2234 }
2235
2236 return true;
2237 }
2238
2239 cout <<
2240 _("Usage: apt-get [options] command\n"
2241 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2242 " apt-get [options] source pkg1 [pkg2 ...]\n"
2243 "\n"
2244 "apt-get is a simple command line interface for downloading and\n"
2245 "installing packages. The most frequently used commands are update\n"
2246 "and install.\n"
2247 "\n"
2248 "Commands:\n"
2249 " update - Retrieve new lists of packages\n"
2250 " upgrade - Perform an upgrade\n"
2251 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2252 " remove - Remove packages\n"
2253 " source - Download source archives\n"
2254 " build-dep - Configure build-dependencies for source packages\n"
2255 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2256 " dselect-upgrade - Follow dselect selections\n"
2257 " clean - Erase downloaded archive files\n"
2258 " autoclean - Erase old downloaded archive files\n"
2259 " check - Verify that there are no broken dependencies\n"
2260 "\n"
2261 "Options:\n"
2262 " -h This help text.\n"
2263 " -q Loggable output - no progress indicator\n"
2264 " -qq No output except for errors\n"
2265 " -d Download only - do NOT install or unpack archives\n"
2266 " -s No-act. Perform ordering simulation\n"
2267 " -y Assume Yes to all queries and do not prompt\n"
2268 " -f Attempt to continue if the integrity check fails\n"
2269 " -m Attempt to continue if archives are unlocatable\n"
2270 " -u Show a list of upgraded packages as well\n"
2271 " -b Build the source package after fetching it\n"
2272 " -V Show verbose version numbers\n"
2273 " -c=? Read this configuration file\n"
2274 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2275 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2276 "pages for more information and options.\n"
2277 " This APT has Super Cow Powers.\n");
2278 return true;
2279 }
2280 /*}}}*/
2281 // GetInitialize - Initialize things for apt-get /*{{{*/
2282 // ---------------------------------------------------------------------
2283 /* */
2284 void GetInitialize()
2285 {
2286 _config->Set("quiet",0);
2287 _config->Set("help",false);
2288 _config->Set("APT::Get::Download-Only",false);
2289 _config->Set("APT::Get::Simulate",false);
2290 _config->Set("APT::Get::Assume-Yes",false);
2291 _config->Set("APT::Get::Fix-Broken",false);
2292 _config->Set("APT::Get::Force-Yes",false);
2293 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
2294 }
2295 /*}}}*/
2296 // SigWinch - Window size change signal handler /*{{{*/
2297 // ---------------------------------------------------------------------
2298 /* */
2299 void SigWinch(int)
2300 {
2301 // Riped from GNU ls
2302 #ifdef TIOCGWINSZ
2303 struct winsize ws;
2304
2305 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2306 ScreenWidth = ws.ws_col - 1;
2307 #endif
2308 }
2309 /*}}}*/
2310
2311 int main(int argc,const char *argv[])
2312 {
2313 CommandLine::Args Args[] = {
2314 {'h',"help","help",0},
2315 {'v',"version","version",0},
2316 {'V',"verbose-versions","APT::Get::Show-Versions",0},
2317 {'q',"quiet","quiet",CommandLine::IntLevel},
2318 {'q',"silent","quiet",CommandLine::IntLevel},
2319 {'d',"download-only","APT::Get::Download-Only",0},
2320 {'b',"compile","APT::Get::Compile",0},
2321 {'b',"build","APT::Get::Compile",0},
2322 {'s',"simulate","APT::Get::Simulate",0},
2323 {'s',"just-print","APT::Get::Simulate",0},
2324 {'s',"recon","APT::Get::Simulate",0},
2325 {'s',"dry-run","APT::Get::Simulate",0},
2326 {'s',"no-act","APT::Get::Simulate",0},
2327 {'y',"yes","APT::Get::Assume-Yes",0},
2328 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2329 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2330 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2331 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2332 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2333 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2334 {0,"download","APT::Get::Download",0},
2335 {0,"fix-missing","APT::Get::Fix-Missing",0},
2336 {0,"ignore-hold","APT::Ignore-Hold",0},
2337 {0,"upgrade","APT::Get::upgrade",0},
2338 {0,"force-yes","APT::Get::force-yes",0},
2339 {0,"print-uris","APT::Get::Print-URIs",0},
2340 {0,"diff-only","APT::Get::Diff-Only",0},
2341 {0,"tar-only","APT::Get::tar-Only",0},
2342 {0,"purge","APT::Get::Purge",0},
2343 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2344 {0,"reinstall","APT::Get::ReInstall",0},
2345 {0,"trivial-only","APT::Get::Trivial-Only",0},
2346 {0,"remove","APT::Get::Remove",0},
2347 {0,"only-source","APT::Get::Only-Source",0},
2348 {0,"arch-only","APT::Get::Arch-Only",0},
2349 {'c',"config-file",0,CommandLine::ConfigFile},
2350 {'o',"option",0,CommandLine::ArbItem},
2351 {0,0,0,0}};
2352 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2353 {"upgrade",&DoUpgrade},
2354 {"install",&DoInstall},
2355 {"remove",&DoInstall},
2356 {"dist-upgrade",&DoDistUpgrade},
2357 {"dselect-upgrade",&DoDSelectUpgrade},
2358 {"build-dep",&DoBuildDep},
2359 {"clean",&DoClean},
2360 {"autoclean",&DoAutoClean},
2361 {"check",&DoCheck},
2362 {"source",&DoSource},
2363 {"moo",&DoMoo},
2364 {"help",&ShowHelp},
2365 {0,0}};
2366
2367 // Set up gettext support
2368 setlocale(LC_ALL,"");
2369 textdomain(PACKAGE);
2370
2371 // Parse the command line and initialize the package library
2372 CommandLine CmdL(Args,_config);
2373 if (pkgInitConfig(*_config) == false ||
2374 CmdL.Parse(argc,argv) == false ||
2375 pkgInitSystem(*_config,_system) == false)
2376 {
2377 if (_config->FindB("version") == true)
2378 ShowHelp(CmdL);
2379
2380 _error->DumpErrors();
2381 return 100;
2382 }
2383
2384 // See if the help should be shown
2385 if (_config->FindB("help") == true ||
2386 _config->FindB("version") == true ||
2387 CmdL.FileSize() == 0)
2388 {
2389 ShowHelp(CmdL);
2390 return 0;
2391 }
2392
2393 // Deal with stdout not being a tty
2394 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2395 _config->Set("quiet","1");
2396
2397 // Setup the output streams
2398 c0out.rdbuf(cout.rdbuf());
2399 c1out.rdbuf(cout.rdbuf());
2400 c2out.rdbuf(cout.rdbuf());
2401 if (_config->FindI("quiet",0) > 0)
2402 c0out.rdbuf(devnull.rdbuf());
2403 if (_config->FindI("quiet",0) > 1)
2404 c1out.rdbuf(devnull.rdbuf());
2405
2406 // Setup the signals
2407 signal(SIGPIPE,SIG_IGN);
2408 signal(SIGWINCH,SigWinch);
2409 SigWinch(0);
2410
2411 // Match the operation
2412 CmdL.DispatchArg(Cmds);
2413
2414 // Print any errors or warnings found during parsing
2415 if (_error->empty() == false)
2416 {
2417 bool Errors = _error->PendingError();
2418 _error->DumpErrors();
2419 return Errors == true?100:0;
2420 }
2421
2422 return 0;
2423 }