123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- // Copyright (C) 2015, Alberto Corona <alberto@0x1a.us>
- // All rights reserved. This file is part of core-utils, distributed under the
- // GPL v3 license. For full terms please see the LICENSE file.
- #![crate_type = "bin"]
- #![crate_name = "ln"]
- #![feature(path_ext,collections)]
- static VERS: &'static str = "0.1.0";
- static PROG: &'static str = "ln";
- extern crate getopts;
- extern crate util;
- use getopts::{Options};
- use util::{Status};
- use std::env;
- use std::fs;
- use std::os;
- use std::path::{PathBuf};
- use std::fs::{PathExt};
- fn unix_symlink(from: &PathBuf, to: &PathBuf, verbose: bool) {
- match os::unix::fs::symlink(from, to) {
- Ok(_) => {
- if verbose {
- println!("{} -> {}", from.display(), to.display());
- }
- },
- Err(e) => {
- util::err(PROG, Status::Error, e.to_string());
- }
- };
- }
- fn sym_link_files(files: Vec<String>, to: &PathBuf, force: bool, verbose: bool) {
- for item in files.iter() {
- if !to.is_dir() {
- util::err(PROG, Status::Error, String::from(String::from(
- to.to_str().unwrap()) + " is not a directory"));
- } else {
- soft_link(&PathBuf::from(item), &to.join(PathBuf::from(item)), force, verbose);
- }
- }
- }
- fn hard_link_files(files: Vec<String>, to: &PathBuf, force: bool, verbose: bool) {
- for item in files.iter() {
- if !to.is_dir() {
- util::err(PROG, Status::Error, String::from(String::from(
- to.to_str().unwrap()) + " is not a directory"));
- } else {
- let to_path = PathBuf::from(item);
- hard_link(&to_path, &to.join(&to_path), force, verbose);
- }
- }
- }
- fn soft_link(from: &PathBuf, to: &PathBuf, force: bool, verbose: bool) {
- if !force {
- if cfg!(target_family = "unix") {
- unix_symlink(from, to, verbose);
- }
- } else {
- if PathBuf::from(to).exists() {
- fs::remove_file(to).ok();
- if cfg!(target_family = "unix") {
- unix_symlink(from, to, verbose);
- }
- }
- }
- }
- fn hard_link(from: &PathBuf, to: &PathBuf, force: bool, verbose: bool) {
- if !force {
- match fs::hard_link(from, to) {
- Ok(_) => {
- if verbose {
- println!("{} -> {}", from.display(), to.display());
- }
- },
- Err(e) => {
- util::err(PROG, Status::Error, e.to_string());
- }
- };
- } else {
- if PathBuf::from(to).exists() {
- fs::remove_file(to).ok();
- match fs::hard_link(from, to) {
- Ok(_) => { },
- Err(e) => {
- util::err(PROG, Status::Error, e.to_string());
- }
- };
- }
- }
- }
- fn print_usage(prog: &str, opts: Options) {
- let breif = format!("Usage: {} [OPTION] TARGET LINK_NAME\nCreate links between files", prog);
- print!("{}", opts.usage(&breif));
- util::exit(Status::Ok);
- }
- fn main() {
- let args: Vec<String> = env::args().collect();
- let mut opts = Options::new();
- opts.optflag("h", "help", "Print the help menu");
- opts.optflag("", "version", "Print the version");
- opts.optflag("v", "verbose", "Verbose print the operation");
- opts.optflag("f", "force", "Force operation. Removes existsing target files");
- opts.optflag("s", "soft", "Create a symbolic link");
- opts.optflag("p", "physical", "Create a hard link");
- let matches = match opts.parse(&args[1..]) {
- Ok(m) => { m },
- Err(f) => {
- util::err(PROG, Status::OptError, f.to_string());
- panic!(f.to_string());
- }
- };
- if matches.opt_present("h") {
- print_usage(PROG, opts);
- } else if matches.opt_present("version") {
- util::copyright(PROG, VERS, "2015", vec!["Alberto Corona"]);
- } else {
- let verb = matches.opt_present("v");
- let force = matches.opt_present("f");
- let src = match matches.free.first() {
- Some(s) => { PathBuf::from(s) },
- None => {
- util::err(PROG, Status::Error, String::from(" no arguments given"));
- panic!();
- },
- };
- let dest = PathBuf::from(matches.free.last().unwrap());
- if matches.free.len() == 1 {
- println!("{}: no link name for {}", PROG, src.display());
- util::exit(Status::Error);
- }
- if matches.opt_present("s") {
- if matches.free.len() > 2 {
- sym_link_files(matches.free.init().to_vec(), &dest, force, verb);
- } else {
- soft_link(&src, &PathBuf::from(&matches.free[1]), force, verb);
- }
- } else if matches.opt_present("p") {
- if matches.free.len() > 2 {
- hard_link_files(matches.free.init().to_vec(), &dest, force, verb);
- } else {
- hard_link(&src, &PathBuf::from(&matches.free[1]), force, verb);
- }
- }
- }
- }
|