Class: Syndi::IRC::Server

Inherits:
Object
  • Object
show all
Includes:
DSL::Base
Defined in:
lib/syndi/irc/server.rb

Overview

A class which maintains a connection to an IRC server and provides a highly usable interface for the IRC server.

@!attribute prefixes @return [Hash=> String] The IRC server's supported prefixes, with the key being the channel mode which represents the prefix, and the value being the prefix.

Author:

  • noxgirl

Since:

  • 4.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DSL::Base

#clock_do, #clock_stop, #emit, #on, #undo_on

Constructor Details

#initialize(name) {|c| ... } ⇒ Server

Produce a new instance of Syndi::IRC::Server.

Configuration attributes are +address+, +port+, +nick+, +user+, +real+, +password+, +bind+, and +ssl+.

Examples:

irc = Syndi::IRC::Server.new('Freenode') do |c|
  c.address = 'irc.freenode.net'
  c.port    = 7000
  c.nick    = 'cowmoon'
  c.user    = 'foo1'
  c.real    = "The night is lovely."
  c.bind    = 'localhost'
  c.ssl     = true
end

Yield Parameters:

Since:

  • 4.0.0



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/syndi/irc/server.rb', line 141

def initialize(name)

  # Prepare attributes.
  @name     = name
  @address  = nil
  @port     = nil
  @nick     = nil
  @user     = nil
  @real     = nil
  @password = nil
  @bind     = nil
  @ssl      = false

  # Yield for configuration.
  yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

  # Additional instance attributes.
  @in         = 0
  @out        = 0
  @socket     = nil
  @connected  = false
  @type       = :irc

  # Pull in commands.
  extend   Syndi::IRC::Std::Commands
  # State managers.
  @supp  = Syndi::IRC::State::Support.new
  @chans = nil
  @users = nil

  # Our receive queue remainder.
  @recv_rem = nil

  # Mutual exclusion for thread safety.
  @lock = Mutex.new

end

Instance Attribute Details

#addressString

Returns The address used to connect to the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#await_self_whotrue, false



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#bindString?

Note:

This appears to be unused at the moment.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#channel_modesHash{Symbol => Array<String>}



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#channelsHash{String => IRC::Object::Channel}



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#chansObject

Since:

  • 4.0.0



117
118
119
# File 'lib/syndi/irc/server.rb', line 117

def chans
  @chans
end

#connectedtrue, false

Returns Whether or not we are connected to the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#inInteger (readonly)

Returns The number of bytes received from the socket.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#maskString



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#max_modesInteger



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#nameString

Returns The name of the server as specified by configuration.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#nickString

Returns The nickname of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#outInteger (readonly)

Returns The number of bytes sent to the socket.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#passwordString?

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#portInteger

Returns The port used to connect to the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#realString

Returns The real name or GECOS of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#recvqArray<String>



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#sasl_idString?

Note:

This is seemingly deprecated?



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#socketTCPSocket (readonly)

Returns The TCP socket being used for the connection.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#ssltrue, false

Returns If SSL should [not] be used for the connection.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#suppSyndi::IRC::State::Support (readonly)

Returns The IRCd capabilities.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#typeSymbol (readonly)

Returns +:irc+.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#userString

Returns The username of the bot on the server.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

#usersHash{String => IRC::Object::User}

Returns A list of users who are known to us, with each key being the user's nickname in all-lowercase, and the respective values being of IRC::Object::User.

Since:

  • 4.0.0



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/syndi/irc/server.rb', line 113

class Server
  include Syndi::DSL::Base

  attr_reader   :socket, :in, :out, :type, :supp
  attr_accessor :name, :address, :port, :nick, :user, :real, :password,
                :bind, :ssl, :connected, :chans, :users

  # Produce a new instance of {Syndi::IRC::Server}.
  #
  # @param [String] name The name of the server to which we should connect.
  #
  # @yieldparam [Syndi::IRC::Server] c This instance, intended for configuration of the
  #   attributes.
  #
  # Configuration attributes are +address+, +port+, +nick+, +user+, +real+,
  # +password+, +bind+, and +ssl+.
  #
  #
  # @example
  #   irc = Syndi::IRC::Server.new('Freenode') do |c|
  #     c.address = 'irc.freenode.net'
  #     c.port    = 7000
  #     c.nick    = 'cowmoon'
  #     c.user    = 'foo1'
  #     c.real    = "The night is lovely."
  #     c.bind    = 'localhost'
  #     c.ssl     = true
  #   end
  def initialize(name)
  
    # Prepare attributes.
    @name     = name
    @address  = nil
    @port     = nil
    @nick     = nil
    @user     = nil
    @real     = nil
    @password = nil
    @bind     = nil
    @ssl      = false

    # Yield for configuration.
    yield(self) if block_given? or raise ArgumentError, "Server #{name} unable to initialize because it was not configured."

    # Additional instance attributes.
    @in         = 0
    @out        = 0
    @socket     = nil
    @connected  = false
    @type       = :irc

    # Pull in commands.
    extend   Syndi::IRC::Std::Commands
    # State managers.
    @supp  = Syndi::IRC::State::Support.new
    @chans = nil
    @users = nil

    # Our receive queue remainder.
    @recv_rem = nil

    # Mutual exclusion for thread safety.
    @lock = Mutex.new

  end

  # Establish (or attempt to) a connection with the server.
  def connect

    # Check for missing attributes.
    begin
      attribute_check
    rescue => e
      $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
    end

    $m.info("Connecting to #@name @ #@address:#@port...")

    # Create a new socket.
    begin
      socket = TCPSocket.new(@address, @port, @bind)
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end

    # Wrap it in SSL if told to.
    if ssl
      begin
        socket = OpenSSL::SSL::SSLSocket.new(socket)
        socket.connect
      rescue => e
        $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
        raise
      end
    end

    @socket = socket

    # Register.
    emit :irc, :preconnect, self
    pass @password if @password
    snd 'CAP LS'
    self.nickname = @nick
    user @user, Socket.gethostname, @address, @real

  end

  # Send data to the socket.
  #
  # @param [String] data The string of data, which should not exceed 512 in length.
  def snd data
    $m.foreground("{irc-send} #@name << #{data}")
    @socket.write("#{data}\r\n")
    @out += "#{data}\r\n".length
  end

  # Receive data from the socket, and push it into the recvQ.
  def recv

    # Thread safety.
    @lock.synchronize do
    
      if @socket.nil? or @socket.eof?
        return
      end

      # Read the data.
      data = @socket.sysread(1024)
      # Increase in.
      @in += data.length
  
      # Split the data.
      recv = []
      until data !~ /\r\n/
        line, data = data.split(/(?<=\r\n)/, 2)
        recv.push line.chomp "\r\n"
      end

      # Check if there's a remainder in the recvQ.
      if @recv_rem != ''
        recv[0] = "#@recv_rem#{recv[0]}"
        @recv_rem = ''
      end
      @recv_rem = data if data != ''

      # Lastly, sent the data out
      recv.each do |dline|
        $m.foreground("{irc-recv} #@name >> #{dline}")
        emit :irc, :receive, self, dline # send it out to :receive
      end
    
    end

  end

  def to_s;    @name; end
  def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end
  alias_method :s, :to_s

  #######
  private
  #######

  # Check the presence of all attributes.
  def attribute_check
    raise(ConfigError, "Missing server address")  unless @address
    raise(ConfigError, "Missing server port")     unless @port
    raise(ConfigError, "Missing nickname to use") unless @nick
    raise(ConfigError, "Missing username to use") unless @user
    raise(ConfigError, "Missing realname to use") unless @real
  end

  # Check if we are connected.
  #
  # @return [true, false]
  def connected?
    return false unless @socket
    return false unless @connected
    true
  end

end

Instance Method Details

#attribute_checkObject (private)

Check the presence of all attributes.

Raises:

Since:

  • 4.0.0



278
279
280
281
282
283
284
# File 'lib/syndi/irc/server.rb', line 278

def attribute_check
  raise(ConfigError, "Missing server address")  unless @address
  raise(ConfigError, "Missing server port")     unless @port
  raise(ConfigError, "Missing nickname to use") unless @nick
  raise(ConfigError, "Missing username to use") unless @user
  raise(ConfigError, "Missing realname to use") unless @real
end

#connectObject

Establish (or attempt to) a connection with the server.

Since:

  • 4.0.0



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/syndi/irc/server.rb', line 180

def connect

  # Check for missing attributes.
  begin
    attribute_check
  rescue => e
    $m.error("Cannot connect to server #@name: #{e}", false, e.backtrace)
  end

  $m.info("Connecting to #@name @ #@address:#@port...")

  # Create a new socket.
  begin
    socket = TCPSocket.new(@address, @port, @bind)
  rescue => e
    $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
    raise
  end

  # Wrap it in SSL if told to.
  if ssl
    begin
      socket = OpenSSL::SSL::SSLSocket.new(socket)
      socket.connect
    rescue => e
      $m.error("Failed to connect to server #@name: #{e}", false, e.backtrace)
      raise
    end
  end

  @socket = socket

  # Register.
  emit :irc, :preconnect, self
  pass @password if @password
  snd 'CAP LS'
  self.nickname = @nick
  user @user, Socket.gethostname, @address, @real

end

#connected?true, false (private)

Check if we are connected.

Since:

  • 4.0.0



289
290
291
292
293
# File 'lib/syndi/irc/server.rb', line 289

def connected?
  return false unless @socket
  return false unless @connected
  true
end

#inspectObject

Since:

  • 4.0.0



270
# File 'lib/syndi/irc/server.rb', line 270

def inspect; "#<Syndi::IRC::Server: name='#@name'>"; end

#recvObject

Receive data from the socket, and push it into the recvQ.

Since:

  • 4.0.0



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/syndi/irc/server.rb', line 231

def recv

  # Thread safety.
  @lock.synchronize do
  
    if @socket.nil? or @socket.eof?
      return
    end

    # Read the data.
    data = @socket.sysread(1024)
    # Increase in.
    @in += data.length

    # Split the data.
    recv = []
    until data !~ /\r\n/
      line, data = data.split(/(?<=\r\n)/, 2)
      recv.push line.chomp "\r\n"
    end

    # Check if there's a remainder in the recvQ.
    if @recv_rem != ''
      recv[0] = "#@recv_rem#{recv[0]}"
      @recv_rem = ''
    end
    @recv_rem = data if data != ''

    # Lastly, sent the data out
    recv.each do |dline|
      $m.foreground("{irc-recv} #@name >> #{dline}")
      emit :irc, :receive, self, dline # send it out to :receive
    end
  
  end

end

#snd(data) ⇒ Object

Send data to the socket.

Since:

  • 4.0.0



224
225
226
227
228
# File 'lib/syndi/irc/server.rb', line 224

def snd data
  $m.foreground("{irc-send} #@name << #{data}")
  @socket.write("#{data}\r\n")
  @out += "#{data}\r\n".length
end

#to_sObject Also known as: s

Since:

  • 4.0.0



269
# File 'lib/syndi/irc/server.rb', line 269

def to_s;    @name; end