wol 0.2.2 → 0.3.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.
- 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
|