wol 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/wol +4 -145
- data/lib/wol/parsefile.rb +54 -0
- data/lib/wol/runner.rb +141 -0
- data/lib/wol/wakeonlan.rb +62 -0
- data/lib/wol.rb +3 -73
- data/spec/parsefile_spec.rb +36 -6
- data/spec/spec_helper.rb +0 -1
- data/spec/wakeonlan_spec.rb +27 -0
- metadata +7 -5
- data/lib/parsefile.rb +0 -44
- data/spec/wol_spec.rb +0 -31
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ begin
|
|
10
10
|
gem.email = "korhonen.matt@gmail.com"
|
11
11
|
gem.homepage = "http://github.com/k33l0r/wol"
|
12
12
|
gem.authors = ["Matias Korhonen"]
|
13
|
-
gem.rubyforge_project = 'wol'
|
13
|
+
gem.rubyforge_project = 'wol'
|
14
14
|
gem.add_development_dependency "rspec", ">= 0"
|
15
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
16
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/wol
CHANGED
@@ -1,149 +1,8 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require 'wol'
|
5
|
-
require 'parsefile'
|
6
|
-
|
7
|
-
class Runner
|
8
|
-
@sample_file = %{# File structure
|
9
|
-
# --------------
|
10
|
-
# - blank lines are ignored
|
11
|
-
# - comment lines are ignored (lines starting with a hash mark '#')
|
12
|
-
# - other lines are considered valid records and can have 3 columns:
|
13
|
-
#
|
14
|
-
# Hardware address, IP address, destination port
|
15
|
-
#
|
16
|
-
# the last two are optional, in which case the following defaults
|
17
|
-
# are used:
|
18
|
-
#
|
19
|
-
# IP address: 255.255.255.255 (the limited broadcast address)
|
20
|
-
# port: 9 (the discard port)
|
21
|
-
#
|
22
|
-
|
23
|
-
01:02:03:04:05:06 192.168.1.255 9
|
24
|
-
07:09:09:0A:0B:0C 255.255.255.255
|
25
|
-
0D:0E:0F:00:10:11}
|
26
|
-
|
27
|
-
def self.parse(args)
|
28
|
-
args = ["-h"] if args.empty?
|
29
|
-
|
30
|
-
options = {}
|
31
|
-
options[:quiet] = false
|
32
|
-
options[:address] = "255.255.255.255"
|
33
|
-
options[:port] = 9
|
34
|
-
options[:interval] = 0.01
|
35
|
-
options[:count] = 3
|
36
|
-
options[:macs] = Array.new
|
37
|
-
options[:file] = nil
|
38
|
-
|
39
|
-
opts = OptionParser.new do |opts|
|
40
|
-
# Set a banner, displayed at the top
|
41
|
-
# of the help screen.
|
42
|
-
opts.banner = "#{version}\nUsage: wol -a ADDRESS ff:ff:ff:ff:ff:ff"
|
43
|
-
|
44
|
-
opts.separator ""
|
45
|
-
opts.separator "Specific options:"
|
46
|
-
|
47
|
-
opts.on( '-q', '--quiet', 'No console output' ) do
|
48
|
-
options[:quiet] = true
|
49
|
-
end
|
50
|
-
|
51
|
-
opts.on( '-a', '--address 255.255.255.255', 'Set the destination address' ) do |address|
|
52
|
-
options[:address] = address
|
53
|
-
end
|
54
|
-
|
55
|
-
opts.on( '-p', '--port 9', Integer, 'Set the destination port' ) do |port|
|
56
|
-
options[:port] = port
|
57
|
-
end
|
58
|
-
|
59
|
-
opts.on( '-i', '--interval 0.01', Float, 'Interval between sending packets in seconds') do |interval|
|
60
|
-
options[:interval] = interval
|
61
|
-
end
|
62
|
-
|
63
|
-
opts.on( '-c', '--count 3', Integer, 'Number of packets to send. Default 3') do |count|
|
64
|
-
options[:count] = count
|
65
|
-
end
|
66
|
-
|
67
|
-
opts.on( '-f', '--file FILE', 'TODO: Uses a file as a source of addresses') do |file|
|
68
|
-
options[:file] = file
|
69
|
-
end
|
70
|
-
|
71
|
-
opts.separator ""
|
72
|
-
opts.separator "Common options:"
|
3
|
+
$LOAD_PATH.push File.join(File.dirname(__FILE__), "/../lib")
|
73
4
|
|
74
|
-
|
75
|
-
puts opts
|
76
|
-
exit
|
77
|
-
end
|
78
|
-
|
79
|
-
opts.on_tail( '-s', '--sample-file', 'Display a sample file') do
|
80
|
-
puts @sample_file
|
81
|
-
exit
|
82
|
-
end
|
83
|
-
|
84
|
-
opts.on_tail( '-v', '--version', 'Show version') do
|
85
|
-
puts version
|
86
|
-
exit
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
begin
|
91
|
-
opts.parse!(args)
|
92
|
-
|
93
|
-
if options[:file].nil?
|
94
|
-
args.each do |arg|
|
95
|
-
options[:macs] << arg if /^(\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2})?$/.match(arg)
|
96
|
-
end
|
97
|
-
|
98
|
-
options[:macs].uniq!
|
99
|
-
end
|
100
|
-
|
101
|
-
return options
|
102
|
-
rescue OptionParser::InvalidOption => e
|
103
|
-
STDERR.puts e.message, "\n", opts
|
104
|
-
exit(-1)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.version
|
109
|
-
"Ruby Wake-On-LAN version 0.2.2"
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.wake(options = {})
|
113
|
-
begin
|
114
|
-
if options[:file].empty?
|
115
|
-
if !options[:macs].empty?
|
116
|
-
puts Wol.new(options).wake unless options[:quiet]
|
117
|
-
else
|
118
|
-
puts "You have to specify a file or MAC address"
|
119
|
-
end
|
120
|
-
else
|
121
|
-
puts wake_from_file(options) unless options[:quiet]
|
122
|
-
end
|
123
|
-
rescue Exception => e
|
124
|
-
puts "An error occured. Please check your inputs."
|
125
|
-
puts "If you used a file, please check that it is properly formatted."
|
126
|
-
STDERR.puts e.message
|
127
|
-
exit(-1)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.wake_from_file(options = {})
|
132
|
-
message = ""
|
133
|
-
hosts = ParseFile.parse(options[:file])
|
134
|
-
|
135
|
-
for host in hosts
|
136
|
-
options[:address], options[:macs], options[:port] = host[:address], host[:mac], host[:port]
|
137
|
-
|
138
|
-
unless options[:quiet]
|
139
|
-
message << Wol.new(options).wake
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
return options[:quiet] ? nil : message
|
144
|
-
end
|
145
|
-
end
|
5
|
+
require 'wol'
|
146
6
|
|
147
|
-
|
7
|
+
Wol::Runner.run!
|
148
8
|
|
149
|
-
Runner.wake(options)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Parse a text file containing hardware addresses, host names/addresses, and port numbers
|
2
|
+
module Wol
|
3
|
+
module ParseFile
|
4
|
+
|
5
|
+
# Parse a given string and return a hash containing the results
|
6
|
+
def self.parse(text)
|
7
|
+
hosts = []
|
8
|
+
text.each_line do |line|
|
9
|
+
unless line.match(/^#/) || line.strip.empty?
|
10
|
+
mac, address, port = line.strip.split
|
11
|
+
|
12
|
+
port ||= 9
|
13
|
+
host ||= "255.255.255.255"
|
14
|
+
|
15
|
+
if check_mac(mac) && check_host(address)
|
16
|
+
hosts << { :mac => mac, :address => address, :port => sanitize_port(port)}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
return hosts
|
22
|
+
end
|
23
|
+
|
24
|
+
# Read a file and then parse its contents
|
25
|
+
def self.read_and_parse_file(file)
|
26
|
+
parse(read_file(file))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Read a file and return the contents
|
32
|
+
def self.read_file(file)
|
33
|
+
if File.exist?(file) && File.readable?(file)
|
34
|
+
File.open(file, "r").read
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Check if a given hardware address is correctly formed.
|
39
|
+
def self.check_mac(mac)
|
40
|
+
/^(\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2})?$/.match(mac)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Check that a host/ip address doesn't contain any illegal characters.
|
44
|
+
def self.check_host(host)
|
45
|
+
/(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$)/.match(host)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Make sure that a given port number is an integer in the correct range (1..61000).
|
49
|
+
def self.sanitize_port(port)
|
50
|
+
p = port.to_i
|
51
|
+
return (1..61000).include?(p) ? p : 9
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/wol/runner.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Wol
|
4
|
+
module Runner
|
5
|
+
@sample_file = %{# File structure
|
6
|
+
# --------------
|
7
|
+
# - blank lines are ignored
|
8
|
+
# - comment lines are ignored (lines starting with a hash mark '#')
|
9
|
+
# - other lines are considered valid records and can have 3 columns:
|
10
|
+
#
|
11
|
+
# Hardware address, address, destination port
|
12
|
+
#
|
13
|
+
# the last two are optional, in which case the following defaults
|
14
|
+
# are used:
|
15
|
+
#
|
16
|
+
# IP address: 255.255.255.255 (the limited broadcast address)
|
17
|
+
# port: 9 (the discard port)
|
18
|
+
#
|
19
|
+
|
20
|
+
01:02:03:04:05:06 192.168.1.255 9
|
21
|
+
07:09:09:0A:0B:0C example.com
|
22
|
+
0D:0E:0F:00:10:11}
|
23
|
+
|
24
|
+
def self.parse(args)
|
25
|
+
args = ["-h"] if args.empty?
|
26
|
+
|
27
|
+
options = {}
|
28
|
+
options[:quiet] = false
|
29
|
+
options[:address] = "255.255.255.255"
|
30
|
+
options[:port] = 9
|
31
|
+
options[:delay] = 0.01
|
32
|
+
options[:count] = 3
|
33
|
+
options[:macs] = Array.new
|
34
|
+
options[:file] = nil
|
35
|
+
|
36
|
+
opts = OptionParser.new do |opts|
|
37
|
+
# Set a banner, displayed at the top
|
38
|
+
# of the help screen.
|
39
|
+
opts.banner = "#{version}\nUsage: wol -a ADDRESS ff:ff:ff:ff:ff:ff"
|
40
|
+
|
41
|
+
opts.separator ""
|
42
|
+
opts.separator "Specific options:"
|
43
|
+
|
44
|
+
opts.on( '-q', '--quiet', 'No console output' ) do
|
45
|
+
options[:quiet] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on( '-i', '--address 255.255.255.255', 'Set the destination address' ) do |address|
|
49
|
+
options[:address] = address
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on( '-p', '--port 9', Integer, 'Set the destination port' ) do |port|
|
53
|
+
options[:port] = port
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on( '-d', '--delay 0.01', Float, 'Delay between sending packets in seconds') do |delay|
|
57
|
+
options[:delay] = delay
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on( '-c', '--count 3', Integer, 'Number of packets to send. Default 3') do |count|
|
61
|
+
options[:count] = count
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on( '-f', '--file FILE', 'TODO: Uses a file as a source of addresses') do |file|
|
65
|
+
options[:file] = file
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.separator ""
|
69
|
+
opts.separator "Common options:"
|
70
|
+
|
71
|
+
opts.on_tail( '-h', '--help', 'Display this message' ) do
|
72
|
+
puts opts
|
73
|
+
exit
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on_tail( '-s', '--sample-file', 'Display a sample file') do
|
77
|
+
puts @sample_file
|
78
|
+
exit
|
79
|
+
end
|
80
|
+
|
81
|
+
opts.on_tail( '-v', '--version', 'Show version') do
|
82
|
+
puts version
|
83
|
+
exit
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
begin
|
88
|
+
opts.parse!(args)
|
89
|
+
|
90
|
+
if options[:file].nil?
|
91
|
+
args.each do |arg|
|
92
|
+
options[:macs] << arg if /^(\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2})?$/.match(arg)
|
93
|
+
end
|
94
|
+
|
95
|
+
options[:macs].uniq!
|
96
|
+
end
|
97
|
+
|
98
|
+
return options
|
99
|
+
rescue OptionParser::InvalidOption => e
|
100
|
+
STDERR.puts e.message, "\n", opts
|
101
|
+
exit(-1)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.version
|
106
|
+
"Ruby Wake-On-LAN version 0.3.0"
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.wake(options = {})
|
110
|
+
begin
|
111
|
+
if options[:file]
|
112
|
+
hosts = ParseFile.read_and_parse_file(options[:file])
|
113
|
+
|
114
|
+
for host in hosts
|
115
|
+
options[:address], options[:macs], options[:port] = host[:address], host[:mac], host[:port]
|
116
|
+
|
117
|
+
puts WakeOnLan.new(options).wake
|
118
|
+
end
|
119
|
+
elsif options[:macs]
|
120
|
+
options[:macs].each do |mac|
|
121
|
+
options[:mac] = mac
|
122
|
+
puts WakeOnLan.new(options).wake
|
123
|
+
end
|
124
|
+
else
|
125
|
+
puts "You have to specify a file or MAC address"
|
126
|
+
end
|
127
|
+
rescue Exception => e
|
128
|
+
puts "An error occured. Please check your inputs."
|
129
|
+
puts "If you used a file, please check that it is properly formatted."
|
130
|
+
STDERR.puts e.message
|
131
|
+
exit(-1)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.run!
|
136
|
+
options = parse(ARGV)
|
137
|
+
|
138
|
+
wake(options)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright (C) 2000-2003 K.Kodama
|
2
|
+
# Original: http://www.math.kobe-u.ac.jp/~kodama/tips-WakeOnLAN.html
|
3
|
+
#
|
4
|
+
# Modified by Matias Korhonen (26.09.2009: Removed command line options, changed to
|
5
|
+
# send the magic packet straight to the IP, not the broadcast address)
|
6
|
+
#
|
7
|
+
# Licensed under the Ruby License: http://www.ruby-lang.org/en/LICENSE.txt
|
8
|
+
# and the GNU General Public License: http://www.gnu.org/copyleft/gpl.html
|
9
|
+
#
|
10
|
+
require "socket"
|
11
|
+
|
12
|
+
# Ruby version of the WakeOnLan command.
|
13
|
+
|
14
|
+
module Wol
|
15
|
+
class WakeOnLan
|
16
|
+
attr_accessor :mac, :address, :port, :count, :delay, :quiet
|
17
|
+
attr_reader :socket
|
18
|
+
|
19
|
+
# Create a new instance
|
20
|
+
# == Options
|
21
|
+
# * <tt>:mac => "ff:ff:ff:ff:ff:ff"</tt> - Specify the destination MAC Address. Defaults to the broadcast MAC, "ff:ff:ff:ff:ff:ff"
|
22
|
+
# * <tt>:address => "255.255.255.255"</tt> - Specify the destination address. Either a IP or hostname. Defaults to "255.255.255.255"
|
23
|
+
# * <tt>:port => 9</tt> - The destination port. Defaults to the discard port, 9
|
24
|
+
# * <tt>:count => 1</tt> - How many times to send the MagicPacket. Defaults to 1
|
25
|
+
# * <tt>:delay => 0.01</tt> - How many seconds to wait between sending packets. Defaults to 0.01
|
26
|
+
# * <tt>:quiet => false</tt> - What to return? Returns a string summary if false, else returns nil
|
27
|
+
def initialize(options = {})
|
28
|
+
@mac = options[:mac] ||= "ff:ff:ff:ff:ff:ff"
|
29
|
+
@address = options[:address] ||= "255.255.255.255"
|
30
|
+
@port = options[:port] ||= 9
|
31
|
+
@count = options[:count] ||= 1
|
32
|
+
@delay = options[:delay] ||= 0.01
|
33
|
+
@quiet = options[:quiet]
|
34
|
+
|
35
|
+
@socket=UDPSocket.open()
|
36
|
+
|
37
|
+
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Close the socket opened by Wol initialization
|
41
|
+
def close
|
42
|
+
@socket.close
|
43
|
+
@socket=""
|
44
|
+
end
|
45
|
+
|
46
|
+
# Wake host
|
47
|
+
def wake
|
48
|
+
magicpacket = (0xff.chr)*6+(@mac.split(/:/).pack("H*H*H*H*H*H*"))*16
|
49
|
+
|
50
|
+
@count.times do
|
51
|
+
@socket.send(magicpacket, 0, @address, @port)
|
52
|
+
sleep @delay if @delay > 0 unless @count == 1
|
53
|
+
end
|
54
|
+
|
55
|
+
if @quiet
|
56
|
+
return nil
|
57
|
+
else
|
58
|
+
return @count == 1 ? "Sending magic packet to #{@address}:#{@port} with #{@mac}" : "Sending magic packet to #{@address}:#{@port} with #{@mac} #{@count} times"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/wol.rb
CHANGED
@@ -1,73 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# Modified by Matias Korhonen (26.09.2009: Removed command line options, changed to
|
5
|
-
# send the magic packet straight to the IP, not the broadcast address)
|
6
|
-
#
|
7
|
-
# Licensed under the Ruby License: http://www.ruby-lang.org/en/LICENSE.txt
|
8
|
-
# and the GNU General Public License: http://www.gnu.org/copyleft/gpl.html
|
9
|
-
#
|
10
|
-
require "socket"
|
11
|
-
|
12
|
-
# Ruby version of the WakeOnLan command.
|
13
|
-
class Wol
|
14
|
-
attr_accessor :macs, :address, :port, :count, :interval, :quiet
|
15
|
-
attr_reader :socket
|
16
|
-
|
17
|
-
# Create a new instance
|
18
|
-
# == Options
|
19
|
-
# * <tt>:mac => "ff:ff:ff:ff:ff:ff"</tt> - Specify the destination MAC Address. Defaults to the broadcast MAC, "ff:ff:ff:ff:ff:ff"
|
20
|
-
# * <tt>:address => "255.255.255.255"</tt> - Specify the destination address. Either a IP or hostname. Defaults to "255.255.255.255"
|
21
|
-
# * <tt>:port => 9</tt> - The destination port. Defaults to the discard port, 9
|
22
|
-
# * <tt>:count => 1</tt> - How many times to send the MagicPacket. Defaults to 1
|
23
|
-
# * <tt>:interval => 0.01</tt> - How many seconds to wait between sending packets. Defaults to 0.01
|
24
|
-
# * <tt>:quiet => false</tt> - What to return? Returns a string summary if false, else returns nil
|
25
|
-
def initialize(options = {})
|
26
|
-
@macs = options[:macs] ||= ["ff:ff:ff:ff:ff:ff"]
|
27
|
-
@address = options[:address] ||= "255.255.255.255"
|
28
|
-
@port = options[:port] ||= 9
|
29
|
-
@count = options[:count] ||= 1
|
30
|
-
@interval = options[:interval] ||= 0.01
|
31
|
-
@quiet = options[:quiet]
|
32
|
-
|
33
|
-
@socket=UDPSocket.open()
|
34
|
-
|
35
|
-
@socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_BROADCAST,1)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Close the socket opened by Wol initialization
|
39
|
-
def close
|
40
|
-
@socket.close
|
41
|
-
@socket=""
|
42
|
-
end
|
43
|
-
|
44
|
-
# Wake host(s)
|
45
|
-
def wake
|
46
|
-
messages = ""
|
47
|
-
|
48
|
-
@macs.each do |mac|
|
49
|
-
messages << send_packet(mac) + "\n"
|
50
|
-
end
|
51
|
-
|
52
|
-
if @quiet
|
53
|
-
return nil
|
54
|
-
else
|
55
|
-
return messages
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
# Send the actual packet
|
62
|
-
def send_packet(mac)
|
63
|
-
magicpacket = (0xff.chr)*6+(mac.split(/:/).pack("H*H*H*H*H*H*"))*16
|
64
|
-
|
65
|
-
@count.times do
|
66
|
-
@socket.send(magicpacket, 0, @address, @port)
|
67
|
-
|
68
|
-
sleep @interval if @interval > 0 unless @count == 1
|
69
|
-
end
|
70
|
-
|
71
|
-
return @count == 1 ? "Sending magic packet to #{@address}:#{@port} with #{mac}" : "Sending magic packet to #{@address}:#{@port} with #{mac} #{@count} times"
|
72
|
-
end
|
73
|
-
end
|
1
|
+
require 'wol/wakeonlan'
|
2
|
+
require 'wol/runner'
|
3
|
+
require 'wol/parsefile'
|
data/spec/parsefile_spec.rb
CHANGED
@@ -1,12 +1,42 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
+
EXPECTED = [{:port=>9, :mac=>"01:02:03:04:05:06", :address=>"192.168.1.255"},
|
4
|
+
{:port=>12, :mac=>"01:02:03:04:05:06", :address=>"192.168.2.230"},
|
5
|
+
{:port=>9, :mac=>"07:09:09:0A:0B:0C", :address=>"example.com"},
|
6
|
+
{:port=>9, :mac=>"07:09:09:0A:0B:0C", :address=>"192.168.1.254"}]
|
7
|
+
|
8
|
+
TEST_STRING = %{# File structure
|
9
|
+
# --------------
|
10
|
+
# - blank lines are ignored
|
11
|
+
# - comment lines are ignored (lines starting with a hash mark '#')
|
12
|
+
# - other lines are considered valid records and can have 3 columns:
|
13
|
+
#
|
14
|
+
# Hardware address, IP address, destination port
|
15
|
+
#
|
16
|
+
# the last two are optional, in which case the following defaults
|
17
|
+
# are used:
|
18
|
+
#
|
19
|
+
# IP address: 255.255.255.255 (the limited broadcast address)
|
20
|
+
# port: 9 (the discard port)
|
21
|
+
#
|
22
|
+
|
23
|
+
01:02:03:04:05:06 192.168.1.255 9
|
24
|
+
01:02:03:04:05:06 192.168.2.230 12
|
25
|
+
07:09:09:0A:0B:0C example.com
|
26
|
+
0D:0E:0F:00:10:11
|
27
|
+
|
28
|
+
# Invalid entries
|
29
|
+
FF:FF:aa
|
30
|
+
0D:0E:0F:00:10:11 ;
|
31
|
+
07:09:09:0A:0B:0C 192.168.1.254 a}
|
32
|
+
|
3
33
|
describe "ParseFile" do
|
4
34
|
it "be able to parse a test file correctly" do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
ParseFile.parse(
|
35
|
+
|
36
|
+
Wol::ParseFile.read_and_parse_file(File.expand_path(File.dirname(__FILE__) + '/hosts.wol')).should == EXPECTED
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be able to parse a test string correctly" do
|
40
|
+
Wol::ParseFile.parse(TEST_STRING).should == EXPECTED
|
11
41
|
end
|
12
42
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Wake-On-LAN" do
|
4
|
+
it "should send a MagicPacket to the broadcast addresses" do
|
5
|
+
Wol::WakeOnLan.new.wake.should == "Sending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:ff:ff"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should send a MagicPacket to a specified mac" do
|
9
|
+
Wol::WakeOnLan.new(:mac => "ff:ff:ff:ff:ff:cc").wake.should == "Sending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:ff:cc"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should send a MagicPacket to a specified address" do
|
13
|
+
Wol::WakeOnLan.new(:address => "example.com").wake.should == "Sending magic packet to example.com:9 with ff:ff:ff:ff:ff:ff"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should send a MagicPacket to a specified port" do
|
17
|
+
Wol::WakeOnLan.new(:port => 12).wake.should == "Sending magic packet to 255.255.255.255:12 with ff:ff:ff:ff:ff:ff"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should send a MagicPacket to a specified mac, address, and port" do
|
21
|
+
Wol::WakeOnLan.new(:mac => "00:08:a1:a9:58:f6", :address => "example.com", :port => 80).wake.should == "Sending magic packet to example.com:80 with 00:08:a1:a9:58:f6"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return nil if quiet is set to true" do
|
25
|
+
Wol::WakeOnLan.new(:quiet => true).wake.should == nil
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matias Korhonen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-13 00:00:00 +02:00
|
13
13
|
default_executable: wol
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -40,13 +40,15 @@ files:
|
|
40
40
|
- Rakefile
|
41
41
|
- VERSION
|
42
42
|
- bin/wol
|
43
|
-
- lib/parsefile.rb
|
44
43
|
- lib/wol.rb
|
44
|
+
- lib/wol/parsefile.rb
|
45
|
+
- lib/wol/runner.rb
|
46
|
+
- lib/wol/wakeonlan.rb
|
45
47
|
- spec/hosts.wol
|
46
48
|
- spec/parsefile_spec.rb
|
47
49
|
- spec/spec.opts
|
48
50
|
- spec/spec_helper.rb
|
49
|
-
- spec/
|
51
|
+
- spec/wakeonlan_spec.rb
|
50
52
|
- test/helper.rb
|
51
53
|
- test/test_wol.rb
|
52
54
|
has_rdoc: true
|
@@ -78,8 +80,8 @@ signing_key:
|
|
78
80
|
specification_version: 3
|
79
81
|
summary: Ruby WoL
|
80
82
|
test_files:
|
83
|
+
- spec/wakeonlan_spec.rb
|
81
84
|
- spec/spec_helper.rb
|
82
|
-
- spec/wol_spec.rb
|
83
85
|
- spec/parsefile_spec.rb
|
84
86
|
- test/test_wol.rb
|
85
87
|
- test/helper.rb
|
data/lib/parsefile.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
# Parse a text file containing hardware addresses, host names/addresses, and port numbers
|
2
|
-
class ParseFile
|
3
|
-
|
4
|
-
# Parse a given text file and return a hash containing the results
|
5
|
-
def self.parse(file)
|
6
|
-
hosts = []
|
7
|
-
if File.exist?(file) && File.readable?(file)
|
8
|
-
File.open(file) do |f|
|
9
|
-
while (line = f.gets)
|
10
|
-
unless line.match(/^#/) || line.strip.empty?
|
11
|
-
mac, address, port = line.strip.split
|
12
|
-
|
13
|
-
port ||= 9
|
14
|
-
host ||= "255.255.255.255"
|
15
|
-
|
16
|
-
if check_mac(mac) && check_host(address)
|
17
|
-
hosts << { :mac => mac, :address => address, :port => sanitize_port(port)}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
return hosts
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
# Check if a given hardware address is correctly formed.
|
30
|
-
def self.check_mac(mac)
|
31
|
-
/^(\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2}:\S{1,2})?$/.match(mac)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Check that a host/ip address doesn't contain any illegal characters.
|
35
|
-
def self.check_host(host)
|
36
|
-
/(^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$)|(^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$)/.match(host)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Make sure that a given port number is an integer in the correct range (1..61000).
|
40
|
-
def self.sanitize_port(port)
|
41
|
-
p = port.to_i
|
42
|
-
return (1..61000).include?(p) ? p : 9
|
43
|
-
end
|
44
|
-
end
|
data/spec/wol_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe "Wake-On-LAN" do
|
4
|
-
it "should send a MagicPacket to the broadcast addresses" do
|
5
|
-
Wol.new.wake.should == "Sending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:ff:ff\n"
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should send a MagicPacket to a specified mac" do
|
9
|
-
Wol.new(:macs => "ff:ff:ff:ff:ff:cc").wake.should == "Sending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:ff:cc\n"
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should send a MagicPacket to a specified address" do
|
13
|
-
Wol.new(:address => "example.com").wake.should == "Sending magic packet to example.com:9 with ff:ff:ff:ff:ff:ff\n"
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should send a MagicPacket to a specified port" do
|
17
|
-
Wol.new(:port => 12).wake.should == "Sending magic packet to 255.255.255.255:12 with ff:ff:ff:ff:ff:ff\n"
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should send a MagicPacket to a specified mac, address, and port" do
|
21
|
-
Wol.new(:macs => "00:08:a1:a9:58:f6", :address => "example.com", :port => 80).wake.should == "Sending magic packet to example.com:80 with 00:08:a1:a9:58:f6\n"
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should send MagicPackets to several hardware addresses at once" do
|
25
|
-
Wol.new(:macs => ["ff:ff:ff:ff:ff:cc", "ff:ff:ff:ff:cc:cc", "ff:ff:ff:ccf:cc:cc"]).wake.should == "Sending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:ff:cc\nSending magic packet to 255.255.255.255:9 with ff:ff:ff:ff:cc:cc\nSending magic packet to 255.255.255.255:9 with ff:ff:ff:ccf:cc:cc\n"
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should return nil if quiet is set to true" do
|
29
|
-
Wol.new(:quiet => true).wake.should == nil
|
30
|
-
end
|
31
|
-
end
|