]> git.saurik.com Git - apt.git/blob - cmdline/apt-get.cc
c4b4852f90b8682c94dee286189050670cf40e47
[apt.git] / cmdline / apt-get.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-get.cc,v 1.129 2003/04/27 05:59:33 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 string SuggestsVersions, RecommendsVersions;
1511 for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
1512 {
1513 pkgCache::PkgIterator I(Cache,Cache.List[J]);
1514
1515 /* Just look at the ones we want to install */
1516 if ((*Cache)[I].Install() == false)
1517 continue;
1518
1519 for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
1520 {
1521 for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
1522 {
1523 pkgCache::DepIterator Start;
1524 pkgCache::DepIterator End;
1525 D.GlobOr(Start,End);
1526 do
1527 {
1528 if (Start->Type == pkgCache::Dep::Suggests) {
1529
1530 /* A suggests relations, let's see if we have it
1531 installed already */
1532
1533 string target = string(Start.TargetPkg().Name()) + " ";
1534 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install)
1535 break;
1536 /* Does another package suggest it as well? If so,
1537 don't print it twice */
1538 if (int(SuggestsList.find(target)) > -1)
1539 break;
1540 SuggestsList += target;
1541 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1542 }
1543
1544 if (Start->Type == pkgCache::Dep::Recommends) {
1545
1546 /* A recommends relation, let's see if we have it
1547 installed already */
1548
1549 string target = string(Start.TargetPkg().Name()) + " ";
1550 if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install)
1551 break;
1552
1553 /* Does another package recommend it as well? If so,
1554 don't print it twice */
1555
1556 if (int(RecommendsList.find(target)) > -1)
1557 break;
1558 RecommendsList += target;
1559 SuggestsVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n";
1560 }
1561 if (Start == End)
1562 break;
1563 Start++;
1564 } while (1);
1565 }
1566 }
1567 }
1568 ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions);
1569 ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions);
1570
1571 }
1572
1573 // See if we need to prompt
1574 if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
1575 return InstallPackages(Cache,false,false);
1576
1577 return InstallPackages(Cache,false);
1578 }
1579 /*}}}*/
1580 // DoDistUpgrade - Automatic smart upgrader /*{{{*/
1581 // ---------------------------------------------------------------------
1582 /* Intelligent upgrader that will install and remove packages at will */
1583 bool DoDistUpgrade(CommandLine &CmdL)
1584 {
1585 CacheFile Cache;
1586 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1587 return false;
1588
1589 c0out << _("Calculating Upgrade... ") << flush;
1590 if (pkgDistUpgrade(*Cache) == false)
1591 {
1592 c0out << _("Failed") << endl;
1593 ShowBroken(c1out,Cache,false);
1594 return false;
1595 }
1596
1597 c0out << _("Done") << endl;
1598
1599 return InstallPackages(Cache,true);
1600 }
1601 /*}}}*/
1602 // DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
1603 // ---------------------------------------------------------------------
1604 /* Follows dselect's selections */
1605 bool DoDSelectUpgrade(CommandLine &CmdL)
1606 {
1607 CacheFile Cache;
1608 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
1609 return false;
1610
1611 // Install everything with the install flag set
1612 pkgCache::PkgIterator I = Cache->PkgBegin();
1613 for (;I.end() != true; I++)
1614 {
1615 /* Install the package only if it is a new install, the autoupgrader
1616 will deal with the rest */
1617 if (I->SelectedState == pkgCache::State::Install)
1618 Cache->MarkInstall(I,false);
1619 }
1620
1621 /* Now install their deps too, if we do this above then order of
1622 the status file is significant for | groups */
1623 for (I = Cache->PkgBegin();I.end() != true; I++)
1624 {
1625 /* Install the package only if it is a new install, the autoupgrader
1626 will deal with the rest */
1627 if (I->SelectedState == pkgCache::State::Install)
1628 Cache->MarkInstall(I,true);
1629 }
1630
1631 // Apply erasures now, they override everything else.
1632 for (I = Cache->PkgBegin();I.end() != true; I++)
1633 {
1634 // Remove packages
1635 if (I->SelectedState == pkgCache::State::DeInstall ||
1636 I->SelectedState == pkgCache::State::Purge)
1637 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
1638 }
1639
1640 /* Resolve any problems that dselect created, allupgrade cannot handle
1641 such things. We do so quite agressively too.. */
1642 if (Cache->BrokenCount() != 0)
1643 {
1644 pkgProblemResolver Fix(Cache);
1645
1646 // Hold back held packages.
1647 if (_config->FindB("APT::Ignore-Hold",false) == false)
1648 {
1649 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++)
1650 {
1651 if (I->SelectedState == pkgCache::State::Hold)
1652 {
1653 Fix.Protect(I);
1654 Cache->MarkKeep(I);
1655 }
1656 }
1657 }
1658
1659 if (Fix.Resolve() == false)
1660 {
1661 ShowBroken(c1out,Cache,false);
1662 return _error->Error("Internal Error, problem resolver broke stuff");
1663 }
1664 }
1665
1666 // Now upgrade everything
1667 if (pkgAllUpgrade(Cache) == false)
1668 {
1669 ShowBroken(c1out,Cache,false);
1670 return _error->Error("Internal Error, problem resolver broke stuff");
1671 }
1672
1673 return InstallPackages(Cache,false);
1674 }
1675 /*}}}*/
1676 // DoClean - Remove download archives /*{{{*/
1677 // ---------------------------------------------------------------------
1678 /* */
1679 bool DoClean(CommandLine &CmdL)
1680 {
1681 if (_config->FindB("APT::Get::Simulate") == true)
1682 {
1683 cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " <<
1684 _config->FindDir("Dir::Cache::archives") << "partial/*" << endl;
1685 return true;
1686 }
1687
1688 // Lock the archive directory
1689 FileFd Lock;
1690 if (_config->FindB("Debug::NoLocking",false) == false)
1691 {
1692 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1693 if (_error->PendingError() == true)
1694 return _error->Error(_("Unable to lock the download directory"));
1695 }
1696
1697 pkgAcquire Fetcher;
1698 Fetcher.Clean(_config->FindDir("Dir::Cache::archives"));
1699 Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/");
1700 return true;
1701 }
1702 /*}}}*/
1703 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
1704 // ---------------------------------------------------------------------
1705 /* This is similar to clean but it only purges things that cannot be
1706 downloaded, that is old versions of cached packages. */
1707 class LogCleaner : public pkgArchiveCleaner
1708 {
1709 protected:
1710 virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St)
1711 {
1712 c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl;
1713
1714 if (_config->FindB("APT::Get::Simulate") == false)
1715 unlink(File);
1716 };
1717 };
1718
1719 bool DoAutoClean(CommandLine &CmdL)
1720 {
1721 // Lock the archive directory
1722 FileFd Lock;
1723 if (_config->FindB("Debug::NoLocking",false) == false)
1724 {
1725 Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
1726 if (_error->PendingError() == true)
1727 return _error->Error(_("Unable to lock the download directory"));
1728 }
1729
1730 CacheFile Cache;
1731 if (Cache.Open() == false)
1732 return false;
1733
1734 LogCleaner Cleaner;
1735
1736 return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) &&
1737 Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache);
1738 }
1739 /*}}}*/
1740 // DoCheck - Perform the check operation /*{{{*/
1741 // ---------------------------------------------------------------------
1742 /* Opening automatically checks the system, this command is mostly used
1743 for debugging */
1744 bool DoCheck(CommandLine &CmdL)
1745 {
1746 CacheFile Cache;
1747 Cache.Open();
1748 Cache.CheckDeps();
1749
1750 return true;
1751 }
1752 /*}}}*/
1753 // DoSource - Fetch a source archive /*{{{*/
1754 // ---------------------------------------------------------------------
1755 /* Fetch souce packages */
1756 struct DscFile
1757 {
1758 string Package;
1759 string Version;
1760 string Dsc;
1761 };
1762
1763 bool DoSource(CommandLine &CmdL)
1764 {
1765 CacheFile Cache;
1766 if (Cache.Open(false) == false)
1767 return false;
1768
1769 if (CmdL.FileSize() <= 1)
1770 return _error->Error(_("Must specify at least one package to fetch source for"));
1771
1772 // Read the source list
1773 pkgSourceList List;
1774 if (List.ReadMainList() == false)
1775 return _error->Error(_("The list of sources could not be read."));
1776
1777 // Create the text record parsers
1778 pkgRecords Recs(Cache);
1779 pkgSrcRecords SrcRecs(List);
1780 if (_error->PendingError() == true)
1781 return false;
1782
1783 // Create the download object
1784 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1785 pkgAcquire Fetcher(&Stat);
1786
1787 DscFile *Dsc = new DscFile[CmdL.FileSize()];
1788
1789 // Load the requestd sources into the fetcher
1790 unsigned J = 0;
1791 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
1792 {
1793 string Src;
1794 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
1795
1796 if (Last == 0)
1797 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
1798
1799 // Back track
1800 vector<pkgSrcRecords::File> Lst;
1801 if (Last->Files(Lst) == false)
1802 return false;
1803
1804 // Load them into the fetcher
1805 for (vector<pkgSrcRecords::File>::const_iterator I = Lst.begin();
1806 I != Lst.end(); I++)
1807 {
1808 // Try to guess what sort of file it is we are getting.
1809 if (I->Type == "dsc")
1810 {
1811 Dsc[J].Package = Last->Package();
1812 Dsc[J].Version = Last->Version();
1813 Dsc[J].Dsc = flNotDir(I->Path);
1814 }
1815
1816 // Diff only mode only fetches .diff files
1817 if (_config->FindB("APT::Get::Diff-Only",false) == true &&
1818 I->Type != "diff")
1819 continue;
1820
1821 // Tar only mode only fetches .tar files
1822 if (_config->FindB("APT::Get::Tar-Only",false) == true &&
1823 I->Type != "tar")
1824 continue;
1825
1826 new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
1827 I->MD5Hash,I->Size,
1828 Last->Index().SourceInfo(*Last,*I),Src);
1829 }
1830 }
1831
1832 // Display statistics
1833 double FetchBytes = Fetcher.FetchNeeded();
1834 double FetchPBytes = Fetcher.PartialPresent();
1835 double DebBytes = Fetcher.TotalNeeded();
1836
1837 // Check for enough free space
1838 struct statvfs Buf;
1839 string OutputDir = ".";
1840 if (statvfs(OutputDir.c_str(),&Buf) != 0)
1841 return _error->Errno("statvfs","Couldn't determine free space in %s",
1842 OutputDir.c_str());
1843 if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize)
1844 return _error->Error(_("You don't have enough free space in %s"),
1845 OutputDir.c_str());
1846
1847 // Number of bytes
1848 if (DebBytes != FetchBytes)
1849 ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"),
1850 SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str());
1851 else
1852 ioprintf(c1out,_("Need to get %sB of source archives.\n"),
1853 SizeToStr(DebBytes).c_str());
1854
1855 if (_config->FindB("APT::Get::Simulate",false) == true)
1856 {
1857 for (unsigned I = 0; I != J; I++)
1858 ioprintf(cout,_("Fetch Source %s\n"),Dsc[I].Package.c_str());
1859 return true;
1860 }
1861
1862 // Just print out the uris an exit if the --print-uris flag was used
1863 if (_config->FindB("APT::Get::Print-URIs") == true)
1864 {
1865 pkgAcquire::UriIterator I = Fetcher.UriBegin();
1866 for (; I != Fetcher.UriEnd(); I++)
1867 cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' <<
1868 I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl;
1869 return true;
1870 }
1871
1872 // Run it
1873 if (Fetcher.Run() == pkgAcquire::Failed)
1874 return false;
1875
1876 // Print error messages
1877 bool Failed = false;
1878 for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
1879 {
1880 if ((*I)->Status == pkgAcquire::Item::StatDone &&
1881 (*I)->Complete == true)
1882 continue;
1883
1884 fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
1885 (*I)->ErrorText.c_str());
1886 Failed = true;
1887 }
1888 if (Failed == true)
1889 return _error->Error(_("Failed to fetch some archives."));
1890
1891 if (_config->FindB("APT::Get::Download-only",false) == true)
1892 {
1893 c1out << _("Download complete and in download only mode") << endl;
1894 return true;
1895 }
1896
1897 // Unpack the sources
1898 pid_t Process = ExecFork();
1899
1900 if (Process == 0)
1901 {
1902 for (unsigned I = 0; I != J; I++)
1903 {
1904 string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str());
1905
1906 // Diff only mode only fetches .diff files
1907 if (_config->FindB("APT::Get::Diff-Only",false) == true ||
1908 _config->FindB("APT::Get::Tar-Only",false) == true ||
1909 Dsc[I].Dsc.empty() == true)
1910 continue;
1911
1912 // See if the package is already unpacked
1913 struct stat Stat;
1914 if (stat(Dir.c_str(),&Stat) == 0 &&
1915 S_ISDIR(Stat.st_mode) != 0)
1916 {
1917 ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"),
1918 Dir.c_str());
1919 }
1920 else
1921 {
1922 // Call dpkg-source
1923 char S[500];
1924 snprintf(S,sizeof(S),"%s -x %s",
1925 _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
1926 Dsc[I].Dsc.c_str());
1927 if (system(S) != 0)
1928 {
1929 fprintf(stderr,_("Unpack command '%s' failed.\n"),S);
1930 _exit(1);
1931 }
1932 }
1933
1934 // Try to compile it with dpkg-buildpackage
1935 if (_config->FindB("APT::Get::Compile",false) == true)
1936 {
1937 // Call dpkg-buildpackage
1938 char S[500];
1939 snprintf(S,sizeof(S),"cd %s && %s %s",
1940 Dir.c_str(),
1941 _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
1942 _config->Find("DPkg::Build-Options","-b -uc").c_str());
1943
1944 if (system(S) != 0)
1945 {
1946 fprintf(stderr,_("Build command '%s' failed.\n"),S);
1947 _exit(1);
1948 }
1949 }
1950 }
1951
1952 _exit(0);
1953 }
1954
1955 // Wait for the subprocess
1956 int Status = 0;
1957 while (waitpid(Process,&Status,0) != Process)
1958 {
1959 if (errno == EINTR)
1960 continue;
1961 return _error->Errno("waitpid","Couldn't wait for subprocess");
1962 }
1963
1964 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
1965 return _error->Error(_("Child process failed"));
1966
1967 return true;
1968 }
1969 /*}}}*/
1970 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
1971 // ---------------------------------------------------------------------
1972 /* This function will look at the build depends list of the given source
1973 package and install the necessary packages to make it true, or fail. */
1974 bool DoBuildDep(CommandLine &CmdL)
1975 {
1976 CacheFile Cache;
1977 if (Cache.Open(true) == false)
1978 return false;
1979
1980 if (CmdL.FileSize() <= 1)
1981 return _error->Error(_("Must specify at least one package to check builddeps for"));
1982
1983 // Read the source list
1984 pkgSourceList List;
1985 if (List.ReadMainList() == false)
1986 return _error->Error(_("The list of sources could not be read."));
1987
1988 // Create the text record parsers
1989 pkgRecords Recs(Cache);
1990 pkgSrcRecords SrcRecs(List);
1991 if (_error->PendingError() == true)
1992 return false;
1993
1994 // Create the download object
1995 AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0));
1996 pkgAcquire Fetcher(&Stat);
1997
1998 unsigned J = 0;
1999 for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
2000 {
2001 string Src;
2002 pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache);
2003 if (Last == 0)
2004 return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
2005
2006 // Process the build-dependencies
2007 vector<pkgSrcRecords::Parser::BuildDepRec> BuildDeps;
2008 if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false)
2009 return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
2010
2011 // Also ensure that build-essential packages are present
2012 Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
2013 if (Opts)
2014 Opts = Opts->Child;
2015 for (; Opts; Opts = Opts->Next)
2016 {
2017 if (Opts->Value.empty() == true)
2018 continue;
2019
2020 pkgSrcRecords::Parser::BuildDepRec rec;
2021 rec.Package = Opts->Value;
2022 rec.Type = pkgSrcRecords::Parser::BuildDependIndep;
2023 rec.Op = 0;
2024 BuildDeps.insert(BuildDeps.begin(), rec);
2025 }
2026
2027 if (BuildDeps.size() == 0)
2028 {
2029 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
2030 continue;
2031 }
2032
2033 // Install the requested packages
2034 unsigned int ExpectedInst = 0;
2035 vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
2036 pkgProblemResolver Fix(Cache);
2037 for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
2038 {
2039 if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
2040 (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
2041 {
2042 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2043 // Build-conflicts on unknown packages are silently ignored
2044 if (Pkg.end() == true)
2045 continue;
2046
2047 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2048
2049 /*
2050 * Remove if we have an installed version that satisfies the
2051 * version criteria
2052 */
2053 if (IV.end() == false &&
2054 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2055 TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
2056 }
2057 else // BuildDep || BuildDepIndep
2058 {
2059 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
2060 if (Pkg.end() == true)
2061 {
2062 // Check if there are any alternatives
2063 if (((*D).Op & pkgCache::Dep::Or) != pkgCache::Dep::Or)
2064 return _error->Error(_("%s dependency for %s cannot be satisfied "
2065 "because the package %s cannot be found"),
2066 Last->BuildDepType((*D).Type),Src.c_str(),
2067 (*D).Package.c_str());
2068 // Try the next alternative
2069 continue;
2070 }
2071
2072 /*
2073 * if there are alternatives, we've already picked one, so skip
2074 * the rest
2075 *
2076 * TODO: this means that if there's a build-dep on A|B and B is
2077 * installed, we'll still try to install A; more importantly,
2078 * if A is currently broken, we cannot go back and try B. To fix
2079 * this would require we do a Resolve cycle for each package we
2080 * add to the install list. Ugh
2081 */
2082 while (D != BuildDeps.end() &&
2083 (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or))
2084 D++;
2085
2086 /*
2087 * If this is a virtual package, we need to check the list of
2088 * packages that provide it and see if any of those are
2089 * installed
2090 */
2091 pkgCache::PrvIterator Prv = Pkg.ProvidesList();
2092 for (; Prv.end() != true; Prv++)
2093 if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
2094 break;
2095
2096 // Get installed version and version we are going to install
2097 pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
2098 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
2099
2100 for (; CV.end() != true; CV++)
2101 {
2102 if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
2103 break;
2104 }
2105 if (CV.end() == true)
2106 return _error->Error(_("%s dependency for %s cannot be satisfied "
2107 "because no available versions of package %s "
2108 "can satisfy version requirements"),
2109 Last->BuildDepType((*D).Type),Src.c_str(),
2110 (*D).Package.c_str());
2111
2112 /*
2113 * TODO: if we depend on a version lower than what we already have
2114 * installed it is not clear what should be done; in practice
2115 * this case should be rare, and right now nothing is
2116 * done about it :-(
2117 */
2118 if (Prv.end() == true && // Nothing provides it; and
2119 (IV.end() == true || // It is not installed, or
2120 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false))
2121 // the version installed doesn't
2122 // satisfy constraints
2123 TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
2124 }
2125 }
2126
2127 Fix.InstallProtect();
2128 if (Fix.Resolve(true) == false)
2129 _error->Discard();
2130
2131 // Now we check the state of the packages,
2132 if (Cache->BrokenCount() != 0)
2133 return _error->Error(_("Some broken packages were found while trying to process build-dependencies.\n"
2134 "You might want to run `apt-get -f install' to correct these."));
2135 }
2136
2137 if (InstallPackages(Cache, false, true) == false)
2138 return _error->Error(_("Failed to process build dependencies"));
2139 return true;
2140 }
2141 /*}}}*/
2142
2143 // DoMoo - Never Ask, Never Tell /*{{{*/
2144 // ---------------------------------------------------------------------
2145 /* */
2146 bool DoMoo(CommandLine &CmdL)
2147 {
2148 cout <<
2149 " (__) \n"
2150 " (oo) \n"
2151 " /------\\/ \n"
2152 " / | || \n"
2153 " * /\\---/\\ \n"
2154 " ~~ ~~ \n"
2155 "....\"Have you mooed today?\"...\n";
2156
2157 return true;
2158 }
2159 /*}}}*/
2160 // ShowHelp - Show a help screen /*{{{*/
2161 // ---------------------------------------------------------------------
2162 /* */
2163 bool ShowHelp(CommandLine &CmdL)
2164 {
2165 ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
2166 COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
2167
2168 if (_config->FindB("version") == true)
2169 {
2170 cout << _("Supported Modules:") << endl;
2171
2172 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
2173 {
2174 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
2175 if (_system != 0 && _system->VS == VS)
2176 cout << '*';
2177 else
2178 cout << ' ';
2179 cout << "Ver: " << VS->Label << endl;
2180
2181 /* Print out all the packaging systems that will work with
2182 this VS */
2183 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
2184 {
2185 pkgSystem *Sys = pkgSystem::GlobalList[J];
2186 if (_system == Sys)
2187 cout << '*';
2188 else
2189 cout << ' ';
2190 if (Sys->VS->TestCompatibility(*VS) == true)
2191 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
2192 }
2193 }
2194
2195 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
2196 {
2197 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
2198 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
2199 }
2200
2201 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
2202 {
2203 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
2204 cout << " Idx: " << Type->Label << endl;
2205 }
2206
2207 return true;
2208 }
2209
2210 cout <<
2211 _("Usage: apt-get [options] command\n"
2212 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
2213 " apt-get [options] source pkg1 [pkg2 ...]\n"
2214 "\n"
2215 "apt-get is a simple command line interface for downloading and\n"
2216 "installing packages. The most frequently used commands are update\n"
2217 "and install.\n"
2218 "\n"
2219 "Commands:\n"
2220 " update - Retrieve new lists of packages\n"
2221 " upgrade - Perform an upgrade\n"
2222 " install - Install new packages (pkg is libc6 not libc6.deb)\n"
2223 " remove - Remove packages\n"
2224 " source - Download source archives\n"
2225 " build-dep - Configure build-dependencies for source packages\n"
2226 " dist-upgrade - Distribution upgrade, see apt-get(8)\n"
2227 " dselect-upgrade - Follow dselect selections\n"
2228 " clean - Erase downloaded archive files\n"
2229 " autoclean - Erase old downloaded archive files\n"
2230 " check - Verify that there are no broken dependencies\n"
2231 "\n"
2232 "Options:\n"
2233 " -h This help text.\n"
2234 " -q Loggable output - no progress indicator\n"
2235 " -qq No output except for errors\n"
2236 " -d Download only - do NOT install or unpack archives\n"
2237 " -s No-act. Perform ordering simulation\n"
2238 " -y Assume Yes to all queries and do not prompt\n"
2239 " -f Attempt to continue if the integrity check fails\n"
2240 " -m Attempt to continue if archives are unlocatable\n"
2241 " -u Show a list of upgraded packages as well\n"
2242 " -b Build the source package after fetching it\n"
2243 " -V Show verbose version numbers\n"
2244 " -c=? Read this configuration file\n"
2245 " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
2246 "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n"
2247 "pages for more information and options.\n"
2248 " This APT has Super Cow Powers.\n");
2249 return true;
2250 }
2251 /*}}}*/
2252 // GetInitialize - Initialize things for apt-get /*{{{*/
2253 // ---------------------------------------------------------------------
2254 /* */
2255 void GetInitialize()
2256 {
2257 _config->Set("quiet",0);
2258 _config->Set("help",false);
2259 _config->Set("APT::Get::Download-Only",false);
2260 _config->Set("APT::Get::Simulate",false);
2261 _config->Set("APT::Get::Assume-Yes",false);
2262 _config->Set("APT::Get::Fix-Broken",false);
2263 _config->Set("APT::Get::Force-Yes",false);
2264 _config->Set("APT::Get::APT::Get::No-List-Cleanup",true);
2265 }
2266 /*}}}*/
2267 // SigWinch - Window size change signal handler /*{{{*/
2268 // ---------------------------------------------------------------------
2269 /* */
2270 void SigWinch(int)
2271 {
2272 // Riped from GNU ls
2273 #ifdef TIOCGWINSZ
2274 struct winsize ws;
2275
2276 if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
2277 ScreenWidth = ws.ws_col - 1;
2278 #endif
2279 }
2280 /*}}}*/
2281
2282 int main(int argc,const char *argv[])
2283 {
2284 CommandLine::Args Args[] = {
2285 {'h',"help","help",0},
2286 {'v',"version","version",0},
2287 {'V',"verbose-versions","APT::Get::Show-Versions",0},
2288 {'q',"quiet","quiet",CommandLine::IntLevel},
2289 {'q',"silent","quiet",CommandLine::IntLevel},
2290 {'d',"download-only","APT::Get::Download-Only",0},
2291 {'b',"compile","APT::Get::Compile",0},
2292 {'b',"build","APT::Get::Compile",0},
2293 {'s',"simulate","APT::Get::Simulate",0},
2294 {'s',"just-print","APT::Get::Simulate",0},
2295 {'s',"recon","APT::Get::Simulate",0},
2296 {'s',"dry-run","APT::Get::Simulate",0},
2297 {'s',"no-act","APT::Get::Simulate",0},
2298 {'y',"yes","APT::Get::Assume-Yes",0},
2299 {'y',"assume-yes","APT::Get::Assume-Yes",0},
2300 {'f',"fix-broken","APT::Get::Fix-Broken",0},
2301 {'u',"show-upgraded","APT::Get::Show-Upgraded",0},
2302 {'m',"ignore-missing","APT::Get::Fix-Missing",0},
2303 {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
2304 {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
2305 {0,"download","APT::Get::Download",0},
2306 {0,"fix-missing","APT::Get::Fix-Missing",0},
2307 {0,"ignore-hold","APT::Ignore-Hold",0},
2308 {0,"upgrade","APT::Get::upgrade",0},
2309 {0,"force-yes","APT::Get::force-yes",0},
2310 {0,"print-uris","APT::Get::Print-URIs",0},
2311 {0,"diff-only","APT::Get::Diff-Only",0},
2312 {0,"tar-only","APT::Get::tar-Only",0},
2313 {0,"purge","APT::Get::Purge",0},
2314 {0,"list-cleanup","APT::Get::List-Cleanup",0},
2315 {0,"reinstall","APT::Get::ReInstall",0},
2316 {0,"trivial-only","APT::Get::Trivial-Only",0},
2317 {0,"remove","APT::Get::Remove",0},
2318 {0,"only-source","APT::Get::Only-Source",0},
2319 {0,"arch-only","APT::Get::Arch-Only",0},
2320 {'c',"config-file",0,CommandLine::ConfigFile},
2321 {'o',"option",0,CommandLine::ArbItem},
2322 {0,0,0,0}};
2323 CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
2324 {"upgrade",&DoUpgrade},
2325 {"install",&DoInstall},
2326 {"remove",&DoInstall},
2327 {"dist-upgrade",&DoDistUpgrade},
2328 {"dselect-upgrade",&DoDSelectUpgrade},
2329 {"build-dep",&DoBuildDep},
2330 {"clean",&DoClean},
2331 {"autoclean",&DoAutoClean},
2332 {"check",&DoCheck},
2333 {"source",&DoSource},
2334 {"moo",&DoMoo},
2335 {"help",&ShowHelp},
2336 {0,0}};
2337
2338 // Set up gettext support
2339 setlocale(LC_ALL,"");
2340 textdomain(PACKAGE);
2341
2342 // Parse the command line and initialize the package library
2343 CommandLine CmdL(Args,_config);
2344 if (pkgInitConfig(*_config) == false ||
2345 CmdL.Parse(argc,argv) == false ||
2346 pkgInitSystem(*_config,_system) == false)
2347 {
2348 if (_config->FindB("version") == true)
2349 ShowHelp(CmdL);
2350
2351 _error->DumpErrors();
2352 return 100;
2353 }
2354
2355 // See if the help should be shown
2356 if (_config->FindB("help") == true ||
2357 _config->FindB("version") == true ||
2358 CmdL.FileSize() == 0)
2359 {
2360 ShowHelp(CmdL);
2361 return 0;
2362 }
2363
2364 // Deal with stdout not being a tty
2365 if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
2366 _config->Set("quiet","1");
2367
2368 // Setup the output streams
2369 c0out.rdbuf(cout.rdbuf());
2370 c1out.rdbuf(cout.rdbuf());
2371 c2out.rdbuf(cout.rdbuf());
2372 if (_config->FindI("quiet",0) > 0)
2373 c0out.rdbuf(devnull.rdbuf());
2374 if (_config->FindI("quiet",0) > 1)
2375 c1out.rdbuf(devnull.rdbuf());
2376
2377 // Setup the signals
2378 signal(SIGPIPE,SIG_IGN);
2379 signal(SIGWINCH,SigWinch);
2380 SigWinch(0);
2381
2382 // Match the operation
2383 CmdL.DispatchArg(Cmds);
2384
2385 // Print any errors or warnings found during parsing
2386 if (_error->empty() == false)
2387 {
2388 bool Errors = _error->PendingError();
2389 _error->DumpErrors();
2390 return Errors == true?100:0;
2391 }
2392
2393 return 0;
2394 }