dd_lib/
lib.rs

1//! # dd: convert and copy a file  
2//!
3//! ## SYNOPSIS         
4//! dd \[OPERAND\]...
5//! dd OPTION
6//! ## DESCRIPTION         
7//! Copy a file converting and formatting according to the operands.
8//!
9//! ## [`opts`]
10//! Note: the parsing of numeric arguments is a little unusual and allows for
11//! numeric suffixes. See the documentation of [opts::number] and
12//! [opts::number::units];
13//!
14//! - **bs**=BYTES: read and write up to BYTES bytes at a time (default: 512).
15//!   - **overrides ibs and obs**
16//!
17//! - **cbs**=BYTES: convert BYTES bytes at a time
18//!
19//! - **conv**=[`CONVS`][opts::Conv]: convert the file as per the coma
20//!   separated symbol list
21//!
22//! - **count**=N: copy only N input blocks
23//!
24//! - **ibs**=BYTES: read up to BYTES bytes at a time (default: 512)
25//!
26//! - **if**=FILE: read from FILE instead of stdin
27//!
28//! - **iflag**=[`FLAGS`][opts::In]: read as per the comma separated   symbol
29//!   list
30//!
31//! - **obs**=BYTES: write BYTES bytes at a time (default: 512)
32//!
33//! - **of**=FILE: write to FILE instead of stdout
34//!
35//! - **oflag**=[`FLAGS`][opts::Out]: write as per the comma separated   symbol
36//!   list
37//!
38//! - **seek**=N: skip N obs-sized blocks at start of output
39//!
40//! - **skip**=N: skip N ibs-sized blocks at start of input
41//!
42//! - **status=[LEVEL][opts::StatusLevel]**: the level of information to print
43//!   to stderr
44//!
45//!    none: suppresses everything but error messages,
46//!    progress //! - **shows** periodic transfer statistics
47//!    noxfer: suppresses the final transfer statistics,
48//!
49//!
50//! ### [Units][opts::number::units]:
51
52//! ### [`CONV`][opts::Conv]
53//! Each CONV symbol may be:
54
55//! 
56//! - **ascii**  from EBCDIC to ASCII
57
58//! 
59//! - **ebcdic** from ASCII to EBCDIC
60
61//! 
62//! - **ibm**    from ASCII to alternate EBCDIC
63
64//! 
65//! - **block**  pad newline-terminated records with spaces to cbs-size
66
67//! 
68//! - **unblock** replace trailing spaces in cbs-size records with newline
69
70//! 
71//! - **lcase**  change upper case to lower case
72
73//! 
74//! - **ucase**  change lower case to upper case
75
76//! 
77//! - **sparse** try to seek rather than write the output for NUL input blocks
78
79//! 
80//! - **swab**   swap every pair of input bytes
81
82//! 
83//! - **sync**   pad every input block with NULs to ibs-size; when used with
84//!   block or unblock, pad with spaces rather than NULs
85
86//! 
87//! - **excl**   fail if the output file already exists
88
89//! 
90//! - **nocreat** do not create the output file
91
92//! 
93//! - **notrunc** do not truncate the output file
94
95//! 
96//! - **noerror** continue after read errors
97
98//! 
99//! - **fdatasync**
100//! physically write output file data before finishing
101//! - **fsync**  likewise, but also write metadata
102
103//! ### SIGNALS
104//! Sending a USR1 signal to a running 'dd' process makes it print I/O
105//! statistics to standard error and then resume copying.
106//!
107//!
108//! ### OPTIONS
109//! --help display this help and exit
110//! --version
111//! output version information and exit
112//! ### AUTHOR         
113//! Originally Written by Paul Rubin, David MacKenzie, and Stuart Kemp.
114//! Clone written _only_ by looking at man page by Efron Licht
115//! input, output, and encoding
116
117pub mod io;
118pub mod opts;
119pub mod units;
120use io::{Converter, ErrHandler, Reader, Writer};
121pub use results::{Result, Success};
122
123mod results;
124
125#[cfg(test)]
126extern crate tempfile;
127#[macro_use]
128extern crate bitflags;
129extern crate encoding8;
130
131#[cfg(test)]
132mod tests;
133
134/// The dd utility copies the standard input to the standard output.  Input data
135/// is read and written in n-byte blocks (default `512`).  If input reads are
136/// short, input from multiple reads are aggregated to form the output block.
137/// When finished, dd displays the number of complete and partial input and
138/// output blocks and truncated input records to the standard error output.
139pub fn dd(o: &opts::Opts) -> Result<Success> {
140    let stderr = std::io::stderr();
141    let lock = stderr.lock();
142    dd_pipe_err(o, lock)
143}
144
145/// dd, piping standard error to E
146pub fn dd_pipe_err<E>(o: &opts::Opts, err: E) -> Result<Success>
147where
148    E: std::io::Write, // in practice, this is always stderr
149{
150    let (stdin, stdout) = (std::io::stdin(), std::io::stdout());
151    let r = Reader::new(&stdin, o)?;
152    let mut w = Writer::new(&stdout, o)?;
153    let c = Converter::new(o)?;
154    let e = ErrHandler::new(err, o);
155    match o.mode {
156        opts::Mode::Block(n) => io::copy::block(r, &mut w, c, e, n),
157        opts::Mode::Unblock(n) => io::copy::unblock(r, &mut w, c, e, n),
158        opts::Mode::Standard => io::copy::standard(r, &mut w, c, e),
159    }
160}