Skip to main content

tar_no_std/
lib.rs

1/*
2MIT License
3
4Copyright (c) 2025 Philipp Schuster
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24//! # `tar-no-std` - Parse Tar Archives (Tarballs)
25//!
26//! _Due to historical reasons, there are several formats of Tar archives. All of
27//! them are based on the same principles, but have some subtle differences that
28//! often make them incompatible with each other._ [(reference)](https://www.gnu.org/software/tar/manual/html_section/Formats.html)
29//!
30//! Library to read Tar archives in `no_std` environments with zero allocations. If
31//! you have a standard environment and need full feature support, I recommend the
32//! use of <https://crates.io/crates/tar> instead.
33//!
34//! ## TL;DR
35//!
36//! Most ordinary Tar archives containing regular files will work.
37//!
38//! ## Limitations
39//!
40//! Archives created by a typical GNU tar or macOS `tar` invocation work when their
41//! regular-file names and sizes fit in the regular Tar headers. This includes
42//! basic Tar and ustar [archives](https://www.gnu.org/software/tar/manual/html_section/Formats.html),
43//! as well as PAX archives that use extended records only for optional metadata
44//! such as high-precision timestamps. PAX headers and their metadata are skipped;
45//! the following regular-file headers provide the filenames and sizes.
46//!
47//! Archives that rely on unsupported extensions do not work correctly. This
48//! includes GNU long names, sparse files, incremental archives, and PAX-only paths
49//! or file sizes. The maximum supported filename length is 256 characters
50//! excluding the NULL-byte, and the maximum supported file size is 8GiB.
51//! Directories, links, and other special entries are skipped; iteration yields only
52//! regular files, preserving directory paths encoded in their names.
53//!
54//! ## Use Case
55//!
56//! This library is useful, if you write a kernel or a similar low-level
57//! application, which needs "a bunch of files" from an archive (like an
58//! "init ramdisk"). The Tar file could for example come as a Multiboot2 boot module
59//! provided by the bootloader.
60//!
61//! ## Example
62//!
63//! ```rust
64//! use tar_no_std::TarArchiveRef;
65//!
66//! // also works in no_std environment (except the println!, of course)
67//! let archive = include_bytes!("../tests/gnu_tar_default.tar");
68//! let archive = TarArchiveRef::new(archive).unwrap();
69//! // Vec needs an allocator of course, but the library itself doesn't need one
70//! let entries = archive.entries().collect::<Vec<_>>();
71//! println!("{:#?}", entries);
72//! ```
73//!
74//! ## Cargo Features
75//!
76//! This crate allows the usage of the additional Cargo build time feature `alloc`.
77//! When this is active, the crate also provides the type `TarArchive`, which owns
78//! the data on the heap.
79//!
80//! ## Compression (`tar.gz`)
81//!
82//! If your Tar file is compressed, e.g. by `.tar.gz`/`gzip`, you need to uncompress
83//! the bytes first (e.g. by a *gzip* library). Afterwards, this crate can read the
84//! Tar archive format from the uncompressed bytes.
85//!
86//! ## MSRV
87//!
88//! The MSRV is 1.85.0 stable.
89
90#![cfg_attr(not(test), no_std)]
91#![deny(
92    clippy::all,
93    clippy::cargo,
94    clippy::nursery,
95    clippy::must_use_candidate,
96    clippy::undocumented_unsafe_blocks
97)]
98#![deny(missing_debug_implementations)]
99#![deny(rustdoc::all)]
100
101#[cfg_attr(test, macro_use)]
102#[cfg(test)]
103extern crate std;
104
105#[cfg(feature = "alloc")]
106extern crate alloc;
107
108/// Each Archive Entry (either Header or Data Block) is a block of 512 bytes.
109const BLOCKSIZE: usize = 512;
110/// Maximum filename length of the base Tar format including the terminating NULL-byte.
111const NAME_LEN: usize = 100;
112/// Maximum long filename length of the base Tar format including the prefix
113const POSIX_1003_MAX_FILENAME_LEN: usize = 256;
114/// Maximum length of the prefix in Posix tar format
115const PREFIX_LEN: usize = 155;
116
117mod archive;
118mod header;
119mod tar_format_types;
120
121pub use archive::*;
122pub use header::*;
123pub use tar_format_types::*;