├── testing ├── empty_file ├── executable_file ├── symlink ├── file_with_text └── multi_line_lang_file ├── .gitignore ├── .gitlab-ci.yml ├── proptest-regressions └── bin │ └── dd.txt ├── README.md ├── src ├── bin │ ├── clear.rs │ ├── reset.rs │ ├── ps.rs │ ├── shutdown.rs │ ├── time.rs │ ├── kill.rs │ ├── which.rs │ ├── uptime.rs │ ├── free.rs │ ├── df.rs │ ├── uname.rs │ └── chown.rs └── lib.rs ├── LICENSE ├── Cargo.toml └── Cargo.lock /testing/empty_file: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /testing/executable_file: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/symlink: -------------------------------------------------------------------------------- 1 | empty_file -------------------------------------------------------------------------------- /testing/file_with_text: -------------------------------------------------------------------------------- 1 | FILE IS NOT EMPTY 2 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: "redoxos/redoxer" 2 | 3 | stages: 4 | - build 5 | - test 6 | 7 | cache: 8 | paths: 9 | - target/ 10 | 11 | build:redox: 12 | stage: build 13 | script: redoxer build --verbose 14 | 15 | test:redox: 16 | stage: test 17 | dependencies: 18 | - build:redox 19 | script: redoxer test --verbose 20 | -------------------------------------------------------------------------------- /testing/multi_line_lang_file: -------------------------------------------------------------------------------- 1 | Hello, 世界. 2 | 3 | This is a file with 4 | several lines and some of them are 5 | 6 | empty or with trailing or…funny spaces. 7 | 8 | Pangrams in different languages: 9 | Жълтата дюля беше щастлива, че пухът, който цъфна, замръзна като гьон. 10 | Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο 11 | いろはにほへとちりぬるを 12 | ? דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה 13 | Pijamalı hasta, yağız şoföre çabucak güvendi. 14 | 15 | 🦀 16 | -------------------------------------------------------------------------------- /proptest-regressions/bin/dd.txt: -------------------------------------------------------------------------------- 1 | # Seeds for failure cases proptest has generated in the past. It is 2 | # automatically read and these particular cases re-run before any 3 | # novel cases are generated. 4 | # 5 | # It is recommended to check this file in to source control so that 6 | # everyone who runs the test benefits from these saved cases. 7 | xs 3557622558 1675326002 1859352426 2755820794 # shrinks to s = 0, b = "b" 8 | xs 3534189441 173085600 1439026548 1986424399 # shrinks to s = 0, b = "," 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Redox OS coreutils 2 | 3 | **DEPRECATED**: This repo is being superseded by [uutils/coreutils](https://github.com/uutils/coreutils). Programs here that don't have counterparts in uutils should be moved to [extrautils](https://gitlab.redox-os.org/dahc/extrautils). 4 | 5 | This repository contains the core UNIX utilities for Redox OS. These are based on BSD coreutils rather than GNU coreutils as these tools should be as minimal as possible. 6 | 7 | **Currently included:** 8 | 9 | - ~~`cat`~~ 10 | - `chown` 11 | - `clear` 12 | - ~~`dd`~~ 13 | - `df` 14 | - `du` 15 | - ~~`env`~~ 16 | - `free` 17 | - `kill` 18 | - ~~`ln`~~ 19 | - ~~`mkdir`~~ 20 | - `ps` 21 | - `reset` 22 | - `shutdown` 23 | - ~~`sort`~~ 24 | - ~~`stat`~~ 25 | - ~~`tail`~~ 26 | - ~~`tee`~~ 27 | - ~~`test`~~ 28 | - `time` 29 | - `touch` 30 | - `uname` 31 | - `uptime` 32 | - `which` 33 | -------------------------------------------------------------------------------- /src/bin/clear.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::{stdout, stderr, Write}; 3 | use std::process::exit; 4 | use arg_parser::ArgParser; 5 | use extra::option::OptionalExt; 6 | 7 | const MAN_PAGE: &'static str = /* @MANSTART{clear} */ r#" 8 | NAME 9 | clear - clear the terminal screen 10 | 11 | SYNOPSIS 12 | clear [ -h | --help] 13 | 14 | DESCRIPTION 15 | Clear the screen, if possible 16 | 17 | OPTIONS 18 | -h 19 | --help 20 | display this help and exit 21 | "#; /* @MANEND */ 22 | 23 | fn main() { 24 | let stdout = stdout(); 25 | let mut stdout = stdout.lock(); 26 | let mut stderr = stderr(); 27 | let mut parser = ArgParser::new(1) 28 | .add_flag(&["h", "help"]); 29 | parser.parse(env::args()); 30 | 31 | if parser.found("help") { 32 | stdout.write_all(MAN_PAGE.as_bytes()).r#try(&mut stderr); 33 | stdout.flush().r#try(&mut stderr); 34 | exit(0); 35 | } 36 | 37 | let _ = stdout.write(b"\x1b[H\x1B[2J"); 38 | } 39 | -------------------------------------------------------------------------------- /src/bin/reset.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::{stdout, stderr, Write}; 3 | use std::process::exit; 4 | use arg_parser::ArgParser; 5 | use extra::option::OptionalExt; 6 | 7 | const MAN_PAGE: &'static str = /* @MANSTART{reset} */ r#" 8 | NAME 9 | reset - terminal initialization 10 | 11 | SYNOPSIS 12 | reset [ -h | --help ] 13 | 14 | DESCRIPTION 15 | Initialize the terminal, clearing the screen and setting all parameters to their default values 16 | 17 | OPTIONS 18 | -h 19 | --help 20 | display this help and exit 21 | "#; /* @MANEND */ 22 | 23 | fn main() { 24 | let stdout = stdout(); 25 | let mut stdout = stdout.lock(); 26 | let mut stderr = stderr(); 27 | let mut parser = ArgParser::new(1) 28 | .add_flag(&["h", "help"]); 29 | parser.parse(env::args()); 30 | 31 | if parser.found("help") { 32 | stdout.write(MAN_PAGE.as_bytes()).r#try(&mut stderr); 33 | stdout.flush().r#try(&mut stderr); 34 | exit(0); 35 | } 36 | 37 | let _ = stdout.write(b"\x1Bc"); 38 | } 39 | -------------------------------------------------------------------------------- /src/bin/ps.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs::File; 3 | use std::io::{stdout, stderr, copy, Write}; 4 | use std::process::exit; 5 | use arg_parser::ArgParser; 6 | use extra::option::OptionalExt; 7 | 8 | const MAN_PAGE: &'static str = /* @MANSTART{ps} */ r#" 9 | NAME 10 | ps - report a snapshot of the current processes 11 | 12 | SYNOPSIS 13 | ps [ -h | --help] 14 | 15 | DESCRIPTION 16 | Displays information about processes and threads that are currently active 17 | 18 | OPTIONS 19 | -h 20 | --help 21 | display this help and exit 22 | "#; /* @MANEND */ 23 | 24 | fn main() { 25 | let stdout = stdout(); 26 | let mut stdout = stdout.lock(); 27 | let mut stderr = stderr(); 28 | let mut parser = ArgParser::new(1) 29 | .add_flag(&["h", "help"]); 30 | parser.parse(env::args()); 31 | 32 | if parser.found("help") { 33 | stdout.write(MAN_PAGE.as_bytes()).r#try(&mut stderr); 34 | stdout.flush().r#try(&mut stderr); 35 | exit(0); 36 | } 37 | 38 | let mut file = File::open("/scheme/sys/context").r#try(&mut stderr); 39 | copy(&mut file, &mut stdout).r#try(&mut stderr); 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2017 The Redox developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/bin/shutdown.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::{stdout, Write}; 3 | use arg_parser::ArgParser; 4 | 5 | const MAN_PAGE: &'static str = /* @MANSTART{shutdown} */ r#" 6 | NAME 7 | shutdown - stop the system 8 | 9 | SYNOPSIS 10 | shutdown [ -h | --help ] [ -r | --reboot ] 11 | 12 | DESCRIPTION 13 | Attempt to shutdown the system using ACPI. Failure will be logged to the terminal 14 | 15 | OPTIONS 16 | -h 17 | --help 18 | display this help and exit 19 | 20 | -r 21 | --reboot 22 | reboot instead of powering off 23 | "#; /* @MANEND */ 24 | 25 | fn main() -> anyhow::Result<()> { 26 | let stdout = stdout(); 27 | let mut stdout = stdout.lock(); 28 | let mut parser = ArgParser::new(1) 29 | .add_flag(&["h", "help"]) 30 | .add_flag(&["r", "reboot"]); 31 | parser.parse(env::args()); 32 | 33 | if parser.found("help") { 34 | stdout.write(MAN_PAGE.as_bytes())?; 35 | stdout.flush()?; 36 | return Ok(()); 37 | } 38 | 39 | shutdown(parser.found("reboot"))?; 40 | Ok(()) 41 | } 42 | 43 | #[cfg(target_os = "redox")] 44 | fn shutdown(reboot: bool) -> anyhow::Result<()> { 45 | let message = if reboot { 46 | "reset" 47 | } else { 48 | "shutdown" 49 | }; 50 | std::fs::write("/scheme/sys/kstop", message.as_bytes())?; 51 | Ok(()) 52 | } 53 | 54 | #[cfg(not(target_os = "redox"))] 55 | fn shutdown(_reboot: bool) -> anyhow::Result<()> { 56 | unimplemented!("This program only works on Redox at present."); 57 | } 58 | -------------------------------------------------------------------------------- /src/bin/time.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::{stdout, stderr, Write}; 3 | use std::process::{exit, Command}; 4 | use std::time::Instant; 5 | use arg_parser::ArgParser; 6 | use extra::option::OptionalExt; 7 | 8 | const MAN_PAGE: &'static str = /* @MANSTART{time} */ r#" 9 | NAME 10 | time - timer for commands 11 | 12 | SYNOPSIS 13 | time [ -h | --help ][COMMAND] [ARGUEMENT]... 14 | 15 | DESCRIPTION 16 | Runs the command taken as the first arguement and outputs the time the command took to execute. 17 | 18 | OPTIONS 19 | -h 20 | --help 21 | display this help and exit 22 | "#; /* @MANEND */ 23 | 24 | fn main() { 25 | let stdout = stdout(); 26 | let mut stdout = stdout.lock(); 27 | let mut stderr = stderr(); 28 | let mut parser = ArgParser::new(1) 29 | .add_flag(&["h", "help"]); 30 | parser.parse(env::args()); 31 | 32 | if parser.found("help") { 33 | stdout.write(MAN_PAGE.as_bytes()).r#try(&mut stderr); 34 | stdout.flush().r#try(&mut stderr); 35 | exit(0); 36 | } 37 | 38 | let time = Instant::now(); 39 | 40 | if !parser.args.is_empty() { 41 | let mut command = Command::new(&parser.args[0]); 42 | for arg in &parser.args[1..] { 43 | command.arg(arg); 44 | } 45 | command.spawn().r#try(&mut stderr).wait().r#try(&mut stderr); 46 | } 47 | 48 | let duration = time.elapsed(); 49 | stdout.write(&format!("{}m{:.3}s\n", duration.as_secs() / 60, 50 | (duration.as_secs()%60) as f64 + (duration.subsec_nanos() as f64)/1000000000.0) 51 | .as_bytes()).r#try(&mut stderr); 52 | } 53 | -------------------------------------------------------------------------------- /src/bin/kill.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | #[cfg(target_os = "redox")] 4 | fn main() -> Result<()> { 5 | use std::env; 6 | use std::io::{stdout, Write}; 7 | use anyhow::{bail, Context}; 8 | use arg_parser::ArgParser; 9 | 10 | const MAN_PAGE: &'static str = /* @MANSTART{kill} */ r#" 11 | NAME 12 | kill - send a signal 13 | 14 | SYNOPSIS 15 | kill [ -h | --help ] MODE PID... 16 | 17 | DESCRIPTION 18 | The kill utility sends a signal to a process. Multiple PIDs can be passed. 19 | 20 | OPTIONS 21 | --help, -h 22 | print this message 23 | "#; /* @MANEND */ 24 | 25 | let stdout = stdout(); 26 | let mut stdout = stdout.lock(); 27 | let mut parser = ArgParser::new(1) 28 | .add_flag(&["h", "help"]); 29 | parser.parse(env::args()); 30 | 31 | if parser.found("help") { 32 | stdout.write_all(MAN_PAGE.as_bytes())?; 33 | stdout.flush()?; 34 | return Ok(()); 35 | } 36 | 37 | let Some(sig_arg) = parser.args.get(0) else { 38 | bail!("No signal. Use --help to see the usage."); 39 | }; 40 | let sig = sig_arg.parse::().context("Failed to parse signal")?; 41 | if sig > 0x7F { 42 | bail!("Signal greater than 127. Use --help to see the usage."); 43 | } 44 | if parser.args.is_empty() { 45 | bail!("No pids. Use --help to see the usage."); 46 | } 47 | 48 | for pid_str in &parser.args[1..] { 49 | let pid = pid_str.parse::()?; 50 | libredox::call::kill(pid, sig)?; 51 | } 52 | Ok(()) 53 | } 54 | 55 | #[cfg(not(target_os = "redox"))] 56 | fn main() -> Result<()> { 57 | Err(anyhow::anyhow!("error: unimplemented outside redox")) 58 | } 59 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Polymetric ", 3 | "Łukasz Jan Niemier ", 4 | "Jeremy Soller ", 5 | "Ticki ", 6 | "Michael Murphy "] 7 | name = "coreutils" 8 | version = "0.1.0" 9 | edition = "2021" 10 | autobins = false 11 | 12 | [dependencies] 13 | anyhow = "1" 14 | arg_parser = { git = "https://gitlab.redox-os.org/redox-os/arg-parser.git" } 15 | extra = { git = "https://gitlab.redox-os.org/redox-os/libextra.git" } 16 | termion = "4" 17 | # https://github.com/alexcrichton/filetime/pull/104 18 | filetime = { git = "https://github.com/jackpot51/filetime.git" } 19 | redox_users = "0.4.5" 20 | walkdir = "2.2.7" 21 | time = "0.1.42" 22 | base64 = "0.10.1" 23 | num = "0.2.0" 24 | failure = "0.1.5" 25 | failure_derive = "0.1.5" 26 | libredox = "0.1" 27 | 28 | [dev-dependencies] 29 | proptest = "0.9.2" 30 | 31 | [lib] 32 | path = "src/lib.rs" 33 | 34 | [[bin]] 35 | name = "chown" 36 | path = "src/bin/chown.rs" 37 | 38 | [[bin]] 39 | name = "clear" 40 | path = "src/bin/clear.rs" 41 | 42 | [[bin]] 43 | name = "df" 44 | path = "src/bin/df.rs" 45 | 46 | [[bin]] 47 | name = "free" 48 | path = "src/bin/free.rs" 49 | 50 | [[bin]] 51 | name = "kill" 52 | path = "src/bin/kill.rs" 53 | 54 | [[bin]] 55 | name = "ps" 56 | path = "src/bin/ps.rs" 57 | 58 | [[bin]] 59 | name = "reset" 60 | path = "src/bin/reset.rs" 61 | 62 | [[bin]] 63 | name = "shutdown" 64 | path = "src/bin/shutdown.rs" 65 | 66 | [[bin]] 67 | name = "time" 68 | path = "src/bin/time.rs" 69 | 70 | [[bin]] 71 | name = "uname" 72 | path = "src/bin/uname.rs" 73 | 74 | [[bin]] 75 | name = "uptime" 76 | path = "src/bin/uptime.rs" 77 | 78 | [[bin]] 79 | name = "which" 80 | path = "src/bin/which.rs" 81 | -------------------------------------------------------------------------------- /src/bin/which.rs: -------------------------------------------------------------------------------- 1 | use arg_parser::ArgParser; 2 | use extra::option::OptionalExt; 3 | use std::env; 4 | use std::io::{stderr, stdout, Write}; 5 | use std::process::{exit, ExitCode}; 6 | 7 | const MAN_PAGE: &'static str = r#" 8 | NAME 9 | which - locate a command 10 | SYNOPSIS 11 | which [ -h | --help ] 12 | DESCRIPTION 13 | which prints the full path of shell commands 14 | OPTIONS 15 | -h 16 | --help 17 | Print this manual page. 18 | "#; /* @MANEND */ 19 | 20 | fn main() -> ExitCode { 21 | let mut not_found_count = 0; 22 | let stdout = stdout(); 23 | let mut stdout = stdout.lock(); 24 | let mut stderr = stderr(); 25 | let mut parser = ArgParser::new(1).add_flag(&["h", "help"]); 26 | parser.parse(env::args()); 27 | 28 | if parser.found("help") { 29 | stdout.write(MAN_PAGE.as_bytes()).r#try(&mut stderr); 30 | stdout.flush().r#try(&mut stderr); 31 | exit(0); 32 | } 33 | 34 | if parser.args.is_empty() { 35 | stderr 36 | .write(b"Please provide a program name\n") 37 | .r#try(&mut stderr); 38 | stderr.flush().r#try(&mut stderr); 39 | exit(1); 40 | } 41 | 42 | let paths = env::var("PATH").unwrap(); 43 | 44 | for program in parser.args.iter() { 45 | let mut executable_path = None; 46 | 47 | for mut path in env::split_paths(&paths) { 48 | path.push(program); 49 | if path.exists() { 50 | executable_path = Some(path); 51 | break; 52 | } 53 | } 54 | 55 | if let Some(path) = executable_path { 56 | let _ = writeln!(stdout, "{}", path.display()); 57 | } else { 58 | let _ = writeln!(stderr, "{} not found", program); 59 | not_found_count += 1; 60 | } 61 | } 62 | if not_found_count == 0 { 63 | ExitCode::SUCCESS 64 | } else { 65 | ExitCode::from(not_found_count) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/bin/uptime.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, Write}; 2 | use anyhow::{Context, Result}; 3 | use arg_parser::ArgParser; 4 | use std::fmt::Write as FmtWrite; 5 | use std::env; 6 | #[cfg(not(target_os = "redox"))] 7 | use std::fs; 8 | 9 | const MAN_PAGE: &'static str = /* @MANSTART{uptime} */ r#" 10 | NAME 11 | uptime - show how long the system has been running 12 | 13 | SYNOPSIS 14 | uptime [ -h | --help] [offset] 15 | 16 | DESCRIPTION 17 | Prints the length of time the system has been up. 18 | 19 | OPTIONS 20 | -h 21 | --help 22 | display this help and exit 23 | "#; /* @MANEND */ 24 | 25 | const SECONDS_PER_MINUTE: i64 = 60; 26 | const SECONDS_PER_HOUR: i64 = 3600; 27 | const SECONDS_PER_DAY: i64 = 86400; 28 | 29 | #[cfg(target_os = "redox")] 30 | fn uptime() -> Result { 31 | let ts = libredox::call::clock_gettime(libredox::flag::CLOCK_MONOTONIC)?; 32 | Ok(ts.tv_sec) 33 | } 34 | 35 | #[cfg(target_os = "linux")] 36 | fn uptime() -> Result { 37 | Ok(fs::read_to_string("/proc/uptime")?.split('.').nth(0).unwrap().parse()?) 38 | } 39 | 40 | fn main() -> Result<()> { 41 | let stdout = io::stdout(); 42 | let mut stdout = stdout.lock(); 43 | 44 | let mut parser = ArgParser::new(1) 45 | .add_flag(&["h", "help"]); 46 | parser.parse(env::args()); 47 | 48 | if parser.found("help") { 49 | stdout.write(MAN_PAGE.as_bytes())?; 50 | stdout.flush()?; 51 | return Ok(()); 52 | } 53 | 54 | let uptime = uptime()?; 55 | let uptime_secs = uptime % 60; 56 | let uptime_mins = (uptime / SECONDS_PER_MINUTE) % 60; 57 | let uptime_hours = (uptime / SECONDS_PER_HOUR) % 24; 58 | let uptime_days = uptime / SECONDS_PER_DAY; 59 | 60 | let mut uptime_str = String::new(); 61 | let fmt_result; 62 | if uptime_days > 0 { 63 | fmt_result = write!(&mut uptime_str, "{}d {}h {}m {}s\n", uptime_days, 64 | uptime_hours, uptime_mins, uptime_secs); 65 | } else if uptime_hours > 0 { 66 | fmt_result = write!(&mut uptime_str, "{}h {}m {}s\n", uptime_hours, 67 | uptime_mins, uptime_secs); 68 | } else if uptime_mins > 0 { 69 | fmt_result = write!(&mut uptime_str, "{}m {}s\n", uptime_mins, 70 | uptime_secs); 71 | } else { 72 | fmt_result = write!(&mut uptime_str, "{}s\n", uptime_secs); 73 | } 74 | 75 | fmt_result.context("failed to parse uptime")?; 76 | stdout.write_all(uptime_str.as_bytes())?; 77 | Ok(()) 78 | } 79 | -------------------------------------------------------------------------------- /src/bin/free.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | #[cfg(target_os = "redox")] 4 | fn free(parser: &arg_parser::ArgParser) -> Result<()> { 5 | use anyhow::Context; 6 | use coreutils::to_human_readable_string; 7 | use libredox::{Fd, flag}; 8 | 9 | let stat = Fd::open("/scheme/memory", flag::O_PATH, 0) 10 | .context("failed to open `/scheme/memory`")? 11 | .statvfs() 12 | .context("failed to fstatvfs `/scheme/memory`")?; 13 | 14 | let size = stat.f_blocks as u64 * stat.f_bsize as u64; 15 | let used = (stat.f_blocks as u64 - stat.f_bfree as u64) * stat.f_bsize as u64; 16 | let free = stat.f_bavail as u64 * stat.f_bsize as u64; 17 | 18 | if parser.found("human-readable") { 19 | println!("{:<8}{:>10}{:>10}{:>10}", 20 | "Mem:", 21 | to_human_readable_string(size), 22 | to_human_readable_string(used), 23 | to_human_readable_string(free)); 24 | } else { 25 | println!("{:<8}{:>10}{:>10}{:>10}", 26 | "Mem:", 27 | (size + 1023)/1024, 28 | (used + 1023)/1024, 29 | (free + 1023)/1024); 30 | } 31 | 32 | Ok(()) 33 | } 34 | 35 | #[cfg(target_os = "redox")] 36 | fn main() -> Result<()> { 37 | use std::env; 38 | use std::io::{stdout, Write}; 39 | use std::process::exit; 40 | use arg_parser::ArgParser; 41 | 42 | const MAN_PAGE: &'static str = /* @MANSTART{free} */ r#" 43 | NAME 44 | free - view memory usage 45 | 46 | SYNOPSIS 47 | free [ -h | --help ] 48 | 49 | DESCRIPTION 50 | free displays the current memory usage of the system 51 | 52 | OPTIONS 53 | -h 54 | --human-readable 55 | human readable output 56 | --help 57 | display this help and exit 58 | "#; /* @MANEND */ 59 | 60 | let mut parser = ArgParser::new(1) 61 | .add_flag(&["h", "human-readable"]) 62 | .add_flag(&["help"]); 63 | parser.parse(env::args()); 64 | 65 | if parser.found("help") { 66 | let stdout = stdout(); 67 | let mut stdout = stdout.lock(); 68 | stdout.write(MAN_PAGE.as_bytes())?; 69 | stdout.flush()?; 70 | exit(0); 71 | } 72 | 73 | println!("{:<8}{:>10}{:>10}{:>10}", "", "total", "used", "free"); 74 | free(&parser)?; 75 | Ok(()) 76 | } 77 | 78 | #[cfg(not(target_os = "redox"))] 79 | fn main() -> Result<()> { 80 | Err(anyhow::anyhow!("error: unimplemented outside redox")) 81 | } 82 | -------------------------------------------------------------------------------- /src/bin/df.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | #[cfg(target_os = "redox")] 4 | fn df(path: &str, parser: &arg_parser::ArgParser) -> Result<()> { 5 | use coreutils::to_human_readable_string; 6 | use libredox::{Fd, flag}; 7 | 8 | let stat = Fd::open(path, flag::O_PATH, 0)?.statvfs()?; 9 | 10 | let size = stat.f_blocks as u64 * stat.f_bsize as u64; 11 | let used = (stat.f_blocks as u64 - stat.f_bfree as u64) * stat.f_bsize as u64; 12 | let free = stat.f_bavail as u64 * stat.f_bsize as u64; 13 | let percent = (100.0 * used as f64 / size as f64) as u64; 14 | 15 | if parser.found("human-readable") { 16 | println!("{:<10}{:>10}{:>10}{:>10}{:>5}", 17 | path, 18 | to_human_readable_string(size), 19 | to_human_readable_string(used), 20 | to_human_readable_string(free), 21 | format!("{}%", percent)); 22 | } else { 23 | println!("{:<10}{:>10}{:>10}{:>10}{:>5}", 24 | path, 25 | (size + 1023)/1024, 26 | (used + 1023)/1024, 27 | (free + 1023)/1024, 28 | format!("{}%", percent)); 29 | } 30 | 31 | Ok(()) 32 | } 33 | 34 | #[cfg(target_os = "redox")] 35 | fn main() -> Result<()> { 36 | use std::env; 37 | use std::fs::File; 38 | use std::io::{stdout, BufRead, BufReader, Write}; 39 | use std::process::exit; 40 | use arg_parser::ArgParser; 41 | 42 | const MAN_PAGE: &'static str = /* @MANSTART{df} */ r#" 43 | NAME 44 | df - view filesystem space usage 45 | 46 | SYNOPSIS 47 | df [ -h | --help ] FILE... 48 | 49 | DESCRIPTION 50 | df gets the filesystem space usage for the filesystem providing FILE 51 | 52 | OPTIONS 53 | -h 54 | --human-readable 55 | human readable output 56 | --help 57 | display this help and exit 58 | "#; /* @MANEND */ 59 | 60 | let mut parser = ArgParser::new(1) 61 | .add_flag(&["h", "human-readable"]) 62 | .add_flag(&["help"]); 63 | parser.parse(env::args()); 64 | 65 | if parser.found("help") { 66 | let stdout = stdout(); 67 | let mut stdout = stdout.lock(); 68 | stdout.write(MAN_PAGE.as_bytes())?; 69 | stdout.flush()?; 70 | exit(0); 71 | } 72 | 73 | println!("{:<10}{:>10}{:>10}{:>10}{:>5}", "Path", "Size", "Used", "Free", "Use%"); 74 | if parser.args.is_empty() { 75 | let file = BufReader::new(File::open("/scheme/sys/scheme")?); 76 | for line in file.lines() { 77 | let _ = df(&format!("/scheme/{}", line?), &parser); 78 | } 79 | } else { 80 | for path in &parser.args { 81 | df(&path, &parser)?; 82 | } 83 | } 84 | Ok(()) 85 | } 86 | 87 | #[cfg(not(target_os = "redox"))] 88 | fn main() -> Result<()> { 89 | Err(anyhow::anyhow!("error: unimplemented outside redox")) 90 | } 91 | -------------------------------------------------------------------------------- /src/bin/uname.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, Write}; 2 | use std::env; 3 | use std::process; 4 | use std::fs::File; 5 | use arg_parser::ArgParser; 6 | use extra::option::OptionalExt; 7 | use std::io::Read; 8 | 9 | const MAN_PAGE: &'static str = /* @MANSTART{uname} */ r#" 10 | NAME 11 | uname - print system information 12 | 13 | SYNOPSIS 14 | uname [-a] [-m] [-n] [-r] [-s] [-v] 15 | 16 | DESCRIPTION 17 | Print system information. 18 | 19 | OPTIONS 20 | -a 21 | print all 22 | 23 | -m 24 | machine 25 | 26 | -n 27 | nodename 28 | 29 | -r 30 | release 31 | 32 | -s 33 | kernel name 34 | 35 | -v 36 | version 37 | 38 | -h 39 | --help 40 | display this help and exit 41 | "#; /* @MANEND */ 42 | 43 | fn main() { 44 | let stdout = io::stdout(); 45 | let mut stdout = stdout.lock(); 46 | let mut stderr = io::stderr(); 47 | let mut parser = ArgParser::new(7) 48 | .add_flag(&["a", "all"]) 49 | .add_flag(&["m", "machine"]) 50 | .add_flag(&["n", "nodename"]) 51 | .add_flag(&["r", "kernel-release"]) 52 | .add_flag(&["s", "kernel-name"]) 53 | .add_flag(&["v", "kernel-version"]) 54 | .add_flag(&["h", "help"]); 55 | parser.parse(env::args()); 56 | 57 | if parser.found("help") { 58 | stdout.write(MAN_PAGE.as_bytes()).r#try(&mut stderr); 59 | stdout.flush().r#try(&mut stderr); 60 | process::exit(0); 61 | } 62 | 63 | if parser.found("all") { 64 | *parser.flag("machine") = true; 65 | *parser.flag("nodename") = true; 66 | *parser.flag("kernel-release") = true; 67 | *parser.flag("kernel-name") = true; 68 | *parser.flag("kernel-version") = true; 69 | } else if !(parser.found("machine") || parser.found("nodename") 70 | || parser.found("kernel-release") || parser.found("kernel-name") 71 | || parser.found("kernel-version")) { 72 | *parser.flag("kernel-name") = true; 73 | } 74 | 75 | let mut file = File::open("/scheme/sys/uname").unwrap(); 76 | let mut uname_str = String::new(); 77 | file.read_to_string(&mut uname_str).unwrap(); 78 | let mut lines = uname_str.lines(); 79 | 80 | let mut uname = Vec::new(); 81 | 82 | let kernel = lines.next().unwrap(); 83 | if parser.found("kernel-name") { 84 | uname.push(kernel); 85 | } 86 | let nodename = lines.next().unwrap(); 87 | if parser.found("nodename") { 88 | uname.push(nodename); 89 | } 90 | let release = lines.next().unwrap(); 91 | if parser.found("kernel-release") { 92 | uname.push(release); 93 | } 94 | let version = lines.next().unwrap(); 95 | if parser.found("kernel-version") { 96 | uname.push(version); 97 | } 98 | let machine = lines.next().unwrap(); 99 | if parser.found("machine") { 100 | uname.push(machine); 101 | } 102 | 103 | let _ = writeln!(stdout, "{}", uname.join(" ")); 104 | } 105 | -------------------------------------------------------------------------------- /src/bin/chown.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::io::{self, Write}; 3 | use std::process::exit; 4 | use anyhow::Result; 5 | use arg_parser::ArgParser; 6 | #[cfg(target_os = "redox")] 7 | use libredox::{Fd, flag}; 8 | #[cfg(not(target_os = "redox"))] 9 | use std::os::unix::fs; 10 | 11 | const MAN_PAGE: &'static str = /* @MANSTART{chown} */ r#" 12 | NAME 13 | chown - set user and/or group ownership of a file 14 | 15 | SYNOPSIS 16 | chown [-h | --help] [OWNER][:[GROUP]] FILE... 17 | 18 | DESCRIPTION 19 | Set the user and/or group ownership of a file 20 | 21 | EXAMPLE 22 | chown 1000:1000 file 23 | 24 | OPTIONS 25 | -h 26 | --help 27 | display this help and exit 28 | 29 | AUTHOR 30 | Written by Jeremy Soller. 31 | "#; /* @MANEND */ 32 | 33 | const MISSING_OPERAND: &'static str = "missing operand\n"; 34 | const HELP_INFO: &'static str = "Try 'chown --help' for more information.\n"; 35 | 36 | #[cfg(not(target_os = "redox"))] 37 | fn chown(path: &str, uid: u32, gid: u32) -> Result<()> { 38 | fs::chown(path, Some(uid), Some(gid))?; 39 | Ok(()) 40 | } 41 | 42 | #[cfg(target_os = "redox")] 43 | fn chown(path: &str, uid: u32, gid: u32) -> Result<()> { 44 | Fd::open(path, flag::O_PATH, 0)?.chown(uid, gid)?; 45 | Ok(()) 46 | } 47 | 48 | fn main() -> Result<()> { 49 | let stdout = io::stdout(); 50 | let mut stdout = stdout.lock(); 51 | let mut stderr = io::stderr(); 52 | let mut parser = ArgParser::new(1) 53 | .add_flag(&["h", "help"]); 54 | parser.parse(env::args()); 55 | 56 | if parser.found("help") { 57 | stdout.write(MAN_PAGE.as_bytes())?; 58 | stdout.flush()?; 59 | return Ok(()); 60 | } 61 | 62 | if parser.args.len() >= 2 { 63 | let mut args = parser.args.iter(); 64 | 65 | let arg = args.next().unwrap(); 66 | 67 | let mut parts = arg.splitn(2, ":"); 68 | 69 | let uid = if let Some(part) = parts.next() { 70 | if part.is_empty() { 71 | -1i32 as u32 72 | } else { 73 | match part.parse() { 74 | Ok(id) => id, 75 | Err(err) => { 76 | let _ = writeln!(stderr, "chown: failed to parse uid {}: {}", part, err); 77 | exit(1); 78 | } 79 | } 80 | } 81 | } else { 82 | -1i32 as u32 83 | }; 84 | 85 | let gid = if let Some(part) = parts.next() { 86 | if part.is_empty() { 87 | -1i32 as u32 88 | } else { 89 | match part.parse() { 90 | Ok(id) => id, 91 | Err(err) => { 92 | let _ = writeln!(stderr, "chown: failed to parse gid {}: {}", part, err); 93 | exit(1); 94 | } 95 | } 96 | } 97 | } else { 98 | -1i32 as u32 99 | }; 100 | 101 | for arg in args { 102 | if let Err(err) = chown(arg, uid, gid) { 103 | let _ = writeln!(stderr, "chown: failed to set uid and gid of {} to {} and {}: {}", arg, uid, gid, err); 104 | exit(1); 105 | } 106 | } 107 | Ok(()) 108 | } else { 109 | stderr.write(MISSING_OPERAND.as_bytes())?; 110 | stderr.write(HELP_INFO.as_bytes())?; 111 | stderr.flush()?; 112 | exit(1) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::time::{SystemTime, UNIX_EPOCH}; 2 | 3 | pub mod columns { 4 | extern crate extra; 5 | use std::cmp::max; 6 | use std::cmp::min; 7 | use std::io::{stdout, stderr, Write, BufWriter}; 8 | use self::extra::option::OptionalExt; 9 | 10 | /// Prints a vector of strings in a table-like way to the terminal 11 | pub fn print_columns(words: Vec) { 12 | let stdout = stdout(); 13 | let mut stdout = BufWriter::new(stdout.lock()); 14 | let mut stderr = stderr(); 15 | 16 | let terminal_size = termion::terminal_size().unwrap().0 as usize; 17 | let columned = make_columns(words, terminal_size); 18 | for i in 0..columned[0].len() { 19 | for j in 0..columned.len() { 20 | if i < columned[j].len() { 21 | stdout.write(columned[j][i].as_bytes()).r#try(&mut stderr); 22 | } 23 | } 24 | stdout.write("\n".as_bytes()).r#try(&mut stderr); 25 | } 26 | stdout.flush().r#try(&mut stderr); 27 | } 28 | 29 | 30 | /// Turns the list of words into this: line> 31 | fn make_columns(mut words: Vec, terminal_width: usize) -> Vec> { 32 | 33 | let word_lengths: Vec = 34 | words.iter().map(|x: &String| -> usize {(&x).len() + 2}).collect(); 35 | 36 | let columns_amt = bin_search( word_lengths.iter().fold(0 , |x, y| {min(x, *y)}) 37 | , word_lengths.iter().fold(1000, |x, y| {max(x, *y)}) 38 | , &word_lengths 39 | , terminal_width); 40 | 41 | let longest_words: Vec = 42 | split_into_columns( &word_lengths 43 | , columns_amt 44 | , (words.len() / columns_amt) + 1 45 | ).iter().map(longest_word).collect(); 46 | 47 | let mut words_with_space: Vec = Vec::new(); 48 | let lines_amt = (words.len() / columns_amt) + 1; 49 | let mut longest_words_rep = Vec::new(); 50 | for longest_word in longest_words { 51 | for _ in 0..lines_amt { 52 | longest_words_rep.push(longest_word.clone()); 53 | } 54 | } 55 | 56 | for i in 0..words.len() { 57 | 58 | let whitespace = " ".repeat(longest_words_rep[i] - words[i].len()); 59 | words[i].push_str(whitespace.as_str()); 60 | words_with_space.push(words[i].clone()); 61 | } 62 | 63 | split_into_columns::(&words_with_space, columns_amt, (words.len() / columns_amt) + 1) 64 | } 65 | 66 | /// Binary search to find the perfect amounth of columns efficiently 67 | fn bin_search(min: usize, max: usize, words: &Vec, terminal_width: usize) -> usize { 68 | let diff = min as isize - max as isize; 69 | let fits = try_rows(words, min + (max - min) / 2, terminal_width); 70 | if diff == -1 || diff == 0 || diff == 1{ 71 | return min; 72 | } else if fits { 73 | return bin_search(min + (max - min) / 2, max, words, terminal_width); 74 | } else { 75 | return bin_search(min, min + (max - min) / 2, words, terminal_width); 76 | } 77 | } 78 | 79 | /// Find the length of the longest word in a list 80 | fn longest_word(words: &Vec) -> usize { 81 | words.iter().fold(0, |x, y| {max(x, *y)}) 82 | } 83 | 84 | /// splits a vector of cloneables into a vector of vectors of cloneables where lines_amt 85 | /// is the length of the outer vector and columns the max len of the inner vector 86 | fn split_into_columns(words: &Vec, columns: usize, lines_amt: usize) -> Vec> { 87 | assert!(words.len() <= columns * lines_amt); 88 | let mut outputs: Vec> = Vec::new(); 89 | for _ in 0..columns { 90 | outputs.push(Vec::new()) 91 | } 92 | let mut i = 0; 93 | 'outer: for output in &mut outputs { 94 | let mut j = 0; 95 | while j < lines_amt { 96 | if i >= words.len() { 97 | break 'outer; 98 | } 99 | output.push(words.get(i).unwrap().clone()); 100 | i += 1; 101 | j += 1; 102 | } 103 | } 104 | outputs 105 | } 106 | 107 | /// Tests wheter a vector of words, split into a certain number of columns fits into given width 108 | fn try_rows(input: &Vec, columns: usize, width: usize) -> bool { 109 | 110 | let lines_amt = (input.len() / columns) + 1; 111 | 112 | let sum_line_widths = |widths_list: Vec| -> usize { 113 | widths_list.iter().fold(0, |x, y| { x + *y}) 114 | }; 115 | 116 | sum_line_widths( 117 | split_into_columns(input, columns, lines_amt).iter().map( 118 | longest_word 119 | ).collect() 120 | ) <= width 121 | } 122 | } 123 | 124 | pub fn format_system_time(time: SystemTime) -> String { 125 | let tz_offset = 0; //TODO Apply timezone offset 126 | match time.duration_since(UNIX_EPOCH) { 127 | Ok(duration) => format_time(duration.as_secs() as i64, tz_offset), 128 | Err(_) => "duration since epoch err".to_string(), 129 | } 130 | } 131 | 132 | // Sweet algorithm from http://ptspts.blogspot.com/2009/11/how-to-convert-unix-timestamp-to-civil.html 133 | // TODO: Apply timezone offset 134 | pub fn get_time_tuple(mut ts: i64, tz_offset: i64) -> (i64, i64, i64, i64, i64, i64) { 135 | ts += tz_offset * 3600; 136 | let s = ts % 86400; 137 | ts /= 86400; 138 | let h = s / 3600; 139 | let m = s / 60 % 60; 140 | let s = s % 60; 141 | let x = (ts * 4 + 102032) / 146097 + 15; 142 | let b = ts + 2442113 + x - (x / 4); 143 | let mut c = (b * 20 - 2442) / 7305; 144 | let d = b - 365 * c - c / 4; 145 | let mut e = d * 1000 / 30601; 146 | let f = d - e * 30 - e * 601 / 1000; 147 | if e < 14 { 148 | c -= 4716; 149 | e -= 1; 150 | } else { 151 | c -= 4715; 152 | e -= 13; 153 | } 154 | (c, e, f, h, m, s) 155 | } 156 | 157 | pub fn format_time(ts: i64, tz_offset: i64) -> String { 158 | let (c, e, f, h, m, s) = get_time_tuple(ts, tz_offset); 159 | format!("{:>04}-{:>02}-{:>02} {:>02}:{:>02}:{:>02}", c, e, f, h, m, s) 160 | } 161 | 162 | pub fn to_human_readable_string(size: u64) -> String { 163 | if size < 1024 { 164 | return format!("{}", size); 165 | } 166 | 167 | static UNITS: [&'static str; 7] = ["", "K", "M", "G", "T", "P", "E"]; 168 | 169 | let sizef = size as f64; 170 | let digit_groups = (sizef.log10() / 1024f64.log10()) as i32; 171 | format!("{:.1}{}", 172 | sizef / 1024f64.powf(digit_groups as f64), 173 | UNITS[digit_groups as usize]) 174 | } 175 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "anyhow" 22 | version = "1.0.89" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" 25 | 26 | [[package]] 27 | name = "arg_parser" 28 | version = "0.1.0" 29 | source = "git+https://gitlab.redox-os.org/redox-os/arg-parser.git#1c434b55f3e1a0375ebcca85b3e88db7378e82fa" 30 | 31 | [[package]] 32 | name = "arrayref" 33 | version = "0.3.9" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" 36 | 37 | [[package]] 38 | name = "arrayvec" 39 | version = "0.5.2" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 42 | 43 | [[package]] 44 | name = "autocfg" 45 | version = "0.1.8" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" 48 | dependencies = [ 49 | "autocfg 1.4.0", 50 | ] 51 | 52 | [[package]] 53 | name = "autocfg" 54 | version = "1.4.0" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 57 | 58 | [[package]] 59 | name = "backtrace" 60 | version = "0.3.74" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 63 | dependencies = [ 64 | "addr2line", 65 | "cfg-if", 66 | "libc", 67 | "miniz_oxide", 68 | "object", 69 | "rustc-demangle", 70 | "windows-targets", 71 | ] 72 | 73 | [[package]] 74 | name = "base64" 75 | version = "0.10.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 78 | dependencies = [ 79 | "byteorder", 80 | ] 81 | 82 | [[package]] 83 | name = "base64" 84 | version = "0.13.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 87 | 88 | [[package]] 89 | name = "bit-set" 90 | version = "0.5.3" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" 93 | dependencies = [ 94 | "bit-vec", 95 | ] 96 | 97 | [[package]] 98 | name = "bit-vec" 99 | version = "0.6.3" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" 102 | 103 | [[package]] 104 | name = "bitflags" 105 | version = "1.3.2" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 108 | 109 | [[package]] 110 | name = "bitflags" 111 | version = "2.6.0" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 114 | 115 | [[package]] 116 | name = "blake2b_simd" 117 | version = "0.5.11" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" 120 | dependencies = [ 121 | "arrayref", 122 | "arrayvec", 123 | "constant_time_eq", 124 | ] 125 | 126 | [[package]] 127 | name = "byteorder" 128 | version = "1.5.0" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 131 | 132 | [[package]] 133 | name = "cfg-if" 134 | version = "1.0.0" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 137 | 138 | [[package]] 139 | name = "cloudabi" 140 | version = "0.0.3" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 143 | dependencies = [ 144 | "bitflags 1.3.2", 145 | ] 146 | 147 | [[package]] 148 | name = "constant_time_eq" 149 | version = "0.1.5" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 152 | 153 | [[package]] 154 | name = "coreutils" 155 | version = "0.1.0" 156 | dependencies = [ 157 | "anyhow", 158 | "arg_parser", 159 | "base64 0.10.1", 160 | "extra", 161 | "failure", 162 | "failure_derive", 163 | "filetime", 164 | "libredox", 165 | "num", 166 | "proptest", 167 | "redox_users", 168 | "termion", 169 | "time", 170 | "walkdir", 171 | ] 172 | 173 | [[package]] 174 | name = "crossbeam-utils" 175 | version = "0.8.20" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 178 | 179 | [[package]] 180 | name = "errno" 181 | version = "0.3.9" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 184 | dependencies = [ 185 | "libc", 186 | "windows-sys 0.52.0", 187 | ] 188 | 189 | [[package]] 190 | name = "extra" 191 | version = "0.1.0" 192 | source = "git+https://gitlab.redox-os.org/redox-os/libextra.git#cf213969493db8667052a591e32a1e26d43c4234" 193 | 194 | [[package]] 195 | name = "failure" 196 | version = "0.1.8" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 199 | dependencies = [ 200 | "backtrace", 201 | "failure_derive", 202 | ] 203 | 204 | [[package]] 205 | name = "failure_derive" 206 | version = "0.1.8" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 209 | dependencies = [ 210 | "proc-macro2", 211 | "quote", 212 | "syn 1.0.109", 213 | "synstructure", 214 | ] 215 | 216 | [[package]] 217 | name = "fastrand" 218 | version = "2.1.1" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" 221 | 222 | [[package]] 223 | name = "filetime" 224 | version = "0.2.24" 225 | source = "git+https://github.com/jackpot51/filetime.git#186e19d3190ead16b05329400cb5b2350d8f44cf" 226 | dependencies = [ 227 | "cfg-if", 228 | "libc", 229 | "libredox", 230 | "windows-sys 0.59.0", 231 | ] 232 | 233 | [[package]] 234 | name = "fnv" 235 | version = "1.0.7" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 238 | 239 | [[package]] 240 | name = "fuchsia-cprng" 241 | version = "0.1.1" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 244 | 245 | [[package]] 246 | name = "getrandom" 247 | version = "0.2.15" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 250 | dependencies = [ 251 | "cfg-if", 252 | "libc", 253 | "wasi 0.11.0+wasi-snapshot-preview1", 254 | ] 255 | 256 | [[package]] 257 | name = "gimli" 258 | version = "0.31.1" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 261 | 262 | [[package]] 263 | name = "lazy_static" 264 | version = "1.5.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 267 | 268 | [[package]] 269 | name = "libc" 270 | version = "0.2.160" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "f0b21006cd1874ae9e650973c565615676dc4a274c965bb0a73796dac838ce4f" 273 | 274 | [[package]] 275 | name = "libredox" 276 | version = "0.1.3" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 279 | dependencies = [ 280 | "bitflags 2.6.0", 281 | "libc", 282 | "redox_syscall", 283 | ] 284 | 285 | [[package]] 286 | name = "linux-raw-sys" 287 | version = "0.4.14" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 290 | 291 | [[package]] 292 | name = "memchr" 293 | version = "2.7.4" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 296 | 297 | [[package]] 298 | name = "miniz_oxide" 299 | version = "0.8.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 302 | dependencies = [ 303 | "adler2", 304 | ] 305 | 306 | [[package]] 307 | name = "num" 308 | version = "0.2.1" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" 311 | dependencies = [ 312 | "num-bigint", 313 | "num-complex", 314 | "num-integer", 315 | "num-iter", 316 | "num-rational", 317 | "num-traits", 318 | ] 319 | 320 | [[package]] 321 | name = "num-bigint" 322 | version = "0.2.6" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" 325 | dependencies = [ 326 | "autocfg 1.4.0", 327 | "num-integer", 328 | "num-traits", 329 | ] 330 | 331 | [[package]] 332 | name = "num-complex" 333 | version = "0.2.4" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" 336 | dependencies = [ 337 | "autocfg 1.4.0", 338 | "num-traits", 339 | ] 340 | 341 | [[package]] 342 | name = "num-integer" 343 | version = "0.1.46" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 346 | dependencies = [ 347 | "num-traits", 348 | ] 349 | 350 | [[package]] 351 | name = "num-iter" 352 | version = "0.1.45" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 355 | dependencies = [ 356 | "autocfg 1.4.0", 357 | "num-integer", 358 | "num-traits", 359 | ] 360 | 361 | [[package]] 362 | name = "num-rational" 363 | version = "0.2.4" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" 366 | dependencies = [ 367 | "autocfg 1.4.0", 368 | "num-bigint", 369 | "num-integer", 370 | "num-traits", 371 | ] 372 | 373 | [[package]] 374 | name = "num-traits" 375 | version = "0.2.19" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 378 | dependencies = [ 379 | "autocfg 1.4.0", 380 | ] 381 | 382 | [[package]] 383 | name = "numtoa" 384 | version = "0.2.4" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" 387 | 388 | [[package]] 389 | name = "object" 390 | version = "0.36.5" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" 393 | dependencies = [ 394 | "memchr", 395 | ] 396 | 397 | [[package]] 398 | name = "once_cell" 399 | version = "1.20.2" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 402 | 403 | [[package]] 404 | name = "proc-macro2" 405 | version = "1.0.88" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" 408 | dependencies = [ 409 | "unicode-ident", 410 | ] 411 | 412 | [[package]] 413 | name = "proptest" 414 | version = "0.9.6" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "01c477819b845fe023d33583ebf10c9f62518c8d79a0960ba5c36d6ac8a55a5b" 417 | dependencies = [ 418 | "bit-set", 419 | "bitflags 1.3.2", 420 | "byteorder", 421 | "lazy_static", 422 | "num-traits", 423 | "quick-error", 424 | "rand", 425 | "rand_chacha", 426 | "rand_xorshift", 427 | "regex-syntax", 428 | "rusty-fork", 429 | "tempfile", 430 | ] 431 | 432 | [[package]] 433 | name = "quick-error" 434 | version = "1.2.3" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 437 | 438 | [[package]] 439 | name = "quote" 440 | version = "1.0.37" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 443 | dependencies = [ 444 | "proc-macro2", 445 | ] 446 | 447 | [[package]] 448 | name = "rand" 449 | version = "0.6.5" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 452 | dependencies = [ 453 | "autocfg 0.1.8", 454 | "libc", 455 | "rand_chacha", 456 | "rand_core 0.4.2", 457 | "rand_hc", 458 | "rand_isaac", 459 | "rand_jitter", 460 | "rand_os", 461 | "rand_pcg", 462 | "rand_xorshift", 463 | "winapi", 464 | ] 465 | 466 | [[package]] 467 | name = "rand_chacha" 468 | version = "0.1.1" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 471 | dependencies = [ 472 | "autocfg 0.1.8", 473 | "rand_core 0.3.1", 474 | ] 475 | 476 | [[package]] 477 | name = "rand_core" 478 | version = "0.3.1" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 481 | dependencies = [ 482 | "rand_core 0.4.2", 483 | ] 484 | 485 | [[package]] 486 | name = "rand_core" 487 | version = "0.4.2" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 490 | 491 | [[package]] 492 | name = "rand_hc" 493 | version = "0.1.0" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 496 | dependencies = [ 497 | "rand_core 0.3.1", 498 | ] 499 | 500 | [[package]] 501 | name = "rand_isaac" 502 | version = "0.1.1" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 505 | dependencies = [ 506 | "rand_core 0.3.1", 507 | ] 508 | 509 | [[package]] 510 | name = "rand_jitter" 511 | version = "0.1.4" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 514 | dependencies = [ 515 | "libc", 516 | "rand_core 0.4.2", 517 | "winapi", 518 | ] 519 | 520 | [[package]] 521 | name = "rand_os" 522 | version = "0.1.3" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 525 | dependencies = [ 526 | "cloudabi", 527 | "fuchsia-cprng", 528 | "libc", 529 | "rand_core 0.4.2", 530 | "rdrand", 531 | "winapi", 532 | ] 533 | 534 | [[package]] 535 | name = "rand_pcg" 536 | version = "0.1.2" 537 | source = "registry+https://github.com/rust-lang/crates.io-index" 538 | checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 539 | dependencies = [ 540 | "autocfg 0.1.8", 541 | "rand_core 0.4.2", 542 | ] 543 | 544 | [[package]] 545 | name = "rand_xorshift" 546 | version = "0.1.1" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 549 | dependencies = [ 550 | "rand_core 0.3.1", 551 | ] 552 | 553 | [[package]] 554 | name = "rdrand" 555 | version = "0.4.0" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 558 | dependencies = [ 559 | "rand_core 0.3.1", 560 | ] 561 | 562 | [[package]] 563 | name = "redox_syscall" 564 | version = "0.5.7" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" 567 | dependencies = [ 568 | "bitflags 2.6.0", 569 | ] 570 | 571 | [[package]] 572 | name = "redox_termios" 573 | version = "0.1.3" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb" 576 | 577 | [[package]] 578 | name = "redox_users" 579 | version = "0.4.6" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" 582 | dependencies = [ 583 | "getrandom", 584 | "libredox", 585 | "rust-argon2", 586 | "thiserror", 587 | "zeroize", 588 | ] 589 | 590 | [[package]] 591 | name = "regex-syntax" 592 | version = "0.6.29" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 595 | 596 | [[package]] 597 | name = "rust-argon2" 598 | version = "0.8.3" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" 601 | dependencies = [ 602 | "base64 0.13.1", 603 | "blake2b_simd", 604 | "constant_time_eq", 605 | "crossbeam-utils", 606 | ] 607 | 608 | [[package]] 609 | name = "rustc-demangle" 610 | version = "0.1.24" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 613 | 614 | [[package]] 615 | name = "rustix" 616 | version = "0.38.37" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 619 | dependencies = [ 620 | "bitflags 2.6.0", 621 | "errno", 622 | "libc", 623 | "linux-raw-sys", 624 | "windows-sys 0.52.0", 625 | ] 626 | 627 | [[package]] 628 | name = "rusty-fork" 629 | version = "0.2.2" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | checksum = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae" 632 | dependencies = [ 633 | "fnv", 634 | "quick-error", 635 | "tempfile", 636 | "wait-timeout", 637 | ] 638 | 639 | [[package]] 640 | name = "same-file" 641 | version = "1.0.6" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 644 | dependencies = [ 645 | "winapi-util", 646 | ] 647 | 648 | [[package]] 649 | name = "syn" 650 | version = "1.0.109" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 653 | dependencies = [ 654 | "proc-macro2", 655 | "quote", 656 | "unicode-ident", 657 | ] 658 | 659 | [[package]] 660 | name = "syn" 661 | version = "2.0.79" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" 664 | dependencies = [ 665 | "proc-macro2", 666 | "quote", 667 | "unicode-ident", 668 | ] 669 | 670 | [[package]] 671 | name = "synstructure" 672 | version = "0.12.6" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 675 | dependencies = [ 676 | "proc-macro2", 677 | "quote", 678 | "syn 1.0.109", 679 | "unicode-xid", 680 | ] 681 | 682 | [[package]] 683 | name = "tempfile" 684 | version = "3.13.0" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" 687 | dependencies = [ 688 | "cfg-if", 689 | "fastrand", 690 | "once_cell", 691 | "rustix", 692 | "windows-sys 0.59.0", 693 | ] 694 | 695 | [[package]] 696 | name = "termion" 697 | version = "4.0.3" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "7eaa98560e51a2cf4f0bb884d8b2098a9ea11ecf3b7078e9c68242c74cc923a7" 700 | dependencies = [ 701 | "libc", 702 | "libredox", 703 | "numtoa", 704 | "redox_termios", 705 | ] 706 | 707 | [[package]] 708 | name = "thiserror" 709 | version = "1.0.64" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" 712 | dependencies = [ 713 | "thiserror-impl", 714 | ] 715 | 716 | [[package]] 717 | name = "thiserror-impl" 718 | version = "1.0.64" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" 721 | dependencies = [ 722 | "proc-macro2", 723 | "quote", 724 | "syn 2.0.79", 725 | ] 726 | 727 | [[package]] 728 | name = "time" 729 | version = "0.1.45" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 732 | dependencies = [ 733 | "libc", 734 | "wasi 0.10.0+wasi-snapshot-preview1", 735 | "winapi", 736 | ] 737 | 738 | [[package]] 739 | name = "unicode-ident" 740 | version = "1.0.13" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 743 | 744 | [[package]] 745 | name = "unicode-xid" 746 | version = "0.2.6" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 749 | 750 | [[package]] 751 | name = "wait-timeout" 752 | version = "0.2.0" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 755 | dependencies = [ 756 | "libc", 757 | ] 758 | 759 | [[package]] 760 | name = "walkdir" 761 | version = "2.5.0" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 764 | dependencies = [ 765 | "same-file", 766 | "winapi-util", 767 | ] 768 | 769 | [[package]] 770 | name = "wasi" 771 | version = "0.10.0+wasi-snapshot-preview1" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 774 | 775 | [[package]] 776 | name = "wasi" 777 | version = "0.11.0+wasi-snapshot-preview1" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 780 | 781 | [[package]] 782 | name = "winapi" 783 | version = "0.3.9" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 786 | dependencies = [ 787 | "winapi-i686-pc-windows-gnu", 788 | "winapi-x86_64-pc-windows-gnu", 789 | ] 790 | 791 | [[package]] 792 | name = "winapi-i686-pc-windows-gnu" 793 | version = "0.4.0" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 796 | 797 | [[package]] 798 | name = "winapi-util" 799 | version = "0.1.9" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 802 | dependencies = [ 803 | "windows-sys 0.59.0", 804 | ] 805 | 806 | [[package]] 807 | name = "winapi-x86_64-pc-windows-gnu" 808 | version = "0.4.0" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 811 | 812 | [[package]] 813 | name = "windows-sys" 814 | version = "0.52.0" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 817 | dependencies = [ 818 | "windows-targets", 819 | ] 820 | 821 | [[package]] 822 | name = "windows-sys" 823 | version = "0.59.0" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 826 | dependencies = [ 827 | "windows-targets", 828 | ] 829 | 830 | [[package]] 831 | name = "windows-targets" 832 | version = "0.52.6" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 835 | dependencies = [ 836 | "windows_aarch64_gnullvm", 837 | "windows_aarch64_msvc", 838 | "windows_i686_gnu", 839 | "windows_i686_gnullvm", 840 | "windows_i686_msvc", 841 | "windows_x86_64_gnu", 842 | "windows_x86_64_gnullvm", 843 | "windows_x86_64_msvc", 844 | ] 845 | 846 | [[package]] 847 | name = "windows_aarch64_gnullvm" 848 | version = "0.52.6" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 851 | 852 | [[package]] 853 | name = "windows_aarch64_msvc" 854 | version = "0.52.6" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 857 | 858 | [[package]] 859 | name = "windows_i686_gnu" 860 | version = "0.52.6" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 863 | 864 | [[package]] 865 | name = "windows_i686_gnullvm" 866 | version = "0.52.6" 867 | source = "registry+https://github.com/rust-lang/crates.io-index" 868 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 869 | 870 | [[package]] 871 | name = "windows_i686_msvc" 872 | version = "0.52.6" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 875 | 876 | [[package]] 877 | name = "windows_x86_64_gnu" 878 | version = "0.52.6" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 881 | 882 | [[package]] 883 | name = "windows_x86_64_gnullvm" 884 | version = "0.52.6" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 887 | 888 | [[package]] 889 | name = "windows_x86_64_msvc" 890 | version = "0.52.6" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 893 | 894 | [[package]] 895 | name = "zeroize" 896 | version = "1.8.1" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 899 | dependencies = [ 900 | "zeroize_derive", 901 | ] 902 | 903 | [[package]] 904 | name = "zeroize_derive" 905 | version = "1.4.2" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 908 | dependencies = [ 909 | "proc-macro2", 910 | "quote", 911 | "syn 2.0.79", 912 | ] 913 | --------------------------------------------------------------------------------