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