Add mktemp
applet
This commit is contained in:
parent
5076dcc350
commit
754f604603
@ -13,9 +13,7 @@ impl Cmd for Hostid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
fn run(&self, _matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let hostid = unsafe {
|
let hostid = unsafe { libc::gethostid() };
|
||||||
libc::gethostid()
|
|
||||||
};
|
|
||||||
let hostid: String = format!("{hostid:x}").chars().skip(8).collect();
|
let hostid: String = format!("{hostid:x}").chars().skip(8).collect();
|
||||||
println!("{}", hostid);
|
println!("{}", hostid);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
88
src/cmd/mktemp/mod.rs
Normal file
88
src/cmd/mktemp/mod.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use super::Cmd;
|
||||||
|
use clap::{Arg, ArgAction, Command, ValueHint};
|
||||||
|
use std::{ffi::CString, fs, io, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct MkTemp;
|
||||||
|
|
||||||
|
impl Cmd for MkTemp {
|
||||||
|
fn cli(&self) -> clap::Command {
|
||||||
|
Command::new("mktemp")
|
||||||
|
.about("create a unique temporary file")
|
||||||
|
.author("Nathan Fisher")
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.args([
|
||||||
|
Arg::new("directory")
|
||||||
|
.short('d')
|
||||||
|
.long("directory")
|
||||||
|
.help("create a directory instead of a file")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
Arg::new("tmpdir")
|
||||||
|
.short('p')
|
||||||
|
.long("tmpdir")
|
||||||
|
.help("specify the directory to create temporary files in")
|
||||||
|
.value_hint(ValueHint::DirPath)
|
||||||
|
.num_args(1),
|
||||||
|
Arg::new("prefix")
|
||||||
|
.short('t')
|
||||||
|
.long("template")
|
||||||
|
.help("specify a prefix to append to the created files")
|
||||||
|
.num_args(1),
|
||||||
|
Arg::new("dryrun")
|
||||||
|
.short('u')
|
||||||
|
.long("dryrun")
|
||||||
|
.help("immediately remove created files and directories")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, matches: Option<&clap::ArgMatches>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let Some(matches) = matches else {
|
||||||
|
return Err(io::Error::new(io::ErrorKind::Other, "no input").into());
|
||||||
|
};
|
||||||
|
let mut path = if let Some(t) = matches.get_one::<String>("tmpdir") {
|
||||||
|
PathBuf::from(t)
|
||||||
|
} else {
|
||||||
|
PathBuf::from("/tmp")
|
||||||
|
};
|
||||||
|
let fname = if let Some(p) = matches.get_one::<String>("prefix") {
|
||||||
|
format!("{p}.XXXXXX")
|
||||||
|
} else {
|
||||||
|
"mktemp.XXXXXX".to_string()
|
||||||
|
};
|
||||||
|
path.push(&fname);
|
||||||
|
let fname = path
|
||||||
|
.to_str()
|
||||||
|
.ok_or(io::Error::new(io::ErrorKind::Other, "utf8 error"))?;
|
||||||
|
let cname = CString::new(fname)?;
|
||||||
|
let ptr = cname.into_raw();
|
||||||
|
if matches.get_flag("directory") {
|
||||||
|
let raw_fd = unsafe { libc::mkdtemp(ptr) };
|
||||||
|
if raw_fd.is_null() {
|
||||||
|
return Err(io::Error::last_os_error().into());
|
||||||
|
}
|
||||||
|
let cname = unsafe { CString::from_raw(ptr) };
|
||||||
|
let fname = cname.to_str()?;
|
||||||
|
println!("{fname}");
|
||||||
|
if matches.get_flag("dryrun") {
|
||||||
|
fs::remove_dir(&fname)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let raw_fd = unsafe { libc::mkstemp(ptr) };
|
||||||
|
if raw_fd == -1 {
|
||||||
|
return Err(io::Error::last_os_error().into());
|
||||||
|
}
|
||||||
|
let cname = unsafe { CString::from_raw(ptr) };
|
||||||
|
let fname = cname.to_str()?;
|
||||||
|
println!("{fname}");
|
||||||
|
if matches.get_flag("dryrun") {
|
||||||
|
fs::remove_file(&fname)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> Option<crate::Path> {
|
||||||
|
Some(crate::Path::UsrBin)
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ mod logname;
|
|||||||
mod ls;
|
mod ls;
|
||||||
mod mkfifo;
|
mod mkfifo;
|
||||||
mod mknod;
|
mod mknod;
|
||||||
|
mod mktemp;
|
||||||
mod mountpoint;
|
mod mountpoint;
|
||||||
mod mv;
|
mod mv;
|
||||||
mod nologin;
|
mod nologin;
|
||||||
@ -93,6 +94,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
"logname" => Some(Box::new(logname::Logname::default())),
|
"logname" => Some(Box::new(logname::Logname::default())),
|
||||||
"mkfifo" => Some(Box::new(mkfifo::MkFifo::default())),
|
"mkfifo" => Some(Box::new(mkfifo::MkFifo::default())),
|
||||||
"mknod" => Some(Box::new(mknod::MkNod::default())),
|
"mknod" => Some(Box::new(mknod::MkNod::default())),
|
||||||
|
"mktemp" => Some(Box::new(mktemp::MkTemp::default())),
|
||||||
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
"mountpoint" => Some(Box::new(mountpoint::Mountpoint::default())),
|
||||||
"nologin" => Some(Box::new(nologin::Nologin::default())),
|
"nologin" => Some(Box::new(nologin::Nologin::default())),
|
||||||
"nproc" => Some(Box::new(nproc::Nproc::default())),
|
"nproc" => Some(Box::new(nproc::Nproc::default())),
|
||||||
@ -116,7 +118,7 @@ pub fn get(name: &str) -> Option<Box<dyn Cmd>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static COMMANDS: [&str; 42] = [
|
pub static COMMANDS: [&str; 43] = [
|
||||||
"base32",
|
"base32",
|
||||||
"base64",
|
"base64",
|
||||||
"basename",
|
"basename",
|
||||||
@ -140,6 +142,7 @@ pub static COMMANDS: [&str; 42] = [
|
|||||||
"logname",
|
"logname",
|
||||||
"mkfifo",
|
"mkfifo",
|
||||||
"mknod",
|
"mknod",
|
||||||
|
"mktemp",
|
||||||
"mountpoint",
|
"mountpoint",
|
||||||
"nologin",
|
"nologin",
|
||||||
"nproc",
|
"nproc",
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
use super::Cmd;
|
use super::Cmd;
|
||||||
use crate::bitflags::BitFlags;
|
use crate::bitflags::BitFlags;
|
||||||
use clap::{Arg, ArgMatches, Command, ArgAction};
|
use clap::{Arg, ArgAction, ArgMatches, Command};
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp,
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{self, Write},
|
fmt::{self, Write},
|
||||||
fs,
|
fs,
|
||||||
io::{self, stdin, Read},
|
io::{self, stdin, Read},
|
||||||
ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, AddAssign},
|
ops::{AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,7 +73,9 @@ impl Cmd for Wc {
|
|||||||
name: "Total",
|
name: "Total",
|
||||||
..Values::default()
|
..Values::default()
|
||||||
};
|
};
|
||||||
files.iter().try_for_each(|f| get_values(f, &mut totals, flags))?;
|
files
|
||||||
|
.iter()
|
||||||
|
.try_for_each(|f| get_values(f, &mut totals, flags))?;
|
||||||
if files.len() > 1 {
|
if files.len() > 1 {
|
||||||
totals.print_values(flags)?;
|
totals.print_values(flags)?;
|
||||||
}
|
}
|
||||||
@ -85,7 +87,11 @@ impl Cmd for Wc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_values<'a>(file: &'a str, totals: &mut Values<'a>, flags: u32) -> Result<(), Box<dyn Error>> {
|
fn get_values<'a>(
|
||||||
|
file: &'a str,
|
||||||
|
totals: &mut Values<'a>,
|
||||||
|
flags: u32,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let contents = if file == "-" {
|
let contents = if file == "-" {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
stdin().read_to_string(&mut buf)?;
|
stdin().read_to_string(&mut buf)?;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{bitflags::BitFlags, mode::Bit};
|
|
||||||
use super::Cmd;
|
use super::Cmd;
|
||||||
|
use crate::{bitflags::BitFlags, mode::Bit};
|
||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command};
|
||||||
use std::{env, fs::File, io, os::unix::prelude::MetadataExt, path::PathBuf, process};
|
use std::{env, fs::File, io, os::unix::prelude::MetadataExt, path::PathBuf, process};
|
||||||
|
|
||||||
|
@ -96,4 +96,3 @@ impl Bit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,11 @@ mod parser;
|
|||||||
mod who;
|
mod who;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
pub use {bit::Bit, parser::{ParseError, Parser}, who::Who};
|
pub use {
|
||||||
|
bit::Bit,
|
||||||
|
parser::{ParseError, Parser},
|
||||||
|
who::Who,
|
||||||
|
};
|
||||||
|
|
||||||
/// Gets the umask for the current user
|
/// Gets the umask for the current user
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
use crate::bitflags::BitFlags;
|
|
||||||
use super::{get_umask, Bit, Who};
|
use super::{get_umask, Bit, Who};
|
||||||
use std::{
|
use crate::bitflags::BitFlags;
|
||||||
error,
|
use std::{error, fmt::Display, num::ParseIntError};
|
||||||
fmt::Display,
|
|
||||||
num::ParseIntError,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Errors which might occur when parsing Unix permissions from a string
|
/// Errors which might occur when parsing Unix permissions from a string
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -46,4 +46,3 @@ impl BitOrAssign<Who> for u32 {
|
|||||||
*self = *self | rhs;
|
*self = *self | rhs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user