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.
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ require 'lancat/version'
2
+ require 'lancat/sender'
3
+ require 'lancat/receiver'
@@ -0,0 +1,4 @@
1
+ module Lancat
2
+ MULTICAST_ADDR = '224.1.2.3'
3
+ MULTICAST_PORT = 7625
4
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Lancat
2
+ VERSION = '1.0.0'
3
+ 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: []