rumi2 1.0.0

Rumi2 simplifies the process of deploying your web applications and servers. With seamless SSH2 integration, it effortlessly manages the publishing process to your existing server infrastructure, ensuring secure and efficient transfers every time.
Documentation
use ssh2::Session;
use std::fs::{self, File};
use std::io::prelude::*;
use std::net::TcpStream;
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Set up the SSH session
    let tcp = TcpStream::connect("example.com:22")?;
    let mut sess = Session::new()?;
    sess.set_tcp_stream(tcp);
    sess.handshake()?;

    // Authenticate with the server
    sess.userauth_password("username", "password")?;
    assert!(sess.authenticated());

    // Initialize SFTP session
    let sftp = sess.sftp()?;

    // Define the local directory and the remote directory
    let local_dir = "./local_folder";
    let remote_dir = "/remote_folder";

    // Recursively upload the folder
    upload_folder(&sftp, Path::new(local_dir), remote_dir)?;

    Ok(())
}

fn upload_folder(sftp: &ssh2::Sftp, local_path: &Path, remote_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    // Create the remote directory
    match sftp.mkdir(Path::new(remote_path), 0o755) {
        Ok(_) => println!("Created directory: {}", remote_path),
        Err(e) => println!("Directory already exists or failed to create: {} - {}", remote_path, e),
    }

    // Iterate over the entries in the local directory
    for entry in fs::read_dir(local_path)? {
        let entry = entry?;
        let path = entry.path();
        let file_name = entry.file_name().into_string().unwrap();
        let remote_file_path = format!("{}/{}", remote_path, file_name);

        if path.is_dir() {
            // Recursively upload directories
            upload_folder(sftp, &path, &remote_file_path)?;
        } else {
            // Upload files
            upload_file(sftp, &path, &remote_file_path)?;
        }
    }

    Ok(())
}

fn upload_file(sftp: &ssh2::Sftp, local_file: &Path, remote_file: &str) -> Result<(), Box<dyn std::error::Error>> {
    let mut local_f = File::open(local_file)?;
    let mut buffer = Vec::new();
    local_f.read_to_end(&mut buffer)?;

    let mut remote_f = sftp.create(Path::new(remote_file))?;
    remote_f.write_all(&buffer)?;

    println!("Uploaded file: {}", remote_file);

    Ok(())
}