#tar-archive #storage #secure #nuts #encryption

nuts-archive

A tar like archive on top of the nuts-container

12 unstable releases (3 breaking)

0.5.0 Mar 5, 2024
0.4.3 Jan 22, 2024
0.2.4 Dec 5, 2023
0.2.3 Nov 10, 2023
0.1.1 Oct 27, 2023

#769 in Cryptography

Download history 9/week @ 2024-01-05 22/week @ 2024-01-12 11/week @ 2024-01-19 1/week @ 2024-02-09 202/week @ 2024-02-16 33/week @ 2024-02-23 135/week @ 2024-03-01 31/week @ 2024-03-08 46/week @ 2024-03-15 68/week @ 2024-03-29 14/week @ 2024-04-05

130 downloads per month
Used in nuts-tool

MIT license

465KB
7.5K SLoC

nuts-archive: A tar like archive on top of a nuts-container.

Introduction

The nuts-archive is an application based on the nuts container. Inspired by the tar tool you can store files, directories and symlinks in a nuts container.

  • Entries can be appended at the end of the archive.
  • They cannot be removed from the archive.
  • You can travere the archive from the first to the last entry in the archive.

Examples

// Append an entry at the end of the archive

use nuts_archive::Archive;
use nuts_container::container::{Cipher, Container, CreateOptionsBuilder, OpenOptionsBuilder};
use nuts_directory::{CreateOptions, DirectoryBackend, OpenOptions};
use tempdir::TempDir;

// This will create an empty archive in a temporary directory.
let tmp_dir = {
    let dir = TempDir::new("nuts-archive").unwrap();

    let backend_options = CreateOptions::for_path(&dir);
    let contaner_options = CreateOptionsBuilder::new(Cipher::Aes128Gcm)
        .with_password_callback(|| Ok(b"123".to_vec()))
        .build::<DirectoryBackend<&TempDir>>()
        .unwrap();

    let container =
        Container::<DirectoryBackend<&TempDir>>::create(backend_options, contaner_options)
            .unwrap();
    Archive::create(container, false).unwrap();

    dir
};

// Open the container (with a directory backend) from the temporary directory.
let backend_options = OpenOptions::for_path(tmp_dir);
let container_options = OpenOptionsBuilder::new()
    .with_password_callback(|| Ok(b"123".to_vec()))
    .build::<DirectoryBackend<TempDir>>()
    .unwrap();
let container =
    Container::<DirectoryBackend<TempDir>>::open(backend_options, container_options).unwrap();

// Open the archive
let mut archive = Archive::open(container).unwrap();

// Append a new entry
let mut entry = archive.append("sample").build().unwrap();
entry.write_all("some sample data".as_bytes()).unwrap();
// Scans the archive for entries

use nuts_archive::Archive;
use nuts_container::container::{Cipher, Container, CreateOptionsBuilder, OpenOptionsBuilder};
use nuts_directory::{CreateOptions, DirectoryBackend, OpenOptions};
use tempdir::TempDir;

// This will create an empty archive in a temporary directory.
let tmp_dir = {
    let dir = TempDir::new("nuts-archive").unwrap();

    let backend_options = CreateOptions::for_path(&dir);
    let contaner_options = CreateOptionsBuilder::new(Cipher::Aes128Gcm)
        .with_password_callback(|| Ok(b"123".to_vec()))
        .build::<DirectoryBackend<&TempDir>>()
        .unwrap();

    let container =
        Container::<DirectoryBackend<&TempDir>>::create(backend_options, contaner_options)
            .unwrap();
    Archive::create(container, false).unwrap();

    dir
};

// Open the container (with a directory backend) from the temporary directory.
let backend_options = OpenOptions::for_path(tmp_dir);
let container_options = OpenOptionsBuilder::new()
    .with_password_callback(|| Ok(b"123".to_vec()))
    .build::<DirectoryBackend<TempDir>>()
    .unwrap();
let container =
    Container::<DirectoryBackend<TempDir>>::open(backend_options, container_options).unwrap();

// Open the archive and append two entries
let mut archive = Archive::open(container).unwrap();

archive.append("f1").build().unwrap();
archive.append("f2").build().unwrap();

// Go through the archive
let entry = archive.first().unwrap().unwrap();
assert_eq!(entry.name(), "f1");

let entry = entry.next().unwrap().unwrap();
assert_eq!(entry.name(), "f2");

assert!(entry.next().is_none());

License

You can check out the full license here.

This project is licensed under the terms of the MIT license.

Dependencies

~4.5MB
~85K SLoC