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