coreutils/mkdir/mkdir.rs

155 lines
4.5 KiB
Rust
Raw Normal View History

2014-03-31 16:40:21 +00:00
#![crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")]
2014-01-01 08:08:27 +00:00
/*
2014-01-01 08:08:27 +00:00
* This file is part of the uutils coreutils package.
*
* (c) Nicholas Juszczak <juszczakn@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
2014-03-31 16:40:21 +00:00
#![feature(macro_rules)]
extern crate getopts;
2014-01-01 08:08:27 +00:00
use std::os;
use std::io::fs;
2014-01-03 23:32:39 +00:00
use std::num::strconv;
2014-01-01 08:08:27 +00:00
2014-02-23 22:17:48 +00:00
#[path = "../common/util.rs"]
mod util;
static NAME: &'static str = "mkdir";
2014-01-01 08:08:27 +00:00
static VERSION: &'static str = "1.0.0";
2014-01-03 23:32:39 +00:00
/**
* Handles option parsing
*/
2014-01-01 08:08:27 +00:00
fn main() {
let args = os::args();
2014-03-22 08:18:52 +00:00
let opts = ~[
2014-01-03 23:32:39 +00:00
// Linux-specific options, not implemented
// getopts::optflag("Z", "context", "set SELinux secutiry context" +
// " of each created directory to CTX"),
getopts::optopt("m", "mode", "set file mode", "755"),
getopts::optflag("p", "parents", "make parent directories as needed"),
getopts::optflag("v", "verbose",
2014-01-01 08:08:27 +00:00
"print a message for each printed directory"),
getopts::optflag("h", "help", "display this help"),
getopts::optflag("V", "version", "display this version")
];
2014-01-01 08:08:27 +00:00
let matches = match getopts::getopts(args.tail(), opts) {
2014-01-01 08:08:27 +00:00
Ok(m) => m,
Err(f) => {
crash!(1, "Invalid options\n{}", f.to_err_msg());
2014-01-01 08:08:27 +00:00
}
};
2014-01-03 23:32:39 +00:00
if args.len() == 1 || matches.opt_present("help") {
2014-01-01 08:08:27 +00:00
print_help(opts);
return;
}
if matches.opt_present("version") {
println!("mkdir v{}", VERSION);
2014-01-01 08:08:27 +00:00
return;
}
let verbose_flag = matches.opt_present("verbose");
let mk_parents = matches.opt_present("parents");
2014-01-03 23:32:39 +00:00
// Translate a ~str in octal form to u32, default to 755
// Not tested on Windows
let mode_match = matches.opts_str(&[~"mode"]);
let mode: u32 = if mode_match.is_some() {
let m = mode_match.unwrap();
2014-01-03 23:32:39 +00:00
let res = strconv::from_str_common(m, 8, false, false, false,
strconv::ExpNone,
false, false);
if res.is_some() {
res.unwrap()
} else {
crash!(1, "no mode given");
2014-01-03 23:32:39 +00:00
}
} else {
0o755
};
let dirs = matches.free;
2014-01-03 23:32:39 +00:00
exec(dirs, mk_parents, mode, verbose_flag);
2014-01-01 08:08:27 +00:00
}
fn print_help(opts: &[getopts::OptGroup]) {
println!("mkdir v{} - make a new directory with the given path", VERSION);
println!("");
println!("Usage:");
print!("{}", getopts::usage("Create the given DIRECTORY(ies)" +
" if they do not exist", opts));
2014-01-01 08:08:27 +00:00
}
2014-01-03 23:32:39 +00:00
/**
* Create the list of new directories
*/
2014-03-22 08:18:52 +00:00
fn exec(dirs: Vec<~str>, mk_parents: bool, mode: u32, verbose: bool) {
let mut parent_dirs = Vec::new();
2014-01-05 22:03:13 +00:00
if mk_parents {
for dir in dirs.iter() {
let path = Path::new((*dir).clone());
// Build list of parent dirs which need to be created
let parent = path.dirname_str();
match parent {
Some(p) => {
if !Path::new(p).exists() {
parent_dirs.push(p.into_owned())
}
},
None => ()
}
}
2014-01-03 23:32:39 +00:00
}
// Recursively build parent dirs that are needed
if !parent_dirs.is_empty() {
exec(parent_dirs, mk_parents, mode, verbose);
}
for dir in dirs.iter() {
let path = Path::new((*dir).clone());
// Determine if parent directory to the one to
// be created exists
let parent = match path.dirname_str() {
2014-01-03 23:32:39 +00:00
Some(p) => p,
None => ""
};
let parent_exists = Path::new(parent).exists();
2014-01-03 23:32:39 +00:00
if parent_exists && !path.exists() {
mkdir(&path, mode);
if verbose {println!("{}", *dir);}
} else if !mk_parents {
let mut error_msg = ~"";
2014-01-03 23:32:39 +00:00
if !parent_exists {
error_msg.push_str("parent directory '");
2014-01-03 23:32:39 +00:00
error_msg.push_str(parent);
error_msg.push_str("' does not exist");
} else {
error_msg.push_str("directory '");
2014-01-03 23:32:39 +00:00
error_msg.push_str(*dir);
error_msg.push_str("' already exists");
}
show_error!(1, "{}", error_msg);
2014-01-03 23:32:39 +00:00
}
}
}
/**
* Wrapper to catch errors, return false if failed
*/
fn mkdir(path: &Path, mode: u32) {
2014-02-05 03:39:17 +00:00
match fs::mkdir(path, mode) {
Ok(_) => {},
2014-01-03 23:32:39 +00:00
Err(e) => {
crash!(1, "test {}", e.to_str());
}
}
}