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