]> git.saurik.com Git - apt.git/blame - cmdline/apt-get.cc
move 'unmet' handling into libapt-private
[apt.git] / cmdline / apt-get.cc
CommitLineData
5ec427c2
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
640c5d94 3// $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $
5ec427c2
AL
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
1e3f4083 18 dist-upgrade - Powerful upgrader designed to handle the issues with
5ec427c2
AL
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 /*{{{*/
ea542140
DK
28#include <config.h>
29
453b82a3
DK
30#include <apt-pkg/acquire-item.h>
31#include <apt-pkg/algorithms.h>
086bb6d7 32#include <apt-pkg/aptconfiguration.h>
453b82a3
DK
33#include <apt-pkg/cachefile.h>
34#include <apt-pkg/cacheset.h>
35#include <apt-pkg/clean.h>
0a8e3465 36#include <apt-pkg/cmndline.h>
453b82a3 37#include <apt-pkg/debmetaindex.h>
0a8e3465 38#include <apt-pkg/depcache.h>
453b82a3 39#include <apt-pkg/error.h>
472ff00e 40#include <apt-pkg/fileutl.h>
453b82a3 41#include <apt-pkg/indexfile.h>
453b82a3 42#include <apt-pkg/init.h>
092ae175 43#include <apt-pkg/md5.h>
453b82a3 44#include <apt-pkg/metaindex.h>
472ff00e 45#include <apt-pkg/pkgrecords.h>
453b82a3
DK
46#include <apt-pkg/pkgsystem.h>
47#include <apt-pkg/progress.h>
48#include <apt-pkg/sourcelist.h>
49#include <apt-pkg/srcrecords.h>
50#include <apt-pkg/strutl.h>
51#include <apt-pkg/version.h>
52#include <apt-pkg/acquire.h>
53#include <apt-pkg/configuration.h>
54#include <apt-pkg/macros.h>
55#include <apt-pkg/pkgcache.h>
56#include <apt-pkg/cacheiterators.h>
82e369c4 57#include <apt-pkg/upgrade.h>
6cfadda1 58#include <apt-pkg/sptr.h>
ffee1c2b 59
453b82a3
DK
60#include <apt-private/acqprogress.h>
61#include <apt-private/private-cacheset.h>
62#include <apt-private/private-cachefile.h>
63#include <apt-private/private-cmndline.h>
866893a6 64#include <apt-private/private-download.h>
b9179170 65#include <apt-private/private-install.h>
453b82a3
DK
66#include <apt-private/private-main.h>
67#include <apt-private/private-moo.h>
b9179170 68#include <apt-private/private-output.h>
b9179170 69#include <apt-private/private-update.h>
453b82a3 70#include <apt-private/private-upgrade.h>
cfacba52 71#include <apt-private/private-utils.h>
9055d5e6 72#include <apt-private/private-source.h>
b9179170 73
453b82a3
DK
74#include <errno.h>
75#include <signal.h>
76#include <stddef.h>
77#include <stdio.h>
78#include <stdlib.h>
79#include <string.h>
a3f1d60c 80#include <sys/ioctl.h>
1bc849af 81#include <sys/stat.h>
453b82a3 82#include <unistd.h>
03aa0847
DK
83#include <pwd.h>
84#include <grp.h>
85
453b82a3
DK
86#include <algorithm>
87#include <fstream>
88#include <iostream>
8881b11e 89#include <sstream>
453b82a3
DK
90#include <set>
91#include <string>
92#include <vector>
5ec427c2 93
b9179170
MV
94#include <apti18n.h>
95 /*}}}*/
afb1e2e3 96
b9179170 97using namespace std;
642ebc1a 98
182a6a55 99/* mark packages as automatically/manually installed. {{{*/
c3ccac92 100static bool DoMarkAuto(CommandLine &CmdL)
d63a1458
JAK
101{
102 bool Action = true;
103 int AutoMarkChanged = 0;
104 OpTextProgress progress;
105 CacheFile Cache;
106 if (Cache.Open() == false)
107 return false;
108
109 if (strcasecmp(CmdL.FileList[0],"markauto") == 0)
110 Action = true;
111 else if (strcasecmp(CmdL.FileList[0],"unmarkauto") == 0)
112 Action = false;
113
114 for (const char **I = CmdL.FileList + 1; *I != 0; I++)
115 {
116 const char *S = *I;
117 // Locate the package
118 pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
119 if (Pkg.end() == true) {
120 return _error->Error(_("Couldn't find package %s"),S);
121 }
122 else
123 {
124 if (!Action)
125 ioprintf(c1out,_("%s set to manually installed.\n"), Pkg.Name());
126 else
127 ioprintf(c1out,_("%s set to automatically installed.\n"),
128 Pkg.Name());
129
130 Cache->MarkAuto(Pkg,Action);
131 AutoMarkChanged++;
132 }
133 }
182a6a55
DK
134
135 _error->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
136
d63a1458
JAK
137 if (AutoMarkChanged && ! _config->FindB("APT::Get::Simulate",false))
138 return Cache->writeStateFile(NULL);
139 return false;
140}
0a8e3465 141 /*}}}*/
0a8e3465
AL
142// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/
143// ---------------------------------------------------------------------
144/* Follows dselect's selections */
65512241 145static bool DoDSelectUpgrade(CommandLine &)
0a8e3465
AL
146{
147 CacheFile Cache;
c37b9502 148 if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false)
0a8e3465
AL
149 return false;
150
a4decc40
MV
151 pkgDepCache::ActionGroup group(Cache);
152
0a8e3465
AL
153 // Install everything with the install flag set
154 pkgCache::PkgIterator I = Cache->PkgBegin();
f7f0d6c7 155 for (;I.end() != true; ++I)
0a8e3465
AL
156 {
157 /* Install the package only if it is a new install, the autoupgrader
158 will deal with the rest */
159 if (I->SelectedState == pkgCache::State::Install)
160 Cache->MarkInstall(I,false);
161 }
162
163 /* Now install their deps too, if we do this above then order of
164 the status file is significant for | groups */
f7f0d6c7 165 for (I = Cache->PkgBegin();I.end() != true; ++I)
0a8e3465
AL
166 {
167 /* Install the package only if it is a new install, the autoupgrader
168 will deal with the rest */
169 if (I->SelectedState == pkgCache::State::Install)
2f45c76a 170 Cache->MarkInstall(I,true);
0a8e3465
AL
171 }
172
173 // Apply erasures now, they override everything else.
f7f0d6c7 174 for (I = Cache->PkgBegin();I.end() != true; ++I)
0a8e3465
AL
175 {
176 // Remove packages
177 if (I->SelectedState == pkgCache::State::DeInstall ||
178 I->SelectedState == pkgCache::State::Purge)
d556d1a1 179 Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge);
0a8e3465
AL
180 }
181
2f45c76a 182 /* Resolve any problems that dselect created, allupgrade cannot handle
1e3f4083 183 such things. We do so quite aggressively too.. */
2f45c76a
AL
184 if (Cache->BrokenCount() != 0)
185 {
186 pkgProblemResolver Fix(Cache);
187
188 // Hold back held packages.
b2e465d6 189 if (_config->FindB("APT::Ignore-Hold",false) == false)
2f45c76a 190 {
f7f0d6c7 191 for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; ++I)
2f45c76a
AL
192 {
193 if (I->SelectedState == pkgCache::State::Hold)
194 {
195 Fix.Protect(I);
196 Cache->MarkKeep(I);
197 }
198 }
199 }
200
201 if (Fix.Resolve() == false)
202 {
421c8d10 203 ShowBroken(c1out,Cache,false);
2a7e07c7 204 return _error->Error(_("Internal error, problem resolver broke stuff"));
2f45c76a
AL
205 }
206 }
207
208 // Now upgrade everything
67caa2e6 209 if (APT::Upgrade::Upgrade(Cache, APT::Upgrade::FORBID_REMOVE_PACKAGES | APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES) == false)
0a8e3465 210 {
421c8d10 211 ShowBroken(c1out,Cache,false);
2a7e07c7 212 return _error->Error(_("Internal error, problem resolver broke stuff"));
0a8e3465
AL
213 }
214
215 return InstallPackages(Cache,false);
216}
217 /*}}}*/
0a8e3465
AL
218// DoCheck - Perform the check operation /*{{{*/
219// ---------------------------------------------------------------------
220/* Opening automatically checks the system, this command is mostly used
221 for debugging */
65512241 222static bool DoCheck(CommandLine &)
0a8e3465
AL
223{
224 CacheFile Cache;
225 Cache.Open();
2d11135a 226 Cache.CheckDeps();
0a8e3465 227
4a6fe09c 228 return true;
a4c40430
MV
229}
230 /*}}}*/
c2a4a8dd 231// DoIndexTargets - Lists all IndexTargets /*{{{*/
8881b11e
DK
232static std::string format_key(std::string key)
233{
234 // deb822 is case-insensitive, but the human eye prefers candy
235 std::transform(key.begin(), key.end(), key.begin(), ::tolower);
236 key[0] = ::toupper(key[0]);
237 size_t found = key.find("_uri");
238 if (found != std::string::npos)
239 key.replace(found, 4, "-URI");
240 while ((found = key.find('_')) != std::string::npos)
241 {
242 key[found] = '-';
243 key[found + 1] = ::toupper(key[found + 1]);
244 }
245 return key;
246}
c2a4a8dd 247static bool DoIndexTargets(CommandLine &CmdL)
8881b11e
DK
248{
249 pkgCacheFile CacheFile;
250 pkgSourceList *SrcList = CacheFile.GetSourceList();
251
252 if (SrcList == NULL)
253 return false;
254
c2a4a8dd
DK
255 std::string const Format = _config->Find("APT::Get::IndexTargets::Format");
256 bool const ReleaseInfo = _config->FindB("APT::Get::IndexTargets::ReleaseInfo", true);
8881b11e
DK
257 bool Filtered = CmdL.FileSize() > 1;
258 for (pkgSourceList::const_iterator S = SrcList->begin(); S != SrcList->end(); ++S)
259 {
260 std::vector<IndexTarget> const targets = (*S)->GetIndexTargets();
261 std::map<std::string, string> AddOptions;
3fd89e62
DK
262 if (ReleaseInfo)
263 {
264 AddOptions.insert(std::make_pair("TRUSTED", ((*S)->IsTrusted() ? "yes" : "no")));
265 pkgCache &Cache = *CacheFile.GetPkgCache();
266 pkgCache::RlsFileIterator const RlsFile = (*S)->FindInCache(Cache, false);
267 if (RlsFile.end())
268 continue;
269#define APT_RELEASE(X,Y) if (RlsFile.Y() != NULL) AddOptions.insert(std::make_pair(X, RlsFile.Y()))
270 APT_RELEASE("CODENAME", Codename);
271 APT_RELEASE("SUITE", Archive);
272 APT_RELEASE("VERSION", Version);
273 APT_RELEASE("ORIGIN", Origin);
274 APT_RELEASE("LABEL", Label);
275#undef APT_RELEASE
276 }
8881b11e
DK
277
278 for (std::vector<IndexTarget>::const_iterator T = targets.begin(); T != targets.end(); ++T)
279 {
3fd89e62
DK
280 std::string filename = T->Option(ReleaseInfo ? IndexTarget::EXISTING_FILENAME : IndexTarget::FILENAME);
281 if (filename.empty())
282 continue;
283
8881b11e
DK
284 std::ostringstream stanza;
285 if (Filtered || Format.empty())
286 {
287 stanza << "MetaKey: " << T->MetaKey << "\n"
288 << "ShortDesc: " << T->ShortDesc << "\n"
289 << "Description: " << T->Description << "\n"
290 << "URI: " << T->URI << "\n"
3fd89e62 291 << "Filename: " << filename << "\n"
d7a51997
DK
292 << "Optional: " << (T->IsOptional ? "yes" : "no") << "\n"
293 << "KeepCompressed: " << (T->KeepCompressed ? "yes" : "no") << "\n";
8881b11e
DK
294 for (std::map<std::string,std::string>::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O)
295 stanza << format_key(O->first) << ": " << O->second << "\n";
296 for (std::map<std::string,std::string>::const_iterator O = T->Options.begin(); O != T->Options.end(); ++O)
1a3a14ac
DK
297 {
298 if (O->first == "PDIFFS")
299 stanza << "PDiffs: " << O->second << "\n";
d7a51997
DK
300 else if (O->first == "COMPRESSIONTYPES")
301 stanza << "CompressionTypes: " << O->second << "\n";
9adb9778
DK
302 else if (O->first == "DEFAULTENABLED")
303 stanza << "DefaultEnabled: " << O->second << "\n";
1a3a14ac
DK
304 else
305 stanza << format_key(O->first) << ": " << O->second << "\n";
306 }
8881b11e
DK
307 stanza << "\n";
308
309 if (Filtered)
310 {
311 // that is a bit crude, but good enough for now
312 bool found = true;
313 std::string haystack = std::string("\n") + stanza.str() + "\n";
314 std::transform(haystack.begin(), haystack.end(), haystack.begin(), ::tolower);
315 size_t const filesize = CmdL.FileSize() - 1;
316 for (size_t i = 0; i != filesize; ++i)
317 {
318 std::string needle = std::string("\n") + CmdL.FileList[i + 1] + "\n";
319 std::transform(needle.begin(), needle.end(), needle.begin(), ::tolower);
320 if (haystack.find(needle) != std::string::npos)
321 continue;
322 found = false;
323 break;
324 }
325 if (found == false)
326 continue;
327 }
328 }
329
330 if (Format.empty())
331 cout << stanza.str();
332 else
333 {
3fd89e62
DK
334 std::string out = SubstVar(Format, "$(FILENAME)", filename);
335 out = T->Format(out);
8881b11e
DK
336 for (std::map<std::string,std::string>::const_iterator O = AddOptions.begin(); O != AddOptions.end(); ++O)
337 out = SubstVar(out, std::string("$(") + O->first + ")", O->second);
338 cout << out << std::endl;
339 }
340 }
341 }
342
343 return true;
344}
345 /*}}}*/
8561c2fe 346bool ShowHelp(CommandLine &) /*{{{*/
0a8e3465 347{
04aa15a8 348 if (_config->FindB("version") == true)
b2e465d6 349 {
db0db9fe 350 cout << _("Supported modules:") << endl;
249aec3b 351
b2e465d6
AL
352 for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++)
353 {
354 pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I];
355 if (_system != 0 && _system->VS == VS)
356 cout << '*';
357 else
358 cout << ' ';
359 cout << "Ver: " << VS->Label << endl;
249aec3b 360
b2e465d6
AL
361 /* Print out all the packaging systems that will work with
362 this VS */
363 for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++)
364 {
365 pkgSystem *Sys = pkgSystem::GlobalList[J];
366 if (_system == Sys)
367 cout << '*';
368 else
369 cout << ' ';
370 if (Sys->VS->TestCompatibility(*VS) == true)
371 cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl;
372 }
373 }
8561c2fe 374
b2e465d6
AL
375 for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++)
376 {
377 pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I];
378 cout << " S.L: '" << Type->Name << "' " << Type->Label << endl;
8561c2fe
DK
379 }
380
b2e465d6
AL
381 for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++)
382 {
383 pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I];
384 cout << " Idx: " << Type->Label << endl;
8561c2fe
DK
385 }
386
b2e465d6
AL
387 return true;
388 }
cbbee23e
DK
389
390 std::cout <<
8561c2fe
DK
391 _("Usage: apt-get [options] command\n"
392 " apt-get [options] install|remove pkg1 [pkg2 ...]\n"
393 " apt-get [options] source pkg1 [pkg2 ...]\n"
394 "\n"
395 "apt-get is a command line interface for retrieval of packages\n"
396 "and information about them from authenticated sources and\n"
397 "for installation, upgrade and removal of packages together\n"
398 "with their dependencies.\n");
b2e465d6 399 return true;
d7827aca
AL
400}
401 /*}}}*/
6079b276 402std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
0a8e3465 403{
011188e3 404 return {
cbbee23e
DK
405 {"update", &DoUpdate, _("Retrieve new lists of packages")},
406 {"upgrade", &DoUpgrade, _("Perform an upgrade")},
407 {"install", &DoInstall, _("Install new packages (pkg is libc6 not libc6.deb)")},
408 {"remove", &DoInstall, _("Remove packages")},
409 {"purge", &DoInstall, _("Remove packages and config files")},
410 {"autoremove", &DoInstall, _("Remove automatically all unused packages")},
411 {"auto-remove", &DoInstall, nullptr},
412 {"markauto", &DoMarkAuto, nullptr},
413 {"unmarkauto", &DoMarkAuto, nullptr},
414 {"dist-upgrade", &DoDistUpgrade, _("Distribution upgrade, see apt-get(8)")},
415 {"full-upgrade", &DoDistUpgrade, nullptr},
416 {"dselect-upgrade", &DoDSelectUpgrade, _("Follow dselect selections")},
417 {"build-dep", &DoBuildDep, _("Configure build-dependencies for source packages")},
418 {"clean", &DoClean, _("Erase downloaded archive files")},
419 {"autoclean", &DoAutoClean, _("Erase old downloaded archive files")},
420 {"auto-clean", &DoAutoClean, nullptr},
421 {"check", &DoCheck, _("Verify that there are no broken dependencies")},
422 {"source", &DoSource, _("Download source archives")},
423 {"download", &DoDownload, _("Download the binary package into the current directory")},
424 {"changelog", &DoChangelog, _("Download and display the changelog for the given package")},
425 {"indextargets", &DoIndexTargets, nullptr},
426 {"moo", &DoMoo, nullptr},
427 {nullptr, nullptr, nullptr}
428 };
011188e3
DK
429}
430 /*}}}*/
431int main(int argc,const char *argv[]) /*{{{*/
432{
433 InitLocale();
67111687 434
0a8e3465 435 // Parse the command line and initialize the package library
ad7e0941 436 CommandLine CmdL;
90986d4d 437 auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_GET, &_config, &_system, argc, argv, &ShowHelp, &GetCommands);
55a5a46c 438
3163087b 439 InitSignals();
b9179170 440 InitOutput();
d7827aca 441
e7e10e47 442 CheckIfSimulateMode(CmdL);
0a8e3465 443
e7e10e47 444 return DispatchCommandLine(CmdL, Cmds);
0a8e3465 445}
92fcbfc1 446 /*}}}*/