home *** CD-ROM | disk | FTP | other *** search
/ ftp.madoka.org / 2014.12.ftp.madoka.org.tar / ftp.madoka.org / pub / irchat-pj / 2.5 / irchat-pj-2.5.6p.tar.gz / irchat-pj-2.5.6p.tar / irchat-pj-2.5.6p / irchat-handle.el < prev    next >
Lisp/Scheme  |  2001-06-04  |  64KB  |  1,743 lines

  1. ;;;
  2. ;;; $Id: irchat-handle.el,v 1.18 2001/06/04 17:46:03 simm Exp $
  3. ;;;
  4. ;;; see file irchat-copyright.el for change log and copyright info
  5.  
  6. (require 'pure-generic)
  7. (require 'pure-vs)
  8. (require 'pure-ds)
  9. (require 'pure-irc-send)
  10. (require 'pure-irc-dcc)
  11. (require 'irchat-vars)
  12.  
  13. (defsubst irchat-scan-channels (str)
  14.   (let ((vstr (irchat-chan-virtual str)))
  15.     (or (string= str vstr)
  16.     (assoc vstr irchat-channel-alist)
  17.     (setq irchat-channel-alist (cons (cons vstr nil) irchat-channel-alist)))
  18.     (or (assoc str irchat-channel-alist)
  19.     (setq irchat-channel-alist (cons (cons str nil) irchat-channel-alist)))))
  20.  
  21. (defsubst irchat-user-on-this-channel (nick chan)
  22.   "return non-NIL if NICK is on channel CHAN"
  23.   (if (null nick) nil
  24.     (let ((n (intern nick)))
  25.       (member-ignore-case chan (get n 'chnl)))))
  26.  
  27. (defun irchat-greet-user (nick chan)
  28.   (let ((n (intern nick)))
  29.     (message "IRCHAT: %s has entered! (%s)" nick
  30.          (if (string= chan "0") "on no channel yet"
  31.            (concat "on channel " (irchat-chan-virtual chan))))
  32.     (if (get n 'irchat-greeting)
  33.     (irchat-send "PRIVMSG %s :%s" nick (get n 'irchat-greeting)))
  34.     (put n 'irchat-waited-for nil)
  35.     (put n 'irchat-greeting nil)))
  36.  
  37.  
  38. (defun irchat-change-nick-of (old new)
  39.   (let ((pair (assoc old irchat-nick-alist)))
  40.     (if pair
  41.     (setcar pair new)
  42.       (setq irchat-nick-alist (cons (cons new nil) irchat-nick-alist)))
  43.     (if (null new) ;; maybe quit
  44.     (put (intern old) 'chnl nil))))
  45.  
  46. (defun irchat-Command-debug-user ()
  47.   "for debugging."
  48.   (interactive)
  49.   (let (rest str chan oper (nick (read-string (format "NICK: "))))
  50.     (setq rest (get (intern nick) 'chnl))
  51.     (setq str (format "%s =" nick))
  52.     (while rest
  53.       (setq chan (car rest))
  54.       (setq rest (cdr rest))
  55.       (setq oper (cdr (assoc nick (get (intern chan) 'nicka))))
  56.       (setq str (format "%s %s%s" str (or oper "")
  57.             (irchat-chan-virtual chan))))
  58.     (irchat-insert0 (format "%s (shared channels)\n" str))
  59.     (irchat-insert0 (format "%s = [%s] to %s last seen\n" nick
  60.                 (irchat-convert-seconds2
  61.                  (get (intern nick) 'lasttime))
  62.                 (irchat-chan-virtual
  63.                  (or (get (intern nick) 'lastchan) "(not yet)"))))
  64.     (irchat-insert0 (format "%s = <%s>\n" nick
  65.                 (or (get (intern nick) 'userhost) "not yet")))))
  66.  
  67.  
  68. (defsubst irchat-remove-from-channel (nick chan)
  69.   "Remove users info from his channel"
  70.   (let* ((u (intern nick))
  71.      (chans (get u 'chnl)))
  72.     (setq chans (delete (car (member-ignore-case chan chans)) chans))
  73.     (put u 'chnl chans)))
  74.  
  75. (defun irchat-add-to-channel (nicks chan)
  76.   "Update our copy of NICKS on channel CHAN."
  77.   (let ((nicka (get (intern chan) 'nicka)))
  78.     (while (string-match "^\\([@+]?\\)\\([^ ]+\\) ?\\(.*\\)" nicks)
  79.       (let ((oper (match-string 1 nicks))
  80.         (nick (match-string 2 nicks))
  81.         chans)
  82.     (setq nicks (match-string 3 nicks))
  83.     (setq nicka (cons (cons nick oper) nicka))
  84.     (setq chans (get (intern nick) 'chnl))
  85.     (if (null (member-ignore-case chan chans))
  86.         (put (intern nick) 'chnl (nconc chans (list chan))))
  87.     (if (get (intern nick) 'irchat-waited-for)
  88.         (irchat-greet-user nick chan))
  89.     (if (null (assoc nick irchat-nick-alist))
  90.         (setq irchat-nick-alist (cons (list nick) irchat-nick-alist)))))
  91.     (put (intern chan) 'nicka nicka)))
  92.  
  93. (defun irchat-channel-operator (nick chan)
  94.   (cdr (assoc nick (get (intern chan) 'nicka))))
  95.  
  96. (defun irchat-channel-operator-set (nick chan oper)
  97.   (let ((nicka (assoc nick (get (intern chan) 'nicka))))
  98.     (and nicka
  99.      (setcdr nicka oper))))
  100.  
  101. (defun irchat-channel-newnick-set (nick chan newnick)
  102.   (let ((nicka (assoc nick (get (intern chan) 'nicka))))
  103.     (and nicka
  104.      (setcar nicka newnick))))
  105.  
  106. (defun irchat-user-last-privmsg (nick)
  107.   (get (intern nick) 'lastchan))
  108.  
  109. (defun irchat-user-last-privmsg-time (nick)
  110.   (let ((time (get (intern nick) 'lasttime)))
  111.     (if time (- (irchat-current-time) time) nil)))
  112.  
  113. ;; begin: moved from irchat-pj-action.el
  114. ;;   by simm@irc.fan.gr.jp, Thu, 31 May 2001 21:57:46 +0900
  115. (defun irchat-pj-auto-oper (nick userhost chan)
  116.   "Give defined-user channel-operator automatically."
  117.   (and (string= "@" (irchat-channel-operator irchat-nickname chan))
  118.        (not (string= "@" (irchat-channel-operator nick chan)))
  119.        (let* (tmp
  120.           (id (concat nick "!" userhost))
  121.           (ok (member-regexp id irchat-pj-auto-oper-list)))
  122.      (if ok ok
  123.        (setq ok  (assoc-regexp id irchat-pj-auto-oper-list)
  124.          tmp (cdr ok))
  125.        (or (and (stringp tmp)
  126.             (string-match chan tmp))
  127.            (and (listp tmp)
  128.             (member chan tmp))
  129.            (setq ok nil)))
  130.      (if (car ok)
  131.          (irchat-send "MODE %s +o %s" chan nick)))))
  132. ;; end
  133.  
  134. ;; begin: add by simm@irc.fan.gr.jp, Tue, 20 Jul 1999
  135. (defsubst irchat-pj-make-verbose-nick (nick userhost flag)
  136.   (if flag
  137.       (concat nick "(" userhost ")")
  138.     nick))
  139. ;; end
  140.  
  141.  
  142. (defun irchat-handle-error (prefix msg)
  143.   (if (not irchat-no-configure-windows)
  144.       (irchat-insert-allchan (format "ERROR: %s\n" msg) nil))
  145.   (setq irchat-fatal-error-message msg)
  146.   (message "IRC ERROR: %s" msg))
  147.  
  148. (defun irchat-handle-482 (prefix me chan msg)
  149.   (message "IRCHAT: You are not a channel operator on %s"
  150.        (irchat-chan-virtual chan)))
  151.  
  152. (defun irchat-handle-464 (prefix me msg)
  153.   (irchat-insert0 (format 
  154.        "*** Password incorrect from %s. Try again with password.\n" prefix))
  155.   (setq irchat-reconnect-with-password t))
  156.  
  157. (defun irchat-handle-nick (prefix userhost nick)
  158.   (irchat-insert (concat
  159.                   (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-nick-verbose)
  160.                   " is now known as " nick "\n")
  161.          (get (intern prefix) 'chnl))
  162.   (irchat-change-nick-of prefix nick)
  163.   (put (intern nick) 'chnl (get (intern prefix) 'chnl))
  164.   (put (intern prefix) 'chnl nil)
  165.   (mapcar
  166.    '(lambda (chan)
  167.       (irchat-channel-newnick-set prefix chan nick))
  168.    (get (intern nick) 'chnl))
  169.   (if (string= prefix irchat-nickname)
  170.       (progn
  171.     (setq irchat-nickname nick)
  172.     (if (string= prefix irchat-current-chat-partner)
  173.         (setq irchat-current-chat-partner nick))
  174.     (irchat-insert-special
  175.          (concat
  176.           (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-nick-verbose)
  177.           " is now known as " nick "\n")))))
  178.  
  179. (defun irchat-handle-notice (prefix chan msg)
  180.   ;; begin: add by simm@irc.fan.gr.jp, Mon, 18 Jan 1999
  181.   (and irchat-pj-rewrite-server-notice
  182.        (string= prefix irchat-server)
  183.        (setq prefix nil msg (concat "=== " msg)))
  184.   ;; end
  185.   (cond 
  186.    ((null prefix)
  187.     (if (string-match "ERROR" msg)
  188.     (irchat-insert-allchan (format "%s\n" msg))
  189.       (irchat-insert-special (format "%s\n" msg))))
  190.    ((string-match "\001\\(.*\\)\001" msg)
  191.     (irchat-ctcp-notice prefix msg))
  192.    ((string-match "^\\*\\*\\* Notice -- \\(.*\\)" msg)
  193.     (let ((notice (match-string 1 msg)))
  194.       (cond
  195.        ((and irchat-ignore-fakes
  196.          (string-match "^Fake" notice))
  197.     t)
  198.        ((and irchat-ignore-noauths
  199.          (string-match "^No Authorization" notice))
  200.     t)
  201.        ((and irchat-ignore-kills
  202.          (string-match "^Received KILL" notice))
  203.     t)
  204.        ((and irchat-shorten-kills
  205.          (string-match 
  206.           "^Received KILL message for \\([^.]*\\)\\. From \\([^ ]*\\) Path: \\([^ ]*\\) ?\\(.*\\)" notice))
  207.     (let ((killed (match-string 1 notice))
  208.           (killer (match-string 2 notice))
  209.           (reason (match-string 4 notice))
  210.           (cbuf (current-buffer)))
  211.       (set-buffer irchat-KILLS-buffer)
  212.       (goto-char (point-max))
  213.       (insert (format "%s\n" notice))
  214.       (set-buffer cbuf)
  215.       (irchat-insert0 (format "%s KILLed %s %s\n" killer killed
  216.                   (if (= (length reason) 0)
  217.                       "-No reason supplied-"
  218.                     reason)))))
  219.        (t
  220.     (irchat-insert0 (format "%s: %s\n" prefix notice))))))
  221.    (t
  222.     (irchat-handle-privmsg2 prefix chan msg))))
  223.  
  224. (defun irchat-handle-ping (prefix msg)
  225.   (pure-irc-send-pong irchat-server-process msg)
  226.   (irchat-maybe-poll))
  227.  
  228. ;; modified by simm@irc.fan.gr.jp, Sat, 13 Jun 1999
  229. (defun irchat-handle-pong (prefix he &optional msg)
  230.   (cond
  231.    ((and msg (string= msg "irchat-polling"))
  232.     (setq irchat-polling t))
  233.    ((string-match he ":irchat-polling$")
  234.     (setq irchat-polling t))
  235.    (t
  236.     ;;(irchat-insert0 (format "[%s]\n" (match-string 1 rest)))
  237.     nil)))
  238.  
  239. (defun irchat-handle-privmsg (prefix chan msg)
  240.   (or (null prefix)
  241.       (and prefix
  242.        (memq (intern prefix) irchat-ignore-nickname)
  243.        (irchat-msg-from-ignored prefix chan msg))
  244.       (let ((temp msg)
  245.         (case-fold-search t))
  246.     ;; begin sound extension: modified by kaoru@kaisei.org
  247.     (cond ((and (string-match "\007" temp) irchat-beep-on-bells)
  248.            (funcall irchat-pj-sound-bell-function))
  249.           ((consp irchat-pj-sound-words-list)
  250.            (let ((re irchat-pj-sound-words-list))
  251.          (while (consp re)
  252.            (save-match-data
  253.              (cond ((string-match (car re) temp)
  254.                 (funcall irchat-pj-sound-words-function prefix)
  255.                 (setq re nil))
  256.                (t (setq re (cdr re)))))))))
  257.     ;; end
  258.     (if (and (string-match "\001\\(.*\\)\001" temp)
  259.          (or (not (string= irchat-nickname prefix))
  260.              (irchat-match-me chan)))
  261.         (setq temp (irchat-ctcp-msg prefix chan temp)))
  262.     (if (not (string= temp ""))
  263.         (irchat-handle-privmsg2 prefix chan temp))
  264.     ;; add by mikami@nk.hcs.ts.fujitsu.co.jp, Tue, 31 Aug 1999 10:48:12 +0900
  265.     (run-hooks 'irchat-privmsg-exit-hook))))
  266.  
  267. (defun irchat-handle-privmsg2 (prefix chan xmsg)
  268.   (or (not (irchat-match-me chan))
  269.       (get-buffer-window irchat-Dialogue-buffer)
  270.       (get-buffer-window irchat-Others-buffer)
  271.       (get-buffer-window irchat-Private-buffer)
  272.       (message "IRCHAT: A private message has arrived from %s" prefix))
  273.   ;; only private messages to us get time-stamp
  274.   (if (irchat-match-me chan)
  275.       (irchat-insert-private t prefix xmsg)
  276.     (if (string= irchat-nickname prefix)
  277.     ;; my message to channel/partner
  278.     (irchat-insert-private nil chan xmsg)
  279.       (if (irchat-user-on-this-channel prefix chan) 
  280.       ;; user on this channel
  281.       (irchat-insert (format "%s %s\n"
  282.                  (format "<%s:%s>"
  283.                      (irchat-chan-virtual chan)
  284.                      prefix) xmsg)
  285.              chan 'privmsg)
  286.     ;; user not on this channel
  287.     (irchat-insert (format "%s %s\n"
  288.                    (format "(%s:%s)"
  289.                        (irchat-chan-virtual chan)
  290.                        prefix) xmsg)
  291.                chan 'privmsg))))
  292.   (put (intern prefix) 'lastchan chan)
  293.   (put (intern prefix) 'lasttime (irchat-current-time)))
  294.  
  295. (defun irchat-match-me (dest)
  296.   (let ((ddest (downcase dest))
  297.     (duser (if (stringp irchat-my-user) (downcase irchat-my-user) ""))
  298.     (dhost (if (stringp irchat-my-host) (downcase irchat-my-host) ""))
  299.     (dserv (if (stringp irchat-my-server) (downcase irchat-my-server) "")))
  300.     (or (string= ddest (downcase irchat-nickname))
  301.     (string= ddest (concat duser "@" dserv))
  302.     (string= ddest (concat duser "%" dhost "@" dserv)))))
  303.  
  304. (defun irchat-handle-wallops (prefix msg)
  305.   "Handle the WALLOPS message."
  306.   (if irchat-show-wallops
  307.       (irchat-insert0 (format "*** Wallops: %s %s\n" prefix msg)))
  308.   (let ((buf (current-buffer)))
  309.     (set-buffer irchat-WALLOPS-buffer)
  310.     (goto-char (point-max))
  311.     (insert (format "%s %s\n"
  312.             (if prefix (concat "from " prefix) "") msg))
  313.     (set-buffer buf)))
  314.  
  315.  
  316. (defun irchat-handle-quit (prefix userhost reason)
  317.   "Handle the QUIT message."
  318.   (pure-irc-dcc-process-kill-nick prefix irchat-server-process)
  319.   (irchat-insert (concat
  320.                   (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-quit-verbose)
  321.                   " has left IRC (" reason ")\n")
  322.          (get (intern prefix) 'chnl)
  323.          (concat "has left IRC (" reason ")")
  324.          t
  325.                  (concat
  326.                   (irchat-pj-make-verbose-nick prefix userhost irchat-pj-handle-quit-verbose)
  327.                   ","))
  328.   ;; begin sound extension: modified by kaoru@kaisei.org
  329.   (and irchat-pj-sound-when-part
  330.        (not irchat-ignore-changes)
  331.        (funcall irchat-pj-sound-part-function prefix userhost))
  332.   ;; end sound extension:
  333.   (put (intern prefix) 'chnl nil)
  334.   (irchat-change-nick-of prefix nil))
  335.  
  336. (defun irchat-handle-topic (prefix chan topic)
  337.   "Handle the TOPIC message."
  338.   (if (not irchat-ignore-changes)
  339.       (irchat-insert (format "New topic on %s set by %s: %s\n"
  340.                  (irchat-chan-virtual chan) prefix topic)
  341.              chan t)))
  342.  
  343. (defun irchat-handle-mode (prefix chan &rest args)
  344.   "Handle the MODE message."
  345.   (let ((str ""))
  346.     (while args
  347.       (cond ((string-match "\\+ooo" (car args))
  348.          (irchat-channel-operator-set (nth 1 args) chan "@")
  349.          (irchat-channel-operator-set (nth 2 args) chan "@")
  350.          (irchat-channel-operator-set (nth 3 args) chan "@"))
  351.         ((string-match "\\+oo-o" (car args))
  352.          (irchat-channel-operator-set (nth 1 args) chan "@")
  353.          (irchat-channel-operator-set (nth 2 args) chan "@")
  354.          (irchat-channel-operator-set (nth 3 args) chan nil))
  355.         ((string-match "\\+o-o\\+o" (car args))
  356.          (irchat-channel-operator-set (nth 1 args) chan "@")
  357.          (irchat-channel-operator-set (nth 2 args) chan nil)
  358.          (irchat-channel-operator-set (nth 3 args) chan "@"))
  359.         ((string-match "-o\\+oo" (car args))
  360.          (irchat-channel-operator-set (nth 1 args) chan nil)
  361.          (irchat-channel-operator-set (nth 2 args) chan "@")
  362.          (irchat-channel-operator-set (nth 3 args) chan "@"))
  363.         ((string-match "-oo\\+o" (car args))
  364.          (irchat-channel-operator-set (nth 1 args) chan nil)
  365.          (irchat-channel-operator-set (nth 2 args) chan nil)
  366.          (irchat-channel-operator-set (nth 3 args) chan "@"))
  367.         ((string-match "-o\\+o-o" (car args))
  368.          (irchat-channel-operator-set (nth 1 args) chan nil)
  369.          (irchat-channel-operator-set (nth 2 args) chan "@")
  370.          (irchat-channel-operator-set (nth 3 args) chan nil))
  371.         ((string-match "\\+o-oo" (car args))
  372.          (irchat-channel-operator-set (nth 1 args) chan "@")
  373.          (irchat-channel-operator-set (nth 2 args) chan nil)
  374.          (irchat-channel-operator-set (nth 3 args) chan nil))
  375.         ((string-match "-ooo" (car args))
  376.          (irchat-channel-operator-set (nth 1 args) chan nil)
  377.          (irchat-channel-operator-set (nth 2 args) chan nil)
  378.          (irchat-channel-operator-set (nth 3 args) chan nil))
  379.         ((string-match "\\+oo" (car args))
  380.          (irchat-channel-operator-set (nth 1 args) chan "@")
  381.          (irchat-channel-operator-set (nth 2 args) chan "@"))
  382.         ((string-match "\\+o-o" (car args))
  383.          (irchat-channel-operator-set (nth 1 args) chan "@")
  384.          (irchat-channel-operator-set (nth 2 args) chan nil))
  385.         ((string-match "-o\\+o" (car args))
  386.          (irchat-channel-operator-set (nth 1 args) chan nil)
  387.          (irchat-channel-operator-set (nth 2 args) chan "@"))
  388.         ((string-match "-oo" (car args))
  389.          (irchat-channel-operator-set (nth 1 args) chan nil)
  390.          (irchat-channel-operator-set (nth 2 args) chan nil))
  391.         ((string-match "\\+o" (car args))
  392.          (irchat-channel-operator-set (nth 1 args) chan "@"))
  393.         ((string-match "-o" (car args))
  394.          (irchat-channel-operator-set (nth 1 args) chan nil)))
  395.       (setq str (format "%s %s" str (car args)))
  396.       (setq args (cdr args)))
  397.     (if (string= chan irchat-nickname)
  398.     (if (not irchat-ignore-changes)
  399.         (irchat-insert (format "Your new mode is set:%s\n" str)
  400.                irchat-Private-buffer
  401.                (format "Your new mode is set:")
  402.                nil
  403.                (format "%s" str)))
  404.       (if (not irchat-ignore-changes)
  405.       (irchat-insert (format "New mode for %s set by %s:%s\n"
  406.                  (irchat-chan-virtual chan) prefix str)
  407.              chan
  408.              (format "New mode for %s set by %s:"
  409.                  (irchat-chan-virtual chan) prefix)
  410.              nil
  411.              (format "%s" str))))))
  412.  
  413.  
  414. (defun irchat-handle-kick (prefix chan nick reason)
  415.   "Handle the KICK message."
  416.   (irchat-remove-from-channel nick chan)
  417.   (if (string= nick irchat-nickname)
  418.       (progn
  419.     (irchat-insert (format
  420.             "You were kicked off channel %s by %s. (%s)\n"
  421.             (irchat-chan-virtual chan) prefix reason)
  422.                (list chan irchat-Private-buffer) t)
  423.     (setq irchat-current-channels
  424.           (delete (car (member-ignore-case chan irchat-current-channels))
  425.               irchat-current-channels))
  426.     (put (intern chan) 'nicka nil)
  427.     (irchat-Channel-part chan))
  428.     (irchat-insert (format
  429.             "%s has kicked %s out from channel %s (%s)\n"
  430.             prefix nick (irchat-chan-virtual chan) reason)
  431.            chan t)))
  432.  
  433. (defun irchat-handle-invite (prefix nick chan)
  434.   (irchat-insert-special
  435.    (format "*** %s invites you to channel %s\n"
  436.        prefix (irchat-chan-virtual chan)) t)
  437.   ;; begin sound extension: modified by kaoru@kaisei.org
  438.   (if irchat-pj-sound-when-invited
  439.       (funcall irchat-pj-sound-invited-function prefix))
  440.   ;; end sound extension:
  441.   (setq irchat-invited-channel chan))
  442.  
  443. (defun irchat-handle-kill (prefix me path)
  444.   (irchat-insert-special
  445.    (format "*** IRCHAT: You were killed by %s. Path: %s\n" 
  446.        prefix path) t)
  447.   (irchat-insert-allchan (format "ERROR: You were Killed.\n") nil)
  448.   (irchat-Channel-part nil))
  449.  
  450. (defun irchat-handle-join (nick userhost chan)
  451.   "Handle the JOIN message."
  452.   (let ((oper "") (voice "") (xnick nick))
  453.     (if (string-match "^\\([^\007]+\\)\007\\(o*\\)\\(v*\\)$" chan)
  454.     (setq voice (match-string 3 chan)
  455.           oper  (match-string 2 chan)
  456.           chan  (match-string 1 chan)))
  457.     (if (string= oper "o")
  458.     (setq xnick (format "@%s" xnick))
  459.       (if (string= voice "v")
  460.       (setq xnick (format "+%s" xnick))))
  461.     (if (string= nick irchat-nickname)
  462.     (progn
  463.       (setq irchat-current-channels
  464.         (cons chan irchat-current-channels))
  465.       (irchat-Channel-join chan)
  466.       (put (intern chan) 'init t)
  467.       (put (intern chan) 'nicka nil))
  468.       ;; add by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 01:26:35 +0900
  469.       (and irchat-pj-auto-oper-list
  470.        (irchat-pj-auto-oper nick userhost chan))
  471.       (irchat-add-to-channel nick chan))
  472.     (if (not irchat-ignore-changes)
  473.     (irchat-insert (concat
  474.                         (irchat-pj-make-verbose-nick xnick userhost
  475.                              irchat-pj-handle-join-verbose)
  476.                         " has joined channel "
  477.                         (irchat-chan-virtual chan)
  478.                         "\n")
  479.                (if (string= nick irchat-nickname)
  480.                (list chan irchat-Private-buffer) chan)
  481.                (concat "has joined channel " (irchat-chan-virtual chan))
  482.                        t
  483.                        (concat
  484.                         (irchat-pj-make-verbose-nick xnick userhost
  485.                              irchat-pj-handle-join-verbose)
  486.                         ",")))
  487.     ;; begin sound extension: modified by kaoru@kaisei.org
  488.     (and irchat-pj-sound-when-join
  489.      (not irchat-ignore-changes)
  490.      (funcall irchat-pj-sound-join-function nick userhost))
  491.     ;; end sound extension:
  492.     (irchat-change-nick-of nick nick)))
  493.  
  494. (defun irchat-handle-part (prefix userhost chan &optional reason)
  495.   "Handle the PART message."
  496.   (if (null reason) (setq reason ""))
  497.   (if (string= prefix irchat-nickname)
  498.       (progn
  499.     (setq irchat-current-channels
  500.           (delete (car (member-ignore-case chan irchat-current-channels))
  501.               irchat-current-channels))
  502.     (put (intern chan) 'nicka nil)))
  503.   (if (not irchat-ignore-changes)
  504.       (irchat-insert (concat
  505.                       (irchat-pj-make-verbose-nick prefix userhost
  506.                            irchat-pj-handle-part-verbose)
  507.                       " has left channel "
  508.                       (irchat-chan-virtual chan)
  509.                       " (" reason ")\n")
  510.              (if (string= prefix irchat-nickname)
  511.              (list chan irchat-Private-buffer) chan)
  512.              (concat "has left channel "
  513.                              (irchat-chan-virtual chan)
  514.                              " (" reason ")")
  515.              t
  516.                      (concat
  517.                       (irchat-pj-make-verbose-nick prefix userhost
  518.                            irchat-pj-handle-part-verbose)
  519.                       ",")))
  520.   (if (not (string= prefix irchat-nickname))
  521.       ;; begin sound extension: modified by kaoru@kaisei.org
  522.       (and irchat-pj-sound-when-part
  523.        (not irchat-ignore-changes)
  524.        (funcall irchat-pj-sound-part-function prefix userhost))
  525.       ;; end sound extension:
  526.     (irchat-Channel-part chan)
  527.     (if (null irchat-invited-channel)
  528.     (setq irchat-invited-channel chan)))
  529.   (irchat-remove-from-channel prefix chan)
  530.   (irchat-change-nick-of prefix prefix))
  531.  
  532. ;;;
  533. ;;;  000 replies -- what the fuck is the author of ircd thinking.
  534. ;;;
  535. (defun irchat-handle-000s (number prefix me &rest args)
  536.   (cond
  537.    ((= (length args) 1)
  538.     (irchat-insert0 (format "*** %s\n" (car args))))
  539.    ((= (length args) 2)
  540.     (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args))))
  541.    ((= (length args) 3)
  542.     (irchat-insert0 (format "*** %s %s (%s)\n"
  543.                 (car args) (nth 2 args) (nth 1 args))))
  544.    (t
  545.     (message "IRCHAT: Strange %s reply" number))))
  546.  
  547.  
  548. (defun irchat-handle-001 (prefix nick msg)
  549.   (setq irchat-my-server prefix)
  550.   (if (string-match ".*!\\([^!]*\\)" msg)
  551.       (setq irchat-pj-my-userhost (match-string 1 msg)))
  552.   (if irchat-no-configure-windows
  553.       (irchat-configure-windows))
  554.   (or (string= irchat-nickname nick)
  555.       (irchat-insert-special (format "%s is now known as %s\n" irchat-nickname nick) t))
  556.   (irchat-insert-special
  557.    (format "*** Welcome to the Internet Relay Chat world. Your nick is %s.\n" nick))
  558.   (setq irchat-servername prefix)
  559.   (setq irchat-nickname nick)
  560.   (irchat-send "USERHOST %s" irchat-nickname)
  561.   (setq irchat-my-userhost nil))
  562.  
  563. (defun irchat-handle-002 (prefix me msg)
  564.   (if (string-match "running version \\(.*\\)" msg)
  565.       (irchat-insert-special
  566.        (format "*** Your server is %s (version %s).\n"
  567.            irchat-servername (match-string 1 msg))))
  568.   (irchat-insert0
  569.    (format "*** Your client version is %s.\n" irchat-pj-version-string)))
  570.  
  571. (defun irchat-handle-003 (prefix me msg)
  572.   (irchat-insert0 (format "*** %s \n" msg)))
  573.  
  574. ;;(defun irchat-handle-004 (prefix me server version mode1 mode2)
  575. (defun irchat-handle-004 (prefix me server &optional version mode1 mode2)
  576.   ;;(irchat-insert0
  577.    ;;(format "*** %s %s %s %s\n" server version mode1 mode2))
  578.   (irchat-maybe-poll))
  579.  
  580.  
  581. ;;;
  582. ;;;  200 replies
  583. ;;;
  584. (defun irchat-handle-200s (number prefix me &rest args)
  585.   (cond
  586.    ((= (length args) 1)
  587.     (irchat-insert0 (format "*** %s\n" (car args))))
  588.    ((= (length args) 2)
  589.     (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args))))
  590.    ((= (length args) 3)
  591.     (irchat-insert0
  592.      (format "*** %s %s (%s)\n" (car args) (nth 2 args) (nth 1 args))))
  593.    (t
  594.     (message "IRCHAT: Strange %s reply" number))))
  595.  
  596. (defun irchat-handle-200 (prefix me status version dest next &optional ver sec q1 q2)
  597.   "200 RPL_TRACELINK Link <version & debug level> <destination> <next server>"
  598.   (irchat-insert0 (format "*** Link %s (%s%s) ==> %s (%s)%s\n"
  599.               prefix version
  600.               (if ver (format " %s" ver) "")
  601.               next dest
  602.               (if sec (format " [%s] %s/%s"
  603.                       (irchat-convert-seconds sec)
  604.                       q1 q2) ""))))
  605.  
  606. (defun irchat-handle-201 (prefix me status class who)
  607.   "201 RPL_TRACECONNECTING Try. <class> <server>"
  608.   (irchat-insert0 (format "*** %s %s (%s) ==> %s\n"
  609.               status prefix class who)))
  610.  
  611. (defun irchat-handle-202 (prefix me status class who)
  612.   "202 RPL_TRACEHANDSHAKE H.S. <class> <server>"
  613.   (irchat-insert0 (format "*** %s %s (%s) ==> %s\n"
  614.               status prefix class who)))
  615.  
  616. (defun irchat-handle-203 (prefix me status class who)
  617.   "203 RPL_TRACEUNKNOWN ???? <class> [<client IP address in dot form>]"
  618.   (irchat-insert0 (format "*** %s %s (%s) ==> %s\n"
  619.               status prefix class who)))
  620.  
  621. (defun irchat-handle-204 (prefix me status class who)
  622.   "204 RPL_TRACEOPERATOR Oper <class> <nick>"
  623.   (irchat-insert0 (format "*** %s %s (%s) ==> %s\n"
  624.               status prefix class who)))
  625.  
  626. (defun irchat-handle-205 (prefix me status class who &optional dummy time)
  627.   (irchat-insert0 (format "*** %s %s (%s) ==> %s%s\n"
  628.               status prefix class who
  629.               (if time (format " (%s)" time) ""))))
  630.  
  631. (defun irchat-handle-206 (prefix me status class Nserver Nclient name how &optional version)
  632.   "206 RPL_TRACELINK Serv 200 3S 15C irc.other *!*@other.host :V3"
  633.   (irchat-insert0 (format "*** Server %s (%s) ==> %s {%s,%s} %s %s\n"
  634.               prefix class name Nserver Nclient how
  635.               (if version (format "[%s]" version) ""))))
  636.  
  637. (defun irchat-handle-209 (prefix me status class entries)
  638.   (irchat-insert0 (format "*** Class %s (%s entries)\n"
  639.                 class entries)))
  640.  
  641. (defvar irchat-stats-now nil)
  642.  
  643. (defun irchat-handle-211 (prefix me link sndq sndm sndb rcvm rcvb time)
  644.   "NOTICE %s :%-15.15s%5u%7u%10u%7u%10u %s"
  645.   (setq    time (string-to-int time))
  646.   (if (not irchat-stats-now)
  647.       (progn
  648.     (irchat-insert0 (format "STATS L %s\n" prefix))
  649.     (irchat-insert0 
  650.    "    Time             Send-Q   Send-Msg    Send-KB   Recv-Msg    Recv-KB\n")
  651.     (setq irchat-stats-now prefix)))
  652.   (irchat-insert0 (format "%s\n" link))
  653.   (irchat-insert0
  654.    (format "%5ddays %02d:%02d:%02d %8s %10s %10s %10s %10s\n"
  655.        (/ (/ (/ time 60) 60) 24)
  656.        (mod (/ (/ time 60) 60) 24)
  657.        (mod (/ time 60) 60)
  658.        (mod time 60)
  659.        sndq sndm sndb rcvm rcvb)))
  660.  
  661. (defun irchat-handle-213 (prefix me cmd host pass server port class)
  662.   (if (not irchat-stats-now)
  663.       (progn
  664.     (irchat-insert0 (format "STATS C %s\n" prefix))
  665.     (setq irchat-stats-now prefix)))
  666.   (irchat-insert0 (format "%s:%s:%s:%s:%s:%s\n"
  667.               cmd host pass server port class)))
  668.  
  669. (defun irchat-handle-214 (prefix me cmd host pass server port class)
  670.   (if (not irchat-stats-now)
  671.       (progn
  672.     (irchat-insert0 (format "STATS C %s\n" prefix))
  673.     (setq irchat-stats-now prefix)))
  674.   (irchat-insert0 (format "%s:%s:%s:%s:%s:%s\n"
  675.               cmd host pass server port class)))
  676.  
  677. (defun irchat-handle-212 (prefix me cmd times bytes &optional rtimes)
  678.   (if (not irchat-stats-now)
  679.       (progn
  680.     (irchat-insert0 (format "STATS M %s\n" prefix))
  681.     (setq irchat-stats-now prefix)))
  682.   (if rtimes
  683.       (irchat-insert0
  684.        (format "%s has been used %s times (remote: %s times) after startup (%s bytes)\n"
  685.            cmd times rtimes bytes))
  686.     (irchat-insert0
  687.      (format "%s has been used %s times after startup (%s bytes)\n"
  688.          cmd times bytes))))
  689.  
  690. (defun irchat-handle-215 (prefix me cmd ip passwd domain port class)
  691.   ":server.name 215 me I ip * domain port class"
  692.   (if (not irchat-stats-now)
  693.       (progn
  694.     (irchat-insert0 (format "STATS I %s\n" prefix))
  695.     (setq irchat-stats-now prefix)))
  696.   (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n"
  697.               cmd ip passwd domain port class)))
  698.  
  699. (defun irchat-handle-216 (prefix me cmd domain &rest args)
  700.   ":servernameirc 216 me K domain ..."
  701.   (if (not irchat-stats-now)
  702.       (progn
  703.     (irchat-insert0 (format "STATS K %s\n" prefix))
  704.     (setq irchat-stats-now prefix)))
  705.   (irchat-insert0 (format "*** %s:%s:%s\n"
  706.               cmd domain
  707.               (let ((str ""))
  708.                 (while args
  709.                   (setq str (format "%s %s" str (car args))
  710.                     args (cdr args)))
  711.                 str))))
  712.  
  713. (defun irchat-handle-217 (prefix me cmd reason star host stuff)
  714.   (if (not irchat-stats-now)
  715.       (progn
  716.     (irchat-insert0 (format "STATS Q %s\n" prefix))
  717.     (setq irchat-stats-now prefix)))
  718.   (irchat-insert0 (format "*** %s:%s:%s:%s:%s\n"
  719.               cmd reason star host stuff)))
  720.  
  721. (defun irchat-handle-218 (prefix me cmd class pfreq cfreq mlinks msendq &optional local global)
  722.   ":server.name 218 me Y class 120 600 1 3000000"
  723.   (if (not irchat-stats-now)
  724.       (progn
  725.     (irchat-insert0 (format "STATS Y %s\n" prefix))
  726.     (setq irchat-stats-now prefix)))
  727.   (irchat-insert0 (format 
  728.        "*** Class %s: PingFreq %s, ConFreq %s, MaxLinks %s, MaxSendQ %s%s%s\n"
  729.          class pfreq cfreq mlinks msendq
  730.          (if local (format ", LocalLimit %s" local) "")
  731.          (if global (format ", GlobalLimit %s" global) ""))))
  732.  
  733. (defun irchat-handle-219 (prefix me type msg)
  734.   "RPL_ENDOFSTATS"
  735.   (if (not irchat-stats-now)
  736.       (irchat-insert0 (format "*** Nothing (STATS %s %s)\n"
  737.                   type prefix)))
  738.   (setq irchat-stats-now nil))
  739.  
  740. (defun irchat-handle-221 (prefix me str) ;;; RPL_USERMODEIS?
  741.   "Handle the MODE message."
  742.   (irchat-insert-special (format "*** Mode for you is %s\n" str) t))
  743.  
  744. (defun irchat-handle-241 (prefix me cmd hostmask star server maxdepth etc)
  745.   ":irc.tokyo.wide.ad.jp 241 nick L * * irc.leaf.server 0 -1"
  746.   (if (not irchat-stats-now)
  747.       (progn
  748.     (irchat-insert0 (format "STATS H %s\n" prefix))
  749.     (setq irchat-stats-now prefix)))
  750.   (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n"
  751.               cmd hostmask star server maxdepth etc)))
  752.  
  753. (defun irchat-handle-242 (prefix me msg)
  754.   (if (not irchat-stats-now)
  755.       (progn
  756.     (irchat-insert0 (format "STATS U %s\n" prefix))
  757.     (setq irchat-stats-now prefix)))
  758.   (irchat-insert0 (format "*** %s\n" msg)))
  759.  
  760. (defun irchat-handle-243 (prefix me cmd hostname password user nazo class)
  761.   ":server.name 243 me O hostname password user nazo class"
  762.   (if (not irchat-stats-now)
  763.       (progn
  764.     (irchat-insert0 (format "STATS O %s\n" prefix))
  765.     (setq irchat-stats-now prefix)))
  766.   (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n"
  767.               cmd hostname password user nazo class)))
  768.  
  769. (defun irchat-handle-244 (prefix me cmd hostmask star server &optional maxdepth etc)
  770.   ":irc.tokyo.wide.ad.jp 244 me H * * irc.tokai-ic.or.jp 0 -1"
  771.   (if (not irchat-stats-now)
  772.       (progn
  773.     (irchat-insert0 (format "STATS H %s\n" prefix))
  774.     (setq irchat-stats-now prefix)))
  775.   ;; plum-2.33.1 returns `maxdepth' is "" and no `etc', so 3-minutes adhoc hack
  776.   (if (and (stringp maxdepth) (/= 0 (length maxdepth)))
  777.       (irchat-insert0 (format "*** %s:%s:%s:%s:%s:%s\n"
  778.                   cmd hostmask star server maxdepth etc))
  779.     (irchat-insert0 (format "*** %s:%s:%s:%s:*:*\n"
  780.                 cmd hostmask star server))))
  781.  
  782. (defun irchat-handle-246 (prefix me server p1 p2 p3 p4)
  783.   ":server0.jp 246 nick server1.jp[*@server1.hostname] 26 26 50 15"
  784.   (if (not irchat-stats-now)
  785.       (progn
  786.     (irchat-insert0 (format "STATS P %s\n" prefix))
  787.     (irchat-insert0 (format "*** %32s %5s %5s %5s %5s\n"
  788.                 "<server name>" "snd#" "rcv#" "ping" "pref"))
  789.     (setq irchat-stats-now prefix)))
  790.   (if (string-match "\\([^[]+\\)\\[[^]]+\\]" server)
  791.       (setq server (match-string 1 server)))
  792.   (irchat-insert0 (format "*** %32s %5s %5s %5s %5s\n" server p1 p2 p3 p4)))
  793.  
  794. (defun irchat-handle-248 (prefix me msg)
  795.   "RPL_STATSDEFINE"
  796.   (if (not irchat-stats-now)
  797.       (progn
  798.     (irchat-insert0 (format "STATS D %s\n" prefix))
  799.     (setq irchat-stats-now prefix)))
  800.   (irchat-insert0 (format "*** %s\n" msg)))
  801.  
  802. (defun irchat-handle-249 (prefix me msg)
  803.   (if (not irchat-stats-now)
  804.       (progn
  805.     (irchat-insert0 (format "STATS T/Z %s\n" prefix))
  806.     (setq irchat-stats-now prefix)))
  807.   (irchat-insert0 (format "*** %s\n" msg)))
  808.  
  809. (defun irchat-handle-250 (prefix me msg)
  810.   "RPL_STATSDLINE"
  811.   (irchat-insert0 (format "*** %s\n" msg)))
  812.  
  813. (defun irchat-handle-251 (prefix me msg)
  814.   "RPL_LUSERCLIENT"
  815.   (irchat-insert0 (format "*** %s\n" msg)))
  816.  
  817. (defun irchat-handle-252 (prefix me count msg)
  818.   "RPL_LUSEROP"
  819.   (irchat-insert0 (format "*** %s %s\n" count msg)))
  820.  
  821. (defun irchat-handle-253 (prefix me count msg)
  822.   "RPL_LUSERUNKNOWN"
  823.   (irchat-insert0 (format "*** %s %s\n" count msg)))
  824.  
  825. (defun irchat-handle-254 (prefix me count msg)
  826.   "RPL_LUSERCHANNELS"
  827.   (irchat-insert0 (format "*** %s %s\n" count msg)))
  828.  
  829. (defun irchat-handle-255 (prefix me msg)
  830.   "RPL_LUSERME"
  831.   (irchat-insert0 (format "*** %s\n" msg)))
  832.  
  833. (defun irchat-handle-256 (prefix me msg)
  834.   "RPL_ADMINME"
  835.   (irchat-insert0 (format "*** %s\n" msg)))
  836.  
  837. (defun irchat-handle-257 (prefix me msg)
  838.   "RPL_ADMINLOC1"
  839.   (if (not (string= msg ""))
  840.       (irchat-insert0 (format "*** %s\n" msg))))
  841.  
  842. (defun irchat-handle-258 (prefix me msg)
  843.   "RPL_ADMINLOC2"
  844.   (if (not (string= msg ""))
  845.       (irchat-insert0 (format "*** %s\n" msg))))
  846.  
  847. (defun irchat-handle-259 (prefix me msg)
  848.   "RPL_ADMINEMAIL"
  849.   (if (not (string= msg ""))
  850.       (irchat-insert0 (format "*** %s\n" msg))))
  851.  
  852. (defun irchat-handle-261 (prefix me status filename port)  ; RPL_TRACELOG
  853.   (irchat-insert0 (format "*** LogFile %s => %s (%s)\n"
  854.               prefix filename port)))
  855.  
  856. (defun irchat-handle-262 (prefix me mask version msg)  ; RPL_ END TRACE
  857.   "262 RPL_TRACEEND *.jp 2.9.5. :End of TRACE"
  858.   (irchat-insert0 (format "*** END of TRACE to (%s) %s [%s]\n"
  859.               mask prefix version)))
  860.  
  861. ;;;
  862. ;;; 300 replies
  863. ;;;
  864. (defun irchat-handle-300s (number prefix me &rest args)
  865.   (cond
  866.    ((= (length args) 1)
  867.     (irchat-insert0 (format "*** %s\n" (car args))))
  868.    ((= (length args) 2)
  869.     (irchat-insert0 (format "*** %s %s\n" (car args) (nth 1 args))))
  870.    ((= (length args) 3)
  871.     (irchat-insert0
  872.      (format "*** %s %s (%s)\n" (car args) (nth 2 args) (nth 1 args))))
  873.    (t
  874.     (message "IRCHAT: Strange %s reply" number))))
  875.  
  876. (defun irchat-handle-301 (prefix me nick iswhat) ; RPL_AWAY
  877.   (if (not (string= nick irchat-auto-whois-nick))
  878.       (if irchat-while-whois-reply
  879.       (irchat-insert0 (format "AWAY: %s\n" iswhat))
  880.     (irchat-insert0 (format "%s is AWAY: %s\n" nick iswhat)))))
  881.  
  882. (defun irchat-handle-302 (prefix me data) ; RPL_USERHOST
  883.   "Handle the 302 reply, USERHOST reply"
  884.   (while (string-match
  885.       "\\([^*=]+\\)\\([*]*\\)=\\([+-]\\)\\([^@]+\\)@\\([^ ]+\\) *\\(.*\\)" data)
  886.     (let ((nick (match-string 1 data))
  887.       (oper (match-string 2 data))
  888.       (away (match-string 3 data))
  889.       (user (match-string 4 data))
  890.       (host (match-string 5 data))
  891.       userhost)
  892.       (setq data (match-string 6 data))
  893.       (setq userhost (format "%s@%s" user host))
  894.       (put (intern nick) 'userhost userhost)
  895.       (if (and (string= nick irchat-nickname)
  896.            (null irchat-my-userhost))
  897.       (progn
  898.         (setq irchat-my-userhost userhost)
  899.         (setq irchat-my-user user)
  900.         (setq irchat-my-host host)
  901.         (irchat-insert-special
  902.          (format "*** You are %s.\n" irchat-my-userhost))
  903.         (and irchat-pj-first-channel
  904.          irchat-pj-initialize-p
  905.          (irchat-Command-join irchat-pj-first-channel))
  906.         (setq irchat-pj-initialize-p nil))
  907.     (irchat-insert0 (format "%s is <%s> [%s, %s]\n"
  908.                 nick userhost
  909.                 (concat 
  910.                  (if (string= oper "")
  911.                      "Not ")
  912.                  "Operator")
  913.                 (concat 
  914.                  (if (string= away "+")
  915.                      "Not ")
  916.                  "AWAY")))))))
  917.  
  918. (defun irchat-handle-303 (prefix me nicks) ; RPL_ISON
  919.   "Handle the 303 reply, ISON reply"
  920.   (if (string= nicks "")
  921.       (irchat-insert0 "No one you requested is on now.\n")
  922.     (irchat-insert0 (format "Following people(s) are on: %s\n" nicks))))
  923.  
  924. (defun irchat-handle-305 (prefix me msg) ; RPL_UNAWAY
  925.   "Handle the 305 reply, UNAWAY reply"
  926.   (if irchat-pj-away-p
  927.       (progn
  928.     (setq irchat-pj-away-p nil)
  929.     (irchat-maybe-poll)
  930.     (irchat-insert0 (format "*** %s (%s)\n"
  931.                 msg (current-time-string))))))
  932.  
  933. (defun irchat-handle-306 (prefix me msg) ; RPL_NOWAWAY
  934.   "Handle the 306 reply, NOWAWAY reply"
  935.   (setq irchat-pj-away-p t)
  936.   (irchat-insert0 (format "*** %s (%s)\n"
  937.               msg (current-time-string))))
  938.  
  939. (defun irchat-handle-311 (prefix me nick user host dummy name) ;; RPL_WHOISUSER
  940.   "Handle the 311 reply (from WHOIS)."
  941.   (setq irchat-while-whois-reply t)
  942.   (if (not (string= nick irchat-auto-whois-nick))
  943.       (irchat-insert0 (format "%s is <%s@%s> %s\n"
  944.                   nick user host name))))
  945.  
  946. (defun irchat-handle-312 (prefix me nick server info) ; RPL_WHOISSERVER
  947.   ":server.name 312 me her server.name2 :server info"
  948.   (if (not (string= nick irchat-auto-whois-nick))
  949.       (irchat-insert0 (format "on via server %s (%s)\n" server info))))
  950.  
  951. (defun irchat-handle-313 (prefix me nick iswhat) ; RPL_WHOISOPERATOR
  952.   (if (not (string= nick irchat-auto-whois-nick))
  953.       (irchat-insert0 (format "STATUS: %s\n" iswhat))))
  954.  
  955. (defun irchat-handle-314 (prefix me nick user host star name) ;; RPL_WHOWASUSER
  956.   "Handle the 314 reply (msa's WHOWAS)."
  957.   (message "")
  958.   (irchat-insert0 (format "%s was <%s@%s> %s\n"
  959.               nick user host name)))
  960.  
  961. (defun irchat-handle-315 (prefix ms chan msg) ; RPL_ENDOFWHO
  962.   (setq irchat-long-reply-count 0))
  963.  
  964. (defun irchat-handle-317 (prefix me nick sec &optional time msg) ;RPL_WHOISIDLE
  965.   ":server.name 317 me her 38 :seconds idle or\
  966.    :server.name 317 me her 38 839678551 :seconds idle, signon time"
  967.   (let (fun sec2)
  968.     (if (not (string= nick irchat-auto-whois-nick))
  969.     (irchat-insert0 (format "IDLE for %s %s\n"
  970.                 (irchat-convert-seconds sec)
  971.                 (if (setq sec2 (irchat-past-time sec))
  972.                     (format "(%s)" sec2)
  973.                   "")))
  974.       (if (fboundp (setq fun (intern "irchat-whois-idle")))
  975.       (apply fun (list nick (string-to-int sec)))))))
  976.  
  977. (defun irchat-handle-318 (prefix me nick msg) ; RPL_ENDOFWHOIS
  978.   ":server.name 318 me her :End of /WHOIS list."
  979.   (setq irchat-while-whois-reply nil)
  980.   (if (string= nick irchat-auto-whois-nick)
  981.       (setq irchat-auto-whois-nick "")))
  982.  
  983. (defun irchat-handle-319 (prefix me nick rest) ; RPL_????
  984.   ":server.name 319 me her :chan1 chan2 chan3"
  985.   (let ((str "") oper chan)
  986.     (while (string-match "^\\([@+]?\\)\\([^ ]+\\) +\\(.*\\)$" rest)
  987.       (setq oper (match-string 1 rest))
  988.       (setq chan (match-string 2 rest))
  989.       (setq rest (match-string 3 rest))
  990.       (if (not (irchat-ischannel chan))
  991.       (setq chan (concat oper chan)
  992.         oper ""))
  993.       (setq str (format "%s %s%s" str oper (irchat-chan-virtual chan))))
  994.     (if (not (string= nick irchat-auto-whois-nick))
  995.     (irchat-insert0 (format "channels:%s\n" str)))))
  996.  
  997. (defun irchat-handle-321 (prefix me chan msg) ;;; RPL_LISTSTART
  998.   "Handle the 321 reply (first line from LIST)."
  999.   nil)
  1000.  
  1001. (defun irchat-handle-322 (prefix &optional me chan users topic bug) ; RPL_LIST
  1002.   "Handle the 322 reply (from LIST)."
  1003.   (setq irchat-long-reply-count (1+ irchat-long-reply-count))
  1004.   (if (> irchat-long-reply-count 38)
  1005.       (progn
  1006.     (setq irchat-long-reply-count 0)
  1007.     (pure-irc-send-pong irchat-server-process irchat-servername)))
  1008.   (if topic
  1009.       (irchat-insert (format "Topic for %s (%s users): %s\n"
  1010.                  (if (string= chan "*") "Private"
  1011.                    (irchat-chan-virtual chan))
  1012.                  users topic)
  1013.              chan t)
  1014.     (irchat-insert (format "*** Error 322: %s %s %s %s %s" prefix me chan users topic))))
  1015.  
  1016. (defun irchat-handle-323 (prefix me msg) ; RPL_LISTEND
  1017.   (setq irchat-channel-filter "")
  1018.   (setq irchat-long-reply-count 0))
  1019.  
  1020.  
  1021. (defun irchat-handle-324 (prefix me chan &rest args) ; RPL_CHANNELMODEIS
  1022.   "Handle the MODE message."
  1023.   (let ((str ""))
  1024.     (while args
  1025.       (setq str (format "%s %s" str (car args)))
  1026.       (setq args (cdr args)))
  1027.     (irchat-insert (format "Mode for %s:%s\n"
  1028.                (irchat-chan-virtual chan) str) chan t)))
  1029.  
  1030. (defun irchat-handle-331 (prefix me chan msg) ; RPL_NOTOPIC
  1031.   (irchat-insert (format "No topic is set for %s\n"
  1032.              (irchat-chan-virtual chan))
  1033.          chan t))
  1034.  
  1035. (defun irchat-handle-332 (prefix me chan topic) ; RPL_TOPIC
  1036.   (irchat-insert (format "Topic for %s: %s\n"
  1037.              (irchat-chan-virtual chan) topic) chan t))
  1038.  
  1039. (defun irchat-handle-341 (prefix me nick chan) ; RPL_INVITING
  1040.   (irchat-insert (format "*** Inviting user %s to channel %s\n"
  1041.               nick (irchat-chan-virtual chan))
  1042.          chan t))
  1043.  
  1044. (defun irchat-handle-351 (prefix me ver server mode) ; RPL_VERSION
  1045.   (irchat-insert0 (format "*** %s is running IRC version %s (%s)\n"
  1046.               server ver mode)))
  1047.  
  1048. (defun irchat-handle-352 (prefix me chan user host serv nick oper name)
  1049.   "Handle the WHOREPLY message (352)"
  1050.   (setq irchat-long-reply-count (1+ irchat-long-reply-count))
  1051.   (if (> irchat-long-reply-count 38)
  1052.       (progn
  1053.     (setq irchat-long-reply-count 0)
  1054.     (pure-irc-send-pong irchat-server-process irchat-servername)))
  1055.   (if (string-match "[0-9]* *\\(.*\\)" name)
  1056.       (setq name (match-string 1 name)))
  1057.   (irchat-insert (format "%-3s %-9s %-9s %-30s %s\n" oper
  1058.              (if (or (string= chan "*") (string= chan "0"))
  1059.                  "Private"
  1060.                (irchat-chan-virtual chan))
  1061.              nick (format "<%s@%s>" user host)  name)
  1062.          chan t))
  1063.  
  1064. (defun irchat-handle-353 (prefix me flag chan nicks) ; RPL_NAMREPLY
  1065.   "Handle the 353 (NAMREPLY) message.   If we are just polling the server,
  1066. don't display anything.  Check if someone we are waiting for has entered."
  1067.   (setq irchat-long-reply-count (1+ irchat-long-reply-count))
  1068.   (if (> irchat-long-reply-count 38)
  1069.       (progn
  1070.     (setq irchat-long-reply-count 0)
  1071.     (pure-irc-send-pong irchat-server-process irchat-servername)))
  1072.   (if irchat-polling
  1073.       nil
  1074.     (irchat-insert (format "%s = %s\n"
  1075.                (if (string= chan "*") "Private"
  1076.                  (irchat-chan-virtual chan))
  1077.                nicks) chan t))
  1078.   (irchat-scan-channels chan)
  1079.   (if (get (intern chan) 'init)
  1080.       (irchat-add-to-channel nicks chan)))
  1081.  
  1082. (defun irchat-handle-361 (prefix me who msg) ; RPL_KILLDONE
  1083.   ;; modified by simm@irc.fan.gr.jp, Sun, 27 Jun 1999
  1084.   (irchat-insert0 (format "You just KILLED %s. %s\n" who msg)))
  1085.  
  1086. (defun irchat-handle-364 (prefix me server next msg)
  1087.   (setq irchat-links-reply-count (1+ irchat-links-reply-count))
  1088.   (if (string-match "^\\([^ ]+\\) \\(\\[[^]]+\\]\\)? *\\(.*\\)" msg)
  1089.       (let ((hop (match-string 1 msg))
  1090.         (comment (match-string 3 msg)))
  1091.     (if irchat-how-to-show-links-reply
  1092.         (irchat-insert0 (format "%2s %-30s <== %-30s\n" hop server next))
  1093.       (irchat-insert0 (format "%-30s %s\n" server comment))))))
  1094.  
  1095. (defun irchat-handle-365 (prefix me mask msg) ; RPL_ENDOFLINKS
  1096.   (if (= 0 irchat-links-reply-count)
  1097.       (irchat-insert0 (format "*** No match server. (%s)\n" mask)))
  1098.   (setq irchat-links-reply-count 0))
  1099.  
  1100. (defun irchat-handle-366 (prefix me chan msg) ; RPL_ENDOFNAMES
  1101.   (setq irchat-long-reply-count 0)
  1102.   (setq irchat-polling nil)
  1103.   (if (get (intern chan) 'init)
  1104.       (put (intern chan) 'init nil)))
  1105.  
  1106. (defun irchat-handle-367 (prefix me chan ban)
  1107.   (irchat-insert (format "Banned on %s: %s\n"
  1108.              (irchat-chan-virtual chan) ban) chan t))
  1109.  
  1110. (defun irchat-handle-368 (prefix me chan msg) ; BAN END
  1111.   nil)
  1112.  
  1113. (defun irchat-handle-369 (prefix me nick msg) ; WHOWAS
  1114.   nil)
  1115.  
  1116. (defun irchat-handle-371 (prefix me msg) ; RPL_INFO
  1117.   (irchat-insert0 (format "*** %s\n" msg)))
  1118.  
  1119. (defun irchat-handle-372 (prefix me msg) ; RPL_MOTD
  1120.   (irchat-insert0 (format "*** %s\n" msg)))
  1121.  
  1122. (defun irchat-handle-374 (prefix me msg) ; RPL_INFO END
  1123.   nil)
  1124.  
  1125. (defun irchat-handle-375 (prefix me msg) ; RPL_MOTD START
  1126.   nil)
  1127.  
  1128. (defun irchat-handle-376 (prefix me msg) ; RPL_MOTD END
  1129.   nil)
  1130.  
  1131. (defun irchat-handle-381 (prefix me msg) ; RPL_YOUREOPER
  1132.   ":server.name 381 me :Good afternoon, gentleman. I am a HAL 9000 computer."
  1133.   (irchat-insert0 (format "OPER: %s\n" msg)))
  1134.  
  1135. (defun irchat-handle-382 (prefix name file msg) ; RPL_REHASHING
  1136.   (irchat-insert0 (format "*** %s: %s %s\n" name msg file)))
  1137.  
  1138. (defun irchat-handle-391 (prefix me server time) ; RPL_TIME
  1139.   ":server.name 391 me server.name :Monday August 5 1996 -- 01:39 +09:00"
  1140.   (irchat-insert0 (format "Time: %s (%s)\n" time server)))
  1141.  
  1142. ;;;
  1143. ;;;  400 replies -- ERRORS
  1144. ;;; 
  1145. (defun irchat-handle-400s (number prefix me &rest args)
  1146.   "Generic handler for 4?? messages. This is called if no specific handler exists"
  1147.   (cond
  1148.    ((= (length args) 1)
  1149.     (irchat-insert0 (format "*** %s\n" (car args))))
  1150.    ((= (length args) 2)
  1151.     (irchat-insert0 (format "*** %s (%s)\n" (nth 1 args)
  1152.                 (irchat-chan-virtual (car args)))))
  1153.    ((= (length args) 3)
  1154.     (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args)
  1155.                 (irchat-chan-virtual (nth 1 args)))))
  1156.    (t
  1157.     (message "IRCHAT: Strange %s reply" number))))
  1158.  
  1159. (defun irchat-handle-401 (prefix me nick msg) ; ERR_NOSUCHNICK
  1160.   ":server.name 401 me nick :No such nick/channel"
  1161.   (if (not (string= nick irchat-auto-whois-nick))
  1162.       (irchat-send "WHOWAS %s" nick)
  1163.     (setq irchat-auto-whois-nick "")))
  1164.  
  1165. (defun irchat-handle-402 (prefix me nick msg) ; ERR_NOSUCHSERVER
  1166.   ":server.name 402 me servername :No such server"
  1167.   (if (string-match "^[^.*]+$" nick)
  1168.       (if (not (string= nick irchat-auto-whois-nick))
  1169.       (irchat-insert0
  1170.        (format "*** Error: No such nick. (%s)\n" nick))
  1171.     (setq irchat-auto-whois-nick ""))
  1172.     (irchat-insert0
  1173.      (format "*** Error: No such server. (%s)\n" nick))))
  1174.  
  1175. (defun irchat-handle-403 (prefix me chan msg)
  1176.   (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan))))
  1177.  
  1178. (defun irchat-handle-404 (prefix me chan msg)
  1179.   (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan))))
  1180.  
  1181. (defun irchat-handle-405 (prefix me chan msg)
  1182.   (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan))))
  1183.  
  1184. (defun irchat-handle-406 (prefix me nick msg)
  1185.   (pure-irc-dcc-process-kill-nick nick irchat-server-process)
  1186.   (irchat-insert0 (format "*** %s (%s)\n" msg nick)))
  1187.  
  1188. (defun irchat-handle-407 (prefix me nick msg)
  1189.   (irchat-insert0 (format "*** %s (%s)\n" msg nick)))
  1190.  
  1191. (defun irchat-handle-412 (prefix me msg)
  1192.   (message "IRCHAT: No text to send"))
  1193.  
  1194. (defun irchat-handle-421 (prefix me cmd msg)
  1195.   (irchat-insert0 (format "*** Unknown command (%s)\n" cmd)))
  1196.  
  1197. (defun irchat-handle-422 (prefix me msg)
  1198.   (irchat-insert0 (format "*** No message of the day in %s\n" prefix)))
  1199.  
  1200. (defun irchat-handle-432 (prefix me nick msg) ;;; ERR_ERRONICK?
  1201.   "Handle the 432 reply (erroneus nickname)"
  1202.   (save-excursion
  1203.     (set-buffer irchat-Command-buffer)
  1204.     ;; modified by simm@irc.fan.gr.jp, Mon, 20 Dec 1999 21:44:10 +0900
  1205.     (funcall irchat-pj-sound-error-function)
  1206.     (if irchat-no-configure-windows
  1207.     (setq irchat-nickname-erroneus t)
  1208.       (message
  1209.        "IRCHAT: Erroneus Nickname.  Choose a new one with %s."
  1210.        (substitute-command-keys "\\[irchat-Command-nickname]")))))
  1211.  
  1212. (defun irchat-handle-433 (prefix me nick msg) ;;; ERR_NICKNAMEINUSE
  1213.   "Handle the 433 reply (nickname already in use)"
  1214.   (save-excursion
  1215.     (set-buffer irchat-Command-buffer)
  1216.     (if irchat-no-configure-windows
  1217.     (setq irchat-nickname-already-in-use t)
  1218.       ;; modified by simm@irc.fan.gr.jp, Mon, 20 Dec 1999 21:44:10 +0900
  1219.       (funcall irchat-pj-sound-error-function)
  1220.       (message
  1221.        "IRCHAT: Nickname %s already in use.  Choose a new one with %s." nick
  1222.        (substitute-command-keys "\\[irchat-Command-nickname]")))))
  1223.  
  1224. (defun irchat-handle-437 (prefix me chan msg)
  1225.   "437 ERR_UNAVAILRESOURCE nick|chan :Nick/channel is temporarily unavailable"
  1226.   (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan))))
  1227.  
  1228. (defun irchat-handle-441 (prefix me nick chan msg)
  1229.   "441 ERR_USERNOTINCHANNEL nick chan :They aren't on that channel"
  1230.   (irchat-insert0 (format "*** %s (%s/%s)\n"
  1231.               msg nick (irchat-chan-virtual chan))))
  1232.  
  1233. (defun irchat-handle-442 (prefix me chan msg)
  1234.   "442 ERR_NOTONCHANNEL chan :You're not on that channel"
  1235.   (irchat-insert0 (format "*** %s (%s)\n" msg (irchat-chan-virtual chan))))
  1236.  
  1237. (defun irchat-handle-451 (prefix &rest args)
  1238.   (if irchat-after-registration
  1239.       (irchat-insert0 (format "*** You have not registered.\n"))))
  1240.  
  1241. (defun irchat-handle-471 (prefix me chan msg) ; ERR_CHANNELISFULL
  1242.   ":server.name 471 me chan :Sorry, cannot join channel."
  1243.   (setq irchat-invited-channel chan)
  1244.   (irchat-insert0
  1245.    (format "*** Error: Sorry, channel %s is full.\n"
  1246.        (irchat-chan-virtual chan))))
  1247.  
  1248. (defun irchat-handle-472 (prefix me char msg) ; ERR_UNKNOWNMODE
  1249.   ":server.name 472 me char :is unknown mode char to me"
  1250.   (irchat-insert0
  1251.    (format "*** Error: '%s' %s.\n" char msg)))
  1252.  
  1253. (defun irchat-handle-473 (prefix me chan msg) ; ERR_INVITEONLYCHAN
  1254.   ":server.name 473 me chan :Sorry, cannot join channel."
  1255.   (setq irchat-invited-channel chan)
  1256.   (irchat-insert0
  1257.    (format "*** Error: Sorry, channel %s is invited only.\n"
  1258.        (irchat-chan-virtual chan))))
  1259.  
  1260. (defun irchat-handle-474 (prefix me chan msg) ; ERR_BANNEDFROMCHAN
  1261.   ":server.name 474 me chan :Sorry, cannot join channel."
  1262.   (setq irchat-invited-channel chan)
  1263.   (irchat-insert0
  1264.    (format "*** Error: Sorry, you are banned from channel %s.\n"
  1265.        (irchat-chan-virtual chan))))
  1266.  
  1267. (defun irchat-handle-475 (prefix me chan msg) ; ERR_BADCHANNELKEY
  1268.   ":server.name 475 me chan :Sorry, cannot join channel."
  1269.   (setq irchat-invited-channel chan)
  1270.   (irchat-insert0
  1271.    (format "*** Error: Sorry, incorrect key for channel %s.\n"
  1272.        (irchat-chan-virtual chan))))
  1273.  
  1274. (defun irchat-handle-477 (prefix me chan msg)
  1275.   ":server.name 477 me chan :Channel doesn't support modes"
  1276.   (irchat-insert0 (format "*** %s (%s)\n" msg
  1277.               (irchat-chan-virtual chan))))
  1278.  
  1279. (defun irchat-handle-484 (prefix me msg)
  1280.   ":server.name 484 me :Your connection is restricted!"
  1281.   (irchat-insert0 (format "*** %s\n" msg)))
  1282.  
  1283. ;;;
  1284. ;;;  500 replies -- ERRORS
  1285. ;;;
  1286. (defun irchat-handle-500s (number prefix me &rest args)
  1287.   "Generic handler for 5?? messages. This is called if no specific handler exists"
  1288.   (cond
  1289.    ((= (length args) 1)
  1290.     (irchat-insert0 (format "*** %s\n" (car args))))
  1291.    ((= (length args) 2)
  1292.     (irchat-insert0 (format "*** %s (%s)\n" (nth 1 args)
  1293.                 (irchat-chan-virtual (car args)))))
  1294.    ((= (length args) 3)
  1295.     (irchat-insert0 (format "*** %s %s (%s)\n" (car args) (nth 2 args)
  1296.                 (irchat-chan-virtual (nth 1 args)))))
  1297.    (t
  1298.     (message "IRCHAT: Strange %s reply" number))))
  1299.  
  1300. ;;;
  1301. ;;; answer to CTCP messages, no postprocessing
  1302. ;;;
  1303. (defun irchat-ctcp-msg (from to rest)
  1304.   "It's CTCP request, act on it."
  1305.   (let* (left now right message rest-of-line hook)
  1306.     (if (string-match "^\\([^\001]*\\)\001\\([^\001]*\\)\001\\(.*\\)" rest)
  1307.     ;; modified by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 00:41:09 +0900
  1308.     ;; progn -> save-excursion
  1309.     (save-excursion
  1310.       ;; add by simm@irc.fan.gr.jp, Sat, 18 Dec 1999 00:54:18 +0900
  1311.       ;; for irchat-pj-sound
  1312.       (if irchat-pj-sound-when-ctcp
  1313.           (funcall irchat-pj-sound-ctcp-function from))
  1314.       (setq left (match-string 1 rest))
  1315.       (setq now (match-string 2 rest))
  1316.       (setq right (match-string 3 rest))
  1317.       (setq rest (concat left right))
  1318.       (if (string-match "^\\([^ ]*\\) \\(.*\\)" now)
  1319.           (progn
  1320.         (setq message (downcase (match-string 1 now)))
  1321.         (setq rest-of-line (match-string 2 now)))
  1322.         (if (string-match "^\\([^ ]*\\)" now)
  1323.         (progn
  1324.           (setq message (downcase (match-string 1 now)))
  1325.           (setq rest-of-line nil))
  1326.           (progn
  1327.         (setq message "errmsg")
  1328.         (setq rest-of-line "Couldn't figure out what was said."))))
  1329.       (if (and (boundp (setq hook
  1330.                  (intern 
  1331.                   (concat "irchat-ctcp-" message "-hook"))))
  1332.            (eval hook)
  1333.            (eq (eval (list hook from to rest-of-line)) t))
  1334.           ;; If we have a hook, and it returns T, do nothing more
  1335.           nil
  1336.         ;; else call the handler
  1337.         (if (fboundp (setq fun (intern
  1338.                     (concat "irchat-ctcp-" message "-msg"))))
  1339.         (progn
  1340.           (eval (list fun from to rest-of-line))
  1341.           (if (not irchat-freeze)
  1342.               (irchat-scroll-if-visible
  1343.                (get-buffer-window (current-buffer)))))
  1344.           (progn
  1345.         (if (string= (downcase to) (downcase irchat-nickname))
  1346.             ;; return unknown error if it's sended to only me.
  1347.             (let ((umsg (upcase message)))
  1348.               (irchat-ctcp-reply from (concat "ERRMSG " umsg " :"
  1349.                               (format irchat-ctcp-error-msg umsg)))))
  1350.         (irchat-insert (format "*** Unknown CTCP %s from %s to %s %s\n"
  1351.                        (upcase message) from to
  1352.                        (if rest-of-line
  1353.                        (if (string= rest-of-line "")
  1354.                            ""
  1355.                          (format "[%s]" rest-of-line))
  1356.                      ""))
  1357.                    to t))))))
  1358.     rest))
  1359.  
  1360. (defun irchat-ctcp-reply (receiver message)
  1361.   (irchat-send "NOTICE %s :\001%s\001" receiver message))
  1362.  
  1363. (defun irchat-ctcp-message (command from to)
  1364.   (message "CTCP %s from %s to %s" command from (irchat-chan-virtual to)))
  1365.  
  1366. (defun irchat-ctcp-version-msg (from to rest)
  1367.   (irchat-ctcp-reply from (format "VERSION %s :" (pure-vs-make irchat-pj-version-string)))
  1368.   (irchat-ctcp-message "VERSION" from to))
  1369.  
  1370. (defun irchat-ctcp-userinfo-msg (from to rest)
  1371.   (irchat-ctcp-reply from (format "USERINFO :%s" irchat-ctcp-userinfo))
  1372.   (irchat-ctcp-message "USERINFO" from to))
  1373.  
  1374. (defun irchat-ctcp-action-msg (from to rest)
  1375.   (if rest
  1376.       (irchat-handle-privmsg2 from to (format "*** %s %s" from rest))
  1377.     (irchat-handle-privmsg2 from to (format "*** %s (nil)" from)))
  1378.   (irchat-ctcp-message "ACTION" from to))
  1379.  
  1380. ;; add by simm@irc.fan.gr.jp, Sun, 29 Aug 1999 22:56:28 +0900
  1381. (defun irchat-ctcp-caesar-msg (from to rest)
  1382.   (if rest
  1383.       (irchat-handle-privmsg2 from to (format "*** %s %s" from (irchat-pj-caesar-string rest)))
  1384.     (irchat-handle-privmsg2 from to (format "*** %s (nil)" from)))
  1385.   (irchat-ctcp-message "CAESAR" from to))
  1386.  
  1387. (defun irchat-ctcp-dcc-msg (from to rest)
  1388.   ;; old: (irchat-dcc-request from to rest)
  1389.   ;; begin: from irchat-dcc.el
  1390.   (cond
  1391.    ((null rest)
  1392.     (irchat-insert0 (format "*** Bad format DCC from %s\n" from))
  1393.     (irchat-ctcp-reply from (format "ERRMSG :DCC: bad format")))
  1394.    ((string-match "^SEND \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)
  1395.     (let ((dinfo (pure-irc-dcc-info-create
  1396.           from
  1397.           (match-string 2 rest)
  1398.           (match-string 3 rest)
  1399.           (match-string 1 rest)
  1400.           (match-string 4 rest)
  1401.           nil
  1402.           (current-time-string))))
  1403.       (pure-ds-add-list dinfo pure-irc-dcc-offer-list)
  1404.       (irchat-insert-special
  1405.        (format "*** DCC SEND request from %s: %s (%s bytes)\n" from
  1406.            (pure-irc-dcc-info-get-file dinfo)
  1407.            (pure-irc-dcc-info-get-size dinfo) t))))
  1408.    ((string-match "^CHAT \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)
  1409.     (let ((dinfo (pure-irc-dcc-info-create
  1410.           from
  1411.           (match-string 2 rest)
  1412.           (match-string 3 rest)
  1413.           (match-string 1 rest)
  1414.           nil
  1415.           nil
  1416.           (current-time-string))))
  1417.       (pure-ds-add-list dinfo pure-irc-dcc-offer-list)
  1418.       (irchat-insert-special
  1419.        (format "*** DCC CHAT request from %s\n" from) t)))
  1420.    ((string-match "^RESUME \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)
  1421.     (let ((dinfo (pure-irc-dcc-info-search-resume
  1422.           (pure-irc-dcc-info-create
  1423.            from nil (match-string 2 rest) (match-string 1 rest)
  1424.            nil nil nil 'wait)
  1425.           pure-irc-dcc-process-list)))
  1426.       (if (pure-irc-dcc-info-resumep dinfo)
  1427.       (progn
  1428.         (pure-irc-dcc-info-put-xpos dinfo (match-string 3 rest))
  1429.         (funcall (intern (format "pure-pr-dcc-%s-resume-accept"
  1430.                      (pure-irc-dcc-info-get-method dinfo))) dinfo)
  1431.         (irchat-insert0
  1432.          (format "*** DCC RESUME request from %s: %s (at %s bytes)\n"
  1433.              from (match-string 1 rest) (match-string 3 rest))))
  1434.     (irchat-insert0
  1435.      (format "*** DCC RESUME request from %s, but I don't support it.\n"
  1436.          (match-string 1 rest))))))
  1437.    ((string-match "^ACCEPT \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest)
  1438.     (let ((dinfo (pure-irc-dcc-info-search-resume
  1439.           (pure-irc-dcc-info-create
  1440.            from nil (match-string 2 rest) (match-string 1 rest)
  1441.            nil (match-string 3 rest) nil 'resume)
  1442.           pure-irc-dcc-process-list)))
  1443.       (if (pure-irc-dcc-info-resumep dinfo)
  1444.       (progn
  1445.         (pure-irc-dcc-info-put-xpos dinfo (match-string 3 rest))
  1446.         (funcall (intern (format "pure-pr-dcc-%s-resume-start"
  1447.                      (pure-irc-dcc-info-get-method dinfo))) dinfo)
  1448.         (irchat-insert0
  1449.          (format "*** DCC RESUME accept from %s: %s (at %s bytes)\n"
  1450.              from (match-string 1 rest) (match-string 3 rest))))
  1451.     (irchat-insert0
  1452.      (format "*** DCC RESUME accept from %s, but I don't support it.\n"
  1453.          (match-string 1 rest))))))
  1454.    ((and pure-irc-dcc-use-dcc-cancel
  1455.      (string-match "^CANCEL \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest))
  1456.     (let ((dinfo (pure-irc-dcc-info-search
  1457.           (pure-irc-dcc-info-create
  1458.            from (match-string 2 rest) (match-string 3 rest) (match-string 1 rest))
  1459.           pure-irc-dcc-offer-list 'nick 'host 'port 'file)))
  1460.       (if (not dinfo)
  1461.       (irchat-insert0
  1462.        (format "*** DCC CANCEL ERROR: no such DCC request to %s: %s %s %s\n"
  1463.            from
  1464.            (pure-irc-dcc-info-get-file dinfo)
  1465.            (pure-irc-dcc-info-get-host dinfo)
  1466.            (pure-irc-dcc-info-get-port dinfo)))
  1467.     (pure-ds-del-list dinfo pure-irc-dcc-offer-list)
  1468.     (irchat-insert0 (format "*** DCC CANCEL from %s\n" from)))))
  1469.    ((string-match "^CANCEL \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\)" rest))
  1470.    (t
  1471.     (irchat-insert0 (format "*** Unknown DCC from %s: %s\n" from rest))
  1472.     (irchat-ctcp-reply from (format "ERRMSG :DCC: bad command"))))
  1473.   ;; end: from irchat-dcc.el
  1474.   (irchat-ctcp-message "DCC" from to))
  1475.  
  1476. (defun irchat-ctcp-time-msg (from to rest)
  1477.   (irchat-ctcp-reply from (format "TIME %s" (current-time-string)))
  1478.   (irchat-ctcp-message "TIME" from to))
  1479.  
  1480. (defun irchat-ctcp-ping-msg (from to rest)
  1481.   (irchat-ctcp-reply from (if rest (format "PING %s" rest) "PING"))
  1482.   (irchat-ctcp-message "PING" from to))
  1483.  
  1484. (defun irchat-ctcp-echo-msg (from to rest)
  1485.   (irchat-ctcp-reply from (if rest (format "ECHO %s" rest) "ECHO"))
  1486.   (irchat-ctcp-message "ECHO" from to))
  1487.  
  1488. (defun irchat-ctcp-clientinfo-msg (from to rest)
  1489.   (if (null rest)
  1490.       (irchat-ctcp-reply from
  1491.        (format "CLIENTINFO :%s :%s"
  1492.            (irchat-ctcp-list-string)
  1493.            "Use CLIENTINFO <COMMAND> to get more specific information"))
  1494.     (setq rest (upcase rest))
  1495.     (let (info)
  1496.       (setq info (get (intern rest) 'info))
  1497.       (if info
  1498.       (irchat-ctcp-reply from (concat "CLIENTINFO " rest " " info))
  1499.     (irchat-ctcp-reply from (concat "ERRMSG :CLIENTINFO: "
  1500.                     rest
  1501.                     " is not a valid command")))))
  1502.   (if (null rest)
  1503.       (irchat-ctcp-message "CLIENTINFO" from to)
  1504.     (irchat-ctcp-message (format "CLIENTINFO %s" rest) from to)))
  1505.     
  1506.  
  1507. (defvar irchat-ctcp-list nil)
  1508.  
  1509. (defun irchat-ctcp-list-string ()
  1510.   (let ((str "") (rest irchat-ctcp-list))
  1511.     (while rest
  1512.       (setq str (concat str (car rest) " "))
  1513.       (setq rest (cdr rest)))
  1514.     str))
  1515.  
  1516. (defsubst irchat-ctcp-add-clientinfo (command info)
  1517.   (setq command (upcase command))
  1518.   (setq irchat-ctcp-list (append irchat-ctcp-list (list command)))
  1519.   (put (intern command) 'info info))
  1520.  
  1521. (irchat-ctcp-add-clientinfo "ACTION"
  1522.                 "contains action descriptions for atmosphere")
  1523. (irchat-ctcp-add-clientinfo "CLIENTINFO"
  1524.                 "gives available CTCP commands")
  1525. (irchat-ctcp-add-clientinfo "CAESAR"
  1526.                 "sends message with X-ROT-5-13-47-48 encoding")
  1527. (irchat-ctcp-add-clientinfo "DCC"
  1528.                 "requests a Direct-Client-Connection")
  1529. (irchat-ctcp-add-clientinfo "ECHO"
  1530.                 "returns the arguments it receives")
  1531. (irchat-ctcp-add-clientinfo "ERRMSG"
  1532.                 "returns error messages")
  1533. (irchat-ctcp-add-clientinfo "PING"
  1534.                 "returns the arguments it receives")
  1535. (irchat-ctcp-add-clientinfo "TIME"
  1536.                 "tells you the time on the user's host")
  1537. (irchat-ctcp-add-clientinfo "USERINFO"
  1538.                 "returns user settable information")
  1539. (irchat-ctcp-add-clientinfo "VERSION"
  1540.                 "shows client type, version and environment")
  1541.  
  1542. ;;;
  1543. ;;; read CTCP messages from notice, no postprocessing done
  1544. ;;;
  1545.  
  1546. (defun irchat-ctcp-notice (prefix rest)
  1547.   "CTCP notice."
  1548.   (let* (message rest-of-line hook to) 
  1549.     (if (string-match "\\([^ ]+\\) :" rest)
  1550.     (setq to (match-string 1 rest)))
  1551.     (if (string-match "\001\\([^ ]*\\) :?\\(.*\\)\001" rest)
  1552.       (setq message (downcase (match-string 1 rest))
  1553.         rest-of-line (match-string 2 rest))
  1554.       (if (string-match "\001\\([^ ]*\\)\001" rest)
  1555.       (setq message (downcase (match-string 1 rest))
  1556.         rest-of-line nil)
  1557.     (setq message "errmsg"
  1558.           rest-of-line "Couldn't figure out what was said.")))
  1559.     (if (and (boundp (setq hook
  1560.                (intern (concat "irchat-ctcp-" message "-notice-hook"))))
  1561.          (eval hook)
  1562.          (eq (eval (list hook prefix rest-of-line)) t))
  1563.     ;; If we have a hook, and it returns T, do nothing more
  1564.     nil
  1565.       ;; else call the handler
  1566.       (if (fboundp (setq fun (intern
  1567.                   (concat "irchat-ctcp-" message "-notice"))))
  1568.       (progn
  1569.         (eval (list fun prefix rest-of-line))
  1570.         (if (not irchat-freeze)
  1571.         (irchat-scroll-if-visible
  1572.          (get-buffer-window (current-buffer)))))
  1573.     (irchat-insert0 (format "*** Unknown CTCP Reply %s from %s to %s %s\n"
  1574.                 (upcase message) prefix to
  1575.                 (if rest-of-line
  1576.                     (format "[%s]" rest-of-line)
  1577.                   "")))))))
  1578.  
  1579.  
  1580. (defun irchat-ctcp-version-notice (prefix rest)  
  1581.   (if rest
  1582.       (irchat-insert0 (format "VERSION@%s: %s\n" prefix rest))
  1583.     (message (format "Empty CTCP version notice from \"%s\"." prefix))))
  1584.  
  1585. (defun irchat-ctcp-clientinfo-notice (prefix rest)
  1586.   (irchat-insert0 (format "CLIENTINFO@%s: %s\n" prefix rest)))
  1587.  
  1588. (defun irchat-ctcp-userinfo-notice (prefix rest)  
  1589.   (irchat-insert0 (format "USERINFO@%s: %s\n" prefix rest)))
  1590.  
  1591. (defun irchat-ctcp-finger-notice (prefix rest)
  1592.   (irchat-insert0 (format "FINGER@%s: %s\n" prefix rest)))
  1593.  
  1594. (defun irchat-ctcp-time-notice (prefix rest)  
  1595.   (irchat-insert0 (format "TIME@%s: %s\n" prefix rest)))
  1596.  
  1597. (defun irchat-ctcp-echo-notice (prefix rest)
  1598.   (irchat-insert0 (format "ECHO@%s: %s\n" prefix rest)))
  1599.  
  1600. (defun irchat-ctcp-ping-notice (prefix rest)
  1601.   (let (to (time rest))
  1602.     (if (string-match "\\([^ ]+\\) \\(.*\\)" rest)
  1603.     (progn
  1604.       (setq time (match-string 1 rest))
  1605.       (setq to (match-string 2 rest))))
  1606.     (if (= 0 (string-to-int (or time "0")))
  1607.     (irchat-insert0 (format "PING@%s: %s\n" prefix (or time "nothing")))
  1608.       (let ((diff (- (irchat-current-time) (string-to-int time))))
  1609.     (while (< diff 0)
  1610.       (setq diff (+ diff 86400)))
  1611.     (irchat-insert (format "PING@%s: %s second%s\n" prefix diff
  1612.                    (if (< diff 2) "" "s"))
  1613.                to t)))))
  1614.  
  1615. (defun irchat-ctcp-errmsg-notice (prefix rest)
  1616.   (irchat-insert0 (format "ERRMSG@%s: %s\n" prefix rest))
  1617.   (if (pure-irc-dcc-info-resumep pure-irc-dcc-info)
  1618.       (pure-irc-dcc-info-resume-cancel pure-irc-dcc-info)))
  1619.  
  1620. (defun irchat-ctcp-comment-notice (from rest)  
  1621.   (message (format "CTCP COMMENT query from %s." from)))
  1622.  
  1623.  
  1624. ;;;
  1625. ;;; decode and encode of binary data
  1626. ;;;
  1627. (defun irchat-quote-decode (string-to-decode)
  1628.   (interactive)
  1629.   (save-excursion
  1630.     (set-buffer (get-buffer-create "*IRC DECODE*"))
  1631.     (delete-region (point-min) (point-max))
  1632.     (insert string-to-decode)
  1633.     (goto-char (point-min))
  1634.     (replace-string "\\\\" "\\")
  1635.     (goto-char (point-min))
  1636.     (replace-string "\\a" "\001")
  1637.     (goto-char (point-min))
  1638.     (replace-string "\\n" "\n")
  1639.     (goto-char (point-min))
  1640.     (replace-string "\\r" "\r")
  1641.     (setq string-to-decode (buffer-substring (point-min) (point-max)))
  1642.     string-to-decode))
  1643.  
  1644. (defun irchat-quote-encode (string)
  1645.   (interactive)
  1646.   (save-excursion
  1647.     (set-buffer (get-buffer-create "*IRC ENCODE*"))
  1648.     (delete-region (point-min) (point-max))
  1649.     (insert string)
  1650.     (goto-char (point-min))
  1651.     (while (search-forward "\\" nil 1)
  1652.       (insert "\\"))
  1653.     (goto-char (point-min))
  1654.     (while (search-forward "\001" nil 1)
  1655.       (delete-char -1)
  1656.       (insert "\\a"))
  1657.     (goto-char (point-min))
  1658.     (while (search-forward "\000" nil 1)
  1659.       (delete-char -1)
  1660.       (insert "\\0"))
  1661.     (goto-char (point-min))
  1662.     (while (search-forward "\n" nil 1)
  1663.       (delete-char -1)
  1664.       (insert "\\n"))
  1665.     (goto-char (point-min))
  1666.     (while (search-forward "\r" nil 1)
  1667.       (delete-char -1)
  1668.       (insert "\\r"))
  1669.     (setq string (buffer-substring (point-min) (point-max)))
  1670.     string))
  1671.  
  1672.  
  1673. (defun irchat-current-time ()
  1674.   (let* ((string (current-time-string))
  1675.          (day (string-to-int (substring string 8 10)))
  1676.          (hour (string-to-int (substring string 11 13)))
  1677.          (min  (string-to-int (substring string 14 16)))
  1678.          (sec  (string-to-int (substring string 17 19))))
  1679.     (+ sec (* 60 min) (* 3600 hour) (* 86400 day))))
  1680.  
  1681. (defun irchat-past-time (second)
  1682.   (let* ((string (current-time-string))
  1683.          (day (string-to-int (substring string 8 10)))
  1684.          (hour (string-to-int (substring string 11 13)))
  1685.          (min  (string-to-int (substring string 14 16)))
  1686.          (sec  (string-to-int (substring string 17 19))))
  1687.     (if (stringp second)
  1688.     (setq second (string-to-int second)))
  1689.     (setq second (- (+ sec (* 60 min) (* 3600 hour) (* 86400 day)) second))
  1690.     (if (< second 0) nil (irchat-convert-seconds2 second))))
  1691.  
  1692.  
  1693. (defun irchat-convert-seconds (time)
  1694.   "Convert seconds to printable string."
  1695.   (if (null time) (setq time 0))
  1696.   (let* ((seconds (if (stringp time) (string-to-int time) time))
  1697.      (minutes (/ seconds 60))
  1698.      (seconds (if minutes (% seconds 60) seconds))
  1699.      (hours (/ minutes 60))
  1700.      (minutes (if hours (% minutes 60) minutes))
  1701.      (days (/ hours 24))
  1702.      (hours (if days (% hours 24) hours))
  1703.      (ds (and (/= 0 days)
  1704.           (format "%d day%s, " days
  1705.               (if (> days 1) "s" ""))))
  1706.      (hs (and (/= 0 hours)
  1707.           (format "%d hour%s, " hours
  1708.               (if (> hours 1) "s" ""))))
  1709.      (ms (and (/= 0 minutes)
  1710.           (format "%d minute%s " minutes
  1711.               (if (> minutes 1) "s" ""))))
  1712.      (ss (format "%d seconds" seconds)))
  1713.     (concat ds hs ms (if seconds ss ""))))
  1714.  
  1715.  
  1716. (defun irchat-convert-seconds2 (time)
  1717.   "Convert seconds to printable string."
  1718.   (if (null time) (setq time 0))
  1719.   (let* ((seconds (if (stringp time) (string-to-int time) time))
  1720.      (minutes (/ seconds 60))
  1721.      (seconds (if minutes (% seconds 60) seconds))
  1722.      (hours (/ minutes 60))
  1723.      (minutes (if hours (% minutes 60) minutes))
  1724.      (days (/ hours 24))
  1725.      (hours (if days (% hours 24) hours)))
  1726.     (format "%d%s %02d:%02d:%02d" days
  1727.         (if (= days 1) "st"
  1728.           (if (= days 2) "nd"
  1729.         (if (= days 3) "rd" "th")))
  1730.         hours minutes seconds)))
  1731.  
  1732.  
  1733. (defun irchat-msg-from-ignored (prefix chan msg)
  1734.   (save-excursion
  1735.     (let ((buf (current-buffer)))
  1736.       (set-buffer irchat-IGNORED-buffer)
  1737.       (goto-char (point-max))
  1738.       (insert (format "%s::%s %s\n" prefix chan msg))
  1739.       (set-buffer buf)
  1740.       t)))
  1741.  
  1742. (provide 'irchat-handle)
  1743.