mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Merge pull request #1110 from Arcterus/mode-to-uucore
chmod, install, mknod: move mode parsing into uucore
This commit is contained in:
commit
7967f3aec7
78 changed files with 298 additions and 673 deletions
|
@ -13,7 +13,7 @@ extern crate uucore;
|
||||||
use uucore::encoding::{Data, Format, wrap_print};
|
use uucore::encoding::{Data, Format, wrap_print};
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read, stdin, Write};
|
use std::io::{BufReader, Read, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[OPTION]... [FILE]";
|
static SYNTAX: &'static str = "[OPTION]... [FILE]";
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate uucore;
|
||||||
use uucore::encoding::{Data, Format, wrap_print};
|
use uucore::encoding::{Data, Format, wrap_print};
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufReader, Read, stdin, Write};
|
use std::io::{BufReader, Read, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[OPTION]... [FILE]";
|
static SYNTAX: &'static str = "[OPTION]... [FILE]";
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{is_separator, PathBuf};
|
use std::path::{is_separator, PathBuf};
|
||||||
|
|
||||||
static NAME: &'static str = "basename";
|
static NAME: &'static str = "basename";
|
||||||
|
|
|
@ -17,7 +17,6 @@ use uucore::fs::resolve_relative_path;
|
||||||
extern crate walkdir;
|
extern crate walkdir;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::io::Result as IOResult;
|
use std::io::Result as IOResult;
|
||||||
use std::io::Error as IOError;
|
use std::io::Error as IOError;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -16,12 +16,12 @@ extern crate walker;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::error::Error;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use walker::Walker;
|
use walker::Walker;
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
use uucore::mode;
|
||||||
|
|
||||||
const NAME: &'static str = "chmod";
|
const NAME: &'static str = "chmod";
|
||||||
static SUMMARY: &'static str = "Change the mode of each FILE to MODE.
|
static SUMMARY: &'static str = "Change the mode of each FILE to MODE.
|
||||||
|
@ -197,9 +197,9 @@ impl Chmoder {
|
||||||
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
let result =
|
let result =
|
||||||
if mode.contains(arr) {
|
if mode.contains(arr) {
|
||||||
self.parse_numeric(fperm, mode)
|
mode::parse_numeric(fperm, mode)
|
||||||
} else {
|
} else {
|
||||||
self.parse_symbolic(fperm, mode, file)
|
mode::parse_symbolic(fperm, mode, file.is_dir())
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
Ok(mode) => {
|
Ok(mode) => {
|
||||||
|
@ -220,126 +220,6 @@ impl Chmoder {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_numeric(&self, fperm: u32, mut mode: &str) -> Result<u32, String> {
|
|
||||||
let (op, pos) = try!(self.parse_op(mode, Some('=')));
|
|
||||||
mode = mode[pos..].trim_left_matches('0');
|
|
||||||
if mode.len() > 4 {
|
|
||||||
Err(format!("mode is too large ({} > 7777)", mode))
|
|
||||||
} else {
|
|
||||||
match u32::from_str_radix(mode, 8) {
|
|
||||||
Ok(change) => {
|
|
||||||
Ok(match op {
|
|
||||||
'+' => fperm | change,
|
|
||||||
'-' => fperm & !change,
|
|
||||||
'=' => change,
|
|
||||||
_ => unreachable!()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(err) => Err(err.description().to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_symbolic(&self, mut fperm: u32, mut mode: &str, file: &Path) -> Result<u32, String> {
|
|
||||||
#[cfg(unix)]
|
|
||||||
use libc::umask;
|
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
|
||||||
unsafe fn umask(_mask: u32) -> u32 {
|
|
||||||
// XXX Redox does not currently have umask
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mask, pos) = self.parse_levels(mode);
|
|
||||||
if pos == mode.len() {
|
|
||||||
return Err(format!("invalid mode ({})", mode));
|
|
||||||
}
|
|
||||||
let respect_umask = pos == 0;
|
|
||||||
let last_umask = unsafe {
|
|
||||||
umask(0)
|
|
||||||
};
|
|
||||||
mode = &mode[pos..];
|
|
||||||
while mode.len() > 0 {
|
|
||||||
let (op, pos) = try!(self.parse_op(mode, None));
|
|
||||||
mode = &mode[pos..];
|
|
||||||
let (mut srwx, pos) = self.parse_change(mode, fperm, file);
|
|
||||||
if respect_umask {
|
|
||||||
srwx &= !(last_umask as u32);
|
|
||||||
}
|
|
||||||
mode = &mode[pos..];
|
|
||||||
match op {
|
|
||||||
'+' => fperm |= srwx & mask,
|
|
||||||
'-' => fperm &= !(srwx & mask),
|
|
||||||
'=' => fperm = (fperm & !mask) | (srwx & mask),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
umask(last_umask);
|
|
||||||
}
|
|
||||||
Ok(fperm)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_levels(&self, mode: &str) -> (u32, usize) {
|
|
||||||
let mut mask = 0;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
mask |= match ch {
|
|
||||||
'u' => 0o7700,
|
|
||||||
'g' => 0o7070,
|
|
||||||
'o' => 0o7007,
|
|
||||||
'a' => 0o7777,
|
|
||||||
_ => break
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
mask = 0o7777; // default to 'a'
|
|
||||||
}
|
|
||||||
(mask, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_op(&self, mode: &str, default: Option<char>) -> Result<(char, usize), String> {
|
|
||||||
match mode.chars().next() {
|
|
||||||
Some(ch) => match ch {
|
|
||||||
'+' | '-' | '=' => Ok((ch, 1)),
|
|
||||||
_ => match default {
|
|
||||||
Some(ch) => Ok((ch, 0)),
|
|
||||||
None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => Err("unexpected end of mode".to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_change(&self, mode: &str, fperm: u32, file: &Path) -> (u32, usize) {
|
|
||||||
let mut srwx = fperm & 0o7000;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
match ch {
|
|
||||||
'r' => srwx |= 0o444,
|
|
||||||
'w' => srwx |= 0o222,
|
|
||||||
'x' => srwx |= 0o111,
|
|
||||||
'X' => {
|
|
||||||
if file.is_dir() || (fperm & 0o0111) != 0 {
|
|
||||||
srwx |= 0o111
|
|
||||||
}
|
|
||||||
}
|
|
||||||
's' => srwx |= 0o4000 | 0o2000,
|
|
||||||
't' => srwx |= 0o1000,
|
|
||||||
'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
|
|
||||||
'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
|
|
||||||
'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
|
|
||||||
_ => break
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
srwx = 0;
|
|
||||||
}
|
|
||||||
(srwx, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn change_file(&self, fperm: u32, mode: u32, file: &Path, path: &str) -> Result<(), i32> {
|
fn change_file(&self, fperm: u32, mode: u32, file: &Path, path: &str) -> Result<(), i32> {
|
||||||
if fperm == mode {
|
if fperm == mode {
|
||||||
if self.verbose && !self.changes {
|
if self.verbose && !self.changes {
|
||||||
|
|
|
@ -23,7 +23,7 @@ use walkdir::WalkDir;
|
||||||
use std::fs::{self, Metadata};
|
use std::fs::{self, Metadata};
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
|
||||||
use std::io::{self, Write};
|
use std::io;
|
||||||
use std::io::Result as IOResult;
|
use std::io::Result as IOResult;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -18,7 +18,7 @@ use uucore::libc::{self, setgid, setuid, chroot, setgroups};
|
||||||
use uucore::entries;
|
use uucore::entries;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::{Error, Write};
|
use std::io::Error;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
* (c) Michael Gehring <mg@ebfe.org>
|
* (c) Michael Gehring <mg@ebfe.org>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, stdin, Read, Write, BufReader};
|
use std::io::{self, stdin, Read, BufReader};
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -39,7 +39,7 @@ use clap::{Arg, App, ArgMatches};
|
||||||
use quick_error::ResultExt;
|
use quick_error::ResultExt;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{BufReader, BufRead, stdin, Write};
|
use std::io::{BufReader, BufRead, stdin, stdout, Write};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf, StripPrefixError};
|
use std::path::{Path, PathBuf, StripPrefixError};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -114,9 +114,9 @@ macro_rules! or_continue(
|
||||||
/// answered yes.
|
/// answered yes.
|
||||||
macro_rules! prompt_yes(
|
macro_rules! prompt_yes(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
pipe_write!(&mut ::std::io::stdout(), $($args)+);
|
print!($($args)+);
|
||||||
pipe_write!(&mut ::std::io::stdout(), " [y/N]: ");
|
print!(" [y/N]: ");
|
||||||
pipe_flush!();
|
crash_if_err!(1, stdout().flush());
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
match BufReader::new(stdin()).read_line(&mut s) {
|
match BufReader::new(stdin()).read_line(&mut s) {
|
||||||
Ok(_) => match s.char_indices().nth(0) {
|
Ok(_) => match s.char_indices().nth(0) {
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl<R: Read> self::Bytes::Select for ByteReader<R> {
|
||||||
};
|
};
|
||||||
|
|
||||||
match out {
|
match out {
|
||||||
Some(out) => pipe_crash_if_err!(1, out.write_all(&buffer[0..consume_val])),
|
Some(out) => crash_if_err!(1, out.write_all(&buffer[0..consume_val])),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
(res, consume_val)
|
(res, consume_val)
|
||||||
|
|
|
@ -150,7 +150,7 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> i32 {
|
||||||
loop {
|
loop {
|
||||||
match buf_read.select(low - cur_pos, None::<&mut Stdout>) {
|
match buf_read.select(low - cur_pos, None::<&mut Stdout>) {
|
||||||
NewlineFound => {
|
NewlineFound => {
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
continue 'newline
|
continue 'newline
|
||||||
}
|
}
|
||||||
Complete(len) => {
|
Complete(len) => {
|
||||||
|
@ -160,7 +160,7 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> i32 {
|
||||||
Partial(len) => cur_pos += len,
|
Partial(len) => cur_pos += len,
|
||||||
EndOfFile => {
|
EndOfFile => {
|
||||||
if orig_pos != cur_pos {
|
if orig_pos != cur_pos {
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
|
|
||||||
break 'newline
|
break 'newline
|
||||||
|
@ -171,7 +171,7 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> i32 {
|
||||||
match opts.out_delim {
|
match opts.out_delim {
|
||||||
Some(ref delim) => {
|
Some(ref delim) => {
|
||||||
if print_delim {
|
if print_delim {
|
||||||
pipe_crash_if_err!(1, out.write_all(delim.as_bytes()));
|
crash_if_err!(1, out.write_all(delim.as_bytes()));
|
||||||
}
|
}
|
||||||
print_delim = true;
|
print_delim = true;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> i32 {
|
||||||
}
|
}
|
||||||
EndOfFile => {
|
EndOfFile => {
|
||||||
if cur_pos != low || low == high {
|
if cur_pos != low || low == high {
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
|
|
||||||
break 'newline
|
break 'newline
|
||||||
|
@ -199,7 +199,7 @@ fn cut_bytes<R: Read>(reader: R, ranges: &[Range], opts: &Options) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_read.consume_line();
|
buf_read.consume_line();
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
0
|
||||||
|
@ -230,9 +230,9 @@ fn cut_fields_delimiter<R: Read>(reader: R, ranges: &[Range], delim: &str, only_
|
||||||
|
|
||||||
if delim_search.peek().is_none() {
|
if delim_search.peek().is_none() {
|
||||||
if ! only_delimited {
|
if ! only_delimited {
|
||||||
pipe_crash_if_err!(1, out.write_all(line));
|
crash_if_err!(1, out.write_all(line));
|
||||||
if line[line.len() - 1] != newline_char {
|
if line[line.len() - 1] != newline_char {
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,14 +249,14 @@ fn cut_fields_delimiter<R: Read>(reader: R, ranges: &[Range], delim: &str, only_
|
||||||
|
|
||||||
for _ in 0..high - low + 1 {
|
for _ in 0..high - low + 1 {
|
||||||
if print_delim {
|
if print_delim {
|
||||||
pipe_crash_if_err!(1, out.write_all(out_delim.as_bytes()));
|
crash_if_err!(1, out.write_all(out_delim.as_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
match delim_search.next() {
|
match delim_search.next() {
|
||||||
Some((high_idx, next_low_idx)) => {
|
Some((high_idx, next_low_idx)) => {
|
||||||
let segment = &line[low_idx..high_idx];
|
let segment = &line[low_idx..high_idx];
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(segment));
|
crash_if_err!(1, out.write_all(segment));
|
||||||
|
|
||||||
print_delim = true;
|
print_delim = true;
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ fn cut_fields_delimiter<R: Read>(reader: R, ranges: &[Range], delim: &str, only_
|
||||||
None => {
|
None => {
|
||||||
let segment = &line[low_idx..];
|
let segment = &line[low_idx..];
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(segment));
|
crash_if_err!(1, out.write_all(segment));
|
||||||
|
|
||||||
if line[line.len() - 1] == newline_char {
|
if line[line.len() - 1] == newline_char {
|
||||||
continue 'newline
|
continue 'newline
|
||||||
|
@ -277,7 +277,7 @@ fn cut_fields_delimiter<R: Read>(reader: R, ranges: &[Range], delim: &str, only_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
0
|
||||||
|
@ -318,9 +318,9 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32
|
||||||
|
|
||||||
if delim_search.peek().is_none() {
|
if delim_search.peek().is_none() {
|
||||||
if ! opts.only_delimited {
|
if ! opts.only_delimited {
|
||||||
pipe_crash_if_err!(1, out.write_all(line));
|
crash_if_err!(1, out.write_all(line));
|
||||||
if line[line.len() - 1] != newline_char {
|
if line[line.len() - 1] != newline_char {
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32
|
||||||
Some((high_idx, next_low_idx)) => {
|
Some((high_idx, next_low_idx)) => {
|
||||||
let segment = &line[low_idx..high_idx];
|
let segment = &line[low_idx..high_idx];
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(segment));
|
crash_if_err!(1, out.write_all(segment));
|
||||||
|
|
||||||
print_delim = true;
|
print_delim = true;
|
||||||
low_idx = next_low_idx;
|
low_idx = next_low_idx;
|
||||||
|
@ -354,7 +354,7 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32
|
||||||
None => {
|
None => {
|
||||||
let segment = &line[low_idx..line.len()];
|
let segment = &line[low_idx..line.len()];
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(segment));
|
crash_if_err!(1, out.write_all(segment));
|
||||||
|
|
||||||
if line[line.len() - 1] == newline_char {
|
if line[line.len() - 1] == newline_char {
|
||||||
continue 'newline
|
continue 'newline
|
||||||
|
@ -364,7 +364,7 @@ fn cut_fields<R: Read>(reader: R, ranges: &[Range], opts: &FieldOptions) -> i32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_crash_if_err!(1, out.write_all(&[newline_char]));
|
crash_if_err!(1, out.write_all(&[newline_char]));
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
0
|
||||||
|
|
|
@ -13,9 +13,8 @@ extern crate glob;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, Write};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::{Write, stdout};
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -173,7 +173,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.newline {
|
if options.newline {
|
||||||
pipe_flush!();
|
return_if_err!(1, stdout().flush())
|
||||||
} else {
|
} else {
|
||||||
println!("")
|
println!("")
|
||||||
}
|
}
|
||||||
|
|
4
src/env/env.rs
vendored
4
src/env/env.rs
vendored
|
@ -17,7 +17,7 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
use std::io::{Write, stdout};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
static NAME: &'static str = "env";
|
static NAME: &'static str = "env";
|
||||||
|
@ -189,7 +189,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
} else {
|
} else {
|
||||||
// no program provided
|
// no program provided
|
||||||
print_env(opts.null);
|
print_env(opts.null);
|
||||||
pipe_flush!();
|
return_if_err!(1, stdout().flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
0
|
||||||
|
|
|
@ -16,8 +16,6 @@ extern crate onig;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
mod syntax_tree;
|
mod syntax_tree;
|
||||||
|
|
||||||
use std::io::{Write};
|
|
||||||
|
|
||||||
static NAME: &'static str = "expr";
|
static NAME: &'static str = "expr";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern crate uucore;
|
||||||
use numeric::*;
|
use numeric::*;
|
||||||
use rand::distributions::{Range, IndependentSample};
|
use rand::distributions::{Range, IndependentSample};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::io::{stdin, BufRead, BufReader, Write};
|
use std::io::{stdin, BufRead, BufReader};
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
use std::mem::swap;
|
use std::mem::swap;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, Read, stdin, Write};
|
use std::io::{BufRead, BufReader, Read, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
|
static SYNTAX: &'static str = "[OPTION]... [FILE]...";
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
use uucore::entries::{Passwd, Locate, get_groups, gid2grp};
|
use uucore::entries::{Passwd, Locate, get_groups, gid2grp};
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[user]";
|
static SYNTAX: &'static str = "[user]";
|
||||||
static SUMMARY: &'static str = "display current group names";
|
static SUMMARY: &'static str = "display current group names";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
* (c) Vsevolod Velichko <torkvemada@sorokdva.net>
|
* (c) Vsevolod Velichko <torkvemada@sorokdva.net>
|
||||||
* (c) Gil Cottle <gcottle@redtown.org>
|
* (c) Gil Cottle <gcottle@redtown.org>
|
||||||
*
|
*
|
||||||
|
@ -34,7 +34,7 @@ use sha2::{Sha224, Sha256, Sha384, Sha512};
|
||||||
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
|
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shake256};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, BufRead, BufReader, Read, stdin, Write};
|
use std::io::{self, BufRead, BufReader, Read, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &'static str = "hashsum";
|
static NAME: &'static str = "hashsum";
|
||||||
|
@ -232,7 +232,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn version() {
|
fn version() {
|
||||||
pipe_println!("{} {}", NAME, VERSION);
|
println!("{} {}", NAME, VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(program: &str, binary_name: &str, opts: &getopts::Options) {
|
fn usage(program: &str, binary_name: &str, opts: &getopts::Options) {
|
||||||
|
@ -251,7 +251,7 @@ Usage:
|
||||||
|
|
||||||
Compute and check message digests.", NAME, VERSION, spec);
|
Compute and check message digests.", NAME, VERSION, spec);
|
||||||
|
|
||||||
pipe_print!("{}", opts.usage(&msg));
|
print!("{}", opts.usage(&msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool, output_bits: usize) -> Result<(), i32> {
|
fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool, output_bits: usize) -> Result<(), i32> {
|
||||||
|
@ -325,11 +325,11 @@ fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary:
|
||||||
.to_ascii_lowercase();
|
.to_ascii_lowercase();
|
||||||
if sum == real_sum {
|
if sum == real_sum {
|
||||||
if !quiet {
|
if !quiet {
|
||||||
pipe_println!("{}: OK", ck_filename);
|
println!("{}: OK", ck_filename);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !status {
|
if !status {
|
||||||
pipe_println!("{}: FAILED", ck_filename);
|
println!("{}: FAILED", ck_filename);
|
||||||
}
|
}
|
||||||
failed += 1;
|
failed += 1;
|
||||||
}
|
}
|
||||||
|
@ -337,9 +337,9 @@ fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary:
|
||||||
} else {
|
} else {
|
||||||
let sum = safe_unwrap!(digest_reader(&mut digest, &mut file, binary, output_bits));
|
let sum = safe_unwrap!(digest_reader(&mut digest, &mut file, binary, output_bits));
|
||||||
if tag {
|
if tag {
|
||||||
pipe_println!("{} ({}) = {}", algoname, filename, sum);
|
println!("{} ({}) = {}", algoname, filename, sum);
|
||||||
} else {
|
} else {
|
||||||
pipe_println!("{} {}{}", sum, binary_marker, filename);
|
println!("{} {}{}", sum, binary_marker, filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::{BufRead, BufReader, Read, stdin, Write};
|
use std::io::{BufRead, BufReader, Read, stdin};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
@ -115,8 +115,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
|
|
||||||
for file in &files {
|
for file in &files {
|
||||||
if settings.verbose {
|
if settings.verbose {
|
||||||
if !firstime { pipe_println!(""); }
|
if !firstime { println!(""); }
|
||||||
pipe_println!("==> {} <==", file);
|
println!("==> {} <==", file);
|
||||||
}
|
}
|
||||||
firstime = false;
|
firstime = false;
|
||||||
|
|
||||||
|
@ -171,16 +171,12 @@ fn head<T: Read>(reader: &mut BufReader<T>, settings: &Settings) -> bool {
|
||||||
match settings.mode {
|
match settings.mode {
|
||||||
FilterMode::Bytes(count) => {
|
FilterMode::Bytes(count) => {
|
||||||
for byte in reader.bytes().take(count) {
|
for byte in reader.bytes().take(count) {
|
||||||
if !pipe_print!("{}", byte.unwrap() as char) {
|
print!("{}", byte.unwrap() as char);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
FilterMode::Lines(count) => {
|
FilterMode::Lines(count) => {
|
||||||
for line in reader.lines().take(count) {
|
for line in reader.lines().take(count) {
|
||||||
if !pipe_println!("{}", line.unwrap()) {
|
println!("{}", line.unwrap());
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ extern crate uucore;
|
||||||
use std::collections::hash_set::HashSet;
|
use std::collections::hash_set::HashSet;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::io::Write;
|
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[OPTION]... [HOSTNAME]";
|
static SYNTAX: &'static str = "[OPTION]... [HOSTNAME]";
|
||||||
|
|
|
@ -22,7 +22,6 @@ pub use uucore::libc;
|
||||||
use uucore::libc::{getlogin, uid_t};
|
use uucore::libc::{getlogin, uid_t};
|
||||||
use uucore::entries::{self, Passwd, Group, Locate};
|
use uucore::entries::{self, Passwd, Group, Locate};
|
||||||
use uucore::process::{getgid, getuid, getegid, geteuid};
|
use uucore::process::{getgid, getuid, getegid, geteuid};
|
||||||
use std::io::Write;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
macro_rules! cstr2cow {
|
macro_rules! cstr2cow {
|
||||||
|
|
|
@ -18,7 +18,6 @@ mod mode;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
use uucore::mode;
|
||||||
|
|
||||||
/// Takes a user-supplied string and tries to parse to u16 mode bitmask.
|
/// Takes a user-supplied string and tries to parse to u16 mode bitmask.
|
||||||
pub fn parse(mode_string: &str, considering_dir: bool) -> Result<u32, String> {
|
pub fn parse(mode_string: &str, considering_dir: bool) -> Result<u32, String> {
|
||||||
|
@ -10,9 +11,9 @@ pub fn parse(mode_string: &str, considering_dir: bool) -> Result<u32, String> {
|
||||||
|
|
||||||
// Passing 000 as the existing permissions seems to mirror GNU behaviour.
|
// Passing 000 as the existing permissions seems to mirror GNU behaviour.
|
||||||
if mode_string.contains(numbers) {
|
if mode_string.contains(numbers) {
|
||||||
chmod_rs::parse_numeric(0, mode_string)
|
mode::parse_numeric(0, mode_string)
|
||||||
} else {
|
} else {
|
||||||
chmod_rs::parse_symbolic(0, mode_string, considering_dir)
|
mode::parse_symbolic(0, mode_string, considering_dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,131 +38,3 @@ pub fn chmod(path: &Path, mode: u32) -> Result<(), ()> {
|
||||||
// chmod on Windows only sets the readonly flag, which isn't even honored on directories
|
// chmod on Windows only sets the readonly flag, which isn't even honored on directories
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parsing functions taken from chmod.rs.
|
|
||||||
///
|
|
||||||
/// We keep these in a dedicated module to minimize debt of duplicated code.
|
|
||||||
///
|
|
||||||
mod chmod_rs {
|
|
||||||
extern crate libc;
|
|
||||||
|
|
||||||
pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result<u32, String> {
|
|
||||||
let (op, pos) = try!(parse_op(mode, Some('=')));
|
|
||||||
mode = mode[pos..].trim_left_matches('0');
|
|
||||||
if mode.len() > 4 {
|
|
||||||
Err(format!("mode is too large ({} > 7777)", mode))
|
|
||||||
} else {
|
|
||||||
match u32::from_str_radix(mode, 8) {
|
|
||||||
Ok(change) => {
|
|
||||||
Ok(match op {
|
|
||||||
'+' => fperm | change,
|
|
||||||
'-' => fperm & !change,
|
|
||||||
'=' => change,
|
|
||||||
_ => unreachable!()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(_) => Err(String::from("numeric parsing error"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_symbolic(mut fperm: u32, mut mode: &str, considering_dir: bool) -> Result<u32, String> {
|
|
||||||
#[cfg(unix)]
|
|
||||||
use libc::umask;
|
|
||||||
|
|
||||||
#[cfg(target_os = "redox")]
|
|
||||||
unsafe fn umask(_mask: u32) -> u32 {
|
|
||||||
// XXX Redox does not currently have umask
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
let (mask, pos) = parse_levels(mode);
|
|
||||||
if pos == mode.len() {
|
|
||||||
return Err(format!("invalid mode ({})", mode));
|
|
||||||
}
|
|
||||||
let respect_umask = pos == 0;
|
|
||||||
let last_umask = unsafe {
|
|
||||||
umask(0)
|
|
||||||
};
|
|
||||||
mode = &mode[pos..];
|
|
||||||
while mode.len() > 0 {
|
|
||||||
let (op, pos) = try!(parse_op(mode, None));
|
|
||||||
mode = &mode[pos..];
|
|
||||||
let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
|
|
||||||
if respect_umask {
|
|
||||||
srwx &= !(last_umask as u32);
|
|
||||||
}
|
|
||||||
mode = &mode[pos..];
|
|
||||||
match op {
|
|
||||||
'+' => fperm |= srwx & mask,
|
|
||||||
'-' => fperm &= !(srwx & mask),
|
|
||||||
'=' => fperm = (fperm & !mask) | (srwx & mask),
|
|
||||||
_ => unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
umask(last_umask);
|
|
||||||
}
|
|
||||||
Ok(fperm)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_levels(mode: &str) -> (u32, usize) {
|
|
||||||
let mut mask = 0;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
mask |= match ch {
|
|
||||||
'u' => 0o7700,
|
|
||||||
'g' => 0o7070,
|
|
||||||
'o' => 0o7007,
|
|
||||||
'a' => 0o7777,
|
|
||||||
_ => break
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
mask = 0o7777; // default to 'a'
|
|
||||||
}
|
|
||||||
(mask, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
|
|
||||||
match mode.chars().next() {
|
|
||||||
Some(ch) => match ch {
|
|
||||||
'+' | '-' | '=' => Ok((ch, 1)),
|
|
||||||
_ => match default {
|
|
||||||
Some(ch) => Ok((ch, 0)),
|
|
||||||
None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => Err("unexpected end of mode".to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) {
|
|
||||||
let mut srwx = fperm & 0o7000;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
match ch {
|
|
||||||
'r' => srwx |= 0o444,
|
|
||||||
'w' => srwx |= 0o222,
|
|
||||||
'x' => srwx |= 0o111,
|
|
||||||
'X' => {
|
|
||||||
if considering_dir || (fperm & 0o0111) != 0 {
|
|
||||||
srwx |= 0o111
|
|
||||||
}
|
|
||||||
}
|
|
||||||
's' => srwx |= 0o4000 | 0o2000,
|
|
||||||
't' => srwx |= 0o1000,
|
|
||||||
'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
|
|
||||||
'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
|
|
||||||
'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
|
|
||||||
_ => break
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
srwx = 0;
|
|
||||||
}
|
|
||||||
(srwx, pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate libc;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use libc::{c_int, pid_t};
|
use libc::{c_int, pid_t};
|
||||||
use std::io::{Error, Write};
|
use std::io::Error;
|
||||||
use uucore::signals::ALL_SIGNALS;
|
use uucore::signals::ALL_SIGNALS;
|
||||||
|
|
||||||
static SYNTAX: &'static str = "[options] <pid> [...]";
|
static SYNTAX: &'static str = "[options] <pid> [...]";
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::hard_link;
|
use std::fs::hard_link;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{BufRead, BufReader, Result, stdin, Write};
|
use std::io::{BufRead, BufReader, Result, stdin};
|
||||||
#[cfg(unix)] use std::os::unix::fs::symlink;
|
#[cfg(unix)] use std::os::unix::fs::symlink;
|
||||||
#[cfg(windows)] use std::os::windows::fs::{symlink_file,symlink_dir};
|
#[cfg(windows)] use std::os::windows::fs::{symlink_file,symlink_dir};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern crate libc;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
// POSIX requires using getlogin (or equivalent code)
|
// POSIX requires using getlogin (or equivalent code)
|
||||||
|
|
|
@ -30,7 +30,6 @@ use uucore::libc::{S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::{DirEntry, FileType, Metadata};
|
use std::fs::{DirEntry, FileType, Metadata};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::io::Write;
|
|
||||||
use std::cmp::Reverse;
|
use std::cmp::Reverse;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
|
@ -16,7 +16,6 @@ extern crate libc;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
static NAME: &'static str = "mkdir";
|
static NAME: &'static str = "mkdir";
|
||||||
|
|
|
@ -17,7 +17,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use libc::mkfifo;
|
use libc::mkfifo;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::{Error, Write};
|
use std::io::Error;
|
||||||
|
|
||||||
static NAME: &'static str = "mkfifo";
|
static NAME: &'static str = "mkfifo";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
|
@ -20,7 +20,6 @@ use libc::{mode_t, dev_t};
|
||||||
use libc::{S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IFIFO, S_IFBLK, S_IFCHR};
|
use libc::{S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IFIFO, S_IFBLK, S_IFCHR};
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
|
|
@ -1,124 +1,23 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
use libc::{mode_t, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IRUSR, S_IWUSR};
|
use libc::{mode_t, S_IRGRP, S_IWGRP, S_IROTH, S_IWOTH, S_IRUSR, S_IWUSR};
|
||||||
|
|
||||||
fn parse_change(mode: &str, fperm: mode_t) -> (mode_t, usize) {
|
use uucore::mode;
|
||||||
let mut srwx = fperm & 0o7000;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
match ch {
|
|
||||||
'r' => srwx |= 0o444,
|
|
||||||
'w' => srwx |= 0o222,
|
|
||||||
'x' => srwx |= 0o111,
|
|
||||||
'X' => srwx |= 0o111,
|
|
||||||
's' => srwx |= 0o4000 | 0o2000,
|
|
||||||
't' => srwx |= 0o1000,
|
|
||||||
'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
|
|
||||||
'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
|
|
||||||
'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
|
|
||||||
_ => break,
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
srwx = 0;
|
|
||||||
}
|
|
||||||
(srwx, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_levels(mode: &str) -> (mode_t, usize) {
|
|
||||||
let mut mask = 0;
|
|
||||||
let mut pos = 0;
|
|
||||||
for ch in mode.chars() {
|
|
||||||
mask |= match ch {
|
|
||||||
'u' => 0o7700,
|
|
||||||
'g' => 0o7070,
|
|
||||||
'o' => 0o7007,
|
|
||||||
'a' => 0o7777,
|
|
||||||
_ => break,
|
|
||||||
};
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == 0 {
|
|
||||||
mask = 0o7777; // default to 'a'
|
|
||||||
}
|
|
||||||
(mask, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_symbolic(mut fperm: mode_t, mut mode: &str) -> Result<mode_t, String> {
|
|
||||||
let (mask, pos) = parse_levels(mode);
|
|
||||||
if pos == mode.len() {
|
|
||||||
return Err("invalid mode".to_owned());
|
|
||||||
}
|
|
||||||
mode = &mode[pos..];
|
|
||||||
while mode.len() > 0 {
|
|
||||||
let (op, pos) = try!(parse_op(mode, None));
|
|
||||||
mode = &mode[pos..];
|
|
||||||
let (srwx, pos) = parse_change(mode, fperm);
|
|
||||||
mode = &mode[pos..];
|
|
||||||
match op {
|
|
||||||
'+' => fperm |= srwx & mask,
|
|
||||||
'-' => fperm &= !(srwx & mask),
|
|
||||||
'=' => fperm = (fperm & !mask) | (srwx & mask),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(fperm)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
|
|
||||||
match mode.chars().next() {
|
|
||||||
Some(ch) => {
|
|
||||||
match ch {
|
|
||||||
'+' | '-' | '=' => Ok((ch, 1)),
|
|
||||||
_ => {
|
|
||||||
match default {
|
|
||||||
Some(ch) => Ok((ch, 0)),
|
|
||||||
None => {
|
|
||||||
Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => Err("unexpected end of mode".to_owned()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_numeric(fperm: mode_t, mut mode: &str) -> Result<mode_t, String> {
|
|
||||||
let (op, pos) = try!(parse_op(mode, Some('=')));
|
|
||||||
mode = mode[pos..].trim_left_matches('0');
|
|
||||||
match mode_t::from_str_radix(mode, 8) {
|
|
||||||
Ok(change) => {
|
|
||||||
let after = match op {
|
|
||||||
'+' => fperm | change,
|
|
||||||
'-' => fperm & !change,
|
|
||||||
'=' => change,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
if after > 0o7777 {
|
|
||||||
return Err("invalid mode".to_owned());
|
|
||||||
}
|
|
||||||
Ok(after)
|
|
||||||
}
|
|
||||||
Err(_) => Err("invalid mode".to_owned()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
|
pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
|
||||||
let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||||
if let Some(mode) = mode {
|
if let Some(mode) = mode {
|
||||||
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||||
let result = if mode.contains(arr) {
|
let result = if mode.contains(arr) {
|
||||||
parse_numeric(fperm, mode.as_str())
|
mode::parse_numeric(fperm, mode.as_str())
|
||||||
} else {
|
} else {
|
||||||
parse_symbolic(fperm, mode.as_str())
|
mode::parse_symbolic(fperm, mode.as_str(), true)
|
||||||
};
|
};
|
||||||
result
|
result.map(|mode| mode as mode_t)
|
||||||
} else {
|
} else {
|
||||||
Ok(fperm)
|
Ok(fperm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn symbolic_modes() {
|
fn symbolic_modes() {
|
||||||
assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern crate rand;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{PathBuf, is_separator};
|
use std::path::{PathBuf, is_separator};
|
||||||
use std::mem::forget;
|
use std::mem::forget;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
|
@ -16,7 +16,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::{BufRead, BufReader, Result, stdin, Write};
|
use std::io::{BufRead, BufReader, Result, stdin};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
static NAME: &'static str = "mv";
|
static NAME: &'static str = "mv";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -17,7 +17,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use libc::{c_char, c_int, execvp};
|
use libc::{c_char, c_int, execvp};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::{Error, Write};
|
use std::io::Error;
|
||||||
|
|
||||||
const NAME: &'static str = "nice";
|
const NAME: &'static str = "nice";
|
||||||
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
const VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern crate regex;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, Read, stdin, Write};
|
use std::io::{BufRead, BufReader, Read, stdin};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ use libc::{c_char, signal, dup2, execvp};
|
||||||
use libc::{SIG_IGN, SIGHUP};
|
use libc::{SIG_IGN, SIGHUP};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{Error, Write};
|
use std::io::Error;
|
||||||
use std::os::unix::prelude::*;
|
use std::os::unix::prelude::*;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
|
@ -18,7 +18,6 @@ extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
pub enum InputSource<'a> {
|
pub enum InputSource<'a> {
|
||||||
|
|
|
@ -34,7 +34,6 @@ mod output_info;
|
||||||
mod mockstream;
|
mod mockstream;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::io::Write;
|
|
||||||
use byteorder_io::*;
|
use byteorder_io::*;
|
||||||
use multifilereader::*;
|
use multifilereader::*;
|
||||||
use partialreader::*;
|
use partialreader::*;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -14,7 +14,7 @@ extern crate getopts;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::{BufRead, BufReader, Read, stdin, Write};
|
use std::io::{BufRead, BufReader, Read, stdin};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -16,7 +16,6 @@ extern crate getopts;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
static NAME: &'static str = "printenv";
|
static NAME: &'static str = "printenv";
|
||||||
|
|
|
@ -14,7 +14,6 @@ extern crate getopts;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
static NAME: &'static str = "pwd";
|
static NAME: &'static str = "pwd";
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::{Write, stdout};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use uucore::fs::{canonicalize, CanonicalizeMode};
|
use uucore::fs::{canonicalize, CanonicalizeMode};
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ fn show(path: &PathBuf, no_newline: bool, use_zero: bool) {
|
||||||
} else {
|
} else {
|
||||||
println!("{}", path);
|
println!("{}", path);
|
||||||
}
|
}
|
||||||
pipe_flush!();
|
crash_if_err!(1, stdout().flush());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_usage(opts: &getopts::Options) {
|
fn show_usage(opts: &getopts::Options) {
|
||||||
|
|
|
@ -15,7 +15,6 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use uucore::fs::{canonicalize, CanonicalizeMode};
|
use uucore::fs::{canonicalize, CanonicalizeMode};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use uucore::fs::{canonicalize, CanonicalizeMode};
|
use uucore::fs::{canonicalize, CanonicalizeMode};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -15,7 +15,6 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &'static str = "rmdir";
|
static NAME: &'static str = "rmdir";
|
||||||
|
|
|
@ -9,7 +9,7 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::io::Write;
|
use std::io::{Write, stdout};
|
||||||
|
|
||||||
static NAME: &'static str = "seq";
|
static NAME: &'static str = "seq";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
@ -225,22 +225,18 @@ fn print_seq(first: f64, step: f64, last: f64, largest_dec: usize, separator: St
|
||||||
let before_dec = istr.find('.').unwrap_or(ilen);
|
let before_dec = istr.find('.').unwrap_or(ilen);
|
||||||
if pad && before_dec < padding {
|
if pad && before_dec < padding {
|
||||||
for _ in 0..(padding - before_dec) {
|
for _ in 0..(padding - before_dec) {
|
||||||
if !pipe_print!("0") {
|
print!("0");
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pipe_print!("{}", istr);
|
print!("{}", istr);
|
||||||
i += 1;
|
i += 1;
|
||||||
value = first + i as f64 * step;
|
value = first + i as f64 * step;
|
||||||
if !done_printing(value, step, last) {
|
if !done_printing(value, step, last) {
|
||||||
if !pipe_print!("{}", separator) {
|
print!("{}", separator);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (first >= last && step < 0f64) || (first <= last && step > 0f64) {
|
if (first >= last && step < 0f64) || (first <= last && step > 0f64) {
|
||||||
pipe_print!("{}", terminator);
|
print!("{}", terminator);
|
||||||
}
|
}
|
||||||
pipe_flush!();
|
crash_if_err!(1, stdout().flush());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -14,8 +14,7 @@ extern crate getopts;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::Write;
|
use std::thread;
|
||||||
use std::thread::{self};
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
static NAME: &'static str = "sleep";
|
static NAME: &'static str = "sleep";
|
||||||
|
|
|
@ -21,7 +21,7 @@ use uucore::entries;
|
||||||
|
|
||||||
use std::{fs, iter, cmp};
|
use std::{fs, iter, cmp};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Write, BufReader, BufRead};
|
use std::io::{BufReader, BufRead};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::os::unix::fs::{FileTypeExt, MetadataExt};
|
use std::os::unix::fs::{FileTypeExt, MetadataExt};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -5,7 +5,6 @@ extern crate uucore;
|
||||||
|
|
||||||
use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF};
|
use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Write;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use getopts::{Matches, Options};
|
use getopts::{Matches, Options};
|
||||||
use std::io::{self, Write};
|
use std::io;
|
||||||
use std::os::unix::process::ExitStatusExt;
|
use std::os::unix::process::ExitStatusExt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
|
@ -15,7 +15,7 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Result, stdin, Write};
|
use std::io::{Read, Result, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &'static str = "sum";
|
static NAME: &'static str = "sum";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -16,7 +16,7 @@ extern crate time;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::io::{ErrorKind, Write};
|
use std::io::ErrorKind;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use uucore::process::ChildExt;
|
use uucore::process::ChildExt;
|
||||||
|
|
|
@ -18,7 +18,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use filetime::*;
|
use filetime::*;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{self, Error, Write};
|
use std::io::{self, Error};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &'static str = "touch";
|
static NAME: &'static str = "touch";
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -16,7 +16,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fs::{File, metadata, OpenOptions};
|
use std::fs::{File, metadata, OpenOptions};
|
||||||
use std::io::{Result, Write};
|
use std::io::Result;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
|
|
|
@ -17,7 +17,7 @@ extern crate uucore;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader, Read, stdin, Write};
|
use std::io::{BufRead, BufReader, Read, stdin};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
static NAME: &'static str = "tsort";
|
static NAME: &'static str = "tsort";
|
||||||
|
|
|
@ -18,7 +18,6 @@ extern crate libc;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::io::Write;
|
|
||||||
use uucore::fs::is_stdin_interactive;
|
use uucore::fs::is_stdin_interactive;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
|
|
@ -273,5 +273,5 @@ fn unexpand(options: Options) {
|
||||||
buf.truncate(0); // clear out the buffer
|
buf.truncate(0); // clear out the buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pipe_flush!(output);
|
crash_if_err!(1, output.flush())
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern crate uucore;
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use libc::{S_IFMT, S_IFLNK, S_IFREG};
|
use libc::{S_IFMT, S_IFLNK, S_IFREG};
|
||||||
use libc::{lstat, unlink, c_char, stat};
|
use libc::{lstat, unlink, c_char, stat};
|
||||||
use std::io::{Error, ErrorKind, Write};
|
use std::io::{Error, ErrorKind};
|
||||||
use std::mem::uninitialized;
|
use std::mem::uninitialized;
|
||||||
|
|
||||||
static NAME: &'static str = "unlink";
|
static NAME: &'static str = "unlink";
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub use uucore::libc;
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::Read;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
|
||||||
static NAME: &'static str = "uptime";
|
static NAME: &'static str = "uptime";
|
||||||
|
|
|
@ -17,13 +17,14 @@ fs = ["libc"]
|
||||||
utf8 = []
|
utf8 = []
|
||||||
encoding = ["data-encoding"]
|
encoding = ["data-encoding"]
|
||||||
parse_time = []
|
parse_time = []
|
||||||
|
mode = ["libc"]
|
||||||
utmpx = ["time", "libc"]
|
utmpx = ["time", "libc"]
|
||||||
process = ["libc"]
|
process = ["libc"]
|
||||||
signals = []
|
signals = []
|
||||||
entries = ["libc"]
|
entries = ["libc"]
|
||||||
wide = []
|
wide = []
|
||||||
utsname = ["libc"]
|
utsname = ["libc"]
|
||||||
default = ["fs", "libc", "utf8", "utsname", "encoding", "parse_time", "utmpx", "process", "entries", "signals", "wide"]
|
default = ["fs", "libc", "utf8", "utsname", "encoding", "parse_time", "mode", "utmpx", "process", "entries", "signals", "wide"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
pub struct HelpText<'a> {
|
pub struct HelpText<'a> {
|
||||||
pub name : &'a str,
|
pub name : &'a str,
|
||||||
|
@ -53,8 +52,8 @@ impl<'a> CoreOptions<'a> {
|
||||||
let matches = match self.options.parse(&args[1..]) {
|
let matches = match self.options.parse(&args[1..]) {
|
||||||
Ok(m) => { Some(m) },
|
Ok(m) => { Some(m) },
|
||||||
Err(f) => {
|
Err(f) => {
|
||||||
pipe_write!(&mut ::std::io::stderr(), "{}: error: ", self.help_text.name);
|
eprint!("{}: error: ", self.help_text.name);
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), "{}", f);
|
eprintln!("{}", f);
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
}
|
}
|
||||||
}.unwrap();
|
}.unwrap();
|
||||||
|
|
|
@ -18,6 +18,8 @@ pub mod encoding;
|
||||||
#[cfg(feature = "parse_time")]
|
#[cfg(feature = "parse_time")]
|
||||||
pub mod parse_time;
|
pub mod parse_time;
|
||||||
|
|
||||||
|
#[cfg(all(not(windows), feature = "mode"))]
|
||||||
|
pub mod mode;
|
||||||
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "utmpx"))]
|
#[cfg(all(unix, not(target_os = "fuchsia"), feature = "utmpx"))]
|
||||||
pub mod utmpx;
|
pub mod utmpx;
|
||||||
#[cfg(all(unix, feature = "utsname"))]
|
#[cfg(all(unix, feature = "utsname"))]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
@ -22,46 +22,36 @@ macro_rules! executable(
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! show_error(
|
macro_rules! show_error(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
pipe_write!(&mut ::std::io::stderr(), "{}: error: ", executable!());
|
eprint!("{}: error: ", executable!());
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
|
eprintln!($($args)+);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! show_warning(
|
macro_rules! show_warning(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
pipe_write!(&mut ::std::io::stderr(), "{}: warning: ", executable!());
|
eprint!("{}: warning: ", executable!());
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
|
eprintln!($($args)+);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! show_info(
|
macro_rules! show_info(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
pipe_write!(&mut ::std::io::stderr(), "{}: ", executable!());
|
eprint!("{}: ", executable!());
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
|
eprintln!($($args)+);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! disp_err(
|
macro_rules! disp_err(
|
||||||
($($args:tt)+) => ({
|
($($args:tt)+) => ({
|
||||||
pipe_write!(&mut ::std::io::stderr(), "{}: ", executable!());
|
eprint!("{}: ", executable!());
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
|
eprintln!($($args)+);
|
||||||
pipe_writeln!(&mut ::std::io::stderr(), "Try '{} --help' for more information.", executable!());
|
eprintln!("Try '{} --help' for more information.", executable!());
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! eprint(
|
|
||||||
($($args:tt)+) => (pipe_write!(&mut ::std::io::stderr(), $($args)+))
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! eprintln(
|
|
||||||
($($args:tt)+) => (pipe_writeln!(&mut ::std::io::stderr(), $($args)+))
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! crash(
|
macro_rules! crash(
|
||||||
($exitcode:expr, $($args:tt)+) => ({
|
($exitcode:expr, $($args:tt)+) => ({
|
||||||
|
@ -87,22 +77,6 @@ macro_rules! crash_if_err(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_crash_if_err(
|
|
||||||
($exitcode:expr, $exp:expr) => (
|
|
||||||
match $exp {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
()
|
|
||||||
} else {
|
|
||||||
crash!($exitcode, "{}", f)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! return_if_err(
|
macro_rules! return_if_err(
|
||||||
($exitcode:expr, $exp:expr) => (
|
($exitcode:expr, $exp:expr) => (
|
||||||
|
@ -116,100 +90,6 @@ macro_rules! return_if_err(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// XXX: should the pipe_* macros return an Err just to show the write failed?
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_print(
|
|
||||||
($($args:tt)+) => (
|
|
||||||
match write!(&mut ::std::io::stdout(), $($args)+) {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_println(
|
|
||||||
($($args:tt)+) => (
|
|
||||||
match writeln!(&mut ::std::io::stdout(), $($args)+) {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_write(
|
|
||||||
($fd:expr, $($args:tt)+) => (
|
|
||||||
match write!($fd, $($args)+) {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_writeln(
|
|
||||||
($fd:expr, $($args:tt)+) => (
|
|
||||||
match writeln!($fd, $($args)+) {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! pipe_flush(
|
|
||||||
() => (
|
|
||||||
match ::std::io::stdout().flush() {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($fd:expr) => (
|
|
||||||
match $fd.flush() {
|
|
||||||
Ok(_) => true,
|
|
||||||
Err(f) => {
|
|
||||||
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
panic!("{}", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! safe_write(
|
macro_rules! safe_write(
|
||||||
($fd:expr, $($args:tt)+) => (
|
($fd:expr, $($args:tt)+) => (
|
||||||
|
|
129
src/uucore/mode.rs
Normal file
129
src/uucore/mode.rs
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
// This file is part of the uutils coreutils package.
|
||||||
|
//
|
||||||
|
// (c) Alex Lyon <arcterus@mail.com>
|
||||||
|
//
|
||||||
|
// For the full copyright and license information, please view the LICENSE
|
||||||
|
// file that was distributed with this source code.
|
||||||
|
//
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result<u32, String> {
|
||||||
|
let (op, pos) = parse_op(mode, Some('='))?;
|
||||||
|
mode = mode[pos..].trim_left_matches('0');
|
||||||
|
if mode.len() > 4 {
|
||||||
|
Err(format!("mode is too large ({} > 7777)", mode))
|
||||||
|
} else {
|
||||||
|
match u32::from_str_radix(mode, 8) {
|
||||||
|
Ok(change) => {
|
||||||
|
Ok(match op {
|
||||||
|
'+' => fperm | change,
|
||||||
|
'-' => fperm & !change,
|
||||||
|
'=' => change,
|
||||||
|
_ => unreachable!()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(err) => Err(err.description().to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_symbolic(mut fperm: u32, mut mode: &str, considering_dir: bool) -> Result<u32, String> {
|
||||||
|
#[cfg(unix)]
|
||||||
|
use libc::umask;
|
||||||
|
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
unsafe fn umask(_mask: u32) -> u32 {
|
||||||
|
// XXX Redox does not currently have umask
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
let (mask, pos) = parse_levels(mode);
|
||||||
|
if pos == mode.len() {
|
||||||
|
return Err(format!("invalid mode ({})", mode));
|
||||||
|
}
|
||||||
|
let respect_umask = pos == 0;
|
||||||
|
let last_umask = unsafe {
|
||||||
|
umask(0)
|
||||||
|
};
|
||||||
|
mode = &mode[pos..];
|
||||||
|
while mode.len() > 0 {
|
||||||
|
let (op, pos) = parse_op(mode, None)?;
|
||||||
|
mode = &mode[pos..];
|
||||||
|
let (mut srwx, pos) = parse_change(mode, fperm, considering_dir);
|
||||||
|
if respect_umask {
|
||||||
|
srwx &= !(last_umask as u32);
|
||||||
|
}
|
||||||
|
mode = &mode[pos..];
|
||||||
|
match op {
|
||||||
|
'+' => fperm |= srwx & mask,
|
||||||
|
'-' => fperm &= !(srwx & mask),
|
||||||
|
'=' => fperm = (fperm & !mask) | (srwx & mask),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
umask(last_umask);
|
||||||
|
}
|
||||||
|
Ok(fperm)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_levels(mode: &str) -> (u32, usize) {
|
||||||
|
let mut mask = 0;
|
||||||
|
let mut pos = 0;
|
||||||
|
for ch in mode.chars() {
|
||||||
|
mask |= match ch {
|
||||||
|
'u' => 0o7700,
|
||||||
|
'g' => 0o7070,
|
||||||
|
'o' => 0o7007,
|
||||||
|
'a' => 0o7777,
|
||||||
|
_ => break
|
||||||
|
};
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
if pos == 0 {
|
||||||
|
mask = 0o7777; // default to 'a'
|
||||||
|
}
|
||||||
|
(mask, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_op(mode: &str, default: Option<char>) -> Result<(char, usize), String> {
|
||||||
|
match mode.chars().next() {
|
||||||
|
Some(ch) => match ch {
|
||||||
|
'+' | '-' | '=' => Ok((ch, 1)),
|
||||||
|
_ => match default {
|
||||||
|
Some(ch) => Ok((ch, 0)),
|
||||||
|
None => Err(format!("invalid operator (expected +, -, or =, but found {})", ch))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => Err("unexpected end of mode".to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) {
|
||||||
|
let mut srwx = fperm & 0o7000;
|
||||||
|
let mut pos = 0;
|
||||||
|
for ch in mode.chars() {
|
||||||
|
match ch {
|
||||||
|
'r' => srwx |= 0o444,
|
||||||
|
'w' => srwx |= 0o222,
|
||||||
|
'x' => srwx |= 0o111,
|
||||||
|
'X' => {
|
||||||
|
if considering_dir || (fperm & 0o0111) != 0 {
|
||||||
|
srwx |= 0o111
|
||||||
|
}
|
||||||
|
}
|
||||||
|
's' => srwx |= 0o4000 | 0o2000,
|
||||||
|
't' => srwx |= 0o1000,
|
||||||
|
'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007),
|
||||||
|
'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007),
|
||||||
|
'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007),
|
||||||
|
_ => break
|
||||||
|
};
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
if pos == 0 {
|
||||||
|
srwx = 0;
|
||||||
|
}
|
||||||
|
(srwx, pos)
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Arcterus <arcterus@mail.com>
|
* (c) Alex Lyon <arcterus@mail.com>
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
|
|
|
@ -17,7 +17,7 @@ extern crate uucore;
|
||||||
use getopts::{Matches, Options};
|
use getopts::{Matches, Options};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{stdin, BufRead, BufReader, Read, Write};
|
use std::io::{stdin, BufRead, BufReader, Read};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
|
|
|
@ -15,7 +15,6 @@ use uucore::utmpx::{self, time, Utmpx};
|
||||||
use uucore::libc::{STDIN_FILENO, ttyname, S_IWGRP};
|
use uucore::libc::{STDIN_FILENO, ttyname, S_IWGRP};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
mod platform;
|
mod platform;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ extern crate getopts;
|
||||||
extern crate uucore;
|
extern crate uucore;
|
||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
static NAME: &'static str = "yes";
|
static NAME: &'static str = "yes";
|
||||||
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
@ -57,5 +56,5 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec(string: &str) {
|
pub fn exec(string: &str) {
|
||||||
while pipe_println!("{}", string) { }
|
loop { println!("{}", string) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ fn test_install_mode_failing() {
|
||||||
at.touch(file);
|
at.touch(file);
|
||||||
at.mkdir(dir);
|
at.mkdir(dir);
|
||||||
assert!(ucmd.arg(file).arg(dir).arg(mode_arg)
|
assert!(ucmd.arg(file).arg(dir).arg(mode_arg)
|
||||||
.fails().stderr.contains("Invalid mode string: numeric parsing error"));
|
.fails().stderr.contains("Invalid mode string: invalid digit found in string"));
|
||||||
|
|
||||||
let dest_file = &format!("{}/{}", dir, file);
|
let dest_file = &format!("{}/{}", dir, file);
|
||||||
assert!(at.file_exists(file));
|
assert!(at.file_exists(file));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue