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",
|
||||
"data-encoding",
|
||||
"digest",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"md-5",
|
||||
"mount",
|
||||
|
@ -30,7 +30,8 @@ clap_complete = "4.1"
|
||||
clap_complete_nushell = "0.1"
|
||||
clap_mangen = "0.2"
|
||||
data-encoding = "2.3"
|
||||
digest = "0.10.6"
|
||||
digest = "0.10"
|
||||
lazy_static = "1.4"
|
||||
libc = { workspace = true }
|
||||
md5 = { version = "0.10", package = "md-5" }
|
||||
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.
|
||||
|
||||
## Provided Commands
|
||||
- b2sum
|
||||
- base32
|
||||
- base64
|
||||
- basename
|
||||
- bootstrap
|
||||
- chgrp
|
||||
- chmod
|
||||
- chown
|
||||
@ -37,6 +37,7 @@ code between applets, making for an overall smaller binary.
|
||||
- hostid
|
||||
- hostname
|
||||
- link
|
||||
- ln
|
||||
- logname
|
||||
- md5sum
|
||||
- mkfifo
|
||||
@ -57,10 +58,11 @@ code between applets, making for an overall smaller binary.
|
||||
- sha256sum
|
||||
- sha384sum
|
||||
- sha512sum
|
||||
- shitbox
|
||||
- sleep
|
||||
- swaplabel
|
||||
- sync
|
||||
- true
|
||||
- umount
|
||||
- unlink
|
||||
- wc
|
||||
- which
|
||||
@ -75,9 +77,8 @@ for the project include:
|
||||
- Network servers
|
||||
- Kernel module handling utilities
|
||||
- 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
|
||||
MacOS or Windows. Development occurs on Linux, so if your OS is more exotic then
|
||||
YMMV.
|
||||
The code is not intended to be portable across different architectures, only
|
||||
Linux is supported.
|
||||
|
||||
## Installation
|
||||
Building is done using the official Rust toolchain. It is recommended that you
|
||||
@ -86,11 +87,16 @@ versions are not supported.
|
||||
```Sh
|
||||
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
|
||||
required symlinks and installing some nice to haves such as **Unix man pages**
|
||||
and **shell completions** [see below].
|
||||
```Sh
|
||||
target/release/shitbox help bootstrap
|
||||
target/release/corebox help bootstrap
|
||||
```
|
||||
### Supported shells for completions
|
||||
- Bash
|
||||
|
@ -4,9 +4,12 @@ mod blkid;
|
||||
mod clear;
|
||||
mod mount;
|
||||
mod mountpoint;
|
||||
mod swaplabel;
|
||||
mod swapoff;
|
||||
mod swapon;
|
||||
mod umount;
|
||||
mod utilbox;
|
||||
///
|
||||
|
||||
/// Parses a string into a command to run
|
||||
#[must_use]
|
||||
#[allow(clippy::box_default)]
|
||||
@ -14,10 +17,11 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
||||
match name {
|
||||
"clear" => Some(Box::new(clear::Clear::default())),
|
||||
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
||||
"swaplabel" => Some(Box::new(swaplabel::Swaplabel::default())),
|
||||
"umount" => Some(Box::new(umount::Umount::default())),
|
||||
"utilbox" => Some(Box::new(utilbox::Utilbox::default())),
|
||||
_ => 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