gitrub 1.1.13

A local git server — push, pull, clone over HTTP and SSH with LFS, hooks, and more
Documentation
pub mod auth;
pub mod git;
pub mod http;
pub mod lfs;
pub mod ssh;
pub mod tui;

use std::net::IpAddr;
use std::path::PathBuf;

#[derive(Clone)]
pub struct Config {
    pub root: PathBuf,
    pub host: String,
    pub port: u16,
    pub ssh_port: u16,
    pub user: Option<String>,
    pub pass: Option<String>,
    pub hooks_dir: Option<PathBuf>,
    pub enable_ssh: bool,
    pub recursive: bool,
}

/// Return all local IP addresses for this machine.
pub fn local_ips() -> Vec<IpAddr> {
    let mut ips = Vec::new();
    if let Ok(interfaces) = std::net::TcpListener::bind("0.0.0.0:0") {
        // That trick doesn't enumerate IPs. Use getifaddrs via /proc on Linux,
        // or fall back to reading from the system.
        drop(interfaces);
    }
    // Read from /proc/net or use a UDP connect trick per-interface
    // Simpler: iterate known approaches
    // 1. Always include loopback
    ips.push(IpAddr::V4(std::net::Ipv4Addr::LOCALHOST));

    // 2. Use UDP socket trick to find the default-route IP
    if let Ok(sock) = std::net::UdpSocket::bind("0.0.0.0:0") {
        // Connect to a public IP (doesn't send data) to discover local IP
        if sock.connect("8.8.8.8:80").is_ok() {
            if let Ok(addr) = sock.local_addr() {
                let ip = addr.ip();
                if !ips.contains(&ip) {
                    ips.push(ip);
                }
            }
        }
    }

    // 3. Parse /proc/net/if_inet6 and /proc/net/fib_trie for more IPs (Linux)
    if let Ok(content) = std::fs::read_to_string("/proc/net/fib_trie") {
        // Look for lines like "           /32 host LOCAL"
        // The IP is on the previous line "          |-- x.x.x.x"
        let lines: Vec<&str> = content.lines().collect();
        for (i, line) in lines.iter().enumerate() {
            if line.contains("/32 host LOCAL") {
                if i > 0 {
                    if let Some(ip_str) = lines[i - 1].trim().strip_prefix("|-- ") {
                        if let Ok(ip) = ip_str.parse::<std::net::Ipv4Addr>() {
                            let ip = IpAddr::V4(ip);
                            if !ips.contains(&ip) {
                                ips.push(ip);
                            }
                        }
                    }
                }
            }
        }
    }

    ips
}