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>
32 #include <sys/params.h>
34 #include <sys/mount.h>
36 #include <sys/statvfs.h>
43 // CheckAuth - check if each download comes form a trusted source /*{{{*/
44 bool CheckAuth(pkgAcquire
& Fetcher
, bool const PromptUser
)
46 std::vector
<std::string
> UntrustedList
;
47 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd(); ++I
)
48 if (!(*I
)->IsTrusted())
49 UntrustedList
.push_back((*I
)->ShortDesc());
51 if (UntrustedList
.empty())
54 return AuthPrompt(UntrustedList
, PromptUser
);
57 bool AuthPrompt(std::vector
<std::string
> const &UntrustedList
, bool const PromptUser
)/*{{{*/
59 ShowList(c2out
,_("WARNING: The following packages cannot be authenticated!"), UntrustedList
,
60 [](std::string
const&) { return true; },
61 [](std::string
const&str
) { return str
; },
62 [](std::string
const&) { return ""; });
64 if (_config
->FindB("APT::Get::AllowUnauthenticated",false) == true)
66 c2out
<< _("Authentication warning overridden.\n");
70 if (PromptUser
== false)
71 return _error
->Error(_("Some packages could not be authenticated"));
73 if (_config
->FindI("quiet",0) < 2
74 && _config
->FindB("APT::Get::Assume-Yes",false) == false)
76 if (!YnPrompt(_("Install these packages without verification?"), false))
77 return _error
->Error(_("Some packages could not be authenticated"));
81 else if (_config
->FindB("APT::Get::Force-Yes",false) == true) {
82 _error
->Warning(_("--force-yes is deprecated, use one of the options starting with --allow instead."));
86 return _error
->Error(_("There were unauthenticated packages and -y was used without --allow-unauthenticated"));
89 bool AcquireRun(pkgAcquire
&Fetcher
, int const PulseInterval
, bool * const Failure
, bool * const TransientNetworkFailure
)/*{{{*/
91 pkgAcquire::RunResult res
;
93 res
= Fetcher
.Run(PulseInterval
);
97 if (res
== pkgAcquire::Failed
)
100 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin();
101 I
!= Fetcher
.ItemsEnd(); ++I
)
104 if ((*I
)->Status
== pkgAcquire::Item::StatDone
&&
105 (*I
)->Complete
== true)
108 if (TransientNetworkFailure
!= NULL
&& (*I
)->Status
== pkgAcquire::Item::StatIdle
)
110 *TransientNetworkFailure
= true;
114 ::URI
uri((*I
)->DescURI());
116 uri
.Password
.clear();
117 std::string descUri
= std::string(uri
);
118 _error
->Error(_("Failed to fetch %s %s"), descUri
.c_str(),
119 (*I
)->ErrorText
.c_str());
128 bool CheckFreeSpaceBeforeDownload(std::string
const &Dir
, unsigned long long FetchBytes
)/*{{{*/
130 uint32_t const RAMFS_MAGIC
= 0x858458f6;
131 /* Check for enough free space, but only if we are actually going to
133 if (_config
->FindB("APT::Get::Print-URIs", false) == true ||
134 _config
->FindB("APT::Get::Download", true) == false)
138 if (statvfs(Dir
.c_str(),&Buf
) != 0) {
139 if (errno
== EOVERFLOW
)
140 return _error
->WarningE("statvfs",_("Couldn't determine free space in %s"),
143 return _error
->Errno("statvfs",_("Couldn't determine free space in %s"),
148 unsigned long long const FreeBlocks
= _config
->Find("APT::Sandbox::User").empty() ? Buf
.f_bfree
: Buf
.f_bavail
;
149 if (FreeBlocks
< (FetchBytes
/ Buf
.f_bsize
))
152 if (statfs(Dir
.c_str(),&Stat
) != 0
153 #ifdef HAVE_STRUCT_STATFS_F_TYPE
154 || Stat
.f_type
!= RAMFS_MAGIC
157 return _error
->Error(_("You don't have enough free space in %s."),
165 aptAcquireWithTextStatus::aptAcquireWithTextStatus() : pkgAcquire::pkgAcquire(),
166 Stat(std::cout
, ScreenWidth
, _config
->FindI("quiet",0))
171 // DoDownload - download a binary /*{{{*/
172 bool DoDownload(CommandLine
&CmdL
)
175 if (Cache
.ReadOnlyOpen() == false)
178 APT::CacheSetHelper helper
;
179 APT::VersionSet verset
= APT::VersionSet::FromCommandLine(Cache
,
180 CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
182 if (verset
.empty() == true)
185 pkgRecords
Recs(Cache
);
186 pkgSourceList
*SrcList
= Cache
.GetSourceList();
188 // reuse the usual acquire methods for deb files, but don't drop them into
189 // the usual directories - keep everything in the current directory
190 aptAcquireWithTextStatus Fetcher
;
191 std::vector
<std::string
> storefile(verset
.size());
192 std::string
const cwd
= SafeGetCWD();
193 _config
->Set("Dir::Cache::Archives", cwd
);
195 for (APT::VersionSet::const_iterator Ver
= verset
.begin();
196 Ver
!= verset
.end(); ++Ver
, ++i
)
198 pkgAcquire::Item
*I
= new pkgAcqArchive(&Fetcher
, SrcList
, &Recs
, *Ver
, storefile
[i
]);
199 if (storefile
[i
].empty())
201 std::string
const filename
= cwd
+ flNotDir(storefile
[i
]);
202 storefile
[i
].assign(filename
);
203 I
->DestFile
.assign(filename
);
206 // Just print out the uris and exit if the --print-uris flag was used
207 if (_config
->FindB("APT::Get::Print-URIs") == true)
209 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
210 for (; I
!= Fetcher
.UriEnd(); ++I
)
211 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
212 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
216 if (_error
->PendingError() == true || CheckAuth(Fetcher
, false) == false)
220 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false)
223 // copy files in local sources to the current directory
224 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
226 std::string
const filename
= cwd
+ flNotDir((*I
)->DestFile
);
227 if ((*I
)->Local
== true &&
228 filename
!= (*I
)->DestFile
&&
229 (*I
)->Status
== pkgAcquire::Item::StatDone
)
231 std::ifstream
src((*I
)->DestFile
.c_str(), std::ios::binary
);
232 std::ofstream
dst(filename
.c_str(), std::ios::binary
);
234 chmod(filename
.c_str(), 0644);
237 return Failed
== false;
240 // DoChangelog - Get changelog from the command line /*{{{*/
241 bool DoChangelog(CommandLine
&CmdL
)
244 if (Cache
.ReadOnlyOpen() == false)
247 APT::CacheSetHelper helper
;
248 APT::VersionList verset
= APT::VersionList::FromCommandLine(Cache
,
249 CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
250 if (verset
.empty() == true)
253 bool const downOnly
= _config
->FindB("APT::Get::Download-Only", false);
254 bool const printOnly
= _config
->FindB("APT::Get::Print-URIs", false);
256 _config
->CndSet("Acquire::Changelogs::AlwaysOnline", true);
258 aptAcquireWithTextStatus Fetcher
;
259 for (APT::VersionList::const_iterator Ver
= verset
.begin();
264 new pkgAcqChangelog(&Fetcher
, Ver
, "/dev/null");
266 new pkgAcqChangelog(&Fetcher
, Ver
, ".");
268 new pkgAcqChangelog(&Fetcher
, Ver
);
271 if (printOnly
== false)
274 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed
== true)
278 if (downOnly
== false || printOnly
== true)
281 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
285 if ((*I
)->ErrorText
.empty() == false)
288 _error
->Error("%s", (*I
)->ErrorText
.c_str());
291 std::cout
<< '\'' << (*I
)->DescURI() << "' " << flNotDir((*I
)->DestFile
) << std::endl
;
294 DisplayFileInPager((*I
)->DestFile
);
296 return Failed
== false;
303 // DoClean - Remove download archives /*{{{*/
304 bool DoClean(CommandLine
&)
306 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
307 std::string
const listsdir
= _config
->FindDir("Dir::state::lists");
309 if (_config
->FindB("APT::Get::Simulate") == true)
311 std::string
const pkgcache
= _config
->FindFile("Dir::cache::pkgcache");
312 std::string
const srcpkgcache
= _config
->FindFile("Dir::cache::srcpkgcache");
313 std::cout
<< "Del " << archivedir
<< "* " << archivedir
<< "partial/*"<< std::endl
314 << "Del " << listsdir
<< "partial/*" << std::endl
315 << "Del " << pkgcache
<< " " << srcpkgcache
<< std::endl
;
320 if (archivedir
.empty() == false && FileExists(archivedir
) == true &&
321 Fetcher
.GetLock(archivedir
) == true)
323 Fetcher
.Clean(archivedir
);
324 Fetcher
.Clean(archivedir
+ "partial/");
327 if (listsdir
.empty() == false && FileExists(listsdir
) == true &&
328 Fetcher
.GetLock(listsdir
) == true)
330 Fetcher
.Clean(listsdir
+ "partial/");
333 pkgCacheFile::RemoveCaches();
338 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
339 // ---------------------------------------------------------------------
340 /* This is similar to clean but it only purges things that cannot be
341 downloaded, that is old versions of cached packages. */
342 class LogCleaner
: public pkgArchiveCleaner
345 virtual void Erase(const char *File
, std::string Pkg
, std::string Ver
,struct stat
&St
) APT_OVERRIDE
347 c1out
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "B]" << std::endl
;
349 if (_config
->FindB("APT::Get::Simulate") == false)
350 RemoveFile("Cleaner::Erase", File
);
353 bool DoAutoClean(CommandLine
&)
355 std::string
const archivedir
= _config
->FindDir("Dir::Cache::Archives");
356 if (FileExists(archivedir
) == false)
359 // Lock the archive directory
361 if (_config
->FindB("Debug::NoLocking",false) == false)
363 int lock_fd
= GetLock(flCombine(archivedir
, "lock"));
365 return _error
->Error(_("Unable to lock the download directory"));
370 if (Cache
.Open() == false)
375 return Cleaner
.Go(archivedir
, *Cache
) &&
376 Cleaner
.Go(flCombine(archivedir
, "partial/"), *Cache
);