Advertisement
Guest User

Untitled

a guest
Jan 18th, 2017
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.44 KB | None | 0 0
  1. extern crate libbig;
  2. use libbig::BigArchive;
  3. use libbig::errors::{Error, ReadError, ExtractError};
  4.  
  5. extern crate clap;
  6. use clap::{Arg, App, AppSettings, SubCommand};
  7.  
  8. use std::fs;
  9. use std::path::Path;
  10.  
  11. fn main() {
  12. let matches = App::new("sagebig")
  13. .version("0.1.0")
  14. .author("Taryn Hill <taryn@phrohdoh.com>")
  15. .about("CLI for libbig")
  16. .setting(AppSettings::SubcommandRequiredElseHelp)
  17. .subcommand(SubCommand::with_name("list")
  18. .about("List all entries in an archive")
  19. .version("0.1.0")
  20. .author("Taryn Hill <taryn@phrohdoh.com>")
  21. .arg(Arg::with_name("archive_path")
  22. .value_name("archive_path")
  23. .required(true)
  24. .index(1)))
  25. .subcommand(SubCommand::with_name("search")
  26. .about("Locate entries with names containing a string")
  27. .version("0.1.0")
  28. .author("Taryn Hill <taryn@phrohdoh.com>")
  29. .arg(Arg::with_name("archive_path")
  30. .value_name("archive_path")
  31. .required(true)
  32. .index(1))
  33. .arg(Arg::with_name("query")
  34. .value_name("query")
  35. .required(true)
  36. .index(2)))
  37. .subcommand(SubCommand::with_name("contains")
  38. .about("Query an archive to determine if it contains an entry with a name")
  39. .version("0.1.0")
  40. .author("Taryn Hill <taryn@phrohdoh.com>")
  41. .arg(Arg::with_name("archive_path")
  42. .value_name("archive_path")
  43. .required(true)
  44. .index(1))
  45. .arg(Arg::with_name("query")
  46. .value_name("query")
  47. .required(true)
  48. .index(2)))
  49. .subcommand(SubCommand::with_name("extract")
  50. .about("Extract all files from an archive")
  51. .version("0.1.0")
  52. .author("Alexandre Oliveira <alex@layerbnc.org>")
  53. .arg(Arg::with_name("archive_path")
  54. .value_name("archive_path")
  55. .required(true)
  56. .index(1))
  57. .arg(Arg::with_name("output_dir")
  58. .value_name("output_dir")
  59. .required(true)
  60. .index(2))
  61. .arg(Arg::with_name("verbose")
  62. .short("v")))
  63. .get_matches();
  64.  
  65. let res = match matches.subcommand() {
  66. ("list", Some(args)) => cmd_list(args),
  67. ("search", Some(args)) => cmd_search(args),
  68. ("contains", Some(args)) => cmd_contains(args),
  69. ("extract", Some(args)) => cmd_extract(args),
  70. _ => unreachable!(),
  71. };
  72.  
  73. let code = if let Some(e) = res.err() {
  74. println!("Error: {:?}", e);
  75. 255
  76. } else {
  77. 0
  78. };
  79.  
  80. std::process::exit(code);
  81. }
  82.  
  83. fn cmd_list(args: &clap::ArgMatches) -> Result<(), ReadError> {
  84. let path = args.value_of("archive_path").unwrap();
  85. let archive = try!(BigArchive::new_from_path(&path));
  86.  
  87. for name in archive.get_all_entry_names() {
  88. let entry = archive.get_entry(name)
  89. .expect(&format!("Failed to read known entry {} from {}", name, path));
  90. println!("{:#?}", entry);
  91. }
  92.  
  93. Ok(())
  94. }
  95.  
  96. fn cmd_search(args: &clap::ArgMatches) -> Result<(), ReadError> {
  97. let path = args.value_of("archive_path").unwrap();
  98. let archive = try!(BigArchive::new_from_path(&path));
  99. let query = args.value_of("query").unwrap();
  100.  
  101. for name in archive.get_all_entry_names().filter(|n| n.contains(query)) {
  102. let entry = archive.get_entry(name)
  103. .expect(&format!("Failed to read known entry {} from {}", name, path));
  104. println!("{:#?}", entry);
  105. }
  106.  
  107. Ok(())
  108. }
  109.  
  110. fn cmd_contains(args: &clap::ArgMatches) -> Result<(), ReadError> {
  111. let path = args.value_of("archive_path").unwrap();
  112. let archive = try!(BigArchive::new_from_path(&path));
  113. let query = args.value_of("query").unwrap();
  114.  
  115. println!("{} contains {}: {}", path, query, archive.contains(query));
  116.  
  117. Ok(())
  118. }
  119.  
  120. fn cmd_extract(args: &clap::ArgMatches) -> Result<(), Error> {
  121. let big_path = args.value_of("archive_path").unwrap();
  122. let archive = try!(BigArchive::new_from_path(&big_path));
  123. let output_dir = Path::new(args.value_of("output_dir").unwrap());
  124. let verbose = args.is_present("verbose");
  125.  
  126. // Create output dir if it doesn't exist
  127. if !output_dir.exists() {
  128. try!(fs::create_dir(&output_dir));
  129.  
  130. if verbose {
  131. println!("Created output_dir `{:?}`", &output_dir.display());
  132. }
  133. }
  134.  
  135. let output_dir = try!(output_dir.canonicalize());
  136.  
  137. for name in archive.get_all_entry_names() {
  138. let entry = archive.get_entry(name)
  139. .expect(&format!("Failed to read known entry {} from {}", name, big_path));
  140.  
  141. let file_path = output_dir.join(Path::new(&entry.name));
  142. let file_dirpath = match file_path.parent() {
  143. Some(x) => x,
  144. None => return Err(Error::ExtractError(ExtractError::InvalidFilePath(file_path.to_string_lossy().into_owned())))
  145. };
  146.  
  147. if !file_dirpath.exists() {
  148. try!(fs::DirBuilder::new().recursive(true).create(&file_dirpath));
  149. if verbose {
  150. println!("Created path `{}`", &file_dirpath.display());
  151. }
  152. }
  153. }
  154.  
  155. Ok(())
  156. }
  157.  
  158. ----
  159.  
  160. $ cargo build
  161. Compiling libbig v0.1.0 (file:///C:/msys64/home/Alexandre/libbig)
  162. warning: unused import: `std::path::Path`, #[warn(unused_imports)] on by default
  163. --> C:\msys64\home\Alexandre\libbig\src\errors/mod.rs:2:5
  164. |
  165. 2 | use std::path::Path;
  166. | ^^^^^^^^^^^^^^^
  167.  
  168. Compiling sagebig v0.1.0 (file:///C:/msys64/home/Alexandre/libbig/cli-tools/sagebig)
  169. error[E0308]: match arms have incompatible types
  170. --> src\main.rs:65:15
  171. |
  172. 65 | let res = match matches.subcommand() {
  173. | ^ expected enum `libbig::errors::ReadError`, found enum `libbig::errors::Error`
  174. |
  175. = note: expected type `std::result::Result<(), libbig::errors::ReadError>`
  176. = note: found type `std::result::Result<(), libbig::errors::Error>`
  177. note: match arm with an incompatible type
  178. --> src\main.rs:69:36
  179. |
  180. 69 | ("extract", Some(args)) => cmd_extract(args),
  181. | ^^^^^^^^^^^^^^^^^
  182.  
  183. error: aborting due to previous error
  184.  
  185. error: Could not compile `sagebig`.
  186.  
  187. To learn more, run the command again with --verbose.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement