lancat 1.0.0

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