;;; Commentary:
-;; This program allows to connect IRC server via asynchronous proxy
-;; which responds to PING request from server in background.
+;; This program allows to connect to an IRC server via local proxy
+;; which responds to PING requests from server.
;; To use, add the following line to your ~/.riece/init.el:
;; (add-to-list 'riece-addons 'riece-async)
-;; If you want to enable this feature to per server, write the server
+;; If you want to enable this feature per server, write the server
;; spec like this:
;; (add-to-list 'riece-server-alist
;; '("async" :host "irc.tokyo.wide.ad.jp"
(defcustom riece-async-server-program
'("\
+require 'io/nonblock'
+
socket = TCPSocket.new(" host ", " service ")
-$stdout.write(\"NOTICE CONNECTED\r\n\")
+$stdout.write(\"NOTICE CONNECTED #{$$}\r\n\")
$stdout.flush
+
+$stdout.nonblock = true
+trap('STOP', 'IGNORE')
+trap('TSTP', 'IGNORE')
+wfds_in = []
+buf = ''
loop do
- rfds, = select([socket, $stdin])
+ rfds, wfds, = select([socket, $stdin], wfds_in)
+ unless wfds.empty?
+ begin
+ until buf.empty?
+ len = $stdout.syswrite(buf)
+ buf.slice!(0 .. len)
+ end
+ wfds_in = []
+ rescue Errno::EAGAIN
+ end
+ end
if rfds.delete(socket)
line = socket.gets(\"\r\n\")
break unless line
socket.write(\"PONG #{$1}\r\n\")
socket.flush
else
- $stdout.write(line)
- $stdout.flush
+ wfds_in = [$stdout]
+ buf << line
+ until buf.length <= " max-buffer-size "
+ buf.slice!(0 .. buf.index(\"\r\n\"))
+ end
end
end
if rfds.delete($stdin)
:type 'list
:group 'riece-async)
+(defcustom riece-async-max-buffer-size 65535
+ "Maximum size of the write buffer"
+ :type 'integer
+ :group 'riece-async)
+
(defun riece-async-substitute-variables (program variable value)
(setq program (copy-sequence program))
(let ((pointer program))
(apply #'concat
(riece-async-substitute-variables
(riece-async-substitute-variables
- riece-async-server-program
- 'host
- (concat "'" host "'"))
- 'service
- (if (numberp service)
- (number-to-string service)
- (concat "'" service "'")))))
+ (riece-async-substitute-variables
+ riece-async-server-program
+ 'host
+ (concat "'" host "'"))
+ 'service
+ (if (numberp service)
+ (number-to-string service)
+ (concat "'" service "'")))
+ 'max-buffer-size
+ (number-to-string
+ riece-async-max-buffer-size))))
(process-send-string process "\0\n") ;input to process is needed
(if buffer
(save-excursion
(while (and (eq (process-status process) 'run)
(progn
(goto-char (point-min))
- (not (looking-at "NOTICE CONNECTED"))))
+ (not (looking-at (format "NOTICE CONNECTED %d"
+ (process-id process))))))
(accept-process-output process))))
process))