Add swaplabel
applet
This commit is contained in:
parent
29af667a0f
commit
565e2c52d4
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -579,6 +579,7 @@ dependencies = [
|
|||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"digest",
|
"digest",
|
||||||
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"md-5",
|
"md-5",
|
||||||
"mount",
|
"mount",
|
||||||
|
@ -30,7 +30,8 @@ clap_complete = "4.1"
|
|||||||
clap_complete_nushell = "0.1"
|
clap_complete_nushell = "0.1"
|
||||||
clap_mangen = "0.2"
|
clap_mangen = "0.2"
|
||||||
data-encoding = "2.3"
|
data-encoding = "2.3"
|
||||||
digest = "0.10.6"
|
digest = "0.10"
|
||||||
|
lazy_static = "1.4"
|
||||||
libc = { workspace = true }
|
libc = { workspace = true }
|
||||||
md5 = { version = "0.10", package = "md-5" }
|
md5 = { version = "0.10", package = "md-5" }
|
||||||
sc = { workspace = true }
|
sc = { workspace = true }
|
||||||
|
18
README.md
18
README.md
@ -17,10 +17,10 @@ worth. Like Busybox it is a multi-call binary which is therefore able to share
|
|||||||
code between applets, making for an overall smaller binary.
|
code between applets, making for an overall smaller binary.
|
||||||
|
|
||||||
## Provided Commands
|
## Provided Commands
|
||||||
|
- b2sum
|
||||||
- base32
|
- base32
|
||||||
- base64
|
- base64
|
||||||
- basename
|
- basename
|
||||||
- bootstrap
|
|
||||||
- chgrp
|
- chgrp
|
||||||
- chmod
|
- chmod
|
||||||
- chown
|
- chown
|
||||||
@ -37,6 +37,7 @@ code between applets, making for an overall smaller binary.
|
|||||||
- hostid
|
- hostid
|
||||||
- hostname
|
- hostname
|
||||||
- link
|
- link
|
||||||
|
- ln
|
||||||
- logname
|
- logname
|
||||||
- md5sum
|
- md5sum
|
||||||
- mkfifo
|
- mkfifo
|
||||||
@ -57,10 +58,11 @@ code between applets, making for an overall smaller binary.
|
|||||||
- sha256sum
|
- sha256sum
|
||||||
- sha384sum
|
- sha384sum
|
||||||
- sha512sum
|
- sha512sum
|
||||||
- shitbox
|
|
||||||
- sleep
|
- sleep
|
||||||
|
- swaplabel
|
||||||
- sync
|
- sync
|
||||||
- true
|
- true
|
||||||
|
- umount
|
||||||
- unlink
|
- unlink
|
||||||
- wc
|
- wc
|
||||||
- which
|
- which
|
||||||
@ -75,9 +77,8 @@ for the project include:
|
|||||||
- Network servers
|
- Network servers
|
||||||
- Kernel module handling utilities
|
- Kernel module handling utilities
|
||||||
- Anything requiring suid or sgid bits such as `su` or `sudo`
|
- Anything requiring suid or sgid bits such as `su` or `sudo`
|
||||||
The code aims to be portable across **Unix** variants, ie Linux and BSD, but not
|
The code is not intended to be portable across different architectures, only
|
||||||
MacOS or Windows. Development occurs on Linux, so if your OS is more exotic then
|
Linux is supported.
|
||||||
YMMV.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Building is done using the official Rust toolchain. It is recommended that you
|
Building is done using the official Rust toolchain. It is recommended that you
|
||||||
@ -86,11 +87,16 @@ versions are not supported.
|
|||||||
```Sh
|
```Sh
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
This produces three binaries: corebox, hashbox and utilbox. Most of the commands
|
||||||
|
ordinarily provided by GNU coreutils are applets of `corebox`, with the exception
|
||||||
|
of cryptographic hash related commands which are split out into `hashbox`. Linux
|
||||||
|
swpecific commands ordinarily provided by the util-linux package are in `utilbox`.
|
||||||
|
|
||||||
The `bootstrap` applet provides facility for installing the binary, creating all
|
The `bootstrap` applet provides facility for installing the binary, creating all
|
||||||
required symlinks and installing some nice to haves such as **Unix man pages**
|
required symlinks and installing some nice to haves such as **Unix man pages**
|
||||||
and **shell completions** [see below].
|
and **shell completions** [see below].
|
||||||
```Sh
|
```Sh
|
||||||
target/release/shitbox help bootstrap
|
target/release/corebox help bootstrap
|
||||||
```
|
```
|
||||||
### Supported shells for completions
|
### Supported shells for completions
|
||||||
- Bash
|
- Bash
|
||||||
|
@ -4,9 +4,12 @@ mod blkid;
|
|||||||
mod clear;
|
mod clear;
|
||||||
mod mount;
|
mod mount;
|
||||||
mod mountpoint;
|
mod mountpoint;
|
||||||
|
mod swaplabel;
|
||||||
|
mod swapoff;
|
||||||
|
mod swapon;
|
||||||
mod umount;
|
mod umount;
|
||||||
mod utilbox;
|
mod utilbox;
|
||||||
///
|
|
||||||
/// Parses a string into a command to run
|
/// Parses a string into a command to run
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(clippy::box_default)]
|
#[allow(clippy::box_default)]
|
||||||
@ -14,10 +17,11 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
match name {
|
match name {
|
||||||
"clear" => Some(Box::new(clear::Clear::default())),
|
"clear" => Some(Box::new(clear::Clear::default())),
|
||||||
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
||||||
|
"swaplabel" => Some(Box::new(swaplabel::Swaplabel::default())),
|
||||||
"umount" => Some(Box::new(umount::Umount::default())),
|
"umount" => Some(Box::new(umount::Umount::default())),
|
||||||
"utilbox" => Some(Box::new(utilbox::Utilbox::default())),
|
"utilbox" => Some(Box::new(utilbox::Utilbox::default())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 4] = ["clear", "mountpoint", "umount", "utilbox"];
|
pub static COMMANDS: [&str; 5] = ["clear", "mountpoint", "swaplabel", "umount", "utilbox"];
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
use clap::{Arg, ArgMatches, Command};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use shitbox::Cmd;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
ffi::CString,
|
||||||
|
fs::OpenOptions,
|
||||||
|
io::{self, Read, Seek, SeekFrom, Write},
|
||||||
|
};
|
||||||
|
|
||||||
|
const SWAP_MAGIC1: &'static str = "SWAPSPACE2";
|
||||||
|
const SWAP_MAGIC2: &'static str = "SWAP_SPACE";
|
||||||
|
const SWAP_MAGIC_LENGTH: u64 = 10;
|
||||||
|
const SWAP_LABEL_LENGTH: u64 = 16;
|
||||||
|
const SWAP_LABEL_OFFSET: u64 = 1024 + 4 + 4 + 4 + 16;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref SWAP_MAGIC_OFFSET: u64 =
|
||||||
|
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as u64 - SWAP_MAGIC_LENGTH };
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Swaplabel;
|
||||||
|
|
||||||
|
impl Cmd for Swaplabel {
|
||||||
|
fn cli(&self) -> Command {
|
||||||
|
Command::new("swaplabel")
|
||||||
|
.about("set the label of a swap filesystem")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([
|
||||||
|
Arg::new("label")
|
||||||
|
.help("set the label")
|
||||||
|
.short('L')
|
||||||
|
.visible_short_alias('l')
|
||||||
|
.long("label")
|
||||||
|
.num_args(1)
|
||||||
|
.required(false),
|
||||||
|
Arg::new("device").num_args(1).required(true),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut opts = OpenOptions::new();
|
||||||
|
let device = matches
|
||||||
|
.get_one::<String>("device")
|
||||||
|
.ok_or(io::Error::new(io::ErrorKind::Other, "no device given"))?;
|
||||||
|
let mut fd = opts.read(true).write(true).open(device)?;
|
||||||
|
fd.seek(SeekFrom::Start(*SWAP_MAGIC_OFFSET))?;
|
||||||
|
let mut magic = [0; SWAP_MAGIC_LENGTH as usize];
|
||||||
|
fd.read_exact(&mut magic)?;
|
||||||
|
let m: String = magic.iter().map(|x| *x as char).collect();
|
||||||
|
if m.as_str() != SWAP_MAGIC1 && m.as_str() != SWAP_MAGIC2 {
|
||||||
|
let msg = format!("{device} is not a swap file or partition");
|
||||||
|
println!("Magic String: {m}");
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, msg).into());
|
||||||
|
}
|
||||||
|
fd.seek(SeekFrom::Start(SWAP_LABEL_OFFSET))?;
|
||||||
|
if let Some(label) = matches.get_one::<String>("label") {
|
||||||
|
if label.len() + 1 > SWAP_LABEL_LENGTH as usize {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "label is too long").into());
|
||||||
|
}
|
||||||
|
let label = CString::new(label.as_str())?;
|
||||||
|
fd.write(label.as_bytes())?;
|
||||||
|
} else {
|
||||||
|
let mut label = [0; SWAP_LABEL_LENGTH as usize];
|
||||||
|
fd.read_exact(&mut label)?;
|
||||||
|
let label: String = label
|
||||||
|
.iter()
|
||||||
|
.map(|x| *x as char)
|
||||||
|
.take_while(|x| *x != '\0')
|
||||||
|
.collect();
|
||||||
|
println!("label: {label}");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<shitbox::Path> {
|
||||||
|
Some(shitbox::Path::UsrSbin)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
|
Loading…
Reference in New Issue
Block a user