summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 215474670e043eecd026c44d8349375e67baffcd (plain)
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
106
107
108
109
110
#![allow(clippy::or_fun_call, clippy::redundant_field_names)]

#[macro_use] extern crate postgres_types;
#[macro_use] extern crate log;
//#[macro_use] extern crate serde_derive;

mod db;
mod config;
mod dispatch;
mod action_meta;
//mod action_fetch;
//mod action_index;
mod httpclient;
mod share_log;
//mod web;

use std::io::{self,Write};
use std::env;
use std::sync::Arc;
use clap::{ArgMatches,SubCommand};

use crate::db::Pool;
use crate::config::Config;


fn config(arg: &ArgMatches) -> Config {
    let configfile = arg
        .value_of("config").map(str::to_string)
        .or_else(|| env::var("CHIFS_HUB_CONFIG").ok());

    let conf = match &configfile {
        None => Config::default(),
        Some(p) => {
            match Config::parse(&p) {
                Err(e) => {
                    error!("{}", e);
                    std::process::exit(1)
                },
                Ok(c) => c
            }
        }
    };

    chifs_common::cli::set_logger("chifs-hub", &arg, &conf.log_file[..], conf.log_level);

    match configfile {
        None    => debug!("Using default configuration"),
        Some(p) => debug!("Using configuration file: {}", &p)
    }
    conf
}


fn main() {
    let mut app = chifs_common::cli::clap_app("chifs-hub")
        .about("ChiFS Hub")
        .subcommand(SubCommand::with_name("dispatcher")
            .about("Run a server to automatically monitor and index Shares")
        )
        .subcommand(SubCommand::with_name("web")
            .about("Run the web server")
        )
        .subcommand(SubCommand::with_name("server")
            .about("Run the web server & dispatcher in a single process")
        )
        .subcommand(SubCommand::with_name("set-admin-pass")
            .about("(Re)set the administration password")
        );
    let mut help = Vec::new();
    app.write_long_help(&mut help).unwrap();
    let arg = app.get_matches();

    if arg.subcommand_matches("dispatcher").is_some() {
        let conf = config(&arg);
        let db = Pool::new(&conf);
        dispatch::run(Arc::new(conf), db);

        /*
    } else if arg.subcommand_matches("web").is_some() {
        let conf = config(&arg);
        let db = Pool::new(&conf);
        web::run(Arc::new(conf), db);
        std::thread::sleep(std::time::Duration::from_secs(3560*24*3600));

    } else if arg.subcommand_matches("server").is_some() {
        let conf = Arc::new(config(&arg));
        let db = Pool::new(&conf);
        web::run(conf.clone(), db.clone());
        dispatch::run(conf, db);
        */

    } else if arg.subcommand_matches("set-admin-pass").is_some() {
        let conf = Arc::new(config(&arg));
        let db = Pool::new(&conf);

        // The password is 12 random bytes (96 bits) encoded into base64. Then hashed and stored in
        // the DB.
        let mut pass = [0u8; 12];
        getrandom::getrandom(&mut pass).expect("Unable to obtain OS randomness");
        let pass = data_encoding::BASE64URL_NOPAD.encode(&pass[..]);

        let b3 = chifs_common::Hash::hash_buf(pass.as_bytes());
        db.get().execute("UPDATE params SET admin_pass = $1", &[&b3]).unwrap();
        println!("The admin password has been set to: {}", pass);

    } else {
        help.push(b'\n');
        let _ = io::stderr().write_all(&help[..]);
    }
}