https://github.com/cleancut/shell_cmds
Port Apple's various shell commands from C to Rust
https://github.com/cleancut/shell_cmds
Last synced: 11 months ago
JSON representation
Port Apple's various shell commands from C to Rust
- Host: GitHub
- URL: https://github.com/cleancut/shell_cmds
- Owner: CleanCut
- Created: 2019-10-24T02:08:45.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-04-03T04:40:25.000Z (almost 5 years ago)
- Last Synced: 2025-01-17T22:43:36.227Z (about 1 year ago)
- Language: Rust
- Size: 185 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: ReadMe.md
Awesome Lists containing this project
README
Rust port of Apple's [shell_cmds](https://opensource.apple.com/source/shell_cmds/shell_cmds-198/)
=================================
Port Apple's shell commands from C to Rust. To learn more about ancient shell commands and Rust, and to have fun.
Contributing
============
- Want to help? Please do! The easiest way to contact me to discuss things is by
[creating an issue](https://github.com/agileperception/shell_cmds/issues/new) or
[pull request](https://github.com/CleanCut/shell_cmds/pulls)
- Code to port: [shell_cmds version 198](https://opensource.apple.com/source/shell_cmds/shell_cmds-198/)
- Commands need a file in `src/bin/` with a `fn main()`. For example `echo` has `src/bin/echo.rs`
- To compile+run your new command (for example) `echo arg1 arg2` you would do `cargo run --bin echo -- arg1 arg2`
- Use `std::env::args()` directly for the dirt-simple utilities. Use
[getopts](https://doc.rust-lang.org/getopts/getopts/index.html) for the fancier ones.
- Put the man pages (files ending in `.1`) in the `man/` directory.
- Put the companion shell scripts in the `sh/` directory.
- When there's a license header, copy it over verbatim into the `.rs` file for the binary. (Lawyer repellent.)
Porting Status
==============
* [x] alias - Just a man page pointer to `builtin.1`, which is `csh`'s manpage.
* [x] apply - Some serious pointer-loop reverse engineering on this one.
* [x] basename - Ancient utilities are frustrating because their behavior with
arguments makes no blasted sense. `basename` is one of these. If it has
exactly two arguments, then it acts completely differently.
* [x] chroot - Many calls to libc. Seems to have matched behavior exactly, except for the buffer overflow vulnerability.
* [ ] date
* [x] dirname - Shares a man page with basename.
* [x] echo - Got an education in rust Strings.
* [ ] env
* [ ] expr
* [x] false - Simple.
* [ ] find
* [ ] getopt
* [ ] hexdump
* [ ] hostname
* [ ] id
* [ ] jot
* [ ] kill
* [ ] killall
* [ ] lastcomm
* [ ] locate
* [ ] logname
* [ ] mktemp
* [ ] nice
* [ ] nohup
* [ ] path_helper
* [x] printenv - Done. Did you know printenv silently ignores any extra arguments?
* [ ] pwd
* [ ] renice
* [ ] script
* [ ] seq
* [ ] sh
* [ ] shlock
* [x] sleep - Instead of treating invalid input as 0 silently, we spit out the
usage and die.
* [ ] su
* [ ] systime
* [x] tee - Done. Good practice with `Vec`, `zip()`, `stdin/stdout/stderr`, and files.
* [ ] test
* [ ] time
* [x] true - Simple.
* [ ] uname
* [ ] users
* [ ] w
* [ ] what
* [ ] whereis
* [ ] which
* [ ] who
* [ ] xargs
* [x] yes - Did you know that `yes` takes an optional argument?
Bugs in Original
================
Below is a partial list of bugs discovered in C code of Apple's [shell_cmds] which ship on macOS.
[shell_cmds]: https://opensource.apple.com/source/shell_cmds/shell_cmds-198/
chroot.c
--------
- Buffer Overflow: If more than 16 valid groups are provided to the `-G`
option, then the `gidlist` buffer overflows and starts overwriting later data
in the stack frame with resolved group ids. That is not difficult to do
since macOS ships with over 100 valid groups by default. In Rust, we use a
`Vec` to store the resolved group ids. `Vec` is dynamically sized, so it
won't overflow.