myph-v2.git


myph-v2

~ rust shellcode loader with evasive capabilities
git clone https://github.com/djnnvx/myph-v2.git
log | files | refs | archive | README

env_setup.rs (5845B)

      1 //! Environment Setup Module
      2 //!
      3 //! Handles the initialization and setup of the build environment for generating
      4 //! shellcode loaders. This includes verifying prerequisites, creating temporary
      5 //! directories, and managing the working directory.
      6 //!
      7 //! # Workflow
      8 //!
      9 //! 1. Verify cargo is installed and accessible
     10 //! 2. Create a unique temporary directory for the build
     11 //! 3. Change the working directory to the temp location
     12 //!
     13 //! # Safety
     14 //!
     15 //! Functions that modify the working directory are not thread-safe. Tests that
     16 //! use these functions must serialize using `TEST_DIR_MUTEX` to prevent race
     17 //! conditions.
     18 //!
     19 //! # Example
     20 //!
     21 //! ```no_run
     22 //! use myph_v2::env_setup::setup_environment;
     23 //!
     24 //! let temp_dir = setup_environment().expect("Failed to setup environment");
     25 //! println!("Build directory: {:?}", temp_dir);
     26 //! ```
     27 
     28 use std::env;
     29 use std::io;
     30 use std::path::PathBuf;
     31 use std::process::Command;
     32 
     33 /// Check if cargo is installed on the system
     34 ///
     35 /// Returns `Ok(())` if cargo is installed and accessible via PATH,
     36 /// otherwise returns an error.
     37 pub fn check_cargo_installed() -> io::Result<()> {
     38     let status = Command::new("cargo")
     39         .arg("--version")
     40         .stdout(std::process::Stdio::null())
     41         .stderr(std::process::Stdio::null())
     42         .status()?;
     43 
     44     if status.success() {
     45         Ok(())
     46     } else {
     47         Err(io::Error::new(
     48             io::ErrorKind::NotFound,
     49             "cargo command failed to execute",
     50         ))
     51     }
     52 }
     53 
     54 /// Create a temporary directory and return its path
     55 ///
     56 /// Creates a new temporary directory with a unique name in the system temp directory.
     57 /// Note: The directory will NOT be automatically cleaned up and must be
     58 /// manually removed when no longer needed.
     59 ///
     60 /// Returns the path to the newly created temporary directory.
     61 pub fn create_temp_directory() -> io::Result<PathBuf> {
     62     let base_temp_dir = env::temp_dir();
     63 
     64     let unique_dir = base_temp_dir.join(format!("myph-{}", rand::random::<u32>()));
     65 
     66     std::fs::create_dir_all(&unique_dir)?;
     67 
     68     Ok(unique_dir)
     69 }
     70 
     71 /// Change the current working directory to the specified path
     72 ///
     73 /// # Arguments
     74 ///
     75 /// * `path` - The path to change to
     76 ///
     77 /// Returns `Ok(())` if successful, otherwise returns an error.
     78 pub fn change_working_directory(path: &PathBuf) -> io::Result<()> {
     79     env::set_current_dir(path)?;
     80     Ok(())
     81 }
     82 
     83 /// Setup the environment for running the application
     84 ///
     85 /// This function performs the following steps:
     86 /// 1. Checks if cargo is installed
     87 /// 2. Creates a temporary directory
     88 /// 3. Changes the working directory to the temporary directory
     89 ///
     90 /// Returns the path to the temporary directory if successful,
     91 /// otherwise returns an error describing what went wrong.
     92 pub fn setup_environment() -> io::Result<PathBuf> {
     93     check_cargo_installed().map_err(|e| {
     94         io::Error::new(
     95             io::ErrorKind::NotFound,
     96             format!("cargo is not installed or not in PATH: {}", e),
     97         )
     98     })?;
     99 
    100     let temp_dir = create_temp_directory()?;
    101 
    102     change_working_directory(&temp_dir)?;
    103 
    104     Ok(temp_dir)
    105 }
    106 
    107 #[cfg(test)]
    108 mod tests {
    109     use super::*;
    110     use crate::TEST_DIR_MUTEX;
    111     use std::env;
    112 
    113     #[test]
    114     fn test_check_cargo_installed() {
    115         // This test assumes cargo is installed in the test environment
    116         let result = check_cargo_installed();
    117         assert!(
    118             result.is_ok(),
    119             "cargo should be installed in test environment"
    120         );
    121     }
    122 
    123     #[test]
    124     fn test_create_temp_directory() {
    125         let result = create_temp_directory();
    126         assert!(result.is_ok(), "should be able to create temp directory");
    127 
    128         let temp_path = result.unwrap();
    129         assert!(temp_path.exists(), "temp directory should exist");
    130         assert!(temp_path.is_dir(), "temp path should be a directory");
    131 
    132         // Clean up
    133         let _ = std::fs::remove_dir_all(&temp_path);
    134     }
    135 
    136     #[test]
    137     fn test_change_working_directory() {
    138         let _lock = TEST_DIR_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
    139 
    140         // Save current directory
    141         let original_dir = env::current_dir().unwrap();
    142 
    143         // Create a temp directory
    144         let temp_dir = create_temp_directory().unwrap();
    145 
    146         // Change to it
    147         let result = change_working_directory(&temp_dir);
    148         assert!(result.is_ok(), "should be able to change directory");
    149 
    150         // Verify we're in the new directory
    151         let current_dir = env::current_dir().unwrap();
    152         assert_eq!(current_dir, temp_dir, "should be in temp directory");
    153 
    154         // Clean up - change back to original directory
    155         let _ = env::set_current_dir(&original_dir);
    156         let _ = std::fs::remove_dir_all(&temp_dir);
    157     }
    158 
    159     #[test]
    160     fn test_setup_environment() {
    161         let _lock = TEST_DIR_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
    162 
    163         // Save current directory
    164         let original_dir = env::current_dir().unwrap();
    165 
    166         // Run setup
    167         let result = setup_environment();
    168         assert!(result.is_ok(), "setup_environment should succeed");
    169 
    170         let temp_dir = result.unwrap();
    171         assert!(temp_dir.exists(), "temp directory should exist");
    172 
    173         // Verify we changed to the temp directory
    174         let current_dir = env::current_dir().unwrap();
    175         assert_eq!(current_dir, temp_dir, "should be in temp directory");
    176 
    177         // Clean up
    178         let _ = env::set_current_dir(&original_dir);
    179         let _ = std::fs::remove_dir_all(&temp_dir);
    180     }
    181 
    182     #[test]
    183     fn test_change_to_nonexistent_directory() {
    184         let nonexistent_path = env::temp_dir().join("definitely-does-not-exist-123456789");
    185         let result = change_working_directory(&nonexistent_path);
    186         assert!(
    187             result.is_err(),
    188             "should fail to change to nonexistent directory"
    189         );
    190     }
    191 }