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