Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a torrent from-link subcommand #511

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ rand = "0.7.3"
open = "1.4.0"
pretty_assertions = "0.6.0"
pretty_env_logger = "0.4.0"
rayon = "<=1.6.0"
regex = "1.0.0"
serde-hex = "0.1.0"
serde_bytes = "0.11.0"
Expand Down
4 changes: 4 additions & 0 deletions bin/gen/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ examples:
text: "Intermodal can be used to create `.torrent` files:"
code: "imdl torrent create --input foo"

- command: imdl torrent from-link
text: "Intermodal can be used to create a `.torrent` file from a magnet link:"
code: "imdl torrent from-link magnet:?foo"

- command: imdl torrent show
text: "Print information about existing `.torrent` files:"
code: "imdl torrent show --input foo.torrent"
Expand Down
10 changes: 7 additions & 3 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ pub(crate) use std::{
hash::Hash,
io::{self, BufRead, BufReader, Cursor, Read, Write},
iter::{self, Sum},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs, UdpSocket},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, TcpStream, ToSocketAddrs, UdpSocket},
num::{ParseFloatError, ParseIntError, TryFromIntError},
ops::{AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
path::{self, Path, PathBuf},
process::ExitStatus,
str::{self, FromStr},
string::FromUtf8Error,
sync::Once,
sync::{mpsc::channel, Once},
time::{Duration, SystemTime, SystemTimeError},
usize,
};
Expand Down Expand Up @@ -54,7 +54,9 @@ pub(crate) use url::{Host, Url};
pub(crate) use log::trace;

// modules
pub(crate) use crate::{consts, error, host_port_parse_error, magnet_link_parse_error, tracker};
pub(crate) use crate::{
consts, error, host_port_parse_error, magnet_link_parse_error, peer, tracker,
};

// functions
pub(crate) use crate::xor_args::xor_args;
Expand Down Expand Up @@ -88,9 +90,11 @@ mod test {
// test stdlib types
pub(crate) use std::{
cell::RefCell,
net::TcpListener,
ops::{Deref, DerefMut},
process::Command,
rc::Rc,
thread,
};

// test dependencies
Expand Down
32 changes: 32 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub(crate) enum Error {
Filesystem { source: io::Error, path: PathBuf },
#[snafu(display("Error searching for files: {}", source))]
FileSearch { source: ignore::Error },
#[snafu(display("Failed to fetch infodict from accessible peers"))]
FromLinkNoInfo,
#[snafu(display("Invalid glob: {}", source))]
GlobParse { source: globset::Error },
#[snafu(display("Failed to serialize torrent info dictionary: {}", source))]
Expand Down Expand Up @@ -68,6 +70,8 @@ pub(crate) enum Error {
input: InputTarget,
source: MetainfoError,
},
#[snafu(display("Network error: {}", source))]
Network { source: io::Error },
#[snafu(display("Failed to invoke opener: {}", source))]
OpenerInvoke { source: io::Error },
#[snafu(display("Opener failed: {}", exit_status))]
Expand Down Expand Up @@ -114,6 +118,34 @@ pub(crate) enum Error {
bytes: Bytes,
source: TryFromIntError,
},
#[snafu(display("Received peer handshake with the wrong infohash"))]
PeerHandshakeInfohash,
#[snafu(display("Received peer handshake with the wrong protocol header"))]
PeerHandshakeHeader,
#[snafu(display("Bencoding error: `{}`", source))]
PeerMessageBencode { source: bendy::serde::Error },
#[snafu(display("Peer extended message payload is malformed"))]
PeerMessageExtendedPayload,
#[snafu(display("Failed to decode bencoded message: `{}`", source))]
PeerMessageFromBencode { source: bendy::serde::Error },
#[snafu(display("Peer message payload is too large"))]
PeerMessagePayload { source: TryFromIntError },
#[snafu(display("Extended handshake has not been received from peer"))]
PeerNoExtendedHandshake,
#[snafu(display("Received UtMetadata info dict that's failed to deserialize"))]
PeerUtMetadataInfoDeserialize { source: bendy::serde::Error },
#[snafu(display("Received UtMetadata info dict that's too long"))]
PeerUtMetadataInfoLength,
#[snafu(display("Received UtMetadata data message that's too long"))]
PeerUtMetadataPieceLength,
#[snafu(display("Peer doesn't know metadata size"))]
PeerUtMetadataMetadataSizeNotKnown,
#[snafu(display("Peer doesn't support UtMetadata extension"))]
PeerUtMetadataNotSupported,
#[snafu(display("Hash of received info dict does not match"))]
PeerUtMetadataWrongInfohash,
#[snafu(display("Received the wrong UtMetadata piece"))]
PeerUtMetadataWrongPiece,
#[snafu(display("Piece length `{}` is not an even power of two", bytes))]
PieceLengthUneven { bytes: Bytes },
#[snafu(display("Piece length must be at least 16 KiB"))]
Expand Down
8 changes: 8 additions & 0 deletions src/infohash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ impl From<Sha1Digest> for Infohash {
}
}

impl From<[u8; 20]> for Infohash {
fn from(bytes: [u8; 20]) -> Self {
Infohash {
inner: Sha1Digest::from_bytes(bytes),
}
}
}

impl From<Infohash> for [u8; 20] {
fn from(infohash: Infohash) -> Self {
infohash.inner.bytes()
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ mod mode;
mod options;
mod output_stream;
mod output_target;
mod peer;
mod piece_length_picker;
mod piece_list;
mod platform;
Expand Down
12 changes: 6 additions & 6 deletions src/magnet_link.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::common::*;

#[derive(Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct MagnetLink {
infohash: Infohash,
name: Option<String>,
peers: Vec<HostPort>,
trackers: Vec<Url>,
indices: BTreeSet<u64>,
pub(crate) infohash: Infohash,
pub(crate) name: Option<String>,
pub(crate) peers: Vec<HostPort>,
pub(crate) trackers: Vec<Url>,
pub(crate) indices: BTreeSet<u64>,
}

impl MagnetLink {
Expand Down
6 changes: 6 additions & 0 deletions src/peer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub(crate) use client::Client;

pub(crate) mod client;
pub(crate) mod connection;
pub(crate) mod handshake;
pub(crate) mod message;
Loading