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