1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use std::convert::TryFrom;
8use std::env;
9use std::io::{self, Read};
10use xmpp_parsers::{
11 caps::{compute_disco as compute_disco_caps, hash_caps, Caps},
12 disco::DiscoInfoResult,
13 ecaps2::{compute_disco as compute_disco_ecaps2, hash_ecaps2, ECaps2},
14 hashes::Algo,
15 Element, Error,
16};
17
18fn get_caps(disco: &DiscoInfoResult, node: String) -> Result<Caps, String> {
19 let data = compute_disco_caps(&disco);
20 let hash = hash_caps(&data, Algo::Sha_1)?;
21 Ok(Caps::new(node, hash))
22}
23
24fn get_ecaps2(disco: &DiscoInfoResult) -> Result<ECaps2, Error> {
25 let data = compute_disco_ecaps2(&disco)?;
26 let hash_sha256 = hash_ecaps2(&data, Algo::Sha_256)?;
27 let hash_sha3_256 = hash_ecaps2(&data, Algo::Sha3_256)?;
28 let hash_blake2b_256 = hash_ecaps2(&data, Algo::Blake2b_256)?;
29 Ok(ECaps2::new(vec![
30 hash_sha256,
31 hash_sha3_256,
32 hash_blake2b_256,
33 ]))
34}
35
36fn main() -> Result<(), Box<dyn std::error::Error>> {
37 let args: Vec<_> = env::args().collect();
38 if args.len() != 2 {
39 println!("Usage: {} <node>", args[0]);
40 std::process::exit(1);
41 }
42 let node = args[1].clone();
43
44 eprintln!("Reading a disco#info payload from stdin...");
45
46 // Read from stdin.
47 let stdin = io::stdin();
48 let mut data = String::new();
49 let mut handle = stdin.lock();
50 handle.read_to_string(&mut data)?;
51
52 // Parse the payload into a DiscoInfoResult.
53 let elem: Element = data.parse()?;
54 let disco = DiscoInfoResult::try_from(elem)?;
55
56 // Compute both kinds of caps.
57 let caps = get_caps(&disco, node)?;
58 let ecaps2 = get_ecaps2(&disco)?;
59
60 // Print them.
61 let caps_elem = Element::from(caps);
62 let ecaps2_elem = Element::from(ecaps2);
63 println!("{}", String::from(&caps_elem));
64 println!("{}", String::from(&ecaps2_elem));
65
66 Ok(())
67}