From fe476404b4ce134c946d1754d2652461340c1186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Tue, 6 Feb 2024 17:27:02 +0100 Subject: patcjh --- rust/src/main.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 8 deletions(-) (limited to 'rust/src/main.rs') diff --git a/rust/src/main.rs b/rust/src/main.rs index 64fa16c..adb656c 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,11 +1,17 @@ extern crate hex; extern crate urlencoding; +extern crate bencode; use std::collections::HashMap; use std::net::IpAddr; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, Utc, TimeZone}; use sha2::{Sha256, Digest}; use sha1::{Sha1}; +use bencode::{Bencode, FromBencode}; +use bencode::util::ByteString; +use std::str; +use std::net::SocketAddr; + enum Version { V1, V2, @@ -17,10 +23,25 @@ struct Torrent { sha256: [u8; 32], version: Version, files: HashMap, - source: IpAddr, - date: DateTime, - hostname: String, - software: String + source: Option, + date: Option>, + hostname: Option, + software: Option +} +impl Default for Torrent { + fn default() -> Torrent { + Torrent { + name: String::from("travnik_default_name_unset"), + sha1: [0; 20], + sha256: [0; 32], + version: Version::V1, + files: HashMap::new(), + source: None, + date: None, + hostname: None, + software: None + } + } } impl Torrent { fn magnet(&self) -> String { @@ -37,8 +58,66 @@ impl Torrent { string } } +fn sockaddr_from_source(string) -> Result // TODO nadaljuj +#[derive(Debug)] +enum TorrentDecodeError { + NotADict, + NoName, + NoLength, + CreatedByNotUtf8, + SoftwareNotUtf8 +} +impl FromBencode for Torrent { + type Err = TorrentDecodeError; + fn from_bencode(bencode: &Bencode) -> Result { + let metainfo = match bencode { + &Bencode::Dict(ref metainfo) => metainfo, + _ => return Err(TorrentDecodeError::NotADict) + }; + let torrent = Torrent { + date: match metainfo.get(&ByteString::from_str("creation date")) { + Some(&Bencode::Number(c)) => Some(Utc.timestamp(c, 0)), + _ => None + }, + hostname: match metainfo.get(&ByteString::from_str("created by")) { + Some(&Bencode::ByteString(ref s)) => match str::from_utf8(&s) { + Ok(v) => Some(match v.split(" ").nth(3) { + Some(c) => String::from(c), + None => String::from("b") + }), + Err(_) => return Err(TorrentDecodeError::CreatedByNotUtf8) + }, + _ => None + }, + software: match metainfo.get(&ByteString::from_str("source")) { + Some(&Bencode::Dict(ref s)) => match s.get(&ByteString::from_str("v")) { + Some(&Bencode::ByteString(ref s)) => match String::from_utf8(s.to_vec()) { + Ok(v) => Some(v), + Err(_) => return Err(TorrentDecodeError::SoftwareNotUtf8) + }, + _ => None + }, + _ => None + }, + source: match metainfo.get(&ByteString::from_str("source")) { + Some(&Bencode::Dict(ref s)) => match s.get(&ByteString::from_str("ip")) { + Some(&Bencode::ByteString(ref s)) => match str::from_utf8(&s) { + Ok(v) => Some(sockaddr_from_source(v)?), // TODO nadaljuj + Err(_) => return Err(Torrent) + }, + _ => None + }, + _ => None + }, + ..Default::default() + }; + Ok(torrent) + } +} fn main() { - let hash2 = Sha256::new().chain_update(b"test").finalize(); - let hash1 = Sha1::new().chain_update(b"test").finalize(); - println!("Hello, world! {:#?} {:#?}", hash2, hash1); + // let hash2 = Sha256::new().chain_update(b"test").finalize(); + // let hash1 = Sha1::new().chain_update(b"test").finalize(); + // println!("Hello, world! {:#?} {:#?}", hash2, hash1); + let bencode: bencode::Bencode = bencode::from_vec(String::from("d1:wlee").as_bytes().to_vec()).unwrap(); + println!("{:#?}", bencode); } -- cgit v1.2.3