lancat 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|