nserver 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/History.txt +7 -0
  2. data/README.txt +8 -0
  3. data/Rakefile +1 -1
  4. data/bin/nclient +7 -2
  5. data/bin/nserver +28 -1
  6. data/lib/nserver.rb +101 -28
  7. metadata +2 -2
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 1.1.0 / 2007-11.07
2
+
3
+ * Major feature - accept connections from any host
4
+ * Bind to any address on machine
5
+ * Allow access based on IPs or Ranges
6
+ * Reject access if not explicitly permitted.
7
+
1
8
  == 1.0.1 / 2007-11-06
2
9
 
3
10
  * Minor enhancement
data/README.txt CHANGED
@@ -22,6 +22,10 @@ If you have the Daemons ruby gem installed, simply run:
22
22
 
23
23
  This starts a persistent NServer::Server instance on port 10001.
24
24
 
25
+ If you want to customize the bind ip or port:
26
+
27
+ % nserver start --bind-ip x.x.x.x --allow y.y.y.y,z.z.z.z/24
28
+
25
29
  === Client Example:
26
30
 
27
31
  Assuming you have a NServer::Server instance running, you can use the client like this:
@@ -39,6 +43,10 @@ or
39
43
 
40
44
  % nclient "Urgent message" -p critical
41
45
 
46
+ If you're NServer is listening on another mahcine, you can:
47
+
48
+ % nclient --host y.y.y.y "My message"
49
+
42
50
  == REQUIREMENTS:
43
51
 
44
52
  * daemons
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake'
6
6
  require 'spec/rake/spectask'
7
7
  require './lib/nserver.rb'
8
8
 
9
- Hoe.new('nserver', NServer::Server::VERSION) do |p|
9
+ Hoe.new('nserver', NServer::VERSION) do |p|
10
10
  p.rubyforge_name = 'burningbush'
11
11
  p.author = 'Jon Moses'
12
12
  p.email = 'jon@burningbush.us'
data/bin/nclient CHANGED
@@ -5,10 +5,12 @@ require 'nserver'
5
5
  require 'getoptlong'
6
6
 
7
7
  opts = GetoptLong.new(
8
- [ '--priority', '-p', GetoptLong::REQUIRED_ARGUMENT ]
8
+ [ '--priority', '-p', GetoptLong::REQUIRED_ARGUMENT ],
9
+ [ '--host', GetoptLong::REQUIRED_ARGUMENT ]
9
10
  )
10
11
 
11
12
  priority = :normal
13
+ host_ip = '127.0.0.1'
12
14
  msg = nil
13
15
 
14
16
  opts.each do |opt,arg|
@@ -20,6 +22,8 @@ opts.each do |opt,arg|
20
22
  exit 1
21
23
  end
22
24
  priority = p
25
+ when '--host'
26
+ host_ip = arg
23
27
  end
24
28
  end
25
29
 
@@ -31,7 +35,8 @@ end
31
35
  msg = ARGV[0]
32
36
 
33
37
  begin
34
- NServer::Client.notify( msg, priority )
38
+ client = NServer::Client.new(:host => host_ip)
39
+ client.notify(msg, priority )
35
40
  rescue NServer::NoServerAvailable
36
41
  STDERR.puts("No server available.")
37
42
  exit 1
data/bin/nserver CHANGED
@@ -3,10 +3,37 @@
3
3
  require 'rubygems'
4
4
  require 'daemons'
5
5
  require 'nserver'
6
+ require 'getoptlong'
7
+
8
+ bind_ip = nil
9
+ allowed_client_ips = nil
10
+ port = nil
11
+
12
+ opts = GetoptLong.new(
13
+ ['--bind-ip', GetoptLong::REQUIRED_ARGUMENT ],
14
+ ['--allowed-client-ips', GetoptLong::REQUIRED_ARGUMENT ],
15
+ ['--port', GetoptLong::REQUIRED_ARGUMENT ]
16
+ )
17
+
18
+ opts.each do |opt,arg|
19
+ case opt
20
+ when '--bind-ip'
21
+ bind_ip = arg
22
+ when '--allowed-client-ips'
23
+ allowed_client_ips = arg
24
+ when '--port'
25
+ port = arg
26
+ end
27
+ end
28
+
6
29
 
7
30
  Daemons.run_proc("nserver", :dir => "/tmp", :dir_mode => :normal) do
8
31
 
9
- server = NServer::Server.new
32
+ server = NServer::Server.new(
33
+ :host => bind_ip,
34
+ :port => port,
35
+ :allow => allowed_client_ips
36
+ )
10
37
  server.start
11
38
  server.join
12
39
 
data/lib/nserver.rb CHANGED
@@ -1,44 +1,56 @@
1
1
  require 'RNotify'
2
2
  require 'gserver'
3
3
  require 'socket'
4
+ require 'ipaddr'
4
5
 
5
6
  module NServer
6
- class NoServerAvailable < StandardError
7
- def initialize
8
- super("No server available.")
9
- end
10
- end
11
-
12
- class Message
13
- PRIORITIES = [:low, :normal, :critical]
14
-
15
- attr :text, :writable => true
16
- attr :priority, :writable => true
17
-
18
- def initialize( text = "", priority = :normal )
19
- @text = text
20
- @priority = ( PRIORITIES.index( priority ) or 1 )
21
- end
22
- end
23
-
7
+ VERSION = '1.1.0'
24
8
  class Server < GServer
25
- VERSION = '1.0.1'
26
9
 
27
- def initialize( port = 10001, *args )
28
- super(port, *args)
10
+ # Create a NServer::Server instance
11
+ #
12
+ # Options:
13
+ #
14
+ # port::
15
+ # Port for the server to listen on. Default is 10001
16
+ # host::
17
+ # Host (IP) for the server to listen on. Default is 127.0.0.1
18
+ # Note that if you specify a non-localhost IP here you *must* specifiy
19
+ # an allow list. Also accepts 0.0.0.0 to listen on all available
20
+ # interfaces.
21
+ # allow::
22
+ # Comma seperated list of IPs to accept connections from. Default is
23
+ # only 127.0.0.1 IP ranges are allowed, in a x.x.x.x/y format.
24
+ # check_interval::
25
+ # Interval to check for messages. Default is 10s.
26
+ # tray_icon::
27
+ # GTK Icon name to use for the systray icon. Default is 'gnome-gmush'.
28
+ # msg_timeout::
29
+ # Message display timeout. Default is 5000ms (5s).
30
+ def initialize( opts = {} )
31
+ opts[:port] ||= 10001
32
+ opts[:host] ||= "127.0.0.1"
29
33
 
30
- @check_interval = 10
34
+ super(opts[:port], opts[:host])
35
+
36
+ opts[:check_interval] ||= 10
37
+ opts[:tray_icon] ||= "gnome-gmush"
38
+ opts[:msg_timeout] ||= 5000
39
+ opts[:allow] = ( opts[:allow] or "127.0.0.1" ).split(',').collect {|i| IPAddr.new( i ) }
40
+
41
+ @check_interval = opts[:check_interval]
31
42
 
32
43
  @msg_list = [ Message.new("NServer Ready.") ]
44
+ @allowed_clients = opts[:allow]
33
45
 
34
46
  Notify.init("Notification Server")
35
47
  tray_icon = Gtk::StatusIcon.new
36
- tray_icon.icon_name = "gnome-gmush"
48
+ tray_icon.icon_name = opts[:tray_icon]
37
49
  #tray_icon.file = File.join( File.dirname(__FILE__), 'icons', 'default.png')
38
50
  tray_icon.tooltip = "NServer"
39
51
 
40
52
  @notification = Notify::Notification::new("X", nil, nil, tray_icon)
41
- @notification.timeout = 5000
53
+ @notification.timeout = opts[:msg_timeout]
42
54
 
43
55
  Thread.new { Gtk.main }
44
56
  sleep 5
@@ -53,24 +65,29 @@ module NServer
53
65
  end
54
66
  end
55
67
 
68
+ # Display the message
56
69
  def notify(msg)
57
70
  @notification.update("Message Received", msg.text, nil)
58
71
  @notification.urgency = msg.priority
59
72
  @notification.show
60
73
  end
61
74
 
75
+ # Add a message to the message queue
62
76
  def add_message(msg, priority = :normal)
63
77
  @msg_list << Message.new(msg, priority)
64
78
  end
65
79
 
80
+ # Display the next message, if any.
66
81
  def process
67
82
  if @msg_list.size > 0
68
83
  notify(@msg_list.shift)
69
84
  end
70
85
  end
71
86
 
87
+ # Get and add a message to the list. GServer method.
72
88
  def serve(io)
73
- unless io.addr.last == "127.0.0.1"
89
+ unless @allowed_clients.include?( IPAddr.new(io.peeraddr.last) )
90
+ io.puts "#{io.addr.last} is not allowed."
74
91
  return
75
92
  end
76
93
  io.puts("Enter message, terminate with line break.")
@@ -92,6 +109,7 @@ module NServer
92
109
  end
93
110
  end
94
111
 
112
+ # On server shutdown, also do GUI shutdown stuff.
95
113
  def shutdown
96
114
  Notify.uninit
97
115
  Gtk.main_quit
@@ -100,9 +118,25 @@ module NServer
100
118
  end
101
119
 
102
120
  class Client
103
- def Client.notify( msg, priority = :normal )
121
+ attr :host_ip, :writable => true
122
+ attr :host_port, :writable => true
123
+
124
+ # Create a new client
125
+ #
126
+ # Options:
127
+ #
128
+ # host::
129
+ # The host to connect to. Default is 127.0.0.1
130
+ # post::
131
+ # The port to connect to. Default is 10001.
132
+ def initialize( opts = {} )
133
+ @host_ip = ( opts[:host] or '127.0.0.1' )
134
+ @host_port = ( opts[:port] or '10001' ).to_i
135
+ end
136
+
137
+ def notify( msg, priority = :normal )
104
138
  begin
105
- sock = TCPSocket.new('127.0.0.1', 10001)
139
+ sock = TCPSocket.new(@host_ip, @host_port)
106
140
  sleep(0.1) ## Needs delay, or wait until prompt.
107
141
  sock.write("#{priority.to_s.upcase}:#{msg}\n")
108
142
  sock.close
@@ -111,7 +145,8 @@ module NServer
111
145
  end
112
146
  end
113
147
 
114
- def Client.try_notify( msg, priority = :normal )
148
+
149
+ def try_notify(msg, priority = :normal )
115
150
  begin
116
151
  notify(msg, priority)
117
152
  rescue NoServerAvailable
@@ -120,9 +155,47 @@ module NServer
120
155
  return true
121
156
  end
122
157
 
158
+ def with_notification( msg )
159
+ yield
160
+ notify(msg)
161
+ end
162
+
163
+ # Connect to the currently running NServer instance and add the
164
+ # message to the queue. If no server, raise a NoServerAvailable
165
+ # error.
166
+ def Client.notify( msg, priority = :normal )
167
+ Client.new.notify(msg, priority)
168
+ end
169
+
170
+ # Connect to the currently running NServer, if any, and add the
171
+ # message. If no server is available, just return false.
172
+ def Client.try_notify( msg, priority = :normal )
173
+ Client.new.try_notify(msg, priority)
174
+ end
175
+
176
+ # Run the block, then notify (with errors).
123
177
  def Client.with_notification( msg )
124
178
  yield
125
179
  notify( msg )
126
180
  end
127
181
  end
182
+
183
+ class NoServerAvailable < StandardError
184
+ def initialize
185
+ super("No server available.")
186
+ end
187
+ end
188
+
189
+ class Message
190
+ PRIORITIES = [:low, :normal, :critical]
191
+
192
+ attr :text, :writable => true
193
+ attr :priority, :writable => true
194
+
195
+ def initialize( text = "", priority = :normal )
196
+ @text = text
197
+ @priority = ( PRIORITIES.index( priority ) or 1 )
198
+ end
199
+ end
200
+
128
201
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4.5
3
3
  specification_version: 2
4
4
  name: nserver
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.1
7
- date: 2007-11-06 00:00:00 -05:00
6
+ version: 1.1.0
7
+ date: 2007-11-07 00:00:00 -05:00
8
8
  summary: Notification server for ruby using libnotify
9
9
  require_paths:
10
10
  - lib