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