lancat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/lancat +49 -0
- data/lib/lancat.rb +3 -0
- data/lib/lancat/addr.rb +4 -0
- data/lib/lancat/receiver.rb +51 -0
- data/lib/lancat/sender.rb +65 -0
- data/lib/lancat/version.rb +3 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff686385a4578bdf07304b2587fc5deaa8095858
|
4
|
+
data.tar.gz: f6427d0551fc09994fa33570bb0a67b5f08533c2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3c4ccb647d9067eb296e54b83aeab4d916d8a8c395eefa0075bdc64978e9dc8ecc6e8fe9b2583ed12f99cf271632f80a3195e2a5e2b4957d59127fe3452b16a4
|
7
|
+
data.tar.gz: a843dbba95498b3b242913891c1ef01d182ed0e0b4d997b8e693bbf96cd47ba04d5566b1a49d30ea876d1a4be867db43aeec58ae119f500a19e0053cbae2e1a5
|
data/bin/lancat
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'lancat'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
options = { :timeout => 300 }
|
6
|
+
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = 'Usage: lancat [options]'
|
9
|
+
opts.separator ''
|
10
|
+
opts.separator 'Options:'
|
11
|
+
|
12
|
+
opts.on('-v', '--verbose', 'Verbose output') do |v|
|
13
|
+
options[:verbose] = v
|
14
|
+
end
|
15
|
+
|
16
|
+
opts.on('-r', '--receive', 'Run in receiving mode') do |v|
|
17
|
+
options[:receive] = v
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-s', '--send', 'Run in sending mode') do |v|
|
21
|
+
options[:send] = v
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-t', '--timeout=N', Integer, 'Timeout in seconds (default: 300)') do |v|
|
25
|
+
options[:timeout] = v
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on_tail('-h' , '--help', 'Show this help message') do
|
29
|
+
puts opts
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on_tail('--version', 'Show version number') do
|
34
|
+
puts Lancat::VERSION
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
end.parse!
|
38
|
+
|
39
|
+
if not (options[:send] ^ options[:receive])
|
40
|
+
abort 'lancat: Either --receive or --send must be specified'
|
41
|
+
end
|
42
|
+
|
43
|
+
if options[:send]
|
44
|
+
sender = Lancat::Sender.new(options[:verbose], options[:timeout], STDIN)
|
45
|
+
sender.start
|
46
|
+
else # options[:receive]
|
47
|
+
receiver = Lancat::Receiver.new(options[:verbose], options[:timeout], STDOUT)
|
48
|
+
receiver.start
|
49
|
+
end
|
data/lib/lancat.rb
ADDED
data/lib/lancat/addr.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'ipaddr'
|
3
|
+
|
4
|
+
module Lancat
|
5
|
+
class Receiver
|
6
|
+
def initialize(verbose, timeout, output)
|
7
|
+
@verbose = verbose
|
8
|
+
@timeout = timeout
|
9
|
+
@output = output
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
STDERR.puts 'Waiting for broadcasts...' if @verbose
|
14
|
+
|
15
|
+
addr = nil
|
16
|
+
port = nil
|
17
|
+
|
18
|
+
multicast_sock = UDPSocket.new(Socket::AF_INET)
|
19
|
+
begin
|
20
|
+
ips = IPAddr.new(MULTICAST_ADDR).hton + IPAddr.new('0.0.0.0').hton
|
21
|
+
multicast_sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ips)
|
22
|
+
multicast_sock.bind(Socket::INADDR_ANY, MULTICAST_PORT)
|
23
|
+
|
24
|
+
# TODO add support for receive timeout
|
25
|
+
msg, addr = multicast_sock.recvfrom(2)
|
26
|
+
port = msg.unpack('S>')[0]
|
27
|
+
addr = addr[3]
|
28
|
+
ensure
|
29
|
+
multicast_sock.close
|
30
|
+
end
|
31
|
+
|
32
|
+
STDERR.puts "Connecting to #{addr}:#{port}..." if @verbose
|
33
|
+
client = TCPSocket.new(addr, port)
|
34
|
+
begin
|
35
|
+
STDERR.puts 'Reading data...' if @verbose
|
36
|
+
loop do
|
37
|
+
begin
|
38
|
+
data = client.readpartial(4096)
|
39
|
+
STDOUT.write(data)
|
40
|
+
rescue EOFError
|
41
|
+
break
|
42
|
+
end
|
43
|
+
end
|
44
|
+
ensure
|
45
|
+
client.close
|
46
|
+
end
|
47
|
+
|
48
|
+
STDERR.puts 'Transfer complete.' if @verbose
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'lancat/addr'
|
3
|
+
|
4
|
+
module Lancat
|
5
|
+
class Sender
|
6
|
+
def initialize(verbose, timeout, input)
|
7
|
+
@verbose = verbose
|
8
|
+
@timeout = timeout
|
9
|
+
@input = input
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
server = TCPServer.new(0)
|
14
|
+
begin
|
15
|
+
_, port, _, _ = server.addr(:numeric)
|
16
|
+
|
17
|
+
STDERR.puts "Listening on port #{port}..." if @verbose
|
18
|
+
|
19
|
+
# keep broadcasting packet indicating our IP/port, stop after timeout
|
20
|
+
# or after a connection arrives
|
21
|
+
client = nil
|
22
|
+
multicast_sock = UDPSocket.new(Socket::AF_INET)
|
23
|
+
begin
|
24
|
+
multicast_sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_LOOP, [1].pack('i'))
|
25
|
+
multicast_sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_TTL, [1].pack('i'))
|
26
|
+
|
27
|
+
msg = [port].pack('S>')
|
28
|
+
|
29
|
+
for i in 1..@timeout
|
30
|
+
STDERR.puts "Broadcast attempt #{i}..." if @verbose
|
31
|
+
multicast_sock.send(msg, 0, MULTICAST_ADDR, MULTICAST_PORT)
|
32
|
+
sleep 1
|
33
|
+
|
34
|
+
begin
|
35
|
+
client = server.accept_nonblock
|
36
|
+
break if not client.nil?
|
37
|
+
rescue IO::WaitReadable
|
38
|
+
# ignore
|
39
|
+
end
|
40
|
+
end
|
41
|
+
ensure
|
42
|
+
multicast_sock.close
|
43
|
+
end
|
44
|
+
|
45
|
+
abort 'lancat: Timeout' if client.nil?
|
46
|
+
|
47
|
+
_, _, _, remote = client.peeraddr(:numeric)
|
48
|
+
STDERR.puts "Connection from #{remote}, writing data..." if @verbose
|
49
|
+
|
50
|
+
loop do
|
51
|
+
begin
|
52
|
+
data = STDIN.readpartial(4096)
|
53
|
+
client.write(data)
|
54
|
+
rescue EOFError
|
55
|
+
break
|
56
|
+
end
|
57
|
+
end
|
58
|
+
ensure
|
59
|
+
server.close
|
60
|
+
end
|
61
|
+
|
62
|
+
STDERR.puts 'Transfer complete.' if @verbose
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lancat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Graham Edgecombe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: lancat is a program which allows files and other data to be quickly transferred
|
14
|
+
over the local network by piping data into lancat in the shell on one machine, and
|
15
|
+
out of lancat in the shell at another machine. It uses multicast so no configuration
|
16
|
+
(e.g. of IP addresses) needs to take place.
|
17
|
+
email: graham@grahamedgecombe.com
|
18
|
+
executables:
|
19
|
+
- lancat
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- bin/lancat
|
24
|
+
- lib/lancat.rb
|
25
|
+
- lib/lancat/sender.rb
|
26
|
+
- lib/lancat/addr.rb
|
27
|
+
- lib/lancat/receiver.rb
|
28
|
+
- lib/lancat/version.rb
|
29
|
+
homepage: http://grahamedgecombe.com/projects/lancat
|
30
|
+
licenses:
|
31
|
+
- ISC
|
32
|
+
metadata: {}
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 2.0.3
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Zero-configuration LAN file transfer
|
53
|
+
test_files: []
|