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//! Look at the [`TarArchiveRef`] type.
37//!
38//! ## Limitations
39//!
40//! This crate is simple and focuses on reading files and their content from a Tar
41//! archive. Historic basic Tar and ustar [formats](https://www.gnu.org/software/tar/manual/html_section/Formats.html)
42//! are supported. Other formats may work, but likely without all supported
43//! features. GNU Extensions such as sparse files, incremental archives, and
44//! long filename extension are not supported.
45//!
46//! The maximum supported file name length is 256 characters excluding the
47//! NULL-byte (using the Tar name/prefix longname implementation of ustar). The
48//! maximum supported file size is 8GiB. Directories are supported, but only regular
49//! fields are yielded in iteration. The path is reflected in their file name.
50//!
51//! ## Use Case
52//!
53//! This library is useful, if you write a kernel or a similar low-level
54//! application, which needs "a bunch of files" from an archive (like an
55//! "init ramdisk"). The Tar file could for example come as a Multiboot2 boot module
56//! provided by the bootloader.
57//!
58//! ## Example
59//!
60//! ```rust
61//! use tar_no_std::TarArchiveRef;
62//!
63//! // also works in no_std environment (except the println!, of course)
64//! let archive = include_bytes!("../tests/gnu_tar_default.tar");
65//! let archive = TarArchiveRef::new(archive).unwrap();
66//! // Vec needs an allocator of course, but the library itself doesn't need one
67//! let entries = archive.entries().collect::<Vec<_>>();
68//! println!("{:#?}", entries);
69//! ```
70//!
71//! ## Cargo Features
72//!
73//! This crate allows the usage of the additional Cargo build time feature `alloc`.
74//! When this is active, the crate also provides the type `TarArchive`, which owns
75//! the data on the heap.
76//!
77//! ## Compression (`tar.gz`)
78//!
79//! If your Tar file is compressed, e.g. by `.tar.gz`/`gzip`, you need to uncompress
80//! the bytes first (e.g. by a *gzip* library). Afterwards, this crate can read the
81//! Tar archive format from the uncompressed bytes.
82//!
83//! ## MSRV
84//!
85//! The MSRV is 1.85.0 stable.
86
87#![cfg_attr(not(test), no_std)]
88#![deny(
89 clippy::all,
90 clippy::cargo,
91 clippy::nursery,
92 clippy::must_use_candidate,
93 // clippy::restriction,
94 // clippy::pedantic
95)]
96// now allow a few rules which are denied by the above statement
97// --> they are ridiculous and not necessary
98#![allow(
99 clippy::suboptimal_flops,
100 clippy::redundant_pub_crate,
101 clippy::fallible_impl_from
102)]
103#![deny(missing_debug_implementations)]
104#![deny(rustdoc::all)]
105
106#[cfg_attr(test, macro_use)]
107#[cfg(test)]
108extern crate std;
109
110#[cfg(feature = "alloc")]
111extern crate alloc;
112
113/// Each Archive Entry (either Header or Data Block) is a block of 512 bytes.
114const BLOCKSIZE: usize = 512;
115/// Maximum filename length of the base Tar format including the terminating NULL-byte.
116const NAME_LEN: usize = 100;
117/// Maximum long filename length of the base Tar format including the prefix
118const POSIX_1003_MAX_FILENAME_LEN: usize = 256;
119/// Maximum length of the prefix in Posix tar format
120const PREFIX_LEN: usize = 155;
121
122mod archive;
123mod header;
124mod tar_format_types;
125
126pub use archive::*;
127pub use header::*;
128pub use tar_format_types::*;