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