;;; ;;; $Id: irchat-handle.el,v 1.18 2001/06/04 17:46:03 simm Exp $ ;;; ;;; see file irchat-copyright.el for change log and copyright info (require 'pure-generic) (require 'pure-vs) (require 'pure-ds) (require 'pure-irc-send) (require 'pure-irc-dcc) (require 'irchat-vars) (defsubst irchat-scan-channels (str) (let ((vstr (irchat-chan-virtual str))) (or (string= str vstr) (assoc vstr irchat-channel-alist) (setq irchat-channel-alist (cons (cons vstr nil) irchat-channel-alist))) (or (assoc str irchat-channel-alist) (setq irchat-channel-alist (cons (cons str nil) irchat-channel-alist))))) (defsubst irchat-user-on-this-channel (nick chan) "return non-NIL if NICK is on channel CHAN" (if (null nick) nil (let ((n (intern nick))) (member-ignore-case chan (get n 'chnl))))) (defun irchat-greet-user (nick chan) (let ((n (intern nick))) (message "IRCHAT: %s has entered! (%s)" nick (if (string= chan "0") "on no channel yet" (concat "on channel " (irchat-chan-virtual chan)))) (if (get n 'irchat-greeting) (irchat-send "PRIVMSG %s :%s" nick (get n 'irchat-greeting))) (put n 'irchat-waited-for nil) (put n 'irchat-greeting nil))) (defun irchat-change-nick-of (old new) (let ((pair (assoc old irchat-nick-alist))) (if pair (setcar pair new) (setq irchat-nick-alist (cons (cons new nil) irchat-nick-alist))) (if (null new) ;; maybe quit (put (intern old) 'chnl nil)))) (defun irchat-Command-debug-user () "for debugging." (interactive) (let (rest str chan oper (nick (read-string (format "NICK: ")))) (setq rest (get (intern nick) 'chnl)) (setq str (format "%s =" nick)) (while rest (setq chan (car rest)) (setq rest (cdr rest)) (setq oper (cdr (assoc nick (get (intern chan) 'nicka)))) (setq str (format "%s %s%s" str (or oper "") (irchat-chan-virtual chan)))) (irchat-insert0 (format "%s (shared channels)\n" str)) (irchat-insert0 (format "%s = [%s] to %s last seen\n" nick (irchat-convert-seconds2 (get (intern nick) 'lasttime)) (irchat-chan-virtual (or (get (intern nick) 'lastchan) "(not yet)")))) (irchat-insert0 (format "%s = <%s>\n" nick (or (get (intern nick) 'userhost) "not yet"))))) (defsubst irchat-remove-from-channel (nick chan) "Remove users info from his channel" (let* ((u (intern nick)) (chans (get u 'chnl))) (setq chans (delete (car (member-ignore-case chan chans)) chans)) (put u 'chnl chans))) (defun irchat-add-to-channel (nicks chan) "Update our copy of NICKS on channel CHAN." (let ((nicka (get (intern chan) 'nicka))) (while (string-match "^\\([@+]?\\)\\([^ ]+\\) ?\\(.*\\)" nicks) (let ((oper (match-string 1 nicks)) (nick (match-string 2 nicks)) chans) (setq nicks (match-string 3 nicks)) (setq nicka (cons (cons nick oper) nicka)) (setq chans (get (intern nick) 'chnl)) (if (null (member-ignore-case chan chans)) (put (intern nick) 'chnl (nconc chans (list chan)))) (if (get (intern nick) 'irchat-waited-for) (irchat-greet-user nick chan)) (if (null (assoc nick irchat-nick-alist)) (setq irchat-nick-alist (cons (list nick) irchat-nick-alist))))) (put (intern chan) 'nicka nicka))) (defun irchat-channel-operator (nick chan) (cdr (assoc nick (get (intern chan) 'nicka)))) (defun irchat-channel-operator-set (nick chan oper) (let ((nicka (assoc nick (get (intern chan) 'nicka)))) (and nicka (setcdr nicka oper)))) (defun irchat-channel-newnick-set (nick chan newnick) (let ((nicka (assoc nick (get (intern chan) 'nicka)))) (and nicka (setcar nicka newnick)))) (defun irchat-user-last-privmsg (nick) (get (intern nick) 'lastchan)) (defun irchat-user-last-privmsg-time (nick) (let ((time (get (intern nick) 'lasttime))) (if time (- (irchat-current-time) time) nil))) ;; begin: moved from irchat-pj-action.el ;; by simm@irc.fan.gr.jp, Thu, 31 May 2001 21:57:46 +0900 (defun irchat-pj-auto-oper (nick userhost chan) "Give defined-user channel-operator automatically." (and (string= "@" (irchat-channel-operator irchat-nickname chan)) (not (string= "@" (irchat-channel-operator nick chan))) (let* (tmp (id (concat nick "!" userhost)) (ok (member-regexp id irchat-pj-auto-oper-list))) (if ok ok (setq ok (assoc-regexp id irchat-pj-auto-oper-list) tmp (cdr ok)) (or (and (stringp tmp) (string-match chan tmp)) (and (listp tmp) (member chan tmp)) (setq ok nil))) (if (car ok) (irchat-send "MODE %s +o %s" chan nick))))) ;; end ;; begin: add by simm@irc.fan.gr.jp, Tue, 20 Jul 1999 (defsubst irchat-pj-make-verbose-nick (nick userhost flag) (if flag (concat nick "(" userhost ")") nick)) ;; end (defun irchat-handle-error (prefix msg) (if (not irchat-no-configure-windows) (irchat-insert-allchan (format "ERROR: %s\n" msg) nil)) (setq irchat-fatal-error-message msg) (message "IRC ERROR: %s" msg)) (defun irchat-handle-482 (prefix me chan msg) (message "IRCHAT: You are not a channel operator on %s" (irchat-chan-virtual chan))) (defun irchat-handle-464 (prefix me msg) (irchat-insert0 (format "*** Password incorrect from %s. Try again with password.\n" prefix)) (setq irchat-reconnect-with-password t)) (defun irchat-handle-nick (prefix userhost nick) (irchat-insert (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-nick-verbose) " is now known as " nick "\n") (get (intern prefix) 'chnl)) (irchat-change-nick-of prefix nick) (put (intern nick) 'chnl (get (intern prefix) 'chnl)) (put (intern prefix) 'chnl nil) (mapcar '(lambda (chan) (irchat-channel-newnick-set prefix chan nick)) (get (intern nick) 'chnl)) (if (string= prefix irchat-nickname) (progn (setq irchat-nickname nick) (if (string= prefix irchat-current-chat-partner) (setq irchat-current-chat-partner nick)) (irchat-insert-special (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-nick-verbose) " is now known as " nick "\n"))))) (defun irchat-handle-notice (prefix chan msg) ;; begin: add by simm@irc.fan.gr.jp, Mon, 18 Jan 1999 (and irchat-pj-rewrite-server-notice (string= prefix irchat-server) (setq prefix nil msg (concat "=== " msg))) ;; end (cond ((null prefix) (if (string-match "ERROR" msg) (irchat-insert-allchan (format "%s\n" msg)) (irchat-insert-special (format "%s\n" msg)))) ((string-match "\001\\(.*\\)\001" msg) (irchat-ctcp-notice prefix msg)) ((string-match "^\\*\\*\\* Notice -- \\(.*\\)" msg) (let ((notice (match-string 1 msg))) (cond ((and irchat-ignore-fakes (string-match "^Fake" notice)) t) ((and irchat-ignore-noauths (string-match "^No Authorization" notice)) t) ((and irchat-ignore-kills (string-match "^Received KILL" notice)) t) ((and irchat-shorten-kills (string-match "^Received KILL message for \\([^.]*\\)\\. From \\([^ ]*\\) Path: \\([^ ]*\\) ?\\(.*\\)" notice)) (let ((killed (match-string 1 notice)) (killer (match-string 2 notice)) (reason (match-string 4 notice)) (cbuf (current-buffer))) (set-buffer irchat-KILLS-buffer) (goto-char (point-max)) (insert (format "%s\n" notice)) (set-buffer cbuf) (irchat-insert0 (format "%s KILLed %s %s\n" killer killed (if (= (length reason) 0) "-No reason supplied-" reason))))) (t (irchat-insert0 (format "%s: %s\n" prefix notice)))))) (t (irchat-handle-privmsg2 prefix chan msg)))) (defun irchat-handle-ping (prefix msg) (pure-irc-send-pong irchat-server-process msg) (irchat-maybe-poll)) ;; modified by simm@irc.fan.gr.jp, Sat, 13 Jun 1999 (defun irchat-handle-pong (prefix he &optional msg) (cond ((and msg (string= msg "irchat-polling")) (setq irchat-polling t)) ((string-match he ":irchat-polling$") (setq irchat-polling t)) (t ;;(irchat-insert0 (format "[%s]\n" (match-string 1 rest))) nil))) (defun irchat-handle-privmsg (prefix chan msg) (or (null prefix) (and prefix (memq (intern prefix) irchat-ignore-nickname) (irchat-msg-from-ignored prefix chan msg)) (let ((temp msg) (case-fold-search t)) ;; begin sound extension: modified by kaoru@kaisei.org (cond ((and (string-match "\007" temp) irchat-beep-on-bells) (funcall irchat-pj-sound-bell-function)) ((consp irchat-pj-sound-words-list) (let ((re irchat-pj-sound-words-list)) (while (consp re) (save-match-data (cond ((string-match (car re) temp) (funcall irchat-pj-sound-words-function prefix) (setq re nil)) (t (setq re (cdr re))))))))) ;; end (if (and (string-match "\001\\(.*\\)\001" temp) (or (not (string= irchat-nickname prefix)) (irchat-match-me chan))) (setq temp (irchat-ctcp-msg prefix chan temp))) (if (not (string= temp "")) (irchat-handle-privmsg2 prefix chan temp)) ;; add by mikami@nk.hcs.ts.fujitsu.co.jp, Tue, 31 Aug 1999 10:48:12 +0900 (run-hooks 'irchat-privmsg-exit-hook)))) (defun irchat-handle-privmsg2 (prefix chan xmsg) (or (not (irchat-match-me chan)) (get-buffer-window irchat-Dialogue-buffer) (get-buffer-window irchat-Others-buffer) (get-buffer-window irchat-Private-buffer) (message "IRCHAT: A private message has arrived from %s" prefix)) ;; only private messages to us get time-stamp (if (irchat-match-me chan) (irchat-insert-private t prefix xmsg) (if (string= irchat-nickname prefix) ;; my message to channel/partner (irchat-insert-private nil chan xmsg) (if (irchat-user-on-this-channel prefix chan) ;; user on this channel (irchat-insert (format "%s %s\n" (format "<%s:%s>" (irchat-chan-virtual chan) prefix) xmsg) chan 'privmsg) ;; user not on this channel (irchat-insert (format "%s %s\n" (format "(%s:%s)" (irchat-chan-virtual chan) prefix) xmsg) chan 'privmsg)))) (put (intern prefix) 'lastchan chan) (put (intern prefix) 'lasttime (irchat-current-time))) (defun irchat-match-me (dest) (let ((ddest (downcase dest)) (duser (if (stringp irchat-my-user) (downcase irchat-my-user) "")) (dhost (if (stringp irchat-my-host) (downcase irchat-my-host) "")) (dserv (if (stringp irchat-my-server) (downcase irchat-my-server) ""))) (or (string= ddest (downcase irchat-nickname)) (string= ddest (concat duser "@" dserv)) (string= ddest (concat duser "%" dhost "@" dserv))))) (defun irchat-handle-wallops (prefix msg) "Handle the WALLOPS message." (if irchat-show-wallops (irchat-insert0 (format "*** Wallops: %s %s\n" prefix msg))) (let ((buf (current-buffer))) (set-buffer irchat-WALLOPS-buffer) (goto-char (point-max)) (insert (format "%s %s\n" (if prefix (concat "from " prefix) "") msg)) (set-buffer buf))) (defun irchat-handle-quit (prefix userhost reason) "Handle the QUIT message." (pure-irc-dcc-process-kill-nick prefix irchat-server-process) (irchat-insert (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-quit-verbose) " has left IRC (" reason ")\n") (get (intern prefix) 'chnl) (concat "has left IRC (" reason ")") t (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-quit-verbose) ",")) ;; begin sound extension: modified by kaoru@kaisei.org (and irchat-pj-sound-when-part (not irchat-ignore-changes) (funcall irchat-pj-sound-part-function prefix userhost)) ;; end sound extension: (put (intern prefix) 'chnl nil) (irchat-change-nick-of prefix nil)) (defun irchat-handle-topic (prefix chan topic) "Handle the TOPIC message." (if (not irchat-ignore-changes) (irchat-insert (format "New topic on %s set by %s: %s\n" (irchat-chan-virtual chan) prefix topic) chan t))) (defun irchat-handle-mode (prefix chan &rest args) "Handle the MODE message." (let ((str "")) (while args (cond ((string-match "\\+ooo" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan "@") (irchat-channel-operator-set (nth 3 args) chan "@")) ((string-match "\\+oo-o" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan "@") (irchat-channel-operator-set (nth 3 args) chan nil)) ((string-match "\\+o-o\\+o" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan nil) (irchat-channel-operator-set (nth 3 args) chan "@")) ((string-match "-o\\+oo" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan "@") (irchat-channel-operator-set (nth 3 args) chan "@")) ((string-match "-oo\\+o" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan nil) (irchat-channel-operator-set (nth 3 args) chan "@")) ((string-match "-o\\+o-o" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan "@") (irchat-channel-operator-set (nth 3 args) chan nil)) ((string-match "\\+o-oo" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan nil) (irchat-channel-operator-set (nth 3 args) chan nil)) ((string-match "-ooo" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan nil) (irchat-channel-operator-set (nth 3 args) chan nil)) ((string-match "\\+oo" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan "@")) ((string-match "\\+o-o" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@") (irchat-channel-operator-set (nth 2 args) chan nil)) ((string-match "-o\\+o" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan "@")) ((string-match "-oo" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil) (irchat-channel-operator-set (nth 2 args) chan nil)) ((string-match "\\+o" (car args)) (irchat-channel-operator-set (nth 1 args) chan "@")) ((string-match "-o" (car args)) (irchat-channel-operator-set (nth 1 args) chan nil))) (setq str (format "%s %s" str (car args))) (setq args (cdr args))) (if (string= chan irchat-nickname) (if (not irchat-ignore-changes) (irchat-insert (format "Your new mode is set:%s\n" str) irchat-Private-buffer (format "Your new mode is set:") nil (format "%s" str))) (if (not irchat-ignore-changes) (irchat-insert (format "New mode for %s set by %s:%s\n" (irchat-chan-virtual chan) prefix str) chan (format "New mode for %s set by %s:" (irchat-chan-virtual chan) prefix) nil (format "%s" str)))))) (defun irchat-handle-kick (prefix chan nick reason) "Handle the KICK message." (irchat-remove-from-channel nick chan) (if (string= nick irchat-nickname) (progn (irchat-insert (format "You were kicked off channel %s by %s. (%s)\n" (irchat-chan-virtual chan) prefix reason) (list chan irchat-Private-buffer) t) (setq irchat-current-channels (delete (car (member-ignore-case chan irchat-current-channels)) irchat-current-channels)) (put (intern chan) 'nicka nil) (irchat-Channel-part chan)) (irchat-insert (format "%s has kicked %s out from channel %s (%s)\n" prefix nick (irchat-chan-virtual chan) reason) chan t))) (defun irchat-handle-invite (prefix nick chan) (irchat-insert-special (format "*** %s invites you to channel %s\n" prefix (irchat-chan-virtual chan)) t) ;; begin sound extension: modified by kaoru@kaisei.org (if irchat-pj-sound-when-invited (funcall irchat-pj-sound-invited-function prefix)) ;; end sound extension: (setq irchat-invited-channel chan)) (defun irchat-handle-kill (prefix me path) (irchat-insert-special (format "*** IRCHAT: You were killed by %s. Path: %s\n" prefix path) t) (irchat-insert-allchan (format "ERROR: You were Killed.\n") nil) (irchat-Channel-part nil)) (defun irchat-handle-join (nick userhost chan) "Handle the JOIN message." (let ((oper "") (voice "") (xnick nick)) (if (string-match "^\\([^\007]+\\)\007\\(o*\\)\\(v*\\)$" chan) (setq voice (match-string 3 chan) oper (match-string 2 chan) chan (match-string 1 chan))) (if (string= oper "o") (setq xnick (format "@%s" xnick)) (if (string= voice "v") (setq xnick (format "+%s" xnick)))) (if (string= nick irchat-nickname) (progn (setq irchat-current-channels (cons chan irchat-current-channels)) (irchat-Channel-join chan) (put (intern chan) 'init t) (put (intern chan) 'nicka nil)) ;; add by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 01:26:35 +0900 (and irchat-pj-auto-oper-list (irchat-pj-auto-oper nick userhost chan)) (irchat-add-to-channel nick chan)) (if (not irchat-ignore-changes) (irchat-insert (concat (irchat-pj-make-verbose-nick xnick userhost irchat-pj-handle-join-verbose) " has joined channel " (irchat-chan-virtual chan) "\n") (if (string= nick irchat-nickname) (list chan irchat-Private-buffer) chan) (concat "has joined channel " (irchat-chan-virtual chan)) t (concat (irchat-pj-make-verbose-nick xnick userhost irchat-pj-handle-join-verbose) ","))) ;; begin sound extension: modified by kaoru@kaisei.org (and irchat-pj-sound-when-join (not irchat-ignore-changes) (funcall irchat-pj-sound-join-function nick userhost)) ;; end sound extension: (irchat-change-nick-of nick nick))) (defun irchat-handle-part (prefix userhost chan &optional reason) "Handle the PART message." (if (null reason) (setq reason "")) (if (string= prefix irchat-nickname) (progn (setq irchat-current-channels (delete (car (member-ignore-case chan irchat-current-channels)) irchat-current-channels)) (put (intern chan) 'nicka nil))) (if (not irchat-ignore-changes) (irchat-insert (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-part-verbose) " has left channel " (irchat-chan-virtual chan) " (" reason ")\n") (if (string= prefix irchat-nickname) (list chan irchat-Private-buffer) chan) (concat "has left channel " (irchat-chan-virtual chan) " (" reason ")") t (concat (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-part-verbose) ","))) (if (not (string= prefix irchat-nickname)) ;; begin sound extension: modified by kaoru@kaisei.org (and irchat-pj-sound-when-part (not irchat-ignore-changes) (funcall irchat-pj-sound-part-function prefix userhost)) ;; end sound extension: (irchat-Channel-part chan) (if (null irchat-invited-channel) (setq irchat-invited-channel chan))) (irchat-remove-from-channel prefix chan) (irchat-change-nick-of prefix prefix)) ;;; ;;; 000 replies -- what the fuck is the author of ircd thinking. ;;; (defun irchat-handle-000s (number prefix me &rest args) (cond ((= (length args) 1) (irchat-insert0 (format "*** %s\n" (car args)))) ((= (length args) 2) (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args)))) ((= (length args) 3) (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args) (nth 1 args)))) (t (message "IRCHAT: Strange %s reply" number)))) (defun irchat-handle-001 (prefix nick msg) (setq irchat-my-server prefix) (if (string-match ".*!\\([^!]*\\)" msg) (setq irchat-pj-my-userhost (match-string 1 msg))) (if irchat-no-configure-windows (irchat-configure-windows)) (or (string= irchat-nickname nick) (irchat-insert-special (format "%s is now known as %s\n" irchat-nickname nick) t)) (irchat-insert-special (format "*** Welcome to the Internet Relay Chat world. Your nick is %s.\n" nick)) (setq irchat-servername prefix) (setq irchat-nickname nick) (irchat-send "USERHOST %s" irchat-nickname) (setq irchat-my-userhost nil)) (defun irchat-handle-002 (prefix me msg) (if (string-match "running version \\(.*\\)" msg) (irchat-insert-special (format "*** Your server is %s (version %s).\n" irchat-servername (match-string 1 msg)))) (irchat-insert0 (format "*** Your client version is %s.\n" irchat-pj-version-string))) (defun irchat-handle-003 (prefix me msg) (irchat-insert0 (format "*** %s \n" msg))) ;;(defun irchat-handle-004 (prefix me server version mode1 mode2) (defun irchat-handle-004 (prefix me server &optional version mode1 mode2) ;;(irchat-insert0 ;;(format "*** %s %s %s %s\n" server version mode1 mode2)) (irchat-maybe-poll)) ;;; ;;; 200 replies ;;; (defun irchat-handle-200s (number prefix me &rest args) (cond ((= (length args) 1) (irchat-insert0 (format "*** %s\n" (car args)))) ((= (length args) 2) (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args)))) ((= (length args) 3) (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args) (nth 1 args)))) (t (message "IRCHAT: Strange %s reply" number)))) (defun irchat-handle-200 (prefix me status version dest next &optional ver sec q1 q2) "200 RPL_TRACELINK Link " (irchat-insert0 (format "*** Link %s (%s%s) ==> %s (%s)%s\n" prefix version (if ver (format " %s" ver) "") next dest (if sec (format " [%s] %s/%s" (irchat-convert-seconds sec) q1 q2) "")))) (defun irchat-handle-201 (prefix me status class who) "201 RPL_TRACECONNECTING Try. " (irchat-insert0 (format "*** %s %s (%s) ==> %s\n" status prefix class who))) (defun irchat-handle-202 (prefix me status class who) "202 RPL_TRACEHANDSHAKE H.S. " (irchat-insert0 (format "*** %s %s (%s) ==> %s\n" status prefix class who))) (defun irchat-handle-203 (prefix me status class who) "203 RPL_TRACEUNKNOWN ???? []" (irchat-insert0 (format "*** %s %s (%s) ==> %s\n" status prefix class who))) (defun irchat-handle-204 (prefix me status class who) "204 RPL_TRACEOPERATOR Oper " (irchat-insert0 (format "*** %s %s (%s) ==> %s\n" status prefix class who))) (defun irchat-handle-205 (prefix me status class who &optional dummy time) (irchat-insert0 (format "*** %s %s (%s) ==> %s%s\n" status prefix class who (if time (format " (%s)" time) "")))) (defun irchat-handle-206 (prefix me status class Nserver Nclient name how &optional version) "206 RPL_TRACELINK Serv 200 3S 15C irc.other *!*@other.host :V3" (irchat-insert0 (format "*** Server %s (%s) ==> %s {%s,%s} %s %s\n" prefix class name Nserver Nclient how (if version (format "[%s]" version) "")))) (defun irchat-handle-209 (prefix me status class entries) (irchat-insert0 (format "*** Class %s (%s entries)\n" class entries))) (defvar irchat-stats-now nil) (defun irchat-handle-211 (prefix me link sndq sndm sndb rcvm rcvb time) "NOTICE %s :%-15.15s%5u%7u%10u%7u%10u %s" (setq time (string-to-int time)) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS L %s\n" prefix)) (irchat-insert0 " Time Send-Q Send-Msg Send-KB Recv-Msg Recv-KB\n") (setq irchat-stats-now prefix))) (irchat-insert0 (format "%s\n" link)) (irchat-insert0 (format "%5ddays %02d:%02d:%02d %8s %10s %10s %10s %10s\n" (/ (/ (/ time 60) 60) 24) (mod (/ (/ time 60) 60) 24) (mod (/ time 60) 60) (mod time 60) sndq sndm sndb rcvm rcvb))) (defun irchat-handle-213 (prefix me cmd host pass server port class) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS C %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "%s:%s:%s:%s:%s:%s\n" cmd host pass server port class))) (defun irchat-handle-214 (prefix me cmd host pass server port class) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS C %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "%s:%s:%s:%s:%s:%s\n" cmd host pass server port class))) (defun irchat-handle-212 (prefix me cmd times bytes &optional rtimes) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS M %s\n" prefix)) (setq irchat-stats-now prefix))) (if rtimes (irchat-insert0 (format "%s has been used %s times (remote: %s times) after startup (%s bytes)\n" cmd times rtimes bytes)) (irchat-insert0 (format "%s has been used %s times after startup (%s bytes)\n" cmd times bytes)))) (defun irchat-handle-215 (prefix me cmd ip passwd domain port class) ":server.name 215 me I ip * domain port class" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS I %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n" cmd ip passwd domain port class))) (defun irchat-handle-216 (prefix me cmd domain &rest args) ":servernameirc 216 me K domain ..." (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS K %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s:%s:%s\n" cmd domain (let ((str "")) (while args (setq str (format "%s %s" str (car args)) args (cdr args))) str)))) (defun irchat-handle-217 (prefix me cmd reason star host stuff) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS Q %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s:%s:%s:%s:%s\n" cmd reason star host stuff))) (defun irchat-handle-218 (prefix me cmd class pfreq cfreq mlinks msendq &optional local global) ":server.name 218 me Y class 120 600 1 3000000" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS Y %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** Class %s: PingFreq %s, ConFreq %s, MaxLinks %s, MaxSendQ %s%s%s\n" class pfreq cfreq mlinks msendq (if local (format ", LocalLimit %s" local) "") (if global (format ", GlobalLimit %s" global) "")))) (defun irchat-handle-219 (prefix me type msg) "RPL_ENDOFSTATS" (if (not irchat-stats-now) (irchat-insert0 (format "*** Nothing (STATS %s %s)\n" type prefix))) (setq irchat-stats-now nil)) (defun irchat-handle-221 (prefix me str) ;;; RPL_USERMODEIS? "Handle the MODE message." (irchat-insert-special (format "*** Mode for you is %s\n" str) t)) (defun irchat-handle-241 (prefix me cmd hostmask star server maxdepth etc) ":irc.tokyo.wide.ad.jp 241 nick L * * irc.leaf.server 0 -1" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS H %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n" cmd hostmask star server maxdepth etc))) (defun irchat-handle-242 (prefix me msg) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS U %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-243 (prefix me cmd hostname password user nazo class) ":server.name 243 me O hostname password user nazo class" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS O %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n" cmd hostname password user nazo class))) (defun irchat-handle-244 (prefix me cmd hostmask star server &optional maxdepth etc) ":irc.tokyo.wide.ad.jp 244 me H * * irc.tokai-ic.or.jp 0 -1" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS H %s\n" prefix)) (setq irchat-stats-now prefix))) ;; plum-2.33.1 returns `maxdepth' is "" and no `etc', so 3-minutes adhoc hack (if (and (stringp maxdepth) (/= 0 (length maxdepth))) (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n" cmd hostmask star server maxdepth etc)) (irchat-insert0 (format "*** %s:%s:%s:%s:*:*\n" cmd hostmask star server)))) (defun irchat-handle-246 (prefix me server p1 p2 p3 p4) ":server0.jp 246 nick server1.jp[*@server1.hostname] 26 26 50 15" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS P %s\n" prefix)) (irchat-insert0 (format "*** %32s %5s %5s %5s %5s\n" "" "snd#" "rcv#" "ping" "pref")) (setq irchat-stats-now prefix))) (if (string-match "\\([^[]+\\)\\[[^]]+\\]" server) (setq server (match-string 1 server))) (irchat-insert0 (format "*** %32s %5s %5s %5s %5s\n" server p1 p2 p3 p4))) (defun irchat-handle-248 (prefix me msg) "RPL_STATSDEFINE" (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS D %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-249 (prefix me msg) (if (not irchat-stats-now) (progn (irchat-insert0 (format "STATS T/Z %s\n" prefix)) (setq irchat-stats-now prefix))) (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-250 (prefix me msg) "RPL_STATSDLINE" (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-251 (prefix me msg) "RPL_LUSERCLIENT" (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-252 (prefix me count msg) "RPL_LUSEROP" (irchat-insert0 (format "*** %s %s\n" count msg))) (defun irchat-handle-253 (prefix me count msg) "RPL_LUSERUNKNOWN" (irchat-insert0 (format "*** %s %s\n" count msg))) (defun irchat-handle-254 (prefix me count msg) "RPL_LUSERCHANNELS" (irchat-insert0 (format "*** %s %s\n" count msg))) (defun irchat-handle-255 (prefix me msg) "RPL_LUSERME" (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-256 (prefix me msg) "RPL_ADMINME" (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-257 (prefix me msg) "RPL_ADMINLOC1" (if (not (string= msg "")) (irchat-insert0 (format "*** %s\n" msg)))) (defun irchat-handle-258 (prefix me msg) "RPL_ADMINLOC2" (if (not (string= msg "")) (irchat-insert0 (format "*** %s\n" msg)))) (defun irchat-handle-259 (prefix me msg) "RPL_ADMINEMAIL" (if (not (string= msg "")) (irchat-insert0 (format "*** %s\n" msg)))) (defun irchat-handle-261 (prefix me status filename port) ; RPL_TRACELOG (irchat-insert0 (format "*** LogFile %s => %s (%s)\n" prefix filename port))) (defun irchat-handle-262 (prefix me mask version msg) ; RPL_ END TRACE "262 RPL_TRACEEND *.jp 2.9.5. :End of TRACE" (irchat-insert0 (format "*** END of TRACE to (%s) %s [%s]\n" mask prefix version))) ;;; ;;; 300 replies ;;; (defun irchat-handle-300s (number prefix me &rest args) (cond ((= (length args) 1) (irchat-insert0 (format "*** %s\n" (car args)))) ((= (length args) 2) (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args)))) ((= (length args) 3) (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args) (nth 1 args)))) (t (message "IRCHAT: Strange %s reply" number)))) (defun irchat-handle-301 (prefix me nick iswhat) ; RPL_AWAY (if (not (string= nick irchat-auto-whois-nick)) (if irchat-while-whois-reply (irchat-insert0 (format "AWAY: %s\n" iswhat)) (irchat-insert0 (format "%s is AWAY: %s\n" nick iswhat))))) (defun irchat-handle-302 (prefix me data) ; RPL_USERHOST "Handle the 302 reply, USERHOST reply" (while (string-match "\\([^*=]+\\)\\([*]*\\)=\\([+-]\\)\\([^@]+\\)@\\([^ ]+\\) *\\(.*\\)" data) (let ((nick (match-string 1 data)) (oper (match-string 2 data)) (away (match-string 3 data)) (user (match-string 4 data)) (host (match-string 5 data)) userhost) (setq data (match-string 6 data)) (setq userhost (format "%s@%s" user host)) (put (intern nick) 'userhost userhost) (if (and (string= nick irchat-nickname) (null irchat-my-userhost)) (progn (setq irchat-my-userhost userhost) (setq irchat-my-user user) (setq irchat-my-host host) (irchat-insert-special (format "*** You are %s.\n" irchat-my-userhost)) (and irchat-pj-first-channel irchat-pj-initialize-p (irchat-Command-join irchat-pj-first-channel)) (setq irchat-pj-initialize-p nil)) (irchat-insert0 (format "%s is <%s> [%s, %s]\n" nick userhost (concat (if (string= oper "") "Not ") "Operator") (concat (if (string= away "+") "Not ") "AWAY"))))))) (defun irchat-handle-303 (prefix me nicks) ; RPL_ISON "Handle the 303 reply, ISON reply" (if (string= nicks "") (irchat-insert0 "No one you requested is on now.\n") (irchat-insert0 (format "Following people(s) are on: %s\n" nicks)))) (defun irchat-handle-305 (prefix me msg) ; RPL_UNAWAY "Handle the 305 reply, UNAWAY reply" (if irchat-pj-away-p (progn (setq irchat-pj-away-p nil) (irchat-maybe-poll) (irchat-insert0 (format "*** %s (%s)\n" msg (current-time-string)))))) (defun irchat-handle-306 (prefix me msg) ; RPL_NOWAWAY "Handle the 306 reply, NOWAWAY reply" (setq irchat-pj-away-p t) (irchat-insert0 (format "*** %s (%s)\n" msg (current-time-string)))) (defun irchat-handle-311 (prefix me nick user host dummy name) ;; RPL_WHOISUSER "Handle the 311 reply (from WHOIS)." (setq irchat-while-whois-reply t) (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "%s is <%s@%s> %s\n" nick user host name)))) (defun irchat-handle-312 (prefix me nick server info) ; RPL_WHOISSERVER ":server.name 312 me her server.name2 :server info" (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "on via server %s (%s)\n" server info)))) (defun irchat-handle-313 (prefix me nick iswhat) ; RPL_WHOISOPERATOR (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "STATUS: %s\n" iswhat)))) (defun irchat-handle-314 (prefix me nick user host star name) ;; RPL_WHOWASUSER "Handle the 314 reply (msa's WHOWAS)." (message "") (irchat-insert0 (format "%s was <%s@%s> %s\n" nick user host name))) (defun irchat-handle-315 (prefix ms chan msg) ; RPL_ENDOFWHO (setq irchat-long-reply-count 0)) (defun irchat-handle-317 (prefix me nick sec &optional time msg) ;RPL_WHOISIDLE ":server.name 317 me her 38 :seconds idle or\ :server.name 317 me her 38 839678551 :seconds idle, signon time" (let (fun sec2) (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "IDLE for %s %s\n" (irchat-convert-seconds sec) (if (setq sec2 (irchat-past-time sec)) (format "(%s)" sec2) ""))) (if (fboundp (setq fun (intern "irchat-whois-idle"))) (apply fun (list nick (string-to-int sec))))))) (defun irchat-handle-318 (prefix me nick msg) ; RPL_ENDOFWHOIS ":server.name 318 me her :End of /WHOIS list." (setq irchat-while-whois-reply nil) (if (string= nick irchat-auto-whois-nick) (setq irchat-auto-whois-nick ""))) (defun irchat-handle-319 (prefix me nick rest) ; RPL_???? ":server.name 319 me her :chan1 chan2 chan3" (let ((str "") oper chan) (while (string-match "^\\([@+]?\\)\\([^ ]+\\) +\\(.*\\)$" rest) (setq oper (match-string 1 rest)) (setq chan (match-string 2 rest)) (setq rest (match-string 3 rest)) (if (not (irchat-ischannel chan)) (setq chan (concat oper chan) oper "")) (setq str (format "%s %s%s" str oper (irchat-chan-virtual chan)))) (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "channels:%s\n" str))))) (defun irchat-handle-321 (prefix me chan msg) ;;; RPL_LISTSTART "Handle the 321 reply (first line from LIST)." nil) (defun irchat-handle-322 (prefix &optional me chan users topic bug) ; RPL_LIST "Handle the 322 reply (from LIST)." (setq irchat-long-reply-count (1+ irchat-long-reply-count)) (if (> irchat-long-reply-count 38) (progn (setq irchat-long-reply-count 0) (pure-irc-send-pong irchat-server-process irchat-servername))) (if topic (irchat-insert (format "Topic for %s (%s users): %s\n" (if (string= chan "*") "Private" (irchat-chan-virtual chan)) users topic) chan t) (irchat-insert (format "*** Error 322: %s %s %s %s %s" prefix me chan users topic)))) (defun irchat-handle-323 (prefix me msg) ; RPL_LISTEND (setq irchat-channel-filter "") (setq irchat-long-reply-count 0)) (defun irchat-handle-324 (prefix me chan &rest args) ; RPL_CHANNELMODEIS "Handle the MODE message." (let ((str "")) (while args (setq str (format "%s %s" str (car args))) (setq args (cdr args))) (irchat-insert (format "Mode for %s:%s\n" (irchat-chan-virtual chan) str) chan t))) (defun irchat-handle-331 (prefix me chan msg) ; RPL_NOTOPIC (irchat-insert (format "No topic is set for %s\n" (irchat-chan-virtual chan)) chan t)) (defun irchat-handle-332 (prefix me chan topic) ; RPL_TOPIC (irchat-insert (format "Topic for %s: %s\n" (irchat-chan-virtual chan) topic) chan t)) (defun irchat-handle-341 (prefix me nick chan) ; RPL_INVITING (irchat-insert (format "*** Inviting user %s to channel %s\n" nick (irchat-chan-virtual chan)) chan t)) (defun irchat-handle-351 (prefix me ver server mode) ; RPL_VERSION (irchat-insert0 (format "*** %s is running IRC version %s (%s)\n" server ver mode))) (defun irchat-handle-352 (prefix me chan user host serv nick oper name) "Handle the WHOREPLY message (352)" (setq irchat-long-reply-count (1+ irchat-long-reply-count)) (if (> irchat-long-reply-count 38) (progn (setq irchat-long-reply-count 0) (pure-irc-send-pong irchat-server-process irchat-servername))) (if (string-match "[0-9]* *\\(.*\\)" name) (setq name (match-string 1 name))) (irchat-insert (format "%-3s %-9s %-9s %-30s %s\n" oper (if (or (string= chan "*") (string= chan "0")) "Private" (irchat-chan-virtual chan)) nick (format "<%s@%s>" user host) name) chan t)) (defun irchat-handle-353 (prefix me flag chan nicks) ; RPL_NAMREPLY "Handle the 353 (NAMREPLY) message. If we are just polling the server, don't display anything. Check if someone we are waiting for has entered." (setq irchat-long-reply-count (1+ irchat-long-reply-count)) (if (> irchat-long-reply-count 38) (progn (setq irchat-long-reply-count 0) (pure-irc-send-pong irchat-server-process irchat-servername))) (if irchat-polling nil (irchat-insert (format "%s = %s\n" (if (string= chan "*") "Private" (irchat-chan-virtual chan)) nicks) chan t)) (irchat-scan-channels chan) (if (get (intern chan) 'init) (irchat-add-to-channel nicks chan))) (defun irchat-handle-361 (prefix me who msg) ; RPL_KILLDONE ;; modified by simm@irc.fan.gr.jp, Sun, 27 Jun 1999 (irchat-insert0 (format "You just KILLED %s. %s\n" who msg))) (defun irchat-handle-364 (prefix me server next msg) (setq irchat-links-reply-count (1+ irchat-links-reply-count)) (if (string-match "^\\([^ ]+\\) \\(\\[[^]]+\\]\\)? *\\(.*\\)" msg) (let ((hop (match-string 1 msg)) (comment (match-string 3 msg))) (if irchat-how-to-show-links-reply (irchat-insert0 (format "%2s %-30s <== %-30s\n" hop server next)) (irchat-insert0 (format "%-30s %s\n" server comment)))))) (defun irchat-handle-365 (prefix me mask msg) ; RPL_ENDOFLINKS (if (= 0 irchat-links-reply-count) (irchat-insert0 (format "*** No match server. (%s)\n" mask))) (setq irchat-links-reply-count 0)) (defun irchat-handle-366 (prefix me chan msg) ; RPL_ENDOFNAMES (setq irchat-long-reply-count 0) (setq irchat-polling nil) (if (get (intern chan) 'init) (put (intern chan) 'init nil))) (defun irchat-handle-367 (prefix me chan ban) (irchat-insert (format "Banned on %s: %s\n" (irchat-chan-virtual chan) ban) chan t)) (defun irchat-handle-368 (prefix me chan msg) ; BAN END nil) (defun irchat-handle-369 (prefix me nick msg) ; WHOWAS nil) (defun irchat-handle-371 (prefix me msg) ; RPL_INFO (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-372 (prefix me msg) ; RPL_MOTD (irchat-insert0 (format "*** %s\n" msg))) (defun irchat-handle-374 (prefix me msg) ; RPL_INFO END nil) (defun irchat-handle-375 (prefix me msg) ; RPL_MOTD START nil) (defun irchat-handle-376 (prefix me msg) ; RPL_MOTD END nil) (defun irchat-handle-381 (prefix me msg) ; RPL_YOUREOPER ":server.name 381 me :Good afternoon, gentleman. I am a HAL 9000 computer." (irchat-insert0 (format "OPER: %s\n" msg))) (defun irchat-handle-382 (prefix name file msg) ; RPL_REHASHING (irchat-insert0 (format "*** %s: %s %s\n" name msg file))) (defun irchat-handle-391 (prefix me server time) ; RPL_TIME ":server.name 391 me server.name :Monday August 5 1996 -- 01:39 +09:00" (irchat-insert0 (format "Time: %s (%s)\n" time server))) ;;; ;;; 400 replies -- ERRORS ;;; (defun irchat-handle-400s (number prefix me &rest args) "Generic handler for 4?? messages. This is called if no specific handler exists" (cond ((= (length args) 1) (irchat-insert0 (format "*** %s\n" (car args)))) ((= (length args) 2) (irchat-insert0 (format "*** %s (%s)\n" (nth 1 args) (irchat-chan-virtual (car args))))) ((= (length args) 3) (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args) (irchat-chan-virtual (nth 1 args))))) (t (message "IRCHAT: Strange %s reply" number)))) (defun irchat-handle-401 (prefix me nick msg) ; ERR_NOSUCHNICK ":server.name 401 me nick :No such nick/channel" (if (not (string= nick irchat-auto-whois-nick)) (irchat-send "WHOWAS %s" nick) (setq irchat-auto-whois-nick ""))) (defun irchat-handle-402 (prefix me nick msg) ; ERR_NOSUCHSERVER ":server.name 402 me servername :No such server" (if (string-match "^[^.*]+$" nick) (if (not (string= nick irchat-auto-whois-nick)) (irchat-insert0 (format "*** Error: No such nick. (%s)\n" nick)) (setq irchat-auto-whois-nick "")) (irchat-insert0 (format "*** Error: No such server. (%s)\n" nick)))) (defun irchat-handle-403 (prefix me chan msg) (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-404 (prefix me chan msg) (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-405 (prefix me chan msg) (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-406 (prefix me nick msg) (pure-irc-dcc-process-kill-nick nick irchat-server-process) (irchat-insert0 (format "*** %s (%s)\n" msg nick))) (defun irchat-handle-407 (prefix me nick msg) (irchat-insert0 (format "*** %s (%s)\n" msg nick))) (defun irchat-handle-412 (prefix me msg) (message "IRCHAT: No text to send")) (defun irchat-handle-421 (prefix me cmd msg) (irchat-insert0 (format "*** Unknown command (%s)\n" cmd))) (defun irchat-handle-422 (prefix me msg) (irchat-insert0 (format "*** No message of the day in %s\n" prefix))) (defun irchat-handle-432 (prefix me nick msg) ;;; ERR_ERRONICK? "Handle the 432 reply (erroneus nickname)" (save-excursion (set-buffer irchat-Command-buffer) ;; modified by simm@irc.fan.gr.jp, Mon, 20 Dec 1999 21:44:10 +0900 (funcall irchat-pj-sound-error-function) (if irchat-no-configure-windows (setq irchat-nickname-erroneus t) (message "IRCHAT: Erroneus Nickname. Choose a new one with %s." (substitute-command-keys "\\[irchat-Command-nickname]"))))) (defun irchat-handle-433 (prefix me nick msg) ;;; ERR_NICKNAMEINUSE "Handle the 433 reply (nickname already in use)" (save-excursion (set-buffer irchat-Command-buffer) (if irchat-no-configure-windows (setq irchat-nickname-already-in-use t) ;; modified by simm@irc.fan.gr.jp, Mon, 20 Dec 1999 21:44:10 +0900 (funcall irchat-pj-sound-error-function) (message "IRCHAT: Nickname %s already in use. Choose a new one with %s." nick (substitute-command-keys "\\[irchat-Command-nickname]"))))) (defun irchat-handle-437 (prefix me chan msg) "437 ERR_UNAVAILRESOURCE nick|chan :Nick/channel is temporarily unavailable" (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-441 (prefix me nick chan msg) "441 ERR_USERNOTINCHANNEL nick chan :They aren't on that channel" (irchat-insert0 (format "*** %s (%s/%s)\n" msg nick (irchat-chan-virtual chan)))) (defun irchat-handle-442 (prefix me chan msg) "442 ERR_NOTONCHANNEL chan :You're not on that channel" (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-451 (prefix &rest args) (if irchat-after-registration (irchat-insert0 (format "*** You have not registered.\n")))) (defun irchat-handle-471 (prefix me chan msg) ; ERR_CHANNELISFULL ":server.name 471 me chan :Sorry, cannot join channel." (setq irchat-invited-channel chan) (irchat-insert0 (format "*** Error: Sorry, channel %s is full.\n" (irchat-chan-virtual chan)))) (defun irchat-handle-472 (prefix me char msg) ; ERR_UNKNOWNMODE ":server.name 472 me char :is unknown mode char to me" (irchat-insert0 (format "*** Error: '%s' %s.\n" char msg))) (defun irchat-handle-473 (prefix me chan msg) ; ERR_INVITEONLYCHAN ":server.name 473 me chan :Sorry, cannot join channel." (setq irchat-invited-channel chan) (irchat-insert0 (format "*** Error: Sorry, channel %s is invited only.\n" (irchat-chan-virtual chan)))) (defun irchat-handle-474 (prefix me chan msg) ; ERR_BANNEDFROMCHAN ":server.name 474 me chan :Sorry, cannot join channel." (setq irchat-invited-channel chan) (irchat-insert0 (format "*** Error: Sorry, you are banned from channel %s.\n" (irchat-chan-virtual chan)))) (defun irchat-handle-475 (prefix me chan msg) ; ERR_BADCHANNELKEY ":server.name 475 me chan :Sorry, cannot join channel." (setq irchat-invited-channel chan) (irchat-insert0 (format "*** Error: Sorry, incorrect key for channel %s.\n" (irchat-chan-virtual chan)))) (defun irchat-handle-477 (prefix me chan msg) ":server.name 477 me chan :Channel doesn't support modes" (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan)))) (defun irchat-handle-484 (prefix me msg) ":server.name 484 me :Your connection is restricted!" (irchat-insert0 (format "*** %s\n" msg))) ;;; ;;; 500 replies -- ERRORS ;;; (defun irchat-handle-500s (number prefix me &rest args) "Generic handler for 5?? messages. This is called if no specific handler exists" (cond ((= (length args) 1) (irchat-insert0 (format "*** %s\n" (car args)))) ((= (length args) 2) (irchat-insert0 (format "*** %s (%s)\n" (nth 1 args) (irchat-chan-virtual (car args))))) ((= (length args) 3) (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args) (irchat-chan-virtual (nth 1 args))))) (t (message "IRCHAT: Strange %s reply" number)))) ;;; ;;; answer to CTCP messages, no postprocessing ;;; (defun irchat-ctcp-msg (from to rest) "It's CTCP request, act on it." (let* (left now right message rest-of-line hook) (if (string-match "^\\([^\001]*\\)\001\\([^\001]*\\)\001\\(.*\\)" rest) ;; modified by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 00:41:09 +0900 ;; progn -> save-excursion (save-excursion ;; add by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 00:54:18 +0900 ;; for irchat-pj-sound (if irchat-pj-sound-when-ctcp (funcall irchat-pj-sound-ctcp-function from)) (setq left (match-string 1 rest)) (setq now (match-string 2 rest)) (setq right (match-string 3 rest)) (setq rest (concat left right)) (if (string-match "^\\([^ ]*\\) \\(.*\\)" now) (progn (setq message (downcase (match-string 1 now))) (setq rest-of-line (match-string 2 now))) (if (string-match "^\\([^ ]*\\)" now) (progn (setq message (downcase (match-string 1 now))) (setq rest-of-line nil)) (progn (setq message "errmsg") (setq rest-of-line "Couldn't figure out what was said.")))) (if (and (boundp (setq hook (intern (concat "irchat-ctcp-" message "-hook")))) (eval hook) (eq (eval (list hook from to rest-of-line)) t)) ;; If we have a hook, and it returns T, do nothing more nil ;; else call the handler (if (fboundp (setq fun (intern (concat "irchat-ctcp-" message "-msg")))) (progn (eval (list fun from to rest-of-line)) (if (not irchat-freeze) (irchat-scroll-if-visible (get-buffer-window (current-buffer))))) (progn (if (string= (downcase to) (downcase irchat-nickname)) ;; return unknown error if it's sended to only me. (let ((umsg (upcase message))) (irchat-ctcp-reply from (concat "ERRMSG " umsg " :" (format irchat-ctcp-error-msg umsg))))) (irchat-insert (format "*** Unknown CTCP %s from %s to %s %s\n" (upcase message) from to (if rest-of-line (if (string= rest-of-line "") "" (format "[%s]" rest-of-line)) "")) to t)))))) rest)) (defun irchat-ctcp-reply (receiver message) (irchat-send "NOTICE %s :\001%s\001" receiver message)) (defun irchat-ctcp-message (command from to) (message "CTCP %s from %s to %s" command from (irchat-chan-virtual to))) (defun irchat-ctcp-version-msg (from to rest) (irchat-ctcp-reply from (format "VERSION %s :" (pure-vs-make irchat-pj-version-string))) (irchat-ctcp-message "VERSION" from to)) (defun irchat-ctcp-userinfo-msg (from to rest) (irchat-ctcp-reply from (format "USERINFO :%s" irchat-ctcp-userinfo)) (irchat-ctcp-message "USERINFO" from to)) (defun irchat-ctcp-action-msg (from to rest) (if rest (irchat-handle-privmsg2 from to (format "*** %s %s" from rest)) (irchat-handle-privmsg2 from to (format "*** %s (nil)" from))) (irchat-ctcp-message "ACTION" from to)) ;; add by simm@irc.fan.gr.jp, Sun, 29 Aug 1999 22:56:28 +0900 (defun irchat-ctcp-caesar-msg (from to rest) (if rest (irchat-handle-privmsg2 from to (format "*** %s %s" from (irchat-pj-caesar-string rest))) (irchat-handle-privmsg2 from to (format "*** %s (nil)" from))) (irchat-ctcp-message "CAESAR" from to)) (defun irchat-ctcp-dcc-msg (from to rest) ;; old: (irchat-dcc-request from to rest) ;; begin: from irchat-dcc.el (cond ((null rest) (irchat-insert0 (format "*** Bad format DCC from %s\n" from)) (irchat-ctcp-reply from (format "ERRMSG :DCC: bad format"))) ((string-match "^SEND \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest) (let ((dinfo (pure-irc-dcc-info-create from (match-string 2 rest) (match-string 3 rest) (match-string 1 rest) (match-string 4 rest) nil (current-time-string)))) (pure-ds-add-list dinfo pure-irc-dcc-offer-list) (irchat-insert-special (format "*** DCC SEND request from %s: %s (%s bytes)\n" from (pure-irc-dcc-info-get-file dinfo) (pure-irc-dcc-info-get-size dinfo) t)))) ((string-match "^CHAT \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest) (let ((dinfo (pure-irc-dcc-info-create from (match-string 2 rest) (match-string 3 rest) (match-string 1 rest) nil nil (current-time-string)))) (pure-ds-add-list dinfo pure-irc-dcc-offer-list) (irchat-insert-special (format "*** DCC CHAT request from %s\n" from) t))) ((string-match "^RESUME \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest) (let ((dinfo (pure-irc-dcc-info-search-resume (pure-irc-dcc-info-create from nil (match-string 2 rest) (match-string 1 rest) nil nil nil 'wait) pure-irc-dcc-process-list))) (if (pure-irc-dcc-info-resumep dinfo) (progn (pure-irc-dcc-info-put-xpos dinfo (match-string 3 rest)) (funcall (intern (format "pure-pr-dcc-%s-resume-accept" (pure-irc-dcc-info-get-method dinfo))) dinfo) (irchat-insert0 (format "*** DCC RESUME request from %s: %s (at %s bytes)\n" from (match-string 1 rest) (match-string 3 rest)))) (irchat-insert0 (format "*** DCC RESUME request from %s, but I don't support it.\n" (match-string 1 rest)))))) ((string-match "^ACCEPT \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest) (let ((dinfo (pure-irc-dcc-info-search-resume (pure-irc-dcc-info-create from nil (match-string 2 rest) (match-string 1 rest) nil (match-string 3 rest) nil 'resume) pure-irc-dcc-process-list))) (if (pure-irc-dcc-info-resumep dinfo) (progn (pure-irc-dcc-info-put-xpos dinfo (match-string 3 rest)) (funcall (intern (format "pure-pr-dcc-%s-resume-start" (pure-irc-dcc-info-get-method dinfo))) dinfo) (irchat-insert0 (format "*** DCC RESUME accept from %s: %s (at %s bytes)\n" from (match-string 1 rest) (match-string 3 rest)))) (irchat-insert0 (format "*** DCC RESUME accept from %s, but I don't support it.\n" (match-string 1 rest)))))) ((and pure-irc-dcc-use-dcc-cancel (string-match "^CANCEL \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)) (let ((dinfo (pure-irc-dcc-info-search (pure-irc-dcc-info-create from (match-string 2 rest) (match-string 3 rest) (match-string 1 rest)) pure-irc-dcc-offer-list 'nick 'host 'port 'file))) (if (not dinfo) (irchat-insert0 (format "*** DCC CANCEL ERROR: no such DCC request to %s: %s %s %s\n" from (pure-irc-dcc-info-get-file dinfo) (pure-irc-dcc-info-get-host dinfo) (pure-irc-dcc-info-get-port dinfo))) (pure-ds-del-list dinfo pure-irc-dcc-offer-list) (irchat-insert0 (format "*** DCC CANCEL from %s\n" from))))) ((string-match "^CANCEL \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)) (t (irchat-insert0 (format "*** Unknown DCC from %s: %s\n" from rest)) (irchat-ctcp-reply from (format "ERRMSG :DCC: bad command")))) ;; end: from irchat-dcc.el (irchat-ctcp-message "DCC" from to)) (defun irchat-ctcp-time-msg (from to rest) (irchat-ctcp-reply from (format "TIME %s" (current-time-string))) (irchat-ctcp-message "TIME" from to)) (defun irchat-ctcp-ping-msg (from to rest) (irchat-ctcp-reply from (if rest (format "PING %s" rest) "PING")) (irchat-ctcp-message "PING" from to)) (defun irchat-ctcp-echo-msg (from to rest) (irchat-ctcp-reply from (if rest (format "ECHO %s" rest) "ECHO")) (irchat-ctcp-message "ECHO" from to)) (defun irchat-ctcp-clientinfo-msg (from to rest) (if (null rest) (irchat-ctcp-reply from (format "CLIENTINFO :%s :%s" (irchat-ctcp-list-string) "Use CLIENTINFO to get more specific information")) (setq rest (upcase rest)) (let (info) (setq info (get (intern rest) 'info)) (if info (irchat-ctcp-reply from (concat "CLIENTINFO " rest " " info)) (irchat-ctcp-reply from (concat "ERRMSG :CLIENTINFO: " rest " is not a valid command"))))) (if (null rest) (irchat-ctcp-message "CLIENTINFO" from to) (irchat-ctcp-message (format "CLIENTINFO %s" rest) from to))) (defvar irchat-ctcp-list nil) (defun irchat-ctcp-list-string () (let ((str "") (rest irchat-ctcp-list)) (while rest (setq str (concat str (car rest) " ")) (setq rest (cdr rest))) str)) (defsubst irchat-ctcp-add-clientinfo (command info) (setq command (upcase command)) (setq irchat-ctcp-list (append irchat-ctcp-list (list command))) (put (intern command) 'info info)) (irchat-ctcp-add-clientinfo "ACTION" "contains action descriptions for atmosphere") (irchat-ctcp-add-clientinfo "CLIENTINFO" "gives available CTCP commands") (irchat-ctcp-add-clientinfo "CAESAR" "sends message with X-ROT-5-13-47-48 encoding") (irchat-ctcp-add-clientinfo "DCC" "requests a Direct-Client-Connection") (irchat-ctcp-add-clientinfo "ECHO" "returns the arguments it receives") (irchat-ctcp-add-clientinfo "ERRMSG" "returns error messages") (irchat-ctcp-add-clientinfo "PING" "returns the arguments it receives") (irchat-ctcp-add-clientinfo "TIME" "tells you the time on the user's host") (irchat-ctcp-add-clientinfo "USERINFO" "returns user settable information") (irchat-ctcp-add-clientinfo "VERSION" "shows client type, version and environment") ;;; ;;; read CTCP messages from notice, no postprocessing done ;;; (defun irchat-ctcp-notice (prefix rest) "CTCP notice." (let* (message rest-of-line hook to) (if (string-match "\\([^ ]+\\) :" rest) (setq to (match-string 1 rest))) (if (string-match "\001\\([^ ]*\\) :?\\(.*\\)\001" rest) (setq message (downcase (match-string 1 rest)) rest-of-line (match-string 2 rest)) (if (string-match "\001\\([^ ]*\\)\001" rest) (setq message (downcase (match-string 1 rest)) rest-of-line nil) (setq message "errmsg" rest-of-line "Couldn't figure out what was said."))) (if (and (boundp (setq hook (intern (concat "irchat-ctcp-" message "-notice-hook")))) (eval hook) (eq (eval (list hook prefix rest-of-line)) t)) ;; If we have a hook, and it returns T, do nothing more nil ;; else call the handler (if (fboundp (setq fun (intern (concat "irchat-ctcp-" message "-notice")))) (progn (eval (list fun prefix rest-of-line)) (if (not irchat-freeze) (irchat-scroll-if-visible (get-buffer-window (current-buffer))))) (irchat-insert0 (format "*** Unknown CTCP Reply %s from %s to %s %s\n" (upcase message) prefix to (if rest-of-line (format "[%s]" rest-of-line) ""))))))) (defun irchat-ctcp-version-notice (prefix rest) (if rest (irchat-insert0 (format "VERSION@%s: %s\n" prefix rest)) (message (format "Empty CTCP version notice from \"%s\"." prefix)))) (defun irchat-ctcp-clientinfo-notice (prefix rest) (irchat-insert0 (format "CLIENTINFO@%s: %s\n" prefix rest))) (defun irchat-ctcp-userinfo-notice (prefix rest) (irchat-insert0 (format "USERINFO@%s: %s\n" prefix rest))) (defun irchat-ctcp-finger-notice (prefix rest) (irchat-insert0 (format "FINGER@%s: %s\n" prefix rest))) (defun irchat-ctcp-time-notice (prefix rest) (irchat-insert0 (format "TIME@%s: %s\n" prefix rest))) (defun irchat-ctcp-echo-notice (prefix rest) (irchat-insert0 (format "ECHO@%s: %s\n" prefix rest))) (defun irchat-ctcp-ping-notice (prefix rest) (let (to (time rest)) (if (string-match "\\([^ ]+\\) \\(.*\\)" rest) (progn (setq time (match-string 1 rest)) (setq to (match-string 2 rest)))) (if (= 0 (string-to-int (or time "0"))) (irchat-insert0 (format "PING@%s: %s\n" prefix (or time "nothing"))) (let ((diff (- (irchat-current-time) (string-to-int time)))) (while (< diff 0) (setq diff (+ diff 86400))) (irchat-insert (format "PING@%s: %s second%s\n" prefix diff (if (< diff 2) "" "s")) to t))))) (defun irchat-ctcp-errmsg-notice (prefix rest) (irchat-insert0 (format "ERRMSG@%s: %s\n" prefix rest)) (if (pure-irc-dcc-info-resumep pure-irc-dcc-info) (pure-irc-dcc-info-resume-cancel pure-irc-dcc-info))) (defun irchat-ctcp-comment-notice (from rest) (message (format "CTCP COMMENT query from %s." from))) ;;; ;;; decode and encode of binary data ;;; (defun irchat-quote-decode (string-to-decode) (interactive) (save-excursion (set-buffer (get-buffer-create "*IRC DECODE*")) (delete-region (point-min) (point-max)) (insert string-to-decode) (goto-char (point-min)) (replace-string "\\\\" "\\") (goto-char (point-min)) (replace-string "\\a" "\001") (goto-char (point-min)) (replace-string "\\n" "\n") (goto-char (point-min)) (replace-string "\\r" "\r") (setq string-to-decode (buffer-substring (point-min) (point-max))) string-to-decode)) (defun irchat-quote-encode (string) (interactive) (save-excursion (set-buffer (get-buffer-create "*IRC ENCODE*")) (delete-region (point-min) (point-max)) (insert string) (goto-char (point-min)) (while (search-forward "\\" nil 1) (insert "\\")) (goto-char (point-min)) (while (search-forward "\001" nil 1) (delete-char -1) (insert "\\a")) (goto-char (point-min)) (while (search-forward "\000" nil 1) (delete-char -1) (insert "\\0")) (goto-char (point-min)) (while (search-forward "\n" nil 1) (delete-char -1) (insert "\\n")) (goto-char (point-min)) (while (search-forward "\r" nil 1) (delete-char -1) (insert "\\r")) (setq string (buffer-substring (point-min) (point-max))) string)) (defun irchat-current-time () (let* ((string (current-time-string)) (day (string-to-int (substring string 8 10))) (hour (string-to-int (substring string 11 13))) (min (string-to-int (substring string 14 16))) (sec (string-to-int (substring string 17 19)))) (+ sec (* 60 min) (* 3600 hour) (* 86400 day)))) (defun irchat-past-time (second) (let* ((string (current-time-string)) (day (string-to-int (substring string 8 10))) (hour (string-to-int (substring string 11 13))) (min (string-to-int (substring string 14 16))) (sec (string-to-int (substring string 17 19)))) (if (stringp second) (setq second (string-to-int second))) (setq second (- (+ sec (* 60 min) (* 3600 hour) (* 86400 day)) second)) (if (< second 0) nil (irchat-convert-seconds2 second)))) (defun irchat-convert-seconds (time) "Convert seconds to printable string." (if (null time) (setq time 0)) (let* ((seconds (if (stringp time) (string-to-int time) time)) (minutes (/ seconds 60)) (seconds (if minutes (% seconds 60) seconds)) (hours (/ minutes 60)) (minutes (if hours (% minutes 60) minutes)) (days (/ hours 24)) (hours (if days (% hours 24) hours)) (ds (and (/= 0 days) (format "%d day%s, " days (if (> days 1) "s" "")))) (hs (and (/= 0 hours) (format "%d hour%s, " hours (if (> hours 1) "s" "")))) (ms (and (/= 0 minutes) (format "%d minute%s " minutes (if (> minutes 1) "s" "")))) (ss (format "%d seconds" seconds))) (concat ds hs ms (if seconds ss "")))) (defun irchat-convert-seconds2 (time) "Convert seconds to printable string." (if (null time) (setq time 0)) (let* ((seconds (if (stringp time) (string-to-int time) time)) (minutes (/ seconds 60)) (seconds (if minutes (% seconds 60) seconds)) (hours (/ minutes 60)) (minutes (if hours (% minutes 60) minutes)) (days (/ hours 24)) (hours (if days (% hours 24) hours))) (format "%d%s %02d:%02d:%02d" days (if (= days 1) "st" (if (= days 2) "nd" (if (= days 3) "rd" "th"))) hours minutes seconds))) (defun irchat-msg-from-ignored (prefix chan msg) (save-excursion (let ((buf (current-buffer))) (set-buffer irchat-IGNORED-buffer) (goto-char (point-max)) (insert (format "%s::%s %s\n" prefix chan msg)) (set-buffer buf) t))) (provide 'irchat-handle)