;;; liece-300.el --- Handler routines for 300 numeric reply. ;; 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: (eval-when-compile (require 'liece-inlines) (require 'liece-intl) (require 'liece-misc) (require 'liece-commands)) (eval-and-compile (autoload 'liece-dcc-compare-hostnames "liece-dcc")) (defvar liece-recursing-whois nil) (defvar liece-recursing-whowas nil) (defun* liece-handle-300-messages (number prefix rest) "300 replies" (or (string-match "[^ ]* \\([^ ]*\\) *\\([^ ]*\\) *:\\(.*\\)" rest) (return-from liece-handle-300-messages)) (let ((target1 (liece-channel-virtual (match-string 1 rest))) (target2 (liece-channel-virtual (match-string 2 rest))) (msg (match-string 3 rest))) (cond ((string= target1 "") (liece-insert-info liece-300-buffer (concat msg "\n"))) ((string= target2 "") (liece-insert-info liece-300-buffer (format "%s (%s)\n" msg target1))) (t (liece-insert-info liece-300-buffer (format "%s %s (%s)\n" target1 msg target2)))))) (defun liece-handle-301-message (prefix rest) "RPL_AWAY \" :\"." (if (string-match "^[^ ]+ \\([^ ]+\\) +:\\(.*\\)" rest) (let ((who (match-string 1 rest)) (iswhat (match-string 2 rest))) (or liece-recursing-whois (liece-insert-info liece-300-buffer (concat who " is marked as being away, " "but left the message:\n" iswhat "\n")))))) (defun liece-handle-302-message (prefix rest) "RPL_USERHOST \":[{}]\"." (while (string-match "^[^ ]* :[ ]*\\([^*=]+\\)\\([*]*\\)=\\([+-]\\)\\([^ ]+\\)" rest) (let ((nick (match-string 1 rest)) (oper (match-string 2 rest)) (away (match-string 3 rest)) (who (match-string 4 rest)) (end (match-end 4))) (if (liece-nick-equal nick liece-real-nickname) (setq liece-my-userhost who)) (liece-insert-info liece-300-buffer (format "Nick %s is %s [%s%s, %s%s]\n" nick who (if (string= oper "") "Not ") "operator" (if (string= away "+") "Not ") "away")) (setq rest (concat " :" (substring rest end nil)))))) (defun liece-303-display-friends (nicks) (let ((on (filter-elements nick nicks (not (string-list-member-ignore-case nick liece-friends-last)))) (off (filter-elements nick liece-friends-last (not (string-list-member-ignore-case nick nicks))))) (setq liece-friends-last nicks) (if on (liece-insert-info liece-300-buffer (format (_ "Following people are now on: %s\n") (mapconcat 'identity on " ")))) (if off (liece-insert-info liece-300-buffer (format (_ "Following people are now off: %s\n") (mapconcat 'identity off " ")))))) (defun* liece-handle-303-message (prefix rest) "RPL_ISON \":[ {}]\"" (or (string-match "[^ ]+ :\\(.*\\)" rest) (return-from liece-handle-303-message)) (setq rest (match-string 1 rest)) (or (string= rest "") (setq rest (substring rest 0 -1))) (let ((nicks (split-string rest))) (when (and (null nicks) (null liece-friends)) (liece-insert-info liece-300-buffer (_ "No one you requested is on now.\n")) (return-from liece-handle-303-message)) (dolist (nick nicks) (when (and (string-list-member-ignore-case nick liece-current-chat-partners) (get (intern nick liece-obarray) 'part)) (liece-insert-change (liece-pick-buffer nick) (format (_ "%s has come back\n") nick)) (put (intern nick liece-obarray) 'part nil))) (unless liece-friends (liece-insert-info liece-300-buffer (format (_ "Following people are on: %s\n") rest)) (return-from liece-handle-303-message)) (if (fboundp liece-display-friends-function) (funcall liece-display-friends-function nicks)))) (defun* liece-handle-305-message (prefix rest) "RPL_UNAWAY \":You are no longer marked as being away\"" (or (string-equal liece-away-indicator "A") (return-from liece-handle-305-message)) (setq liece-away-indicator "-") (liece-maybe-poll) (when (string-match "[^:]:\\(.*\\)" rest) (setq rest (match-string 1 rest)) (liece-insert-info liece-300-buffer (format "%s (%s)\n" rest (funcall liece-format-time-function (current-time)))))) (defun liece-handle-306-message (prefix rest) "RPL_NOWAWAY \":You have been marked as being away\"." (setq liece-away-indicator "A") (if (string-match "[^:]:\\(.*\\)" rest) (liece-insert-info liece-300-buffer (format "%s (%s)\n" (match-string 1 rest) (funcall liece-format-time-function (current-time)))))) (defun liece-handle-311-message (prefix rest) "RPL_WHOISUSER \" * :\"." (and (string-match "[^ ]+ \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest) (not liece-recursing-whois) (liece-insert-info liece-300-buffer (format "%s is %s (%s@%s)\n" (match-string 1 rest) ; nick (match-string 5 rest) ; realname (match-string 2 rest) ; username (match-string 3 rest) ; machine )))) (defun* liece-handle-312-message (prefix rest) "RPL_WHOISSERVER \" :\"" (or (string-match "^[^ ]+ \\(\\([^ ]+\\) \\)?\\([^ ]+\\) :\\(.*\\)" rest) (return-from liece-handle-312-message)) (let ((who (match-string 2 rest)) (server (match-string 3 rest)) (real (match-string 4 rest))) (if (and liece-dcc-resolve-server (not (liece-dcc-compare-hostnames server (liece-server-host))) (not liece-recursing-whois) (not liece-recursing-whowas)) (progn (setq liece-recursing-whois t) (liece-send "WHOIS %s %s" server who)) (setq liece-recursing-whois nil) (liece-insert-info liece-300-buffer (format "on via server %s (%s)\n" server real))))) (defun liece-handle-313-message (prefix rest) "RPL_WHOISOPERATOR \" :is an IRC operator\"." (if (string-match "^[^ ]+ \\([^ ]+\\) :\\(.*\\)" rest) (or liece-recursing-whois (liece-insert-info liece-300-buffer (concat (match-string 2 rest) " is an IRC operator\n"))))) (defun liece-handle-316-message (prefix rest) "RPL_WHOISCHANOP." (cond ((string-match "^\\([^ ]+\\) :\\(.*\\)" rest) (if (not liece-recursing-whois) (liece-insert-info liece-300-buffer (concat "Status: " (match-string 2 rest) "\n")))) ((string-match "^\\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest) (if (not liece-recursing-whois) (liece-insert-info liece-300-buffer (concat "Status: " (match-string 3 rest) "\n")))))) (defun* liece-handle-319-message (prefix rest) "RPL_WHOISCHANNELS \" :{[@|+]}\"" (or (string-match "^\\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest) (return-from liece-handle-319-message)) (let ((chnls (split-string (match-string 3 rest))) isonchnls flag) (dolist (chnl chnls) (if (and (or (eq ?@ (string-to-char chnl)) (eq ?+ (string-to-char chnl))) (liece-channel-p (substring chnl 1))) (progn (setq flag (substring chnl 0 1) chnl (substring chnl 1))) (setq flag "")) (push (concat flag (liece-channel-virtual chnl)) isonchnls)) (if (not liece-recursing-whois) (liece-insert-info liece-300-buffer (format (_ "Channels: %s\n") (mapconcat (function identity) (nreverse isonchnls) " ")))))) (defun liece-handle-314-message (prefix rest) "RPL_WHOWASUSER \" * :\"." (if (string-match "[^ ]+ \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest) (let ((nick (match-string 1 rest)) (username (match-string 2 rest)) (machine (match-string 3 rest)) (chnl (match-string 4 rest)) (realname (match-string 5 rest))) (setq liece-recursing-whowas t) (liece-insert-info liece-300-buffer (format "%s [%s] was %s (%s@%s)\n" nick (if (string= chnl "*") "Private" chnl) realname username machine))))) (defun liece-handle-315-message (prefix rest) "RPL_ENDOFWHO." (if (zerop liece-long-reply-count) (liece-insert-info liece-300-buffer (concat "No matches found" (if liece-who-expression (concat ": " liece-who-expression) "") "\n"))) (setq liece-who-expression nil) (liece-reset-long-reply-count)) (defun liece-handle-317-message (prefix rest) "RPL_WHOISIDLE \" :seconds idle\"." (cond ((string-match "^[^ ]+ [^ ]+ \\([0-9]*\\) :\\(.*\\)" rest) (liece-insert-info liece-300-buffer (concat "Idle for " (liece-convert-seconds (match-string 1 rest)) "\n"))) ((string-match "^[^ ]+ \\([0-9]*\\) :\\(.*\\)" rest) (liece-insert-info liece-300-buffer (concat "Idle for " (liece-convert-seconds (match-string 1 rest)) "\n"))))) (defun liece-handle-318-message (prefix rest) "RPL_ENDOFWHOIS \" :End of /WHOIS list\"." nil) (defun liece-handle-321-message (prefix rest) "RPL_LISTSTART \"Channel :Users Name\"." (liece-insert-info liece-300-buffer (format "%-10s%6s %s\n" (_ "Channel") (_ "Users") (_ "Topic")))) (defun* liece-handle-322-message (prefix rest) "RPL_LIST \" <# visible> :\"" (or (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) :\\(.*\\)" rest) (return-from liece-handle-322-message)) (liece-increment-long-reply-count) (liece-check-long-reply-count) (let ((chnl (match-string 2 rest)) (users (match-string 3 rest)) (topic (match-string 4 rest))) (when (or (string= liece-channel-filter (downcase chnl)) (string= liece-channel-filter "") (and (string= liece-channel-filter "0") (string= chnl "*"))) (setq chnl (liece-channel-virtual chnl)) (put (intern chnl liece-obarray) 'topic topic) (liece-insert-info (append (liece-pick-buffer chnl) liece-300-buffer) (format "%-10s%6s user%s%s%s\n" (if (string= chnl "*") "Priv" chnl) users (if (> (string-to-int users) 1) "s" "") (if (string= "" topic) "" ": ") topic))))) (defun liece-handle-323-message (prefix rest) "RPL_LISTEND \":End of /LIST\"." (liece-reset-long-reply-count)) (defun liece-handle-324-message (prefix rest) "RPL_CHANNELMODEIS \" \"." (if (string-match "[^ ]* \\([^ ]*\\) +\\+\\([^ ]*\\)\\( *[^ ]*\\)" rest) (let ((chnl (match-string 1 rest)) (mode (match-string 2 rest)) (param (match-string 3 rest))) (setq chnl (liece-channel-virtual chnl)) (put (intern chnl liece-obarray) 'mode mode) (liece-insert-info (append (liece-pick-buffer chnl) liece-300-buffer) (format (_ "Mode for %s is %s%s\n") chnl mode param)) (liece-set-channel-indicator)))) (defun liece-handle-331-message (prefix rest) "RPL_NOTOPIC \" :No topic is set\"." (if (string-match "[^ ]* \\([^ ]*\\) \\(.*\\)" rest) (let ((chnl (match-string 1 rest))) (setq chnl (liece-channel-virtual chnl)) (put (intern chnl liece-obarray) 'topic nil) (liece-insert-info (append (liece-pick-buffer chnl) liece-300-buffer) (_ "No topic is set\n")) (liece-set-channel-indicator)))) (defun liece-handle-332-message (prefix rest) "RPL_TOPIC \" :\"." (if (string-match "[^ ]* \\([^ ]*\\) +:\\(.*\\)" rest) (let ((chnl (liece-channel-virtual (match-string 1 rest))) (topic (match-string 2 rest))) (liece-channel-set-topic topic chnl) (liece-insert-info (liece-pick-buffer chnl) (format (_ "Topic: %s\n") topic)) (liece-insert-info liece-300-buffer (format (_ "Topic for %s: %s\n") chnl topic)) (liece-set-channel-indicator)))) (defun liece-handle-333-message (prefix rest) "RPL_TOPICWHOTIME