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>
36 // CheckAuth - check if each download comes form a trusted source /*{{{*/
37 bool CheckAuth(pkgAcquire
& Fetcher
, bool const PromptUser
)
39 std::vector
<std::string
> UntrustedList
;
40 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
< Fetcher
.ItemsEnd(); ++I
)
41 if (!(*I
)->IsTrusted())
42 UntrustedList
.push_back((*I
)->ShortDesc());
44 if (UntrustedList
.empty())
47 return AuthPrompt(UntrustedList
, PromptUser
);
50 bool AuthPrompt(std::vector
<std::string
> const &UntrustedList
, bool const PromptUser
)/*{{{*/
52 ShowList(c2out
,_("WARNING: The following packages cannot be authenticated!"), UntrustedList
,
53 [](std::string
const&) { return true; },
54 [](std::string
const&str
) { return str
; },
55 [](std::string
const&) { return ""; });
57 if (_config
->FindB("APT::Get::AllowUnauthenticated",false) == true)
59 c2out
<< _("Authentication warning overridden.\n");
63 if (PromptUser
== false)
64 return _error
->Error(_("Some packages could not be authenticated"));
66 if (_config
->FindI("quiet",0) < 2
67 && _config
->FindB("APT::Get::Assume-Yes",false) == false)
69 if (!YnPrompt(_("Install these packages without verification?"), false))
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"), 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 #ifdef 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
);
227 chmod(filename
.c_str(), 0644);
230 return Failed
== false;
233 // DoChangelog - Get changelog from the command line /*{{{*/
234 bool DoChangelog(CommandLine
&CmdL
)
237 if (Cache
.ReadOnlyOpen() == false)
240 APT::CacheSetHelper helper
;
241 APT::VersionList verset
= APT::VersionList::FromCommandLine(Cache
,
242 CmdL
.FileList
+ 1, APT::CacheSetHelper::CANDIDATE
, helper
);
243 if (verset
.empty() == true)
246 bool const downOnly
= _config
->FindB("APT::Get::Download-Only", false);
247 bool const printOnly
= _config
->FindB("APT::Get::Print-URIs", false);
249 _config
->CndSet("Acquire::Changelogs::AlwaysOnline", true);
251 aptAcquireWithTextStatus Fetcher
;
252 for (APT::VersionList::const_iterator Ver
= verset
.begin();
257 new pkgAcqChangelog(&Fetcher
, Ver
, "/dev/null");
259 new pkgAcqChangelog(&Fetcher
, Ver
, ".");
261 new pkgAcqChangelog(&Fetcher
, Ver
);
264 if (printOnly
== false)
267 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed
== true)
271 if (downOnly
== false || printOnly
== true)
274 for (pkgAcquire::ItemIterator I
= Fetcher
.ItemsBegin(); I
!= Fetcher
.ItemsEnd(); ++I
)
278 if ((*I
)->ErrorText
.empty() == false)
281 _error
->Error("%s", (*I
)->ErrorText
.c_str());
284 std::cout
<< '\'' << (*I
)->DescURI() << "' " << flNotDir((*I
)->DestFile
) << std::endl
;
287 DisplayFileInPager((*I
)->DestFile
);
289 return Failed
== false;
296 // DoClean - Remove download archives /*{{{*/
297 bool DoClean(CommandLine
&)
299 std::string
const archivedir
= _config
->FindDir("Dir::Cache::archives");
300 std::string
const listsdir
= _config
->FindDir("Dir::state::lists");
302 if (_config
->FindB("APT::Get::Simulate") == true)
304 std::string
const pkgcache
= _config
->FindFile("Dir::cache::pkgcache");
305 std::string
const srcpkgcache
= _config
->FindFile("Dir::cache::srcpkgcache");
306 std::cout
<< "Del " << archivedir
<< "* " << archivedir
<< "partial/*"<< std::endl
307 << "Del " << listsdir
<< "partial/*" << std::endl
308 << "Del " << pkgcache
<< " " << srcpkgcache
<< std::endl
;
313 if (archivedir
.empty() == false && FileExists(archivedir
) == true &&
314 Fetcher
.GetLock(archivedir
) == true)
316 Fetcher
.Clean(archivedir
);
317 Fetcher
.Clean(archivedir
+ "partial/");
320 if (listsdir
.empty() == false && FileExists(listsdir
) == true &&
321 Fetcher
.GetLock(listsdir
) == true)
323 Fetcher
.Clean(listsdir
+ "partial/");
326 pkgCacheFile::RemoveCaches();
331 // DoAutoClean - Smartly remove downloaded archives /*{{{*/
332 // ---------------------------------------------------------------------
333 /* This is similar to clean but it only purges things that cannot be
334 downloaded, that is old versions of cached packages. */
335 class LogCleaner
: public pkgArchiveCleaner
338 virtual void Erase(const char *File
, std::string Pkg
, std::string Ver
,struct stat
&St
) APT_OVERRIDE
340 c1out
<< "Del " << Pkg
<< " " << Ver
<< " [" << SizeToStr(St
.st_size
) << "B]" << std::endl
;
342 if (_config
->FindB("APT::Get::Simulate") == false)
343 RemoveFile("Cleaner::Erase", File
);
346 bool DoAutoClean(CommandLine
&)
348 std::string
const archivedir
= _config
->FindDir("Dir::Cache::Archives");
349 if (FileExists(archivedir
) == false)
352 // Lock the archive directory
354 if (_config
->FindB("Debug::NoLocking",false) == false)
356 int lock_fd
= GetLock(flCombine(archivedir
, "lock"));
358 return _error
->Error(_("Unable to lock the download directory"));
363 if (Cache
.Open() == false)
368 return Cleaner
.Go(archivedir
, *Cache
) &&
369 Cleaner
.Go(flCombine(archivedir
, "partial/"), *Cache
);