1 // Include Files /*{{{*/
4 #include <apt-pkg/acquire.h>
5 #include <apt-pkg/acquire-item.h>
6 #include <apt-pkg/cacheset.h>
7 #include <apt-pkg/cmndline.h>
8 #include <apt-pkg/clean.h>
9 #include <apt-pkg/configuration.h>
10 #include <apt-pkg/error.h>
11 #include <apt-pkg/fileutl.h>
12 #include <apt-pkg/strutl.h>
14 #include <apt-private/private-cachefile.h>
15 #include <apt-private/private-download.h>
16 #include <apt-private/private-output.h>
17 #include <apt-private/private-utils.h>
18 #include <apt-private/acqprogress.h>
25 #include <sys/types.h>
29 #include <sys/statvfs.h>
35 // CheckAuth - check if each download comes form a trusted source /*{{{*/
36 bool CheckAuth(pkgAcquire
& Fetcher
, bool const PromptUser
)
38 std::vector
<std::string
> UntrustedList
;
39 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd(); ++I
)
40 if (!(*I
)->IsTrusted())
41 UntrustedList
.push_back((*I
)->ShortDesc());
43 if (UntrustedList
.empty())
46 return AuthPrompt(UntrustedList
, PromptUser
);
49 bool AuthPrompt(std::vector
<std::string
> const &UntrustedList
, bool const PromptUser
)/*{{{*/
51 ShowList(c2out
,_("WARNING: The following packages cannot be authenticated!"), UntrustedList
,
52 [](std::string
const&) { return true; },
53 [](std::string
const&str
) { return str
; },
54 [](std::string
const&) { return ""; });
56 if (_config
->FindB("APT::Get::AllowUnauthenticated",false) == true)
58 c2out
<< _("Authentication warning overridden.\n");
62 if (PromptUser
== false)
63 return _error
->Error(_("Some packages could not be authenticated"));
65 if (_config
->FindI("quiet",0) < 2
66 && _config
->FindB("APT::Get::Assume-Yes",false) == false)
68 c2out
<< _("Install these packages without verification?") << std::flush
;
70 return _error
->Error(_("Some packages could not be authenticated"));
74 else if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
75 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
79 return _error
->Error(_("There were unauthenticated packages and -y was used without --allow-unauthenticated"));
82 bool AcquireRun(pkgAcquire
&Fetcher
, int const PulseInterval
, bool * const Failure
, bool * const TransientNetworkFailure
)/*{{{*/
84 pkgAcquire::RunResult res
;
86 res
= Fetcher
.Run(PulseInterval
);
90 if (res
== pkgAcquire::Failed
)
93 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
94 I
!= Fetcher
.ItemsEnd(); ++I
)
97 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
98 (*I
)->Complete
== true)
101 if (TransientNetworkFailure
!= NULL
&& (*I
)->Status
== pkgAcquire::Item::StatIdle
)
103 *TransientNetworkFailure
= true;
107 ::URI
uri((*I
)->DescURI());
109 uri
.Password
.clear();
110 std::string descUri
= std::string(uri
);
111 _error
->Error(_("Failed to fetch %s %s\n"), descUri
.c_str(),
112 (*I
)->ErrorText
.c_str());
121 bool CheckFreeSpaceBeforeDownload(std::string
const &Dir
, unsigned long long FetchBytes
)/*{{{*/
123 uint32_t const RAMFS_MAGIC
= 0x858458f6;
124 /* Check for enough free space, but only if we are actually going to
126 if (_config
->FindB("APT::Get::Print-URIs", false) == true ||
127 _config
->FindB("APT::Get::Download", true) == false)
131 if (statvfs(Dir
.c_str(),&Buf
) != 0) {
132 if (errno
== EOVERFLOW
)
133 return _error
->WarningE("statvfs",_("Couldn't determine free space in %s"),
136 return _error
->Errno("statvfs",_("Couldn't determine free space in %s"),
141 unsigned long long const FreeBlocks
= _config
->Find("APT::Sandbox::User").empty() ? Buf
.f_bfree
: Buf
.f_bavail
;
142 if (FreeBlocks
< (FetchBytes
/ Buf
.f_bsize
))
145 if (statfs(Dir
.c_str(),&Stat
) != 0
146 #if HAVE_STRUCT_STATFS_F_TYPE
147 || Stat
.f_type
!= RAMFS_MAGIC
150 return _error
->Error(_("You don't have enough free space in %s."),
158 aptAcquireWithTextStatus::aptAcquireWithTextStatus() : pkgAcquire::pkgAcquire(),
159 Stat(std::cout
, ScreenWidth
, _config
->FindI("quiet",0))
164 // DoDownload - download a binary /*{{{*/
165 bool DoDownload(CommandLine
&CmdL
)
168 if (Cache
.ReadOnlyOpen() == false)
171 APT::CacheSetHelper helper
;
172 APT::VersionSet verset
= APT::VersionSet::FromCommandLine(Cache
,
173 CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
175 if (verset
.empty() == true)
178 pkgRecords
Recs(Cache
);
179 pkgSourceList
*SrcList
= Cache
.GetSourceList();
181 // reuse the usual acquire methods for deb files, but don't drop them into
182 // the usual directories - keep everything in the current directory
183 aptAcquireWithTextStatus Fetcher
;
184 std::vector
<std::string
> storefile(verset
.size());
185 std::string
const cwd
= SafeGetCWD();
186 _config
->Set("Dir::Cache::Archives", cwd
);
188 for (APT::VersionSet::const_iterator Ver
= verset
.begin();
189 Ver
!= verset
.end(); ++Ver
, ++i
)
191 pkgAcquire::Item
*I
= new pkgAcqArchive(&Fetcher
, SrcList
, &Recs
, *Ver
, storefile
[i
]);
192 if (storefile
[i
].empty())
194 std::string
const filename
= cwd
+ flNotDir(storefile
[i
]);
195 storefile
[i
].assign(filename
);
196 I
->DestFile
.assign(filename
);
199 // Just print out the uris and exit if the --print-uris flag was used
200 if (_config
->FindB("APT::Get::Print-URIs") == true)
202 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
203 for (; I
!= Fetcher
.UriEnd(); ++I
)
204 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
205 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
209 if (_error
->PendingError() == true || CheckAuth(Fetcher
, false) == false)
213 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false)
216 // copy files in local sources to the current directory
217 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
219 std::string
const filename
= cwd
+ flNotDir((*I
)->DestFile
);
220 if ((*I
)->Local
== true &&
221 filename
!= (*I
)->DestFile
&&
222 (*I
)->Status
== pkgAcquire::Item::StatDone
)
224 std::ifstream
src((*I
)->DestFile
.c_str(), std::ios::binary
);
225 std::ofstream
dst(filename
.c_str(), std::ios::binary
);
229 return Failed
== false;
232 // DoChangelog - Get changelog from the command line /*{{{*/
233 bool DoChangelog(CommandLine
&CmdL
)
236 if (Cache
.ReadOnlyOpen() == false)
239 APT::CacheSetHelper helper
;
240 APT::VersionList verset
= APT::VersionList::FromCommandLine(Cache
,
241 CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
242 if (verset
.empty() == true)
245 bool const downOnly
= _config
->FindB("APT::Get::Download-Only", false);
246 bool const printOnly
= _config
->FindB("APT::Get::Print-URIs", false);
248 aptAcquireWithTextStatus Fetcher
;
249 for (APT::VersionList::const_iterator Ver
= verset
.begin();
254 new pkgAcqChangelog(&Fetcher
, Ver
, "/dev/null");
256 new pkgAcqChangelog(&Fetcher
, Ver
, ".");
258 new pkgAcqChangelog(&Fetcher
, Ver
);
261 if (printOnly
== false)
264 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed
== true)
268 if (downOnly
== false || printOnly
== true)
271 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
275 if ((*I
)->ErrorText
.empty() == false)
278 _error
->Error("%s", (*I
)->ErrorText
.c_str());
281 std::cout
<< '\'' << (*I
)->DescURI() << "' " << flNotDir((*I
)->DestFile
) << std::endl
;
284 DisplayFileInPager((*I
)->DestFile
);
286 return Failed
== false;
293 // DoClean - Remove download archives /*{{{*/
294 bool DoClean(CommandLine
&)
296 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
297 std::string
const listsdir
= _config
->FindDir("Dir::state::lists");
299 if (_config
->FindB("APT::Get::Simulate") == true)
301 std::string
const pkgcache
= _config
->FindFile("Dir::cache::pkgcache");
302 std::string
const srcpkgcache
= _config
->FindFile("Dir::cache::srcpkgcache");
303 std::cout
<< "Del " << archivedir
<< "* " << archivedir
<< "partial/*"<< std::endl
304 << "Del " << listsdir
<< "partial/*" << std::endl
305 << "Del " << pkgcache
<< " " << srcpkgcache
<< std::endl
;
310 Fetcher
.GetLock(archivedir
);
311 Fetcher
.Clean(archivedir
);
312 Fetcher
.Clean(archivedir
+ "partial/");
314 Fetcher
.GetLock(listsdir
);
315 Fetcher
.Clean(listsdir
+ "partial/");
317 pkgCacheFile::RemoveCaches();
322 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
323 // ---------------------------------------------------------------------
324 /* This is similar to clean but it only purges things that cannot be
325 downloaded, that is old versions of cached packages. */
326 class LogCleaner
: public pkgArchiveCleaner
329 virtual void Erase(const char *File
, std::string Pkg
, std::string Ver
,struct stat
&St
) APT_OVERRIDE
331 c1out
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "B]" << std::endl
;
333 if (_config
->FindB("APT::Get::Simulate") == false)
337 bool DoAutoClean(CommandLine
&)
339 // Lock the archive directory
341 if (_config
->FindB("Debug::NoLocking",false) == false)
343 int lock_fd
= GetLock(_config
->FindDir("Dir::Cache::Archives") + "lock");
345 return _error
->Error(_("Unable to lock the download directory"));
350 if (Cache
.Open() == false)
355 return Cleaner
.Go(_config
->FindDir("Dir::Cache::archives"),*Cache
) &&
356 Cleaner
.Go(_config
->FindDir("Dir::Cache::archives") + "partial/",*Cache
);