Renamed.
[riece] / lisp / riece-300.el
1 ;;; riece-300.el --- handlers for 300 replies
2 ;; Copyright (C) 1998-2003 Daiki Ueno
3
4 ;; Author: Daiki Ueno <ueno@unixuser.org>
5 ;; Created: 1998-09-28
6 ;; Keywords: IRC, riece
7
8 ;; This file is part of Riece.
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Code:
26
27 (require 'riece-misc)
28 (require 'riece-naming)
29 (require 'riece-signal)
30 (require 'riece-display)
31
32 (eval-when-compile
33   (autoload 'riece-default-handle-numeric-reply "riece-handle"))
34 (defun riece-handle-default-300-message (prefix number name string)
35   (riece-default-handle-numeric-reply
36    riece-info-prefix prefix number name string))
37
38 (defun riece-handle-302-message (prefix number name string)
39   "RPL_USERHOST \":*1<reply> *( \" \" <reply> )\""
40   (let ((replies (split-string (if (eq (aref string 0) ?:)
41                                    (substring string 1)
42                                  string)
43                                " ")))
44     (while replies
45       (if (string-match
46            (concat "^\\([^ ]+\\)\\(\\*\\)?=\\([-+]\\)\\([^ ]+\\)")
47            (car replies))
48           (let ((user (match-string 1 (car replies)))
49                 (operator (not (null (match-beginning 2))))
50                 (away (eq (match-string 3 (car replies)) ?-))
51                 (user-at-host (match-string 4 (car replies)))
52                 status)
53             (if away
54                 (setq status (cons "away" status)))
55             (if operator
56                 (setq status (cons "operator" status)))
57             (riece-user-toggle-away user away)
58             (riece-emit-signal 'user-away-changed
59                                (riece-make-identity user riece-server-name)
60                                away)
61             (riece-user-toggle-operator user operator)
62             (riece-emit-signal 'user-operator-changed
63                                (riece-make-identity user riece-server-name)
64                                operator)
65             (riece-insert-info
66              (list riece-dialogue-buffer riece-others-buffer)
67              (concat
68               (riece-concat-server-name
69                (riece-concat-user-status
70                 status
71                 (format "%s is (%s)"
72                         (riece-format-identity
73                          (riece-make-identity user riece-server-name)
74                          t)
75                         (riece-strip-user-at-host user-at-host))))
76               "\n"))))
77       (setq replies (cdr replies)))))
78
79 (defun riece-handle-303-message (prefix number name string)
80   (riece-insert-info
81    (list riece-dialogue-buffer riece-others-buffer)
82    (concat
83     (riece-concat-server-name
84      (concat "Online: "
85              (mapconcat
86               (lambda (user)
87                 (riece-format-identity
88                  (riece-make-identity user riece-server-name)
89                  t))
90               (split-string (if (eq (aref string 0) ?:)
91                                 (substring string 1)
92                               string)
93                             " ")
94               "")))
95     "\n")))
96
97 (defun riece-handle-301-message (prefix number name string)
98   (if (string-match (concat "^\\([^ ]+\\) :?") string)
99       (let ((user (match-string 1 string))
100             (message (substring string (match-end 0))))
101         (riece-user-toggle-away user t)
102         (riece-emit-signal 'user-away-changed
103                            (riece-make-identity user riece-server-name)
104                            t)
105         (riece-insert-info
106          (list riece-dialogue-buffer riece-others-buffer)
107          (concat
108           (riece-concat-server-name
109            (format "%s is away: %s"
110                    (riece-format-identity
111                     (riece-make-identity user riece-server-name)
112                     t)
113                    message))
114           "\n")))))
115
116 (defun riece-handle-305-message (prefix number name string)
117   (riece-user-toggle-away riece-real-nickname nil)
118   (riece-emit-signal 'user-away-changed
119                       (riece-make-identity riece-real-nickname
120                                            riece-server-name)
121                       nil))
122
123 (defun riece-handle-306-message (prefix number name string)
124   (riece-user-toggle-away riece-real-nickname t)
125   (riece-emit-signal 'user-away-changed
126                      (riece-make-identity riece-real-nickname
127                                           riece-server-name)
128                      t))
129
130 (defun riece-handle-311-message (prefix number name string)
131   (if (string-match
132        (concat "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\* :?")
133        string)
134       (let ((user (match-string 1 string))
135             (name (substring string (match-end 0)))
136             (user-at-host (concat (match-string 2 string) "@"
137                                   (match-string 3 string))))
138         (riece-insert-info
139          (list riece-dialogue-buffer riece-others-buffer)
140          (concat
141           (riece-concat-server-name
142            (format "%s is %s (%s)"
143                    (riece-format-identity
144                     (riece-make-identity user riece-server-name)
145                     t)
146                    name
147                    user-at-host))
148           "\n")))))
149
150 (defun riece-handle-312-message (prefix number name string)
151   (if (string-match
152        (concat "^\\([^ ]+\\) \\([^ ]+\\) :?")
153        string)
154       (riece-insert-info
155        (list riece-dialogue-buffer riece-others-buffer)
156        (concat
157         (riece-concat-server-name
158          (format "on via server %s: %s"
159                  (match-string 2 string)
160                  (substring string (match-end 0))))
161         "\n"))))
162
163 (defun riece-handle-313-message (prefix number name string)
164   (if (string-match "^[^ ]+" string)
165       (let ((user (match-string 0 string)))
166         (riece-insert-info
167          (list riece-dialogue-buffer riece-others-buffer)
168          (concat
169           (riece-concat-server-name
170            (concat (riece-format-identity
171                     (riece-make-identity user riece-server-name)
172                     t)
173                    " is an IRC operator"))
174           "\n")))))
175
176 (defun riece-handle-317-message (prefix number name string)
177   (if (string-match
178        (concat "^\\([^ ]+\\) \\([0-9]+\\) ")
179        string)
180       (let* ((user (match-string 1 string))
181              (seconds (string-to-number (match-string 2 string)))
182              (units (list (cons (/ seconds 60 60 24) "days")
183                           (cons (mod (/ seconds 60 60) 24) "hours")
184                           (cons (mod (/ seconds 60) 60) "minutes")
185                           (cons (mod seconds 60) "seconds"))))
186         (riece-insert-info
187          (list riece-dialogue-buffer riece-others-buffer)
188          (concat
189           (riece-concat-server-name
190            (format "%s is %s idle"
191                    (riece-format-identity
192                     (riece-make-identity user riece-server-name)
193                     t)
194                    (mapconcat #'identity
195                               (delq nil
196                                     (mapcar
197                                      (lambda (unit)
198                                        (if (/= (car unit) 0)
199                                            (format "%d %s"
200                                                    (car unit) (cdr unit))))
201                                      units))
202                               " ")))
203           "\n")))))
204
205 (defun riece-handle-319-message (prefix number name string)
206   (if (string-match (concat "^\\([^ ]+\\) :?") string)
207       (let ((user (match-string 1 string))
208             (channels
209              (mapconcat
210               (lambda (channel)
211                 (if (string-match
212                      (concat "^\\([@+]?\\)\\(" riece-channel-regexp "\\)")
213                      channel)
214                     (concat
215                      (match-string 1 channel)
216                      (riece-format-identity
217                       (riece-make-identity (match-string 2 channel)
218                                            riece-server-name)
219                       t))))
220               (split-string (substring string (match-end 0)) " ")
221               " ")))
222         (riece-insert-info
223          (list riece-dialogue-buffer riece-others-buffer)
224          (concat
225           (riece-concat-server-name
226            (format "%s: %s"
227                    (riece-format-identity
228                     (riece-make-identity user riece-server-name)
229                     t)
230                    channels))
231           "\n")))))
232
233 (defun riece-handle-351-message (prefix number name string)
234   (if (string-match "\\([^ ]+\\.[^ ]+\\) \\([^ ]+\\) :?" string)
235       (riece-insert-info
236        (list riece-dialogue-buffer riece-others-buffer)
237        (concat
238         (riece-concat-server-name
239          (format "%s is running on %s: %s"
240                  (match-string 1 string)
241                  (match-string 2 string)
242                  (substring string (match-end 0))))
243         "\n"))))
244
245 (defvar riece-353-message-alist nil)
246 (defun riece-handle-353-message (prefix number name string)
247   "RPL_NAMREPLY \"[=\*@] <channel> :[[@|+]<nick> [[@|+]<nick> [...]]]\"."
248   (make-local-variable 'riece-353-message-alist)      
249   (if (string-match "^[=\*@] *\\([^ ]+\\) +:?" string)
250       (let* ((channel (match-string 1 string))
251              (entry (riece-identity-assoc channel riece-353-message-alist t)))
252         (if entry
253             (setcdr entry
254                     (concat (cdr entry)
255                             (substring string (match-end 0))))
256           (setq riece-353-message-alist
257                 (cons (cons channel (substring string (match-end 0)))
258                       riece-353-message-alist))))))
259
260 (defun riece-handle-322-message (prefix number name decoded)
261   (let* ((parameters (riece-split-parameters (riece-decoded-string decoded)))
262          (channel (car parameters))
263          (visible (nth 1 parameters))
264          (channel-identity (riece-make-identity channel riece-server-name))
265          (buffer (riece-channel-buffer channel-identity))
266          topic)
267     (setq parameters (riece-split-parameters
268                       (riece-decoded-string-for-identity decoded
269                                                          channel-identity))
270           topic (nth 1 parameters))
271     (riece-channel-set-topic (riece-get-channel channel) topic)
272     (riece-insert-info buffer (concat visible " users, topic: " topic "\n"))
273     (riece-insert-info
274      (if (and riece-channel-buffer-mode
275               (not (eq buffer riece-channel-buffer)))
276          (list riece-dialogue-buffer riece-others-buffer)
277        riece-dialogue-buffer)
278      (concat
279       (riece-concat-server-name
280        (format "%s: %s users, topic: %s"
281                (riece-format-identity channel-identity t) visible topic))
282       "\n"))))
283
284 (defun riece-handle-324-message (prefix number name string)
285   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) " string)
286       (let* ((channel (match-string 1 string))
287              (mode-string (match-string 2 string)))
288         (riece-naming-assert-channel-modes channel
289                                            (riece-parse-modes mode-string))
290         (let* ((channel-identity (riece-make-identity channel
291                                                       riece-server-name))
292                (buffer (riece-channel-buffer channel-identity)))
293           (riece-insert-info buffer (concat "Mode: " mode-string "\n"))
294           (riece-insert-info
295            (if (and riece-channel-buffer-mode
296                     (not (eq buffer riece-channel-buffer)))
297                (list riece-dialogue-buffer riece-others-buffer)
298              riece-dialogue-buffer)
299            (concat
300             (riece-concat-server-name
301              (format "Mode for %s: %s"
302                      (riece-format-identity channel-identity t)
303                      mode-string))
304             "\n"))))))
305
306 (defun riece-handle-set-topic (prefix number name decoded remove)
307   (let* ((parameters (riece-split-parameters (riece-decoded-string decoded)))
308          (channel (car parameters))
309          topic
310          (channel-identity (riece-make-identity channel riece-server-name))
311          (buffer (riece-channel-buffer channel-identity)))
312     (if remove
313         (riece-channel-set-topic (riece-get-channel channel) nil)
314       (setq parameters (riece-split-parameters
315                         (riece-decoded-string-for-identity decoded
316                                                            channel-identity))
317             topic (nth 1 parameters))
318       (riece-channel-set-topic (riece-get-channel channel) topic)
319       (riece-insert-info buffer (concat "Topic: " topic "\n"))
320       (riece-insert-info
321        (if (and riece-channel-buffer-mode
322                 (not (eq buffer riece-channel-buffer)))
323            (list riece-dialogue-buffer riece-others-buffer)
324          riece-dialogue-buffer)
325        (concat
326         (riece-concat-server-name
327          (format "Topic for %s: %s"
328                  (riece-format-identity channel-identity t)
329                  topic))
330         "\n")))
331     (riece-emit-signal 'channel-topic-changed channel-identity topic)))
332
333 (defun riece-handle-331-message (prefix number name string)
334   (riece-handle-set-topic prefix number name string t))
335
336 (defun riece-handle-332-message (prefix number name string)
337   (riece-handle-set-topic prefix number name string nil))
338
339 (defun riece-handle-341-message (prefix number name string)
340   (if (string-match "^\\([^ ]+\\) " string)
341       (let* ((channel (match-string 1 string))
342              (user (substring string (match-end 0)))
343              (channel-identity (riece-make-identity channel riece-server-name))
344              (buffer (riece-channel-buffer channel-identity)))
345         (riece-insert-info buffer (concat "Inviting " user "\n"))
346         (riece-insert-info
347          (if (and riece-channel-buffer-mode
348                   (not (eq buffer riece-channel-buffer)))
349              (list riece-dialogue-buffer riece-others-buffer)
350            riece-dialogue-buffer)
351          (concat
352           (riece-concat-server-name
353            (format "Inviting %s to %s" user
354                    (riece-format-identity channel-identity t)))
355           "\n")))))
356
357 (defun riece-handle-352-message (prefix number name string)
358   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([HG]\\)\\(\\*\\)?\\([@+]\\)? :\\([0-9]+\\) " string)
359       (let* ((channel (match-string 1 string))
360              (user (match-string 2 string))
361              (host (match-string 3 string))
362              (server (match-string 4 string))
363              (nick (match-string 5 string))
364              (away (equal (match-string 6 string) "G"))
365              (operator (not (null (match-beginning 7))))
366              (flag (match-string 8 string))
367              (hops (match-string 9 string))
368              (name (substring string (match-end 0)))
369              (buffer (riece-channel-buffer (riece-make-identity
370                                             channel riece-server-name)))
371              (info (format "%10s = %s (%s)"
372                            (concat
373                             (if (memq flag '(?@ ?+))
374                                 (char-to-string flag)
375                               " ")
376                             (riece-format-identity
377                              (riece-make-identity nick riece-server-name)
378                              t))
379                            name
380                            (riece-strip-user-at-host
381                             (concat user "@" host))))
382              status)
383         (if operator
384             (setq status (cons "operator" status)))
385         (if away
386             (setq status (cons "away" status)))
387         (unless (equal hops "0")
388           (setq status (cons (concat "on " server)
389                              (cons (concat hops " hops")
390                                    status))))
391         (if status
392             (setq status (nreverse status)))
393         (riece-naming-assert-join nick channel)
394         (riece-user-toggle-away user away)
395         (riece-emit-signal 'user-away-changed
396                            (riece-make-identity user riece-server-name)
397                            away)
398         (riece-user-toggle-operator user operator)
399         (riece-emit-signal 'user-operator-changed
400                            (riece-make-identity user riece-server-name)
401                            operator)
402         (riece-insert-info buffer (concat (riece-concat-user-status
403                                            status info)
404                                           "\n"))
405         (riece-insert-info
406          (if (and riece-channel-buffer-mode
407                   (not (eq buffer riece-channel-buffer)))
408              (list riece-dialogue-buffer riece-others-buffer)
409            riece-dialogue-buffer)
410          (concat
411           (riece-concat-server-name
412            (riece-concat-user-status
413             status
414             (concat
415              (riece-format-identity
416               (riece-make-identity channel riece-server-name)
417               t)
418              " "
419              info)))
420           "\n")))))
421
422 (defun riece-handle-315-message (prefix number name string))
423 (defun riece-handle-318-message (prefix number name string))
424 (defun riece-handle-323-message (prefix number name string))
425
426 (defun riece-handle-366-message (prefix number name string)
427   "RPL_ENDOFNAMES \"<channel> :End of NAMES list\""
428   (if (string-match "^\\([^ ]+\\) " string)
429       (let* ((channel (match-string 1 string))
430              (channel-identity (riece-make-identity channel
431                                                     riece-server-name))
432              (buffer (riece-channel-buffer channel-identity))
433              (entry (riece-identity-assoc channel riece-353-message-alist t))
434              (string (cdr entry))
435              (start 0)
436              users)
437         (if entry
438             (setq riece-353-message-alist
439                   (delq entry riece-353-message-alist)))
440         (while (string-match
441                 (concat "\\([@+]\\)?\\([^ ]+\\) *")
442                 string start)
443           (put-text-property (match-beginning 2) (match-end 2)
444                              'riece-identity
445                              (riece-make-identity (match-string 2 string)
446                                                   riece-server-name)
447                              string)
448           (setq start (match-end 0)
449                 users (cons (if (match-beginning 1)
450                                 (if (eq (aref string (match-beginning 1)) ?@)
451                                     (list (match-string 2 string) ?o)
452                                   (if (eq (aref string (match-beginning 1)) ?+)
453                                       (list (match-string 2 string) ?v)))
454                               (list (match-string 2 string)))
455                             users)))
456         (setq users (nreverse users))
457         (riece-naming-assert-channel-users users channel)
458         (riece-insert-info
459          buffer
460          (concat (format "%d users: " (length users)) string "\n"))
461         (riece-insert-info
462          (if (and riece-channel-buffer-mode
463                   (not (eq buffer riece-channel-buffer)))
464              (list riece-dialogue-buffer riece-others-buffer)
465            riece-dialogue-buffer)
466          (concat
467           (riece-concat-server-name
468            (concat (format "%d users on %s: "
469                            (length users)
470                            (riece-format-identity channel-identity t))
471                    string))
472           "\n")))))
473
474 (provide 'riece-300)
475
476 ;;; riece-300.el ends here