rust/chg/src/locator.rs
changeset 45620 426294d06ddc
parent 44756 27fe8cc1338f
equal deleted inserted replaced
45619:e8078af6af30 45620:426294d06ddc
    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"--" {