1. xemacs
  2. erc


erc / erc-ezbounce.el

adrian f698a3f 

adrian e7c06cb 
adrian f698a3f 

adrian d59f55b 

adrian f698a3f 

adrian d59f55b 
adrian f698a3f 

adrian d59f55b 
adrian f698a3f 

adrian e7c06cb 
adrian f698a3f 

adrian 570475e 
adrian f698a3f 

adrian b7ef514 

adrian f698a3f 

adrian b7ef514 
adrian f698a3f 

;;; erc-ezbounce.el ---  Handle EZBounce bouncer commands

;; Copyright (C) 2002  Andreas Fuchs <asf@void.at>

;; Author: Andreas Fuchs <asf@void.at>
;; Keywords: comm

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:


;;; Code:

(require 'erc)

(defconst erc-ezb-version "$Revision$"
  "ERC EZBouncer revision.")

(defgroup erc-ezbounce nil
  "Interface to the EZBounce IRC bouncer (a virtual IRC server)"
  :group 'erc)

(defcustom erc-ezb-regexp "^ezbounce!srv$"
  "Regexp used by the EZBouncer to identify itself to the user."
  :group 'erc-ezbounce
  :type 'string)

(defcustom erc-ezb-login-alist '()
  "Alist of logins suitable for the server we're connecting to.

The alist's format is as follows:

 (((server . port) . (username . password))
  ((server . port) . (username . password))
  :group 'erc-ezbounce
  :type '(repeat
	  (cons (cons :tag "Server"
		(cons :tag "Login"

(defvar erc-ezb-action-alist '(("^\\[awaiting login/pass command\\]$" . erc-ezb-identify)
			       ("^\\[use /quote CONN <server> to connect\\]$"    . erc-ezb-select)
			       ("^ID +IRC NICK +TO +TIME$" . erc-ezb-init-session-list)
			       ("^$"                       . erc-ezb-end-of-session-list)
			       (".*"                       . erc-ezb-add-session))
  "Alist of actions to take on NOTICEs from EZBounce.")

(defvar erc-ezb-session-list '()
  "List of detached EZBounce sessions.")
(make-variable-buffer-local 'erc-ezb-session-list)

(defvar erc-ezb-inside-session-listing nil
  "Indicate whether current notices are expected to be EZB session listings.")

(defun erc-cmd-ezb (line &optional force)
  "Send EZB commands to the EZBouncer verbatim."
  (erc-send-command (concat "EZB " line)))
(put 'erc-cmd-EZB 'do-not-parse-args t)

(defun erc-ezb-get-login (server port)
  "Return an appropriate EZBounce login for SERVER and PORT.
Look up entries in `erc-ezb-login-alist'. If the username or password
in the alist is `nil', prompt for the appropriate values."
  (let ((login (cdr (assoc (cons server port) erc-ezb-login-alist))))
    (when login
      (let ((username (car login))
	    (password (cdr login)))
	(when (null username)
	  (setq username (read-from-minibuffer (format "EZBounce user name for %s:%s: " server port))))
	(when (null password)
	  (setq password (read-passwd (format "EZBounce password for %s:%s: " server port))))
	(cons username password)))))

(defun erc-ezb-lookup-action (message)
  (let ((function-alist erc-ezb-action-alist)
    (while (and (not found)
      (let ((regexp (caar function-alist))
	    (function (cdar function-alist)))
	(when (string-match regexp message)
	  (setq found function))
	(setq function-alist (cdr function-alist))))

(defun erc-ezb-notice-autodetect (proc parsed)
  "React on an EZBounce NOTICE request."
  (let* ((sender (erc-response.sender parsed))
	 (message (erc-response.contents parsed))
	 (function (erc-ezb-lookup-action message)))
    (when (and (string-match erc-ezb-regexp sender)
      (funcall function message)))

(defun erc-ezb-identify (message)
  "Identify to the EZBouncer server."
  (let ((login (erc-ezb-get-login erc-session-server (erc-port-to-string erc-session-port))))
    (unless (null login)
      (let ((username (car login))
	    (pass (cdr login)))
	(erc-send-command (concat "LOGIN " username " " pass))))))

(defun erc-ezb-init-session-list (message)
  "Reset the EZBounce session list to NIL."
  (setq erc-ezb-session-list nil)
  (setq erc-ezb-inside-session-listing t))

(defun erc-ezb-end-of-session-list (message)
  "Indicate the end of the EZBounce session listing."
  (setq erc-ezb-inside-session-listing nil))
(defun erc-ezb-add-session (message)
  "Add an EZBounce session to the session list."
  (when (and erc-ezb-inside-session-listing
	     (string-match "^\\([^ ]+\\) +\\([^ ]+\\) +\\([^ ]+\\) +\\([^ ]+\\)$" message))
    (let ((id (match-string 1 message))
	  (nick (match-string 2 message))
	  (to   (match-string 3 message)))
      (add-to-list 'erc-ezb-session-list (list id nick to)))))

(defun erc-ezb-select (message)
  "Select an IRC server to use by EZBounce, in ERC style."
  (unless (and erc-ezb-session-list
    (let* ((server (read-from-minibuffer
		    "IRC server: " "" nil nil 'erc-server-history-list))
	     (read-from-minibuffer "IRC port: "
				   (erc-port-to-string "6667")))))
      (erc-send-command (format "CONN %s %s" server port)))))

(defun erc-ezb-select-session ()
  "Select a detached EZBounce session."
  (let ((session (completing-read "Existing Session (RET to enter a new one): "
    (if (string= session "")
      (erc-send-command (format "REATTACH %s" session)))))

(defun erc-ezb-initialize ()
  "Add EZBouncer convenience functions to ERC."
  (add-hook 'erc-server-NOTICE-functions 'erc-ezb-notice-autodetect))
(provide 'erc-ezbounce)

;;; erc-ezbounce.el ends here