Inital commit 🤗

This commit is contained in:
Sivert V. Sæther 2023-01-20 19:29:06 +01:00
commit c662090ce8
6 changed files with 113 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
/Cargo.lock

16
Cargo.toml Normal file
View File

@ -0,0 +1,16 @@
[package]
name = "whosdom"
authors = ["Sivert V. Sæther <gmail@sivert.pw>"]
version = "0.1.0"
edition = "2021"
license = "MIT"
[dependencies]
whois-rust = { version = "1.5.1", features = ["tokio"] }
serde = { version = "1.0.152", features = ["derive"] }
tokio = { version = "1.24.2", features = ["full"] }
clap = { version = "4.1.1", features = ["derive"] }
serde_json = "1.0.91"
env_logger = "0.10.0"
reqwest = "0.11.14"
log = "0.4.17"

3
TODO.md Normal file
View File

@ -0,0 +1,3 @@
# TODO
* Make some scuffed system to scan for the expected "404" response per whois server/tld
* Then implement the actual watcher constantly checking wether the domain is still registered

33
src/bin/watch.rs Normal file
View File

@ -0,0 +1,33 @@
use std::{
vec::Vec,
io};
use clap::Parser;
use whosdom::whois::{Watcher, get_servers};
/// Domain registry watcher
#[derive(Parser, Debug)]
#[command(author, version, about)]
struct Args {
/// Domain(s) to watch
#[arg(short, long)]
domains: Vec<String>,
}
#[tokio::main]
async fn main() -> io::Result<()> {
let mut args = Args::parse();
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
log::info!("Starting whosdomain watch");
log::trace!("With args: {args:?}");
if args.domains.is_empty() {
log::error!("No domains specified, using \"example.com\"");
args.domains.push(String::from("example.com"));
}
log::info!("Watchin' domains: {:?}", args.domains);
let watcher = Watcher::new(get_servers().await.unwrap(), args.domains.clone());
log::info!("\n{}", watcher.lookup(&args.domains[0]).await);
//watcher.watch();
Ok(())
}

10
src/lib.rs Normal file
View File

@ -0,0 +1,10 @@
pub mod whois;
pub fn open(file_name: &str) -> std::io::Result<std::fs::File> {
std::fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(file_name)
}

49
src/whois.rs Normal file
View File

@ -0,0 +1,49 @@
use std::{
io::{self, Read, Write},
env::home_dir,
vec::Vec,
fs};
use whois_rust::{WhoIsLookupOptions, WhoIs};
use crate::open;
const SERVERS: &'static str = "https://raw.githubusercontent.com/FurqanSoftware/node-whois/master/servers.json";
const CACHE_FOLDER: &'static str = ".cache/whosdom";
const SERVER_FILE: &'static str = "servers.json";
#[derive(Debug)]
pub struct Watcher {
pub domains: Vec<String>,
whois: WhoIs,
}
impl Watcher {
pub fn new(servers: String, domains: Vec<String>) -> Self {
let whois = WhoIs::from_string(servers).unwrap();
Self { domains, whois }
}
pub async fn watch(&mut self) -> ! {
loop {
}
}
pub async fn lookup(&self, domain: &str) -> String {
self.whois.lookup_async(WhoIsLookupOptions::from_string(domain).unwrap()).await.unwrap()
}
}
pub async fn get_servers() -> Result<String, reqwest::Error> {
let path = match home_dir() {
Some(home) => format!("{}/{CACHE_FOLDER}", home.display()),
None => format!("/tmp/whosdom")
};
fs::create_dir_all(&path).unwrap();
let mut file = open(&format!("{path}/{SERVER_FILE}")).unwrap();
let mut servers = String::new();
file.read_to_string(&mut servers);
if servers.is_empty() {
servers = reqwest::get(SERVERS).await?.text().await?;
file.write_all(&servers.as_bytes()).unwrap();
}
Ok(servers)
}