|
2 | 2 | extern crate clap; |
3 | 3 | extern crate loopdev; |
4 | 4 |
|
5 | | -use std::io::Write; |
| 5 | +use std::io::{self, Write}; |
6 | 6 | use std::process::exit; |
7 | 7 | use loopdev::{LoopControl, LoopDevice}; |
8 | 8 |
|
9 | | -macro_rules! exit_on_error { |
10 | | - ($e:expr) => ({match $e { |
11 | | - Ok(d) => d, |
12 | | - Err(err) => { |
13 | | - writeln!(&mut std::io::stderr(), "{}", err).unwrap(); |
14 | | - exit(1) |
15 | | - }, |
16 | | - } |
17 | | - }) |
| 9 | +fn find() -> io::Result<()> { |
| 10 | + let loopdev = LoopControl::open()?.next_free()?; |
| 11 | + println!("{}", loopdev.path().unwrap().display()); |
| 12 | + Ok(()) |
18 | 13 | } |
19 | 14 |
|
20 | | -fn find() { |
21 | | - match LoopControl::open().and_then(|lc| lc.next_free()) { |
22 | | - Ok(ld) => println!("{}", ld.path().unwrap().display()), |
23 | | - Err(err) => { |
24 | | - writeln!(&mut std::io::stderr(), "{}", err).unwrap(); |
25 | | - exit(1) |
26 | | - } |
| 15 | +fn attach(matches: &clap::ArgMatches) -> io::Result<()> { |
| 16 | + let quite = matches.is_present("quite"); |
| 17 | + let image = matches.value_of("image").unwrap(); |
| 18 | + let offset = value_t!(matches.value_of("offset"), u64).unwrap_or(0); |
| 19 | + let sizelimit = value_t!(matches.value_of("sizelimit"), u64).unwrap_or(0); |
| 20 | + let loopdev = match matches.value_of("loopdev") { |
| 21 | + Some(loopdev) => LoopDevice::open(&loopdev)?, |
| 22 | + None => LoopControl::open().and_then(|lc| lc.next_free())?, |
| 23 | + }; |
| 24 | + loopdev.attach_with_sizelimit(&image, offset, sizelimit)?; |
| 25 | + if !quite { |
| 26 | + println!("{}", loopdev.path().unwrap().display()); |
27 | 27 | } |
| 28 | + Ok(()) |
28 | 29 | } |
29 | 30 |
|
30 | | -fn attach(image: &str, loopdev: Option<&str>, offset: u64, sizelimit: u64) { |
31 | | - exit_on_error!(match loopdev { |
32 | | - None => LoopControl::open().and_then(|lc| lc.next_free()), |
33 | | - Some(dev) => LoopDevice::open(&dev), |
34 | | - } |
35 | | - .and_then(|ld| ld.attach_with_sizelimit(&image, offset, sizelimit))) |
| 31 | +fn detach(matches: &clap::ArgMatches) -> io::Result<()> { |
| 32 | + let loopdev = matches.value_of("file").unwrap(); |
| 33 | + LoopDevice::open(loopdev)?.detach() |
36 | 34 | } |
37 | 35 |
|
38 | | -fn detach(dev: &str) { |
39 | | - exit_on_error!(LoopDevice::open(dev).and_then(|ld| ld.detach())) |
40 | | -} |
41 | | - |
42 | | -fn list(_free: bool, _used: bool) { |
| 36 | +fn list(matches: Option<&clap::ArgMatches>) -> io::Result<()> { |
| 37 | + let (_free, _used) = match matches { |
| 38 | + Some(matches) => (matches.is_present("free"), matches.is_present("used")), |
| 39 | + None => (false, false), |
| 40 | + }; |
43 | 41 | unimplemented!(); |
44 | 42 | } |
45 | 43 |
|
46 | 44 | fn main() { |
47 | 45 | let matches = clap_app!(losetup => |
48 | | - (version: "0.1.2") |
49 | | - (author : "Michael Daffin <[email protected]>") |
50 | | - (about: "Setup and control loop devices") |
| 46 | + (version: crate_version!()) |
| 47 | + (author: crate_authors!()) |
| 48 | + (about: crate_description!()) |
51 | 49 | (@subcommand find => |
52 | 50 | (about: "find the next free loop device") |
53 | | - ) |
| 51 | + ) |
54 | 52 | (@subcommand attach => |
55 | 53 | (about: "attach the loop device to a backing file") |
56 | | - (@arg image: +required "the backing file to attach") |
57 | | - (@arg loopdev: "the loop device to attach") |
| 54 | + (@arg image: +required "the backing file to attach") |
| 55 | + (@arg loopdev: "the loop device to attach") |
58 | 56 | (@arg offset: -o --offset +takes_value "the offset within the file to start at") |
59 | 57 | (@arg sizelimit: -s --sizelimit +takes_value "the file is limited to this size") |
60 | | - ) |
| 58 | + (@arg quite: -q --quite "don't print the device name") |
| 59 | + ) |
61 | 60 | (@subcommand detach => |
62 | 61 | (about: "detach the loop device from the backing file") |
63 | | - (@arg file: +required "The file to detach") |
64 | | - ) |
| 62 | + (@arg file: +required "The file to detach") |
| 63 | + ) |
65 | 64 | (@subcommand list => |
66 | 65 | (about: "list the available loop devices") |
67 | 66 | (@arg free: -f --free "find free devices") |
68 | 67 | (@arg used: -u --used "find used devices") |
69 | | - ) |
70 | | - ) |
71 | | - .get_matches(); |
| 68 | + ) |
| 69 | + ).get_matches(); |
| 70 | + |
| 71 | + let result = match matches.subcommand() { |
| 72 | + ("find", _) => find(), |
| 73 | + ("attach", Some(matches)) => attach(matches), |
| 74 | + ("detach", Some(matches)) => detach(matches), |
| 75 | + (_, matches) => list(matches), |
| 76 | + }; |
72 | 77 |
|
73 | | - if let Some(_) = matches.subcommand_matches("find") { |
74 | | - find(); |
75 | | - } else if let Some(matches) = matches.subcommand_matches("attach") { |
76 | | - let image = matches.value_of("image").unwrap(); |
77 | | - let loopdev = matches.value_of("loopdev"); |
78 | | - attach(image, |
79 | | - loopdev, |
80 | | - value_t!(matches.value_of("offset"), u64).unwrap_or(0), |
81 | | - value_t!(matches.value_of("sizelimit"), u64).unwrap_or(0)); |
82 | | - } else if let Some(matches) = matches.subcommand_matches("detach") { |
83 | | - let file = matches.value_of("file").unwrap(); |
84 | | - detach(file); |
85 | | - } else { |
86 | | - list(matches.is_present("free"), matches.is_present("used")); |
| 78 | + if let Err(err) = result { |
| 79 | + writeln!(&mut std::io::stderr(), "{}", err).unwrap(); |
| 80 | + exit(1); |
87 | 81 | } |
88 | 82 | } |
0 commit comments