rust_apt/
cache.rs

1//! Contains Cache related structs.
2
3use std::cell::OnceCell;
4use std::fs;
5use std::path::Path;
6
7use cxx::{Exception, UniquePtr};
8
9use crate::Package;
10use crate::config::{Config, init_config_system};
11use crate::depcache::DepCache;
12use crate::error::{AptErrors, pending_error};
13use crate::pkgmanager::raw::OrderResult;
14use crate::progress::{AcquireProgress, InstallProgress, OperationProgress};
15use crate::raw::{
16	IntoRawIter, IterPkgIterator, PackageManager, PkgCacheFile, PkgIterator, ProblemResolver,
17	create_cache, create_pkgmanager, create_problem_resolver,
18};
19use crate::records::{PackageRecords, SourceRecords};
20use crate::util::{apt_lock, apt_unlock, apt_unlock_inner};
21
22/// Selection of Upgrade type
23#[repr(i32)]
24#[derive(Clone, Debug)]
25pub enum Upgrade {
26	/// Upgrade will Install new and Remove packages in addition to
27	/// upgrading them.
28	///
29	/// Equivalent to `apt full-upgrade` and `apt-get dist-upgrade`.
30	FullUpgrade = 0,
31	/// Upgrade will Install new but not Remove packages.
32	///
33	/// Equivalent to `apt upgrade`.
34	Upgrade = 1,
35	/// Upgrade will Not Install new or Remove packages.
36	///
37	/// Equivalent to `apt-get upgrade`.
38	SafeUpgrade = 3,
39}
40
41/// Selection of how to sort
42enum Sort {
43	/// Disable the sort method.
44	Disable,
45	/// Enable the sort method.
46	Enable,
47	/// Reverse the sort method.
48	Reverse,
49}
50
51/// Determines how to sort packages from the Cache.
52pub struct PackageSort {
53	names: bool,
54	upgradable: Sort,
55	virtual_pkgs: Sort,
56	installed: Sort,
57	auto_installed: Sort,
58	auto_removable: Sort,
59}
60
61impl Default for PackageSort {
62	fn default() -> PackageSort {
63		PackageSort {
64			names: false,
65			upgradable: Sort::Disable,
66			virtual_pkgs: Sort::Disable,
67			installed: Sort::Disable,
68			auto_installed: Sort::Disable,
69			auto_removable: Sort::Disable,
70		}
71	}
72}
73
74impl PackageSort {
75	/// Packages will be sorted by their names a -> z.
76	pub fn names(mut self) -> Self {
77		self.names = true;
78		self
79	}
80
81	/// Only packages that are upgradable will be included.
82	pub fn upgradable(mut self) -> Self {
83		self.upgradable = Sort::Enable;
84		self
85	}
86
87	/// Only packages that are NOT upgradable will be included.
88	pub fn not_upgradable(mut self) -> Self {
89		self.upgradable = Sort::Reverse;
90		self
91	}
92
93	/// Virtual packages will be included.
94	pub fn include_virtual(mut self) -> Self {
95		self.virtual_pkgs = Sort::Enable;
96		self
97	}
98
99	/// Only Virtual packages will be included.
100	pub fn only_virtual(mut self) -> Self {
101		self.virtual_pkgs = Sort::Reverse;
102		self
103	}
104
105	/// Only packages that are installed will be included.
106	pub fn installed(mut self) -> Self {
107		self.installed = Sort::Enable;
108		self
109	}
110
111	/// Only packages that are NOT installed will be included.
112	pub fn not_installed(mut self) -> Self {
113		self.installed = Sort::Reverse;
114		self
115	}
116
117	/// Only packages that are auto installed will be included.
118	pub fn auto_installed(mut self) -> Self {
119		self.auto_installed = Sort::Enable;
120		self
121	}
122
123	/// Only packages that are manually installed will be included.
124	pub fn manually_installed(mut self) -> Self {
125		self.auto_installed = Sort::Reverse;
126		self.installed = Sort::Enable;
127		self
128	}
129
130	/// Only packages that are auto removable will be included.
131	pub fn auto_removable(mut self) -> Self {
132		self.auto_removable = Sort::Enable;
133		self
134	}
135
136	/// Only packages that are NOT auto removable will be included.
137	pub fn not_auto_removable(mut self) -> Self {
138		self.auto_removable = Sort::Reverse;
139		self
140	}
141}
142
143/// The main struct for accessing any and all `apt` data.
144pub struct Cache {
145	pub(crate) ptr: UniquePtr<PkgCacheFile>,
146	depcache: OnceCell<DepCache>,
147	records: OnceCell<PackageRecords>,
148	source_records: OnceCell<SourceRecords>,
149	pkgmanager: OnceCell<UniquePtr<PackageManager>>,
150	problem_resolver: OnceCell<UniquePtr<ProblemResolver>>,
151	local_debs: Vec<String>,
152}
153
154impl Cache {
155	/// Initialize the configuration system, open and return the cache.
156	/// This is the entry point for all operations of this crate.
157	///
158	/// `local_files` allows you to temporarily add local files to the cache, as
159	/// long as they are one of the following:
160	///
161	/// - `*.deb` or `*.ddeb` files
162	/// - `Packages` and `Sources` files from apt repositories. These files can
163	///   be compressed.
164	/// - `*.dsc` or `*.changes` files
165	/// - A valid directory containing the file `./debian/control`
166	///
167	/// This function returns an [`AptErrors`] if any of the files cannot
168	/// be found or are invalid.
169	///
170	/// Note that if you run [`Cache::commit`] or [`Cache::update`],
171	/// You will be required to make a new cache to perform any further changes
172	pub fn new<T: AsRef<str>>(local_files: &[T]) -> Result<Cache, AptErrors> {
173		let volatile_files: Vec<_> = local_files.iter().map(|d| d.as_ref()).collect();
174
175		init_config_system();
176		Ok(Cache {
177			ptr: create_cache(&volatile_files)?,
178			depcache: OnceCell::new(),
179			records: OnceCell::new(),
180			source_records: OnceCell::new(),
181			pkgmanager: OnceCell::new(),
182			problem_resolver: OnceCell::new(),
183			local_debs: volatile_files
184				.into_iter()
185				.filter(|f| f.ends_with(".deb"))
186				.map(|f| f.to_string())
187				.collect(),
188		})
189	}
190
191	/// Internal Method for generating the package list.
192	pub fn raw_pkgs(&self) -> impl Iterator<Item = UniquePtr<PkgIterator>> {
193		unsafe { self.begin().raw_iter() }
194	}
195
196	/// Get the DepCache
197	pub fn depcache(&self) -> &DepCache {
198		self.depcache
199			.get_or_init(|| DepCache::new(unsafe { self.create_depcache() }))
200	}
201
202	/// Get the PkgRecords
203	pub fn records(&self) -> &PackageRecords {
204		self.records
205			.get_or_init(|| PackageRecords::new(unsafe { self.create_records() }))
206	}
207
208	/// Get the PkgRecords
209	pub fn source_records(&self) -> Result<&SourceRecords, AptErrors> {
210		if let Some(records) = self.source_records.get() {
211			return Ok(records);
212		}
213
214		match unsafe { self.ptr.source_records() } {
215			Ok(raw_records) => {
216				self.source_records
217					.set(SourceRecords::new(raw_records))
218					// Unwrap: This is verified empty at the beginning.
219					.unwrap_or_default();
220				// Unwrap: Records was just added above.
221				Ok(self.source_records.get().unwrap())
222			},
223			Err(_) => Err(AptErrors::new()),
224		}
225	}
226
227	/// Get the PkgManager
228	pub fn pkg_manager(&self) -> &PackageManager {
229		self.pkgmanager
230			.get_or_init(|| unsafe { create_pkgmanager(self.depcache()) })
231	}
232
233	/// Get the ProblemResolver
234	pub fn resolver(&self) -> &ProblemResolver {
235		self.problem_resolver
236			.get_or_init(|| unsafe { create_problem_resolver(self.depcache()) })
237	}
238
239	/// Iterate through the packages in a random order
240	pub fn iter(&self) -> CacheIter<'_> {
241		CacheIter {
242			pkgs: unsafe { self.begin().raw_iter() },
243			cache: self,
244		}
245	}
246
247	/// An iterator of packages in the cache.
248	pub fn packages(&self, sort: &PackageSort) -> impl Iterator<Item = Package<'_>> {
249		let mut pkg_list = vec![];
250		for pkg in self.raw_pkgs() {
251			match sort.virtual_pkgs {
252				// Virtual packages are enabled, include them.
253				// This works differently than the rest. I should probably change defaults.
254				Sort::Enable => {},
255				// If disabled and pkg has no versions, exclude
256				Sort::Disable => {
257					if unsafe { pkg.versions().end() } {
258						continue;
259					}
260				},
261				// If reverse and the package has versions, exclude
262				// This section is for if you only want virtual packages
263				Sort::Reverse => {
264					if unsafe { !pkg.versions().end() } {
265						continue;
266					}
267				},
268			}
269
270			match sort.upgradable {
271				// Virtual packages are enabled, include them.
272				Sort::Disable => {},
273				// If disabled and pkg has no versions, exclude
274				Sort::Enable => {
275					// If the package isn't installed, then it can not be upgradable
276					if unsafe { pkg.current_version().end() }
277						|| !self.depcache().is_upgradable(&pkg)
278					{
279						continue;
280					}
281				},
282				// If reverse and the package is installed and upgradable, exclude
283				// This section is for if you only want packages that are not upgradable
284				Sort::Reverse => {
285					if unsafe { !pkg.current_version().end() }
286						&& self.depcache().is_upgradable(&pkg)
287					{
288						continue;
289					}
290				},
291			}
292
293			match sort.installed {
294				// Installed Package is Disabled, so we keep them
295				Sort::Disable => {},
296				Sort::Enable => {
297					if unsafe { pkg.current_version().end() } {
298						continue;
299					}
300				},
301				// Only include installed packages.
302				Sort::Reverse => {
303					if unsafe { !pkg.current_version().end() } {
304						continue;
305					}
306				},
307			}
308
309			match sort.auto_installed {
310				// Installed Package is Disabled, so we keep them
311				Sort::Disable => {},
312				Sort::Enable => {
313					if !self.depcache().is_auto_installed(&pkg) {
314						continue;
315					}
316				},
317				// Only include installed packages.
318				Sort::Reverse => {
319					if self.depcache().is_auto_installed(&pkg) {
320						continue;
321					}
322				},
323			}
324
325			match sort.auto_removable {
326				// auto_removable is Disabled, so we keep them
327				Sort::Disable => {},
328				// If the package is not auto removable skip it.
329				Sort::Enable => {
330					// If the Package isn't auto_removable skip
331					if !self.depcache().is_garbage(&pkg) {
332						continue;
333					}
334				},
335				// If the package is auto removable skip it.
336				Sort::Reverse => {
337					if self.depcache().is_garbage(&pkg) {
338						continue;
339					}
340				},
341			}
342
343			// If this is reached we're clear to include the package.
344			pkg_list.push(pkg);
345		}
346
347		if sort.names {
348			pkg_list.sort_by_cached_key(|pkg| pkg.name().to_string());
349		}
350
351		pkg_list.into_iter().map(|pkg| Package::new(self, pkg))
352	}
353
354	/// Updates the package cache and returns a Result
355	///
356	/// Here is an example of how you may parse the Error messages.
357	///
358	/// ```
359	/// use rust_apt::new_cache;
360	/// use rust_apt::progress::AcquireProgress;
361	///
362	/// let cache = new_cache!().unwrap();
363	/// let mut progress = AcquireProgress::apt();
364	/// if let Err(e) = cache.update(&mut progress) {
365	///     for error in e.iter() {
366	///         if error.is_error {
367	///             println!("Error: {}", error.msg);
368	///         } else {
369	///             println!("Warning: {}", error.msg);
370	///         }
371	///     }
372	/// }
373	/// ```
374	/// # Known Errors:
375	/// * E:Could not open lock file /var/lib/apt/lists/lock - open (13:
376	///   Permission denied)
377	/// * E:Unable to lock directory /var/lib/apt/lists/
378	pub fn update(self, progress: &mut AcquireProgress) -> Result<(), AptErrors> {
379		Ok(self.ptr.update(progress.mut_status())?)
380	}
381
382	/// Mark all packages for upgrade
383	///
384	/// # Example:
385	///
386	/// ```
387	/// use rust_apt::new_cache;
388	/// use rust_apt::cache::Upgrade;
389	///
390	/// let cache = new_cache!().unwrap();
391	///
392	/// cache.upgrade(Upgrade::FullUpgrade).unwrap();
393	/// ```
394	pub fn upgrade(&self, upgrade_type: Upgrade) -> Result<(), AptErrors> {
395		let mut progress = OperationProgress::quiet();
396		Ok(self
397			.depcache()
398			.upgrade(progress.pin().as_mut(), upgrade_type as i32)?)
399	}
400
401	/// Resolve dependencies with the changes marked on all packages. This marks
402	/// additional packages for installation/removal to satisfy the dependency
403	/// chain.
404	///
405	/// Note that just running a `mark_*` function on a package doesn't
406	/// guarantee that the selected state will be kept during dependency
407	/// resolution. If you need such, make sure to run
408	/// [`crate::Package::protect`] after marking your requested
409	/// modifications.
410	///
411	/// If `fix_broken` is set to [`true`], the library will try to repair
412	/// broken dependencies of installed packages.
413	///
414	/// Returns [`Err`] if there was an error reaching dependency resolution.
415	#[allow(clippy::result_unit_err)]
416	pub fn resolve(&self, fix_broken: bool) -> Result<(), AptErrors> {
417		Ok(self
418			.resolver()
419			.resolve(fix_broken, OperationProgress::quiet().pin().as_mut())?)
420	}
421
422	/// Autoinstall every broken package and run the problem resolver
423	/// Returns false if the problem resolver fails.
424	///
425	/// # Example:
426	///
427	/// ```
428	/// use rust_apt::new_cache;
429	///
430	/// let cache = new_cache!().unwrap();
431	///
432	/// cache.fix_broken();
433	///
434	/// for pkg in cache.get_changes(false) {
435	///     println!("Pkg Name: {}", pkg.name())
436	/// }
437	/// ```
438	pub fn fix_broken(&self) -> bool { self.depcache().fix_broken() }
439
440	/// Fetch any archives needed to complete the transaction.
441	///
442	/// # Returns:
443	/// * A [`Result`] enum: the [`Ok`] variant if fetching succeeded, and
444	///   [`Err`] if there was an issue.
445	///
446	/// # Example:
447	/// ```
448	/// use rust_apt::new_cache;
449	/// use rust_apt::progress::AcquireProgress;
450	///
451	/// let cache = new_cache!().unwrap();
452	/// let pkg = cache.get("neovim").unwrap();
453	/// let mut progress = AcquireProgress::apt();
454	///
455	/// pkg.mark_install(true, true);
456	/// pkg.protect();
457	/// cache.resolve(true).unwrap();
458	///
459	/// cache.get_archives(&mut progress).unwrap();
460	/// ```
461	/// # Known Errors:
462	/// * W:Problem unlinking the file
463	///   /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
464	///   PrepareFiles (13: Permission denied)
465	/// * W:Problem unlinking the file
466	///   /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
467	///   PrepareFiles (13: Permission denied)
468	/// * W:Problem unlinking the file
469	///   /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
470	///   PrepareFiles (13: Permission denied)
471	/// * W:Problem unlinking the file
472	///   /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
473	///   PrepareFiles (13: Permission denied)
474	/// * W:Problem unlinking the file
475	///   /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
476	///   PrepareFiles (13: Permission denied)
477	/// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
478	///   (13: Permission denied)
479	/// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
480	///   exists)
481	/// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
482	///   (17: File exists)
483	/// * E:Internal Error, ordering was unable to handle the media swap"
484	pub fn get_archives(&self, progress: &mut AcquireProgress) -> Result<(), Exception> {
485		self.pkg_manager()
486			.get_archives(&self.ptr, self.records(), progress.mut_status())
487	}
488
489	/// Install, remove, and do any other actions requested by the cache.
490	///
491	/// # Returns:
492	/// * A [`Result`] enum: the [`Ok`] variant if transaction was successful,
493	///   and [`Err`] if there was an issue.
494	///
495	/// # Example:
496	/// ```
497	/// use rust_apt::new_cache;
498	/// use rust_apt::progress::{AcquireProgress, InstallProgress};
499	///
500	/// let cache = new_cache!().unwrap();
501	/// let pkg = cache.get("neovim").unwrap();
502	/// let mut acquire_progress = AcquireProgress::apt();
503	/// let mut install_progress = InstallProgress::apt();
504	///
505	/// pkg.mark_install(true, true);
506	/// pkg.protect();
507	/// cache.resolve(true).unwrap();
508	///
509	/// // These need root
510	/// // cache.get_archives(&mut acquire_progress).unwrap();
511	/// // cache.do_install(&mut install_progress).unwrap();
512	/// ```
513	///
514	/// # Known Errors:
515	/// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
516	///   (13: Permission denied)
517	/// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
518	///   exists)
519	/// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
520	///   (17: File exists)
521	/// * E:Could not create temporary file for /var/lib/apt/extended_states -
522	///   mkstemp (13: Permission denied)
523	/// * E:Failed to write temporary StateFile /var/lib/apt/extended_states
524	/// * W:Could not open file '/var/log/apt/term.log' - OpenLog (13:
525	///   Permission denied)
526	/// * E:Sub-process /usr/bin/dpkg returned an error code (2)
527	/// * W:Problem unlinking the file /var/cache/apt/pkgcache.bin -
528	///   pkgDPkgPM::Go (13: Permission denied)
529	pub fn do_install(self, progress: &mut InstallProgress) -> Result<(), AptErrors> {
530		let res = match progress {
531			InstallProgress::Fancy(inner) => self.pkg_manager().do_install(inner.pin().as_mut()),
532			InstallProgress::Fd(fd) => self.pkg_manager().do_install_fd(*fd),
533		};
534
535		if pending_error() {
536			return Err(AptErrors::new());
537		}
538
539		match res {
540			OrderResult::Completed => {},
541			OrderResult::Failed => panic!(
542				"DoInstall failed with no error from libapt. Please report this as an issue."
543			),
544			OrderResult::Incomplete => {
545				panic!("Result is 'Incomplete', please request media swapping as a feature.")
546			},
547			_ => unreachable!(),
548		}
549
550		Ok(())
551	}
552
553	/// Handle get_archives and do_install in an easy wrapper.
554	///
555	/// # Returns:
556	/// * A [`Result`]: the [`Ok`] variant if transaction was successful, and
557	///   [`Err`] if there was an issue.
558	/// # Example:
559	/// ```
560	/// use rust_apt::new_cache;
561	/// use rust_apt::progress::{AcquireProgress, InstallProgress};
562	///
563	/// let cache = new_cache!().unwrap();
564	/// let pkg = cache.get("neovim").unwrap();
565	/// let mut acquire_progress = AcquireProgress::apt();
566	/// let mut install_progress = InstallProgress::apt();
567	///
568	/// pkg.mark_install(true, true);
569	/// pkg.protect();
570	/// cache.resolve(true).unwrap();
571	///
572	/// // This needs root
573	/// // cache.commit(&mut acquire_progress, &mut install_progress).unwrap();
574	/// ```
575	pub fn commit(
576		self,
577		progress: &mut AcquireProgress,
578		install_progress: &mut InstallProgress,
579	) -> Result<(), AptErrors> {
580		// Lock the whole thing so as to prevent tamper
581		apt_lock()?;
582
583		let config = Config::new();
584		let archive_dir = config.dir("Dir::Cache::Archives", "/var/cache/apt/archives/");
585
586		// Copy local debs into archives dir
587		for deb in &self.local_debs {
588			// If file is already in the archive we don't copy
589			if deb.starts_with(archive_dir.as_str()) {
590				continue;
591			}
592			// If it reaches this point it really will be a valid filename, allegedly
593			if let Some(filename) = Path::new(deb).file_name() {
594				// Append the file name onto the archive dir
595				fs::copy(deb, archive_dir.to_string() + &filename.to_string_lossy())?;
596			}
597		}
598
599		// The archives can be grabbed during the apt lock.
600		self.get_archives(progress)?;
601
602		// If the system is locked we will want to unlock the dpkg files.
603		// This way when dpkg is running it can access its files.
604		apt_unlock_inner();
605
606		// Perform the operation.
607		self.do_install(install_progress)?;
608
609		// Finally Unlock the whole thing.
610		apt_unlock();
611		Ok(())
612	}
613
614	/// Get a single package.
615	///
616	/// `cache.get("apt")` Returns a Package object for the native arch.
617	///
618	/// `cache.get("apt:i386")` Returns a Package object for the i386 arch
619	pub fn get(&self, name: &str) -> Option<Package<'_>> {
620		Some(Package::new(self, unsafe {
621			self.find_pkg(name).make_safe()?
622		}))
623	}
624
625	/// An iterator over the packages
626	/// that will be altered when `cache.commit()` is called.
627	///
628	/// # sort_name:
629	/// * [`true`] = Packages will be in alphabetical order
630	/// * [`false`] = Packages will not be sorted by name
631	pub fn get_changes(&self, sort_name: bool) -> impl Iterator<Item = Package<'_>> {
632		let mut changed = Vec::new();
633		let depcache = self.depcache();
634
635		for pkg in self.raw_pkgs() {
636			if depcache.marked_install(&pkg)
637				|| depcache.marked_delete(&pkg)
638				|| depcache.marked_upgrade(&pkg)
639				|| depcache.marked_downgrade(&pkg)
640				|| depcache.marked_reinstall(&pkg)
641			{
642				changed.push(pkg);
643			}
644		}
645
646		if sort_name {
647			// Sort by cached key seems to be the fastest for what we're doing.
648			// Maybe consider impl ord or something for these.
649			changed.sort_by_cached_key(|pkg| pkg.name().to_string());
650		}
651
652		changed
653			.into_iter()
654			.map(|pkg_ptr| Package::new(self, pkg_ptr))
655	}
656}
657
658/// Iterator Implementation for the Cache.
659pub struct CacheIter<'a> {
660	pkgs: IterPkgIterator,
661	cache: &'a Cache,
662}
663
664impl<'a> Iterator for CacheIter<'a> {
665	type Item = Package<'a>;
666
667	fn next(&mut self) -> Option<Self::Item> { Some(Package::new(self.cache, self.pkgs.next()?)) }
668}
669
670#[cxx::bridge]
671pub(crate) mod raw {
672	impl UniquePtr<PkgRecords> {}
673
674	unsafe extern "C++" {
675		include!("rust-apt/apt-pkg-c/cache.h");
676		type PkgCacheFile;
677
678		type PkgIterator = crate::raw::PkgIterator;
679		type VerIterator = crate::raw::VerIterator;
680		type PkgFileIterator = crate::raw::PkgFileIterator;
681		type PkgRecords = crate::records::raw::PkgRecords;
682		type SourceRecords = crate::records::raw::SourceRecords;
683		type IndexFile = crate::records::raw::IndexFile;
684		type PkgDepCache = crate::depcache::raw::PkgDepCache;
685		type AcqTextStatus = crate::acquire::raw::AcqTextStatus;
686		type PkgAcquire = crate::acquire::raw::PkgAcquire;
687
688		/// Create the CacheFile.
689		pub fn create_cache(volatile_files: &[&str]) -> Result<UniquePtr<PkgCacheFile>>;
690
691		/// Update the package lists, handle errors and return a Result.
692		pub fn update(self: &PkgCacheFile, progress: Pin<&mut AcqTextStatus>) -> Result<()>;
693
694		/// Loads the index files into PkgAcquire.
695		///
696		/// Used to get to source list uris.
697		///
698		/// It's not clear if this returning a bool is useful.
699		pub fn get_indexes(self: &PkgCacheFile, fetcher: &PkgAcquire) -> bool;
700
701		/// Return a pointer to PkgDepcache.
702		///
703		/// # Safety
704		///
705		/// The returned UniquePtr cannot outlive the cache.
706		unsafe fn create_depcache(self: &PkgCacheFile) -> UniquePtr<PkgDepCache>;
707
708		/// Return a pointer to PkgRecords.
709		///
710		/// # Safety
711		///
712		/// The returned UniquePtr cannot outlive the cache.
713		unsafe fn create_records(self: &PkgCacheFile) -> UniquePtr<PkgRecords>;
714
715		unsafe fn source_records(self: &PkgCacheFile) -> Result<UniquePtr<SourceRecords>>;
716
717		/// The priority of the Version as shown in `apt policy`.
718		pub fn priority(self: &PkgCacheFile, version: &VerIterator) -> i32;
719
720		/// Lookup the IndexFile of the Package file
721		///
722		/// # Safety
723		///
724		/// The IndexFile can not outlive PkgCacheFile.
725		///
726		/// The returned UniquePtr cannot outlive the cache.
727		unsafe fn find_index(self: &PkgCacheFile, file: &PkgFileIterator) -> UniquePtr<IndexFile>;
728
729		/// Return a package by name and optionally architecture.
730		///
731		/// # Safety
732		///
733		/// If the Internal Pkg Pointer is NULL, operations can segfault.
734		/// You should call `make_safe()` asap to convert it to an Option.
735		///
736		/// The returned UniquePtr cannot outlive the cache.
737		unsafe fn find_pkg(self: &PkgCacheFile, name: &str) -> UniquePtr<PkgIterator>;
738
739		/// Return the pointer to the start of the PkgIterator.
740		///
741		/// # Safety
742		///
743		/// If the Internal Pkg Pointer is NULL, operations can segfault.
744		/// You should call `raw_iter()` asap.
745		///
746		/// The returned UniquePtr cannot outlive the cache.
747		unsafe fn begin(self: &PkgCacheFile) -> UniquePtr<PkgIterator>;
748	}
749}