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