tar_no_std/lib.rs
1/*
2MIT License
3
4Copyright (c) 2023 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//! // init a logger (optional)
64//! std::env::set_var("RUST_LOG", "trace");
65//! env_logger::init();
66//!
67//! // also works in no_std environment (except the println!, of course)
68//! let archive = include_bytes!("../tests/gnu_tar_default.tar");
69//! let archive = TarArchiveRef::new(archive).unwrap();
70//! // Vec needs an allocator of course, but the library itself doesn't need one
71//! let entries = archive.entries().collect::<Vec<_>>();
72//! println!("{:#?}", entries);
73//! ```
74//!
75//! ## Cargo Feature
76//!
77//! This crate allows the usage of the additional Cargo build time feature `alloc`.
78//! When this is active, the crate also provides the type `TarArchive`, which owns
79//! the data on the heap. The `unstable` feature provides additional convenience
80//! only available on the nightly channel.
81//!
82//! ## Compression (`tar.gz`)
83//!
84//! If your Tar file is compressed, e.g. by `.tar.gz`/`gzip`, you need to uncompress
85//! the bytes first (e.g. by a *gzip* library). Afterwards, this crate can read the
86//! Tar archive format from the uncompressed bytes.
87//!
88//! ## MSRV
89//!
90//! The MSRV is 1.76.0 stable.
91
92#![cfg_attr(feature = "unstable", feature(error_in_core))]
93#![cfg_attr(not(test), no_std)]
94#![deny(
95 clippy::all,
96 clippy::cargo,
97 clippy::nursery,
98 clippy::must_use_candidate,
99 // clippy::restriction,
100 // clippy::pedantic
101)]
102// now allow a few rules which are denied by the above statement
103// --> they are ridiculous and not necessary
104#![allow(
105 clippy::suboptimal_flops,
106 clippy::redundant_pub_crate,
107 clippy::fallible_impl_from
108)]
109#![deny(missing_debug_implementations)]
110#![deny(rustdoc::all)]
111
112#[cfg_attr(test, macro_use)]
113#[cfg(test)]
114extern crate std;
115
116#[cfg(feature = "alloc")]
117extern crate alloc;
118
119/// Each Archive Entry (either Header or Data Block) is a block of 512 bytes.
120const BLOCKSIZE: usize = 512;
121/// Maximum filename length of the base Tar format including the terminating NULL-byte.
122const NAME_LEN: usize = 100;
123/// Maximum long filename length of the base Tar format including the prefix
124const POSIX_1003_MAX_FILENAME_LEN: usize = 256;
125/// Maximum length of the prefix in Posix tar format
126const PREFIX_LEN: usize = 155;
127
128mod archive;
129mod header;
130mod tar_format_types;
131
132pub use archive::*;
133pub use header::*;
134pub use tar_format_types::*;