21ca8964ef3139d4ba9029991ffff61de0d72fcf
[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
29 (require 'riece-filter)                 ;riece-default-handle-message
30
31 (eval-when-compile
32   (autoload 'riece-default-handle-numeric-reply "riece-filter"))
33 (defun riece-handle-default-300-message (prefix number name string)
34   (riece-default-handle-numeric-reply
35    riece-info-prefix prefix number name string))
36
37 (defun riece-handle-302-message (prefix number name string)
38   "RPL_USERHOST \":*1<reply> *( \" \" <reply> )\""
39   (let ((replies (split-string (substring string 1) " ")))
40     (while replies
41       (if (string-match
42            (concat "^\\(" riece-user-regexp
43                    "\\)\\(\\*\\)?=\\([-+]\\)\\([^ ]+\\)")
44            (car replies))
45           (let ((user (match-string 1 (car replies)))
46                 (operator (not (null (match-beginning 2))))
47                 (away (eq (match-string 3 (car replies)) ?-))
48                 (user-at-host (match-string 4 (car replies)))
49                 status)
50             (if away
51                 (setq status (cons "away" status)))
52             (if operator
53                 (setq status (cons "operator" status)))
54             (riece-user-toggle-away user away)
55             (riece-emit-signal 'user-away-changed
56                                (riece-make-identity user riece-server-name)
57                                away)
58             (riece-user-toggle-operator user operator)
59             (riece-emit-signal 'user-operator-changed
60                                (riece-make-identity user riece-server-name)
61                                operator)
62             (riece-insert-info
63              (list riece-dialogue-buffer riece-others-buffer)
64              (concat
65               (riece-concat-server-name
66                (riece-concat-user-status
67                 status
68                 (format "%s is (%s)"
69                         (riece-format-identity
70                          (riece-make-identity user riece-server-name)
71                          t)
72                         (riece-strip-user-at-host user-at-host))))
73               "\n"))))
74       (setq replies (cdr replies)))))
75
76 (defun riece-handle-303-message (prefix number name string)
77   (riece-insert-info
78    (list riece-dialogue-buffer riece-others-buffer)
79    (concat
80     (riece-concat-server-name
81      (concat "Online: "
82              (mapconcat
83               (lambda (user)
84                 (riece-format-identity
85                  (riece-make-identity user riece-server-name)
86                  t))
87               (split-string (substring string 1) " ")
88               "")))
89     "\n")))
90
91 (defun riece-handle-301-message (prefix number name string)
92   (if (string-match (concat "^\\(" riece-user-regexp "\\) :") string)
93       (let ((user (match-string 1 string))
94             (message (substring string (match-end 0))))
95         (riece-user-toggle-away user t)
96         (riece-emit-signal 'user-away-changed
97                            (riece-make-identity user riece-server-name)
98                            t)
99         (riece-insert-info
100          (list riece-dialogue-buffer riece-others-buffer)
101          (concat
102           (riece-concat-server-name
103            (format "%s is away: %s"
104                    (riece-format-identity
105                     (riece-make-identity user riece-server-name)
106                     t)
107                    message))
108           "\n")))))
109
110 (defun riece-handle-305-message (prefix number name string)
111   (riece-user-toggle-away riece-real-nickname nil)
112   (riece-emit-signal 'user-away-changed
113                       (riece-make-identity riece-real-nickname
114                                            riece-server-name)
115                       nil))
116
117 (defun riece-handle-306-message (prefix number name string)
118   (riece-user-toggle-away riece-real-nickname t)
119   (riece-emit-signal 'user-away-changed
120                      (riece-make-identity riece-real-nickname
121                                           riece-server-name)
122                      t))
123
124 (defun riece-handle-311-message (prefix number name string)
125   (if (string-match
126        (concat "^\\(" riece-user-regexp
127                "\\) \\([^ ]+\\) \\([^ ]+\\) \\* :")
128        string)
129       (let ((user (match-string 1 string))
130             (name (substring string (match-end 0)))
131             (user-at-host (concat (match-string 2 string) "@"
132                                   (match-string 3 string))))
133         (riece-insert-info
134          (list riece-dialogue-buffer riece-others-buffer)
135          (concat
136           (riece-concat-server-name
137            (format "%s is %s (%s)"
138                    (riece-format-identity
139                     (riece-make-identity user riece-server-name)
140                     t)
141                    name
142                    user-at-host))
143           "\n")))))
144
145 (defun riece-handle-312-message (prefix number name string)
146   (if (string-match
147        (concat "^\\(" riece-user-regexp "\\) \\([^ ]+\\) :")
148        string)
149       (riece-insert-info
150        (list riece-dialogue-buffer riece-others-buffer)
151        (concat
152         (riece-concat-server-name
153          (format "on via server %s: %s"
154                  riece-real-server-name
155                  (substring string (match-end 0))))
156         "\n"))))
157
158 (defun riece-handle-313-message (prefix number name string)
159   (if (string-match (concat "^" riece-user-regexp) string)
160       (let ((user (match-string 0 string)))
161         (riece-insert-info
162          (list riece-dialogue-buffer riece-others-buffer)
163          (concat
164           (riece-concat-server-name
165            (concat (riece-format-identity
166                     (riece-make-identity user riece-server-name)
167                     t)
168                    " is an IRC operator"))
169           "\n")))))
170
171 (defun riece-handle-317-message (prefix number name string)
172   (if (string-match
173        (concat "^\\(" riece-user-regexp "\\) \\([0-9]+\\) [^:]*:seconds")
174        string)
175       (let ((user (match-string 1 string))
176             (idle (match-string 2 string)))
177         (riece-insert-info
178          (list riece-dialogue-buffer riece-others-buffer)
179          (concat
180           (riece-concat-server-name
181            (format "%s is %s seconds idle"
182                    (riece-format-identity
183                     (riece-make-identity user riece-server-name)
184                     t)
185                    idle))
186           "\n")))))
187
188 (defun riece-handle-319-message (prefix number name string)
189   (if (string-match (concat "^\\(" riece-user-regexp "\\) :") string)
190       (let ((user (match-string 1 string))
191             (channels
192              (mapconcat
193               (lambda (channel)
194                 (if (string-match
195                      (concat "^\\([@+]?\\)\\(" riece-channel-regexp "\\)")
196                      channel)
197                     (concat
198                      (match-string 1 channel)
199                      (riece-format-identity
200                       (riece-make-identity (match-string 2 channel)
201                                            riece-server-name)
202                       t))))
203               (split-string (substring string (match-end 0)) " ")
204               " ")))
205         (riece-insert-info
206          (list riece-dialogue-buffer riece-others-buffer)
207          (concat
208           (riece-concat-server-name
209            (format "%s: %s"
210                    (riece-format-identity
211                     (riece-make-identity user riece-server-name)
212                     t)
213                    channels))
214           "\n")))))
215
216 (defun riece-handle-351-message (prefix number name string)
217   (if (string-match "\\([^ ]+\\.[^ ]+\\) \\([^ ]+\\) :" string)
218       (riece-insert-info
219        (list riece-dialogue-buffer riece-others-buffer)
220        (concat
221         (riece-concat-server-name
222          (format "%s is running on %s: %s"
223                  (match-string 1 string)
224                  (match-string 2 string)
225                  (substring string (match-end 0))))
226         "\n"))))
227
228 (defun riece-handle-353-message (prefix number name string)
229   "RPL_NAMREPLY \"<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]\"."
230   (if (string-match "^[=\*@] *\\([^ ]+\\) +:" string)
231       (let ((channel (match-string 1 string))
232             (start 0)
233             user users)
234         (setq string (substring string (match-end 0)))
235         (while (string-match
236                 (concat "\\([@+]\\)?\\(" riece-user-regexp "\\) *")
237                 string start)
238           (put-text-property (match-beginning 2) (match-end 2)
239                              'riece-identity
240                              (riece-make-identity (match-string 2 string)
241                                                   riece-server-name)
242                              string)
243           (setq start (match-end 0)
244                 user (if (match-beginning 1)
245                          (if (eq (aref string (match-beginning 1)) ?@)
246                              (list (match-string 2 string) ?o)
247                            (if (eq (aref string (match-beginning 1)) ?+)
248                                (list (match-string 2 string) ?v)))
249                        (list (match-string 2 string)))
250                 users (cons user users)))
251         (riece-naming-assert-channel-users (nreverse users) channel)
252         (let* ((channel-identity (riece-make-identity channel
253                                                       riece-server-name))
254                (buffer (riece-channel-buffer channel-identity)))
255           (riece-insert-info buffer (concat "Users: " string "\n"))
256           (riece-insert-info
257            (if (and riece-channel-buffer-mode
258                     (not (eq buffer riece-channel-buffer)))
259                (list riece-dialogue-buffer riece-others-buffer)
260              riece-dialogue-buffer)
261            (concat
262             (riece-concat-server-name
263              (format "Users on %s: %s"
264                      (riece-format-identity channel-identity t) string))
265             "\n"))))))
266
267 (defun riece-handle-322-message (prefix number name string)
268   (if (string-match "^\\([^ ]+\\) \\([0-9]+\\) :" string)
269       (let* ((channel (match-string 1 string))
270              (visible (match-string 2 string))
271              (topic (substring string (match-end 0))))
272         (riece-channel-set-topic (riece-get-channel channel) topic)
273         (let* ((channel-identity (riece-make-identity channel
274                                                       riece-server-name))
275                (buffer (riece-channel-buffer channel-identity)))
276           (riece-insert-info buffer (concat visible " users, topic: "
277                                             topic "\n"))
278           (riece-insert-info
279            (if (and riece-channel-buffer-mode
280                     (not (eq buffer riece-channel-buffer)))
281                (list riece-dialogue-buffer riece-others-buffer)
282              riece-dialogue-buffer)
283            (concat
284             (riece-concat-server-name
285              (format "%s: %s users, topic: %s"
286                      (riece-format-identity channel-identity t) visible topic))
287             "\n"))))))
288
289 (defun riece-handle-324-message (prefix number name string)
290   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) " string)
291       (let* ((channel (match-string 1 string))
292              (mode-string (match-string 2 string)))
293         (riece-naming-assert-channel-modes channel
294                                            (riece-parse-modes mode-string))
295         (let* ((channel-identity (riece-make-identity channel
296                                                       riece-server-name))
297                (buffer (riece-channel-buffer channel-identity)))
298           (riece-insert-info buffer (concat "Mode: " mode-string "\n"))
299           (riece-insert-info
300            (if (and riece-channel-buffer-mode
301                     (not (eq buffer riece-channel-buffer)))
302                (list riece-dialogue-buffer riece-others-buffer)
303              riece-dialogue-buffer)
304            (concat
305             (riece-concat-server-name
306              (format "Mode for %s: %s"
307                      (riece-format-identity channel-identity t)
308                      mode-string))
309             "\n"))))))
310
311 (defun riece-handle-set-topic (prefix number name string remove)
312   (if (string-match "^\\([^ ]+\\) :" string)
313       (let* ((channel (match-string 1 string))
314              (message (substring string (match-end 0)))
315              (channel-identity (riece-make-identity channel riece-server-name))
316              (buffer (riece-channel-buffer channel-identity)))
317         (if remove
318             (riece-channel-set-topic (riece-get-channel channel) nil)
319           (riece-channel-set-topic (riece-get-channel channel) message)
320           (riece-insert-info buffer (concat "Topic: " message "\n"))
321           (riece-insert-info
322            (if (and riece-channel-buffer-mode
323                     (not (eq buffer riece-channel-buffer)))
324                (list riece-dialogue-buffer riece-others-buffer)
325              riece-dialogue-buffer)
326            (concat
327             (riece-concat-server-name
328              (format "Topic for %s: %s"
329                      (riece-format-identity channel-identity t)
330                      message))
331             "\n")))
332         (riece-emit-signal 'channel-topic-changed
333                             channel-identity
334                             (unless remove
335                               message)))))
336
337 (defun riece-handle-331-message (prefix number name string)
338   (riece-handle-set-topic prefix number name string t))
339
340 (defun riece-handle-332-message (prefix number name string)
341   (riece-handle-set-topic prefix number name string nil))
342
343 (defun riece-handle-341-message (prefix number name string)
344   (if (string-match "^\\([^ ]+\\) " string)
345       (let* ((channel (match-string 1 string))
346              (user (substring string (match-end 0)))
347              (channel-identity (riece-make-identity channel riece-server-name))
348              (buffer (riece-channel-buffer channel-identity)))
349         (riece-insert-info buffer (concat "Inviting " user "\n"))
350         (riece-insert-info
351          (if (and riece-channel-buffer-mode
352                   (not (eq buffer riece-channel-buffer)))
353              (list riece-dialogue-buffer riece-others-buffer)
354            riece-dialogue-buffer)
355          (concat
356           (riece-concat-server-name
357            (format "Inviting %s to %s" user
358                    (riece-format-identity channel-identity t)))
359           "\n")))))
360
361 (defun riece-handle-352-message (prefix number name string)
362   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([HG]\\)\\(\\*\\)?\\([@+]\\)? :\\([0-9]+\\) " string)
363       (let* ((channel (match-string 1 string))
364              (user (match-string 2 string))
365              (host (match-string 3 string))
366              (server (match-string 4 string))
367              (nick (match-string 5 string))
368              (away (equal (match-string 6 string) "G"))
369              (operator (not (null (match-beginning 7))))
370              (flag (match-string 8 string))
371              (hops (match-string 9 string))
372              (name (substring string (match-end 0)))
373              (buffer (riece-channel-buffer (riece-make-identity
374                                             channel riece-server-name)))
375              (info (format "%10s = %s (%s)"
376                            (concat
377                             (if (memq flag '(?@ ?+))
378                                 (char-to-string flag)
379                               " ")
380                             (riece-format-identity
381                              (riece-make-identity nick riece-server-name)
382                              t))
383                            name
384                            (riece-strip-user-at-host
385                             (concat user "@" host))))
386              status)
387         (if operator
388             (setq status (cons "operator" status)))
389         (if away
390             (setq status (cons "away" status)))
391         (unless (equal hops "0")
392           (setq status (cons (concat "on " server)
393                              (cons (concat hops " hops")
394                                    status))))
395         (if status
396             (setq status (nreverse status)))
397         (riece-naming-assert-join nick channel)
398         (riece-user-toggle-away user away)
399         (riece-emit-signal 'user-away-changed
400                            (riece-make-identity user riece-server-name)
401                            away)
402         (riece-user-toggle-operator user operator)
403         (riece-emit-signal 'user-operator-changed
404                            (riece-make-identity user riece-server-name)
405                            operator)
406         (riece-insert-info buffer (concat (riece-concat-user-status
407                                            status info)
408                                           "\n"))
409         (riece-insert-info
410          (if (and riece-channel-buffer-mode
411                   (not (eq buffer riece-channel-buffer)))
412              (list riece-dialogue-buffer riece-others-buffer)
413            riece-dialogue-buffer)
414          (concat
415           (riece-concat-server-name
416            (riece-concat-user-status
417             status
418             (concat
419              (riece-format-identity
420               (riece-make-identity channel riece-server-name)
421               t)
422              " "
423              info)))
424           "\n")))))
425
426 (defun riece-handle-315-message (prefix number name string))
427 (defun riece-handle-318-message (prefix number name string))
428 (defun riece-handle-323-message (prefix number name string))
429 (defun riece-handle-366-message (prefix number name string))
430
431 (provide 'riece-300)
432
433 ;;; riece-300.el ends here