|
0 |
Index: coreutils/src/uu/install/Cargo.toml
|
|
1 |
===================================================================
|
|
2 |
--- coreutils.orig/src/uu/install/Cargo.toml
|
|
3 |
+++ coreutils/src/uu/install/Cargo.toml
|
|
4 |
@@ -20,7 +20,6 @@ path = "src/install.rs"
|
|
5 |
[dependencies]
|
|
6 |
clap = "2.33"
|
|
7 |
filetime = "0.2"
|
|
8 |
-file_diff = "1.0.0"
|
|
9 |
libc = ">= 0.2"
|
|
10 |
uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features=["mode", "perms", "entries"] }
|
|
11 |
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
|
12 |
Index: coreutils/src/uu/install/src/install.rs
|
|
13 |
===================================================================
|
|
14 |
--- coreutils.orig/src/uu/install/src/install.rs
|
|
15 |
+++ coreutils/src/uu/install/src/install.rs
|
|
16 |
@@ -13,12 +13,10 @@ mod mode;
|
|
17 |
extern crate uucore;
|
|
18 |
|
|
19 |
use clap::{App, Arg, ArgMatches};
|
|
20 |
-use file_diff::diff;
|
|
21 |
use filetime::{set_file_times, FileTime};
|
|
22 |
use uucore::entries::{grp2gid, usr2uid};
|
|
23 |
use uucore::perms::{wrap_chgrp, wrap_chown, Verbosity};
|
|
24 |
|
|
25 |
-use libc::{getegid, geteuid};
|
|
26 |
use std::fs;
|
|
27 |
use std::fs::File;
|
|
28 |
use std::os::unix::fs::MetadataExt;
|
|
29 |
@@ -36,7 +34,6 @@ pub struct Behavior {
|
|
30 |
group: String,
|
|
31 |
verbose: bool,
|
|
32 |
preserve_timestamps: bool,
|
|
33 |
- compare: bool,
|
|
34 |
}
|
|
35 |
|
|
36 |
#[derive(Clone, Eq, PartialEq)]
|
|
37 |
@@ -115,10 +112,11 @@ pub fn uumain(args: impl uucore::Args) -
|
|
38 |
.help("ignored")
|
|
39 |
)
|
|
40 |
.arg(
|
|
41 |
+ // TODO implement flag
|
|
42 |
Arg::with_name(OPT_COMPARE)
|
|
43 |
.short("C")
|
|
44 |
.long(OPT_COMPARE)
|
|
45 |
- .help("compare each pair of source and destination files, and in some cases, do not modify the destination at all")
|
|
46 |
+ .help("(unimplemented) compare each pair of source and destination files, and in some cases, do not modify the destination at all")
|
|
47 |
)
|
|
48 |
.arg(
|
|
49 |
Arg::with_name(OPT_DIRECTORY)
|
|
50 |
@@ -264,6 +262,8 @@ fn check_unimplemented<'a>(matches: &Arg
|
|
51 |
Err("--backup")
|
|
52 |
} else if matches.is_present(OPT_BACKUP_2) {
|
|
53 |
Err("-b")
|
|
54 |
+ } else if matches.is_present(OPT_COMPARE) {
|
|
55 |
+ Err("--compare, -C")
|
|
56 |
} else if matches.is_present(OPT_CREATED) {
|
|
57 |
Err("-D")
|
|
58 |
} else if matches.is_present(OPT_STRIP) {
|
|
59 |
@@ -338,7 +338,6 @@ fn behavior(matches: &ArgMatches) -> Res
|
|
60 |
group: matches.value_of(OPT_GROUP).unwrap_or("").to_string(),
|
|
61 |
verbose: matches.is_present(OPT_VERBOSE),
|
|
62 |
preserve_timestamps: matches.is_present(OPT_PRESERVE_TIMESTAMPS),
|
|
63 |
- compare: matches.is_present(OPT_COMPARE),
|
|
64 |
})
|
|
65 |
}
|
|
66 |
|
|
67 |
@@ -507,13 +506,7 @@ fn copy(from: &PathBuf, to: &PathBuf, b:
|
|
68 |
);
|
|
69 |
return Err(());
|
|
70 |
}
|
|
71 |
- }
|
|
72 |
-
|
|
73 |
- if b.compare && !need_copy(from, to, b) {
|
|
74 |
- return Ok(());
|
|
75 |
- }
|
|
76 |
-
|
|
77 |
- if let Err(err) = fs::copy(from, to) {
|
|
78 |
+ } else if let Err(err) = fs::copy(from, to) {
|
|
79 |
show_error!(
|
|
80 |
"cannot install '{}' to '{}': {}",
|
|
81 |
from.display(),
|
|
82 |
@@ -596,81 +589,3 @@ fn copy(from: &PathBuf, to: &PathBuf, b:
|
|
83 |
|
|
84 |
Ok(())
|
|
85 |
}
|
|
86 |
-
|
|
87 |
-/// Return true if a file is necessary to copy. This is the case when:
|
|
88 |
-/// - _from_ or _to_ is nonexistent;
|
|
89 |
-/// - either file has a sticky bit or set[ug]id bit, or the user specified one;
|
|
90 |
-/// - either file isn't a regular file;
|
|
91 |
-/// - the sizes of _from_ and _to_ differ;
|
|
92 |
-/// - _to_'s owner differs from intended; or
|
|
93 |
-/// - the contents of _from_ and _to_ differ.
|
|
94 |
-///
|
|
95 |
-/// # Parameters
|
|
96 |
-///
|
|
97 |
-/// _from_ and _to_, if existent, must be non-directories.
|
|
98 |
-///
|
|
99 |
-/// # Errors
|
|
100 |
-///
|
|
101 |
-/// Crashes the program if a nonexistent owner or group is specified in _b_.
|
|
102 |
-///
|
|
103 |
-fn need_copy(from: &PathBuf, to: &PathBuf, b: &Behavior) -> bool {
|
|
104 |
- let from_meta = match fs::metadata(from) {
|
|
105 |
- Ok(meta) => meta,
|
|
106 |
- Err(_) => return true,
|
|
107 |
- };
|
|
108 |
- let to_meta = match fs::metadata(to) {
|
|
109 |
- Ok(meta) => meta,
|
|
110 |
- Err(_) => return true,
|
|
111 |
- };
|
|
112 |
-
|
|
113 |
- // setuid || setgid || sticky
|
|
114 |
- let extra_mode: u32 = 0o7000;
|
|
115 |
-
|
|
116 |
- if b.specified_mode.unwrap_or(0) & extra_mode != 0
|
|
117 |
- || from_meta.mode() & extra_mode != 0
|
|
118 |
- || to_meta.mode() & extra_mode != 0
|
|
119 |
- {
|
|
120 |
- return true;
|
|
121 |
- }
|
|
122 |
-
|
|
123 |
- if !from_meta.is_file() || !to_meta.is_file() {
|
|
124 |
- return true;
|
|
125 |
- }
|
|
126 |
-
|
|
127 |
- if from_meta.len() != to_meta.len() {
|
|
128 |
- return true;
|
|
129 |
- }
|
|
130 |
-
|
|
131 |
- // TODO: if -P (#1809) and from/to contexts mismatch, return true.
|
|
132 |
-
|
|
133 |
- if !b.owner.is_empty() {
|
|
134 |
- let owner_id = match usr2uid(&b.owner) {
|
|
135 |
- Ok(id) => id,
|
|
136 |
- _ => crash!(1, "no such user: {}", b.owner),
|
|
137 |
- };
|
|
138 |
- if owner_id != to_meta.uid() {
|
|
139 |
- return true;
|
|
140 |
- }
|
|
141 |
- } else if !b.group.is_empty() {
|
|
142 |
- let group_id = match grp2gid(&b.group) {
|
|
143 |
- Ok(id) => id,
|
|
144 |
- _ => crash!(1, "no such group: {}", b.group),
|
|
145 |
- };
|
|
146 |
- if group_id != to_meta.gid() {
|
|
147 |
- return true;
|
|
148 |
- }
|
|
149 |
- } else {
|
|
150 |
- #[cfg(not(target_os = "windows"))]
|
|
151 |
- unsafe {
|
|
152 |
- if to_meta.uid() != geteuid() || to_meta.gid() != getegid() {
|
|
153 |
- return true;
|
|
154 |
- }
|
|
155 |
- }
|
|
156 |
- }
|
|
157 |
-
|
|
158 |
- if !diff(from.to_str().unwrap(), to.to_str().unwrap()) {
|
|
159 |
- return true;
|
|
160 |
- }
|
|
161 |
-
|
|
162 |
- false
|
|
163 |
-}
|
|
164 |
Index: coreutils/tests/by-util/test_install.rs
|
|
165 |
===================================================================
|
|
166 |
--- coreutils.orig/tests/by-util/test_install.rs
|
|
167 |
+++ coreutils/tests/by-util/test_install.rs
|
|
168 |
@@ -1,5 +1,4 @@
|
|
169 |
use crate::common::util::*;
|
|
170 |
-use filetime::FileTime;
|
|
171 |
use rust_users::*;
|
|
172 |
use std::os::unix::fs::PermissionsExt;
|
|
173 |
#[cfg(target_os = "linux")]
|
|
174 |
@@ -481,6 +480,7 @@ fn test_install_failing_no_such_file() {
|
|
175 |
}
|
|
176 |
|
|
177 |
#[test]
|
|
178 |
+#[ignore]
|
|
179 |
fn test_install_copy_then_compare_file() {
|
|
180 |
let scene = TestScenario::new(util_name!());
|
|
181 |
let at = &scene.fixtures;
|
|
182 |
@@ -515,6 +515,7 @@ fn test_install_copy_then_compare_file()
|
|
183 |
|
|
184 |
#[test]
|
|
185 |
#[cfg(target_os = "linux")]
|
|
186 |
+#[ignore]
|
|
187 |
fn test_install_copy_then_compare_file_with_extra_mode() {
|
|
188 |
let scene = TestScenario::new(util_name!());
|
|
189 |
let at = &scene.fixtures;
|