equal
deleted
inserted
replaced
69 buf.extend_from_slice(format!(".{}", self.process_id).as_bytes()); |
69 buf.extend_from_slice(format!(".{}", self.process_id).as_bytes()); |
70 OsString::from_vec(buf).into() |
70 OsString::from_vec(buf).into() |
71 } |
71 } |
72 |
72 |
73 /// Specifies the arguments to be passed to the server at start. |
73 /// Specifies the arguments to be passed to the server at start. |
74 pub fn set_early_args(&mut self, args: impl IntoIterator<Item = impl AsRef<OsStr>>) { |
74 pub fn set_early_args( |
75 self.hg_early_args = args.into_iter().map(|a| a.as_ref().to_owned()).collect(); |
75 &mut self, |
|
76 args: impl IntoIterator<Item = impl AsRef<OsStr>>, |
|
77 ) { |
|
78 self.hg_early_args = |
|
79 args.into_iter().map(|a| a.as_ref().to_owned()).collect(); |
76 } |
80 } |
77 |
81 |
78 /// Connects to the server. |
82 /// Connects to the server. |
79 /// |
83 /// |
80 /// The server process will be spawned if not running. |
84 /// The server process will be spawned if not running. |
102 } |
106 } |
103 |
107 |
104 /// Runs instructions received from the server. |
108 /// Runs instructions received from the server. |
105 /// |
109 /// |
106 /// Returns true if the client should try connecting to the other server. |
110 /// Returns true if the client should try connecting to the other server. |
107 fn run_instructions(&mut self, instructions: &[Instruction]) -> io::Result<bool> { |
111 fn run_instructions( |
|
112 &mut self, |
|
113 instructions: &[Instruction], |
|
114 ) -> io::Result<bool> { |
108 let mut reconnect = false; |
115 let mut reconnect = false; |
109 for inst in instructions { |
116 for inst in instructions { |
110 debug!("instruction: {:?}", inst); |
117 debug!("instruction: {:?}", inst); |
111 match inst { |
118 match inst { |
112 Instruction::Exit(_) => { |
119 Instruction::Exit(_) => { |
121 if path.parent() != self.base_sock_path.parent() { |
128 if path.parent() != self.base_sock_path.parent() { |
122 let msg = format!( |
129 let msg = format!( |
123 "insecure redirect instruction from server: {}", |
130 "insecure redirect instruction from server: {}", |
124 path.display() |
131 path.display() |
125 ); |
132 ); |
126 return Err(io::Error::new(io::ErrorKind::InvalidData, msg)); |
133 return Err(io::Error::new( |
|
134 io::ErrorKind::InvalidData, |
|
135 msg, |
|
136 )); |
127 } |
137 } |
128 self.redirect_sock_path = Some(path.to_owned()); |
138 self.redirect_sock_path = Some(path.to_owned()); |
129 reconnect = true; |
139 reconnect = true; |
130 } |
140 } |
131 Instruction::Unlink(path) => { |
141 Instruction::Unlink(path) => { |
132 if path.parent() != self.base_sock_path.parent() { |
142 if path.parent() != self.base_sock_path.parent() { |
133 let msg = format!( |
143 let msg = format!( |
134 "insecure unlink instruction from server: {}", |
144 "insecure unlink instruction from server: {}", |
135 path.display() |
145 path.display() |
136 ); |
146 ); |
137 return Err(io::Error::new(io::ErrorKind::InvalidData, msg)); |
147 return Err(io::Error::new( |
|
148 io::ErrorKind::InvalidData, |
|
149 msg, |
|
150 )); |
138 } |
151 } |
139 fs::remove_file(path).unwrap_or(()); // may race |
152 fs::remove_file(path).unwrap_or(()); // may race |
140 } |
153 } |
141 } |
154 } |
142 } |
155 } |
317 fn check_secure_dir<P>(path: P) -> io::Result<P> |
330 fn check_secure_dir<P>(path: P) -> io::Result<P> |
318 where |
331 where |
319 P: AsRef<Path>, |
332 P: AsRef<Path>, |
320 { |
333 { |
321 let a = fs::symlink_metadata(path.as_ref())?; |
334 let a = fs::symlink_metadata(path.as_ref())?; |
322 if a.is_dir() && a.uid() == procutil::get_effective_uid() && (a.mode() & 0o777) == 0o700 { |
335 if a.is_dir() |
|
336 && a.uid() == procutil::get_effective_uid() |
|
337 && (a.mode() & 0o777) == 0o700 |
|
338 { |
323 Ok(path) |
339 Ok(path) |
324 } else { |
340 } else { |
325 Err(io::Error::new(io::ErrorKind::Other, "insecure directory")) |
341 Err(io::Error::new(io::ErrorKind::Other, "insecure directory")) |
326 } |
342 } |
327 } |
343 } |
342 Err(io::Error::new(io::ErrorKind::Other, msg)) |
358 Err(io::Error::new(io::ErrorKind::Other, msg)) |
343 } |
359 } |
344 } |
360 } |
345 |
361 |
346 /// Collects arguments which need to be passed to the server at start. |
362 /// Collects arguments which need to be passed to the server at start. |
347 pub fn collect_early_args(args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Vec<OsString> { |
363 pub fn collect_early_args( |
|
364 args: impl IntoIterator<Item = impl AsRef<OsStr>>, |
|
365 ) -> Vec<OsString> { |
348 let mut args_iter = args.into_iter(); |
366 let mut args_iter = args.into_iter(); |
349 let mut early_args = Vec::new(); |
367 let mut early_args = Vec::new(); |
350 while let Some(arg) = args_iter.next() { |
368 while let Some(arg) = args_iter.next() { |
351 let argb = arg.as_ref().as_bytes(); |
369 let argb = arg.as_ref().as_bytes(); |
352 if argb == b"--" { |
370 if argb == b"--" { |