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 upgradable
305 if unsafe { pkg.current_version().end() }
306 || !self.depcache().is_upgradable(&pkg)
307 {
308 continue;
309 }
310 },
311 // If reverse and the package is installed and upgradable, exclude
312 // This section is for if you only want packages that are not upgradable
313 Sort::Reverse => {
314 if unsafe { !pkg.current_version().end() }
315 && self.depcache().is_upgradable(&pkg)
316 {
317 continue;
318 }
319 },
320 }
321
322 match sort.installed {
323 // Installed Package is Disabled, so we keep them
324 Sort::Disable => {},
325 Sort::Enable => {
326 if unsafe { pkg.current_version().end() } {
327 continue;
328 }
329 },
330 // Only include installed packages.
331 Sort::Reverse => {
332 if unsafe { !pkg.current_version().end() } {
333 continue;
334 }
335 },
336 }
337
338 match sort.auto_installed {
339 // Installed Package is Disabled, so we keep them
340 Sort::Disable => {},
341 Sort::Enable => {
342 if !self.depcache().is_auto_installed(&pkg) {
343 continue;
344 }
345 },
346 // Only include installed packages.
347 Sort::Reverse => {
348 if self.depcache().is_auto_installed(&pkg) {
349 continue;
350 }
351 },
352 }
353
354 match sort.auto_removable {
355 // auto_removable is Disabled, so we keep them
356 Sort::Disable => {},
357 // If the package is not auto removable skip it.
358 Sort::Enable => {
359 // If the Package isn't auto_removable skip
360 if !self.depcache().is_garbage(&pkg) {
361 continue;
362 }
363 },
364 // If the package is auto removable skip it.
365 Sort::Reverse => {
366 if self.depcache().is_garbage(&pkg) {
367 continue;
368 }
369 },
370 }
371
372 // If this is reached we're clear to include the package.
373 pkg_list.push(pkg);
374 }
375
376 if sort.names {
377 pkg_list.sort_by_cached_key(|pkg| pkg.name().to_string());
378 }
379
380 pkg_list.into_iter().map(|pkg| Package::new(self, pkg))
381 }
382
383 /// Updates the package cache and returns a Result
384 ///
385 /// Here is an example of how you may parse the Error messages.
386 ///
387 /// ```
388 /// use rust_apt::new_cache;
389 /// use rust_apt::progress::AcquireProgress;
390 ///
391 /// let cache = new_cache!().unwrap();
392 /// let mut progress = AcquireProgress::apt();
393 /// if let Err(e) = cache.update(&mut progress) {
394 /// for error in e.iter() {
395 /// if error.is_error {
396 /// println!("Error: {}", error.msg);
397 /// } else {
398 /// println!("Warning: {}", error.msg);
399 /// }
400 /// }
401 /// }
402 /// ```
403 /// # Known Errors:
404 /// * E:Could not open lock file /var/lib/apt/lists/lock - open (13:
405 /// Permission denied)
406 /// * E:Unable to lock directory /var/lib/apt/lists/
407 pub fn update(self, progress: &mut AcquireProgress) -> Result<(), AptErrors> {
408 Ok(self.ptr.update(progress.mut_status())?)
409 }
410
411 /// Mark all packages for upgrade
412 ///
413 /// # Example:
414 ///
415 /// ```
416 /// use rust_apt::new_cache;
417 /// use rust_apt::cache::Upgrade;
418 ///
419 /// let cache = new_cache!().unwrap();
420 ///
421 /// cache.upgrade(Upgrade::FullUpgrade).unwrap();
422 /// ```
423 pub fn upgrade(&self, upgrade_type: Upgrade) -> Result<(), AptErrors> {
424 let mut progress = OperationProgress::quiet();
425 Ok(self
426 .depcache()
427 .upgrade(progress.pin().as_mut(), upgrade_type as i32)?)
428 }
429
430 /// Resolve dependencies with the changes marked on all packages. This marks
431 /// additional packages for installation/removal to satisfy the dependency
432 /// chain.
433 ///
434 /// Note that just running a `mark_*` function on a package doesn't
435 /// guarantee that the selected state will be kept during dependency
436 /// resolution. If you need such, make sure to run
437 /// [`crate::Package::protect`] after marking your requested
438 /// modifications.
439 ///
440 /// If `fix_broken` is set to [`true`], the library will try to repair
441 /// broken dependencies of installed packages.
442 ///
443 /// Returns [`Err`] if there was an error reaching dependency resolution.
444 #[allow(clippy::result_unit_err)]
445 pub fn resolve(&self, fix_broken: bool) -> Result<(), AptErrors> {
446 Ok(self
447 .resolver()
448 .resolve(fix_broken, OperationProgress::quiet().pin().as_mut())?)
449 }
450
451 /// Autoinstall every broken package and run the problem resolver
452 /// Returns false if the problem resolver fails.
453 ///
454 /// # Example:
455 ///
456 /// ```
457 /// use rust_apt::new_cache;
458 ///
459 /// let cache = new_cache!().unwrap();
460 ///
461 /// cache.fix_broken();
462 ///
463 /// for pkg in cache.get_changes(false) {
464 /// println!("Pkg Name: {}", pkg.name())
465 /// }
466 /// ```
467 pub fn fix_broken(&self) -> bool { self.depcache().fix_broken() }
468
469 /// Fetch any archives needed to complete the transaction.
470 ///
471 /// # Returns:
472 /// * A [`Result`] enum: the [`Ok`] variant if fetching succeeded, and
473 /// [`Err`] if there was an issue.
474 ///
475 /// # Example:
476 /// ```
477 /// use rust_apt::new_cache;
478 /// use rust_apt::progress::AcquireProgress;
479 ///
480 /// let cache = new_cache!().unwrap();
481 /// let pkg = cache.get("neovim").unwrap();
482 /// let mut progress = AcquireProgress::apt();
483 ///
484 /// pkg.mark_install(true, true);
485 /// pkg.protect();
486 /// cache.resolve(true).unwrap();
487 ///
488 /// cache.get_archives(&mut progress).unwrap();
489 /// ```
490 /// # Known Errors:
491 /// * W:Problem unlinking the file
492 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
493 /// PrepareFiles (13: Permission denied)
494 /// * W:Problem unlinking the file
495 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
496 /// PrepareFiles (13: Permission denied)
497 /// * W:Problem unlinking the file
498 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
499 /// PrepareFiles (13: Permission denied)
500 /// * W:Problem unlinking the file
501 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
502 /// PrepareFiles (13: Permission denied)
503 /// * W:Problem unlinking the file
504 /// /var/cache/apt/archives/partial/neofetch_7.1.0-4_all.deb -
505 /// PrepareFiles (13: Permission denied)
506 /// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
507 /// (13: Permission denied)
508 /// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
509 /// exists)
510 /// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
511 /// (17: File exists)
512 /// * E:Internal Error, ordering was unable to handle the media swap"
513 pub fn get_archives(&self, progress: &mut AcquireProgress) -> Result<(), Exception> {
514 self.pkg_manager()
515 .get_archives(&self.ptr, self.records(), progress.mut_status())
516 }
517
518 /// Install, remove, and do any other actions requested by the cache.
519 ///
520 /// # Returns:
521 /// * A [`Result`] enum: the [`Ok`] variant if transaction was successful,
522 /// and [`Err`] if there was an issue.
523 ///
524 /// # Example:
525 /// ```
526 /// use rust_apt::new_cache;
527 /// use rust_apt::progress::{AcquireProgress, InstallProgress};
528 ///
529 /// let cache = new_cache!().unwrap();
530 /// let pkg = cache.get("neovim").unwrap();
531 /// let mut acquire_progress = AcquireProgress::apt();
532 /// let mut install_progress = InstallProgress::apt();
533 ///
534 /// pkg.mark_install(true, true);
535 /// pkg.protect();
536 /// cache.resolve(true).unwrap();
537 ///
538 /// // These need root
539 /// // cache.get_archives(&mut acquire_progress).unwrap();
540 /// // cache.do_install(&mut install_progress).unwrap();
541 /// ```
542 ///
543 /// # Known Errors:
544 /// * W:Problem unlinking the file /var/log/apt/eipp.log.xz - FileFd::Open
545 /// (13: Permission denied)
546 /// * W:Could not open file /var/log/apt/eipp.log.xz - open (17: File
547 /// exists)
548 /// * W:Could not open file '/var/log/apt/eipp.log.xz' - EIPP::OrderInstall
549 /// (17: File exists)
550 /// * E:Could not create temporary file for /var/lib/apt/extended_states -
551 /// mkstemp (13: Permission denied)
552 /// * E:Failed to write temporary StateFile /var/lib/apt/extended_states
553 /// * W:Could not open file '/var/log/apt/term.log' - OpenLog (13:
554 /// Permission denied)
555 /// * E:Sub-process /usr/bin/dpkg returned an error code (2)
556 /// * W:Problem unlinking the file /var/cache/apt/pkgcache.bin -
557 /// pkgDPkgPM::Go (13: Permission denied)
558 pub fn do_install(self, progress: &mut InstallProgress) -> Result<(), AptErrors> {
559 let res = match progress {
560 InstallProgress::Fancy(inner) => self.pkg_manager().do_install(inner.pin().as_mut()),
561 InstallProgress::Fd(fd) => self.pkg_manager().do_install_fd(*fd),
562 };
563
564 if pending_error() {
565 return Err(AptErrors::new());
566 }
567
568 match res {
569 OrderResult::Completed => {},
570 OrderResult::Failed => panic!(
571 "DoInstall failed with no error from libapt. Please report this as an issue."
572 ),
573 OrderResult::Incomplete => {
574 panic!("Result is 'Incomplete', please request media swapping as a feature.")
575 },
576 _ => unreachable!(),
577 }
578
579 Ok(())
580 }
581
582 /// Handle get_archives and do_install in an easy wrapper.
583 ///
584 /// # Returns:
585 /// * A [`Result`]: the [`Ok`] variant if transaction was successful, and
586 /// [`Err`] if there was an issue.
587 /// # Example:
588 /// ```
589 /// use rust_apt::new_cache;
590 /// use rust_apt::progress::{AcquireProgress, InstallProgress};
591 ///
592 /// let cache = new_cache!().unwrap();
593 /// let pkg = cache.get("neovim").unwrap();
594 /// let mut acquire_progress = AcquireProgress::apt();
595 /// let mut install_progress = InstallProgress::apt();
596 ///
597 /// pkg.mark_install(true, true);
598 /// pkg.protect();
599 /// cache.resolve(true).unwrap();
600 ///
601 /// // This needs root
602 /// // cache.commit(&mut acquire_progress, &mut install_progress).unwrap();
603 /// ```
604 pub fn commit(
605 self,
606 progress: &mut AcquireProgress,
607 install_progress: &mut InstallProgress,
608 ) -> Result<(), AptErrors> {
609 // Lock the whole thing so as to prevent tamper
610 apt_lock()?;
611
612 let config = Config::new();
613 let archive_dir = config.dir("Dir::Cache::Archives", "/var/cache/apt/archives/");
614
615 // Copy local debs into archives dir
616 for deb in &self.local_debs {
617 // If file is already in the archive we don't copy
618 if deb.starts_with(archive_dir.as_str()) {
619 continue;
620 }
621 // If it reaches this point it really will be a valid filename, allegedly
622 if let Some(filename) = Path::new(deb).file_name() {
623 // Append the file name onto the archive dir
624 fs::copy(deb, archive_dir.to_string() + &filename.to_string_lossy())?;
625 }
626 }
627
628 // The archives can be grabbed during the apt lock.
629 self.get_archives(progress)?;
630
631 // If the system is locked we will want to unlock the dpkg files.
632 // This way when dpkg is running it can access its files.
633 apt_unlock_inner();
634
635 // Perform the operation.
636 self.do_install(install_progress)?;
637
638 // Finally Unlock the whole thing.
639 apt_unlock();
640 Ok(())
641 }
642
643 /// Get a single package.
644 ///
645 /// `cache.get("apt")` Returns a Package object for the native arch.
646 ///
647 /// `cache.get("apt:i386")` Returns a Package object for the i386 arch
648 pub fn get(&self, name: &str) -> Option<Package<'_>> {
649 Some(Package::new(self, unsafe {
650 self.find_pkg(name).make_safe()?
651 }))
652 }
653
654 /// An iterator over the packages
655 /// that will be altered when `cache.commit()` is called.
656 ///
657 /// # sort_name:
658 /// * [`true`] = Packages will be in alphabetical order
659 /// * [`false`] = Packages will not be sorted by name
660 pub fn get_changes(&self, sort_name: bool) -> impl Iterator<Item = Package<'_>> {
661 let mut changed = Vec::new();
662 let depcache = self.depcache();
663
664 for pkg in self.raw_pkgs() {
665 if depcache.marked_install(&pkg)
666 || depcache.marked_delete(&pkg)
667 || depcache.marked_upgrade(&pkg)
668 || depcache.marked_downgrade(&pkg)
669 || depcache.marked_reinstall(&pkg)
670 {
671 changed.push(pkg);
672 }
673 }
674
675 if sort_name {
676 // Sort by cached key seems to be the fastest for what we're doing.
677 // Maybe consider impl ord or something for these.
678 changed.sort_by_cached_key(|pkg| pkg.name().to_string());
679 }
680
681 changed
682 .into_iter()
683 .map(|pkg_ptr| Package::new(self, pkg_ptr))
684 }
685}
686
687/// Iterator Implementation for the Cache.
688pub struct CacheIter<'a> {
689 pkgs: IterPkgIterator,
690 cache: &'a Cache,
691}
692
693impl<'a> Iterator for CacheIter<'a> {
694 type Item = Package<'a>;
695
696 fn next(&mut self) -> Option<Self::Item> { Some(Package::new(self.cache, self.pkgs.next()?)) }
697}
698
699#[cxx::bridge]
700pub(crate) mod raw {
701 impl UniquePtr<PkgRecords> {}
702
703 unsafe extern "C++" {
704 include!("rust-apt/apt-pkg-c/cache.h");
705 type PkgCacheFile;
706
707 type PkgIterator = crate::raw::PkgIterator;
708 type VerIterator = crate::raw::VerIterator;
709 type PkgFileIterator = crate::raw::PkgFileIterator;
710 type PkgRecords = crate::records::raw::PkgRecords;
711 type SourceRecords = crate::records::raw::SourceRecords;
712 type IndexFile = crate::records::raw::IndexFile;
713 type PkgDepCache = crate::depcache::raw::PkgDepCache;
714 type AcqTextStatus = crate::acquire::raw::AcqTextStatus;
715 type PkgAcquire = crate::acquire::raw::PkgAcquire;
716
717 /// Create the CacheFile.
718 pub fn create_cache(volatile_files: &[&str]) -> Result<UniquePtr<PkgCacheFile>>;
719
720 /// Update the package lists, handle errors and return a Result.
721 pub fn update(self: &PkgCacheFile, progress: Pin<&mut AcqTextStatus>) -> Result<()>;
722
723 /// Loads the index files into PkgAcquire.
724 ///
725 /// Used to get to source list uris.
726 ///
727 /// It's not clear if this returning a bool is useful.
728 pub fn get_indexes(self: &PkgCacheFile, fetcher: &PkgAcquire) -> bool;
729
730 /// Return a pointer to PkgDepcache.
731 ///
732 /// # Safety
733 ///
734 /// The returned UniquePtr cannot outlive the cache.
735 unsafe fn create_depcache(self: &PkgCacheFile) -> UniquePtr<PkgDepCache>;
736
737 /// Return a pointer to PkgRecords.
738 ///
739 /// # Safety
740 ///
741 /// The returned UniquePtr cannot outlive the cache.
742 unsafe fn create_records(self: &PkgCacheFile) -> UniquePtr<PkgRecords>;
743
744 unsafe fn source_records(self: &PkgCacheFile) -> Result<UniquePtr<SourceRecords>>;
745
746 /// The priority of the Version as shown in `apt policy`.
747 pub fn priority(self: &PkgCacheFile, version: &VerIterator) -> i32;
748
749 /// The priority of the Version as shown in `apt policy`.
750 ///
751 /// When `consider_files` is `true`, this is equivalent to
752 /// [`crate::Version::priority`] and includes package-file priorities in
753 /// the result.
754 ///
755 /// When `consider_files` is `false`, this returns only pin priority
756 /// without considering package-file priorities.
757 pub fn priority_with_files(
758 self: &PkgCacheFile,
759 version: &VerIterator,
760 consider_files: bool,
761 ) -> i32;
762
763 /// Lookup the IndexFile of the Package file
764 ///
765 /// # Safety
766 ///
767 /// The IndexFile can not outlive PkgCacheFile.
768 ///
769 /// The returned UniquePtr cannot outlive the cache.
770 unsafe fn find_index(self: &PkgCacheFile, file: &PkgFileIterator) -> UniquePtr<IndexFile>;
771
772 /// Return a package by name and optionally architecture.
773 ///
774 /// # Safety
775 ///
776 /// If the Internal Pkg Pointer is NULL, operations can segfault.
777 /// You should call `make_safe()` asap to convert it to an Option.
778 ///
779 /// The returned UniquePtr cannot outlive the cache.
780 unsafe fn find_pkg(self: &PkgCacheFile, name: &str) -> UniquePtr<PkgIterator>;
781
782 /// Return the pointer to the start of the PkgIterator.
783 ///
784 /// # Safety
785 ///
786 /// If the Internal Pkg Pointer is NULL, operations can segfault.
787 /// You should call `raw_iter()` asap.
788 ///
789 /// The returned UniquePtr cannot outlive the cache.
790 unsafe fn begin(self: &PkgCacheFile) -> UniquePtr<PkgIterator>;
791
792 /// Return the pointer to the start of the PkgFileIterator list.
793 ///
794 /// # Safety
795 ///
796 /// The returned UniquePtr cannot outlive the cache.
797 unsafe fn file_begin(self: &PkgCacheFile) -> UniquePtr<PkgFileIterator>;
798
799 /// Return the priority for a PackageFile as shown in `apt-cache
800 /// policy`.
801 pub fn file_priority(self: &PkgCacheFile, file: &PkgFileIterator) -> i32;
802 }
803}