1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
use crate::misc::{eval_resolved_or_ip_present, sanitize_target_string};
use clap::{load_yaml, value_t, App};
use std::{collections::HashSet, time::Instant};

pub struct Args {
    pub target: String,
    pub file_name: String,
    pub file: String,
    pub postgres_connection: String,
    pub discord_webhook: String,
    pub slack_webhook: String,
    pub telegram_bot_token: String,
    pub telegram_webhook: String,
    pub telegram_chat_id: String,
    pub resolver: String,
    pub threads: usize,
    pub only_resolved: bool,
    pub with_ip: bool,
    pub with_output: bool,
    pub unique_output_flag: bool,
    pub monitoring_flag: bool,
    pub from_file_flag: bool,
    pub quiet_flag: bool,
    pub query_database: bool,
    pub with_imported_subdomains: bool,
    pub enable_dot: bool,
    pub ipv4_only: bool,
    pub ipv6_only: bool,
    pub enable_empty_push: bool,
    pub subdomains: HashSet<String>,
    pub import_subdomains_from: Vec<String>,
    pub time_wasted: Instant,
}

pub fn get_args() -> Args {
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();
    Args {
        target: sanitize_target_string(
            value_t!(matches, "target", String).unwrap_or_else(|_| String::new()),
        ),
        file_name: if matches.is_present("output") && matches.is_present("target") {
            format!(
                "{}.txt",
                sanitize_target_string(matches.value_of("target").unwrap().to_string())
            )
        } else if matches.is_present("unique-output") {
            matches.value_of("unique-output").unwrap().to_string()
        } else {
            String::new()
        },
        file: if matches.is_present("file") {
            matches.value_of("file").unwrap().to_string()
        } else {
            String::new()
        },
        postgres_connection: format!(
            "postgresql://{}:{}@{}:{}/{}",
            value_t!(matches, "postgres-user", String).unwrap_or_else(|_| "postgres".to_string()),
            value_t!(matches, "postgres-password", String)
                .unwrap_or_else(|_| "postgres".to_string()),
            value_t!(matches, "postgres-host", String).unwrap_or_else(|_| "localhost".to_string()),
            value_t!(matches, "postgres-port", usize).unwrap_or_else(|_| 5432),
            value_t!(matches, "postgres-database", String).unwrap_or_else(|_| String::new()),
        ),
        discord_webhook: String::new(),
        slack_webhook: String::new(),
        telegram_bot_token: String::new(),
        telegram_webhook: String::new(),
        telegram_chat_id: String::new(),
        resolver: value_t!(matches, "resolver", String)
            .unwrap_or_else(|_| "cloudflare".to_string()),
        threads: value_t!(matches, "threads", usize).unwrap_or_else(|_| 50),
        only_resolved: matches.is_present("resolved"),
        with_ip: matches.is_present("ip"),
        with_output: matches.is_present("output") || matches.is_present("unique-output"),
        unique_output_flag: matches.is_present("unique-output"),
        monitoring_flag: matches.is_present("monitoring-flag"),
        from_file_flag: matches.is_present("file"),
        quiet_flag: matches.is_present("quiet"),
        with_imported_subdomains: matches.is_present("import-subdomains"),
        query_database: matches.is_present("query-database"),
        enable_dot: eval_resolved_or_ip_present(
            matches.is_present("enable-dot"),
            matches.is_present("ip")
                || matches.is_present("ipv4-only")
                || matches.is_present("ipv6-only"),
            matches.is_present("resolved"),
        ),
        ipv4_only: matches.is_present("ipv4-only"),
        ipv6_only: matches.is_present("ipv6-only"),
        enable_empty_push: matches.is_present("enable-empty-push"),
        subdomains: HashSet::new(),
        import_subdomains_from: if matches.is_present("import-subdomains") {
            matches
                .values_of("import-subdomains")
                .unwrap()
                .map(str::to_owned)
                .collect()
        } else {
            Vec::new()
        },
        time_wasted: Instant::now(),
    }
}