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