;;; liece-filter.el --- Process filters for IRC process. ;; Copyright (C) 1998-2000 Daiki Ueno ;; Author: Daiki Ueno ;; Created: 1998-09-28 ;; Revised: 1998-11-25 ;; Keywords: IRC, liece ;; This file is part of Liece. ;; This program 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 program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; 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 'liece-inlines) (require 'liece-misc) (require 'liece-intl) (require 'liece-handler) (defvar liece-current-function nil) (defun* liece-handle-message (prefix message line) (let ((hook (intern (concat "liece-" message "-hook"))) (after-hook (intern (concat "liece-after-" message "-hook"))) (number (car (read-from-string message))) function) (if (run-hook-with-args-until-success hook prefix line) (return-from liece-handle-message)) (if (not (numberp number)) (setq function (liece-handler-find-function message '(prefix line) "generic")) (let ((base (format "%03d" (- number (mod number 100))))) (require (intern (concat "liece-" base)) nil 'noerror) (setq function (liece-handler-find-function message '(prefix line) base)) (or function (setq function (let ((default (concat "liece-handle-" base "-messages"))) `(lambda (prefix line) (funcall (intern ,default) ,message prefix line))))))) (if function (funcall function prefix line)) (run-hook-with-args after-hook prefix line))) (defun liece-parse-user-at-host () (let ((cookie (and (stringp liece-user-at-host) (> (length liece-user-at-host) 2) (string-to-char liece-user-at-host)))) (cond ((null cookie) (setq liece-user-at-host-type 'invalid)) ((or (eq cookie ?^) (eq cookie ?=)) (setq liece-user-at-host (substring liece-user-at-host 1) liece-user-at-host-type 'fake)) ((or (eq cookie ?~) (eq cookie ?-)) (setq liece-user-at-host (substring liece-user-at-host 1) liece-user-at-host-type 'not-verified)) ((eq cookie ?+) (setq liece-user-at-host (substring liece-user-at-host 1) liece-user-at-host-type 'ok)) (t (setq liece-user-at-host-type 'ok))))) (defun liece-parse-line (line) (let (prefix message) (when (or (string-match "^\\(:[^! ]*\\)!\\([^ ]*\\) +\\([^ ]+\\) +:?" line) (string-match "^\\(:[^ ]*\\)?\\(\\) *\\([^ ]+\\) +:?" line) (string-match "^\\(:[^! \t]*\\)!\\([^ \t]*\\) +\\([^ \t]+\\) +:?" line) (string-match "^\\(:[^ ]*\\)?\\(\\) *\\([^ \t]+\\) +:?" line)) (setq prefix (if (match-beginning 1) (substring (match-string 1 line) 1)) liece-user-at-host (match-string 2 line) message (downcase (match-string 3 line)) line (liece-coding-decode-charset-string (substring line (match-end 0)))) (liece-parse-user-at-host) (setq liece-current-function (list prefix message)) (liece-handle-message prefix message line) (setq liece-current-function '("" ""))))) (defun liece-filter (process output) "Filter function for IRC server process." (with-current-buffer (process-buffer process) (goto-char (point-max)) (insert (liece-convert-received-input output)) (goto-char (point-min)) (while (progn (end-of-line) (and (not (eobp)) (eq (char-after) ?\n))) (if (eq (char-after (1- (point))) ?\r) ; cut off preceding LF (delete-region (1- (point)) (point))) (liece-parse-line (buffer-substring (point-min) (point))) (delete-region (point-min) (progn (beginning-of-line 2) (point)))))) (defun liece-sentinel (proc status) "Sentinel function for Liece process." (cond ((or (not liece-server-process) (liece-server-opened))) ((not (or liece-reconnect-automagic liece-reconnect-with-password)) (if (process-id proc) (liece-sentinel-error proc status) (liece-message (_ "Connection closed. (%s)") (substring status 0 (1- (length status))))) (liece-close-server)) (liece-reconnect-with-password (liece)) (t (condition-case nil (progn (set-process-filter liece-server-process nil) (set-process-sentinel liece-server-process nil)) (wrong-type-argument nil)) (setq liece-server-process nil) (liece)))) (defun liece-sentinel-error (proc status) (if (not (string-match "^exited abnormally with code \\([0-9]+\\)" status)) (liece-message (_ "Connection closed. (%s)") (substring status 0 (1- (length status)))) (let ((status (string-to-int (match-string 1 status)))) (cond ((= 99 status) ;; unsupported command (liece-message (_ "Please use a newer \"%s\".") liece-dcc-program)) ((= 98 status) ;; bad argment number (liece-message (_ "Please use a newer \"%s\".") liece-dcc-program)) ((= 97 status) (liece-message (_ "Cannot connect to IRC server."))) (t (liece-message (_ "Server connection closed."))))))) (provide 'liece-filter) ;;; liece-filter.el ends here