* configure.ac: Generate lisp/riece-package-info.el.
[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., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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
258                             (concat (substring string (match-end 0)) " "))
259                       riece-353-message-alist))))))
260
261 (defun riece-handle-322-message (prefix number name decoded)
262   (let* ((parameters (riece-split-parameters (riece-decoded-string decoded)))
263          (channel (car parameters))
264          (visible (nth 1 parameters))
265          (channel-identity (riece-make-identity channel riece-server-name))
266          (buffer (riece-channel-buffer channel-identity))
267          topic)
268     (setq parameters (riece-split-parameters
269                       (riece-decoded-string-for-identity decoded
270                                                          channel-identity))
271           topic (nth 2 parameters))
272     (riece-channel-set-topic (riece-get-channel channel) topic)
273     (riece-insert-info buffer (concat visible " users, topic: " topic "\n"))
274     (riece-insert-info
275      (if (and riece-channel-buffer-mode
276               (not (eq buffer riece-channel-buffer)))
277          (list riece-dialogue-buffer riece-others-buffer)
278        riece-dialogue-buffer)
279      (concat
280       (riece-concat-server-name
281        (format "%s: %s users, topic: %s"
282                (riece-format-identity channel-identity t) visible topic))
283       "\n"))))
284
285 (defun riece-handle-324-message (prefix number name string)
286   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) " string)
287       (let* ((channel (match-string 1 string))
288              (mode-string (match-string 2 string)))
289         (riece-naming-assert-channel-modes channel
290                                            (riece-parse-modes mode-string))
291         (let* ((channel-identity (riece-make-identity channel
292                                                       riece-server-name))
293                (buffer (riece-channel-buffer channel-identity)))
294           (riece-insert-info buffer (concat "Mode: " mode-string "\n"))
295           (riece-insert-info
296            (if (and riece-channel-buffer-mode
297                     (not (eq buffer riece-channel-buffer)))
298                (list riece-dialogue-buffer riece-others-buffer)
299              riece-dialogue-buffer)
300            (concat
301             (riece-concat-server-name
302              (format "Mode for %s: %s"
303                      (riece-format-identity channel-identity t)
304                      mode-string))
305             "\n"))))))
306
307 (defun riece-handle-set-topic (prefix number name decoded remove)
308   (let* ((parameters (riece-split-parameters (riece-decoded-string decoded)))
309          (channel (car parameters))
310          topic
311          (channel-identity (riece-make-identity channel riece-server-name))
312          (buffer (riece-channel-buffer channel-identity)))
313     (if remove
314         (riece-channel-set-topic (riece-get-channel channel) nil)
315       (setq parameters (riece-split-parameters
316                         (riece-decoded-string-for-identity decoded
317                                                            channel-identity))
318             topic (nth 1 parameters))
319       (riece-channel-set-topic (riece-get-channel channel) topic)
320       (riece-insert-info buffer (concat "Topic: " topic "\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                  topic))
331         "\n")))
332     (riece-emit-signal 'channel-topic-changed channel-identity topic)))
333
334 (defun riece-handle-331-message (prefix number name string)
335   (riece-handle-set-topic prefix number name string t))
336
337 (defun riece-handle-332-message (prefix number name string)
338   (riece-handle-set-topic prefix number name string nil))
339
340 (defun riece-handle-341-message (prefix number name string)
341   (if (string-match "^\\([^ ]+\\) " string)
342       (let* ((channel (substring string (match-end 0)))
343              (user (match-string 1 string))
344              (channel-identity (riece-make-identity channel riece-server-name))
345              (buffer (riece-channel-buffer channel-identity)))
346         (riece-insert-info buffer (concat "Inviting " user "\n"))
347         (riece-insert-info
348          (if (and riece-channel-buffer-mode
349                   (not (eq buffer riece-channel-buffer)))
350              (list riece-dialogue-buffer riece-others-buffer)
351            riece-dialogue-buffer)
352          (concat
353           (riece-concat-server-name
354            (format "Inviting %s to %s" user
355                    (riece-format-identity channel-identity t)))
356           "\n")))))
357
358 (defun riece-handle-352-message (prefix number name string)
359   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([HG]\\)\\(\\*\\)?\\([@+]\\)? :\\([0-9]+\\) " string)
360       (let* ((channel (match-string 1 string))
361              (user (match-string 2 string))
362              (host (match-string 3 string))
363              (server (match-string 4 string))
364              (nick (match-string 5 string))
365              (away (equal (match-string 6 string) "G"))
366              (operator (not (null (match-beginning 7))))
367              (flag (match-string 8 string))
368              (hops (match-string 9 string))
369              (name (substring string (match-end 0)))
370              (buffer (riece-channel-buffer (riece-make-identity
371                                             channel riece-server-name)))
372              (info (format "%10s = %s (%s)"
373                            (concat
374                             (if (memq flag '(?@ ?+))
375                                 (char-to-string flag)
376                               " ")
377                             (riece-format-identity
378                              (riece-make-identity nick riece-server-name)
379                              t))
380                            name
381                            (riece-strip-user-at-host
382                             (concat user "@" host))))
383              status)
384         (if operator
385             (setq status (cons "operator" status)))
386         (if away
387             (setq status (cons "away" status)))
388         (unless (equal hops "0")
389           (setq status (cons (concat "on " server)
390                              (cons (concat hops " hops")
391                                    status))))
392         (if status
393             (setq status (nreverse status)))
394         (riece-naming-assert-join nick channel)
395         (riece-user-toggle-away user away)
396         (riece-emit-signal 'user-away-changed
397                            (riece-make-identity user riece-server-name)
398                            away)
399         (riece-user-toggle-operator user operator)
400         (riece-emit-signal 'user-operator-changed
401                            (riece-make-identity user riece-server-name)
402                            operator)
403         (riece-insert-info buffer (concat (riece-concat-user-status
404                                            status info)
405                                           "\n"))
406         (riece-insert-info
407          (if (and riece-channel-buffer-mode
408                   (not (eq buffer riece-channel-buffer)))
409              (list riece-dialogue-buffer riece-others-buffer)
410            riece-dialogue-buffer)
411          (concat
412           (riece-concat-server-name
413            (riece-concat-user-status
414             status
415             (concat
416              (riece-format-identity
417               (riece-make-identity channel riece-server-name)
418               t)
419              " "
420              info)))
421           "\n")))))
422
423 (defun riece-handle-315-message (prefix number name string))
424 (defun riece-handle-318-message (prefix number name string))
425 (defun riece-handle-323-message (prefix number name string))
426
427 (defun riece-handle-366-message (prefix number name string)
428   "RPL_ENDOFNAMES \"<channel> :End of NAMES list\""
429   (if (string-match "^\\([^ ]+\\) " string)
430       (let* ((channel (match-string 1 string))
431              (channel-identity (riece-make-identity channel
432                                                     riece-server-name))
433              (buffer (riece-channel-buffer channel-identity))
434              (entry (riece-identity-assoc channel riece-353-message-alist t))
435              (string (cdr entry))
436              (start 0)
437              users)
438         (if entry
439             (setq riece-353-message-alist
440                   (delq entry riece-353-message-alist)))
441         (while (string-match
442                 (concat "\\([@+]\\)?\\([^ ]+\\) +")
443                 string start)
444           (put-text-property (match-beginning 2) (match-end 2)
445                              'riece-identity
446                              (riece-make-identity (match-string 2 string)
447                                                   riece-server-name)
448                              string)
449           (setq start (match-end 0)
450                 users (cons (if (match-beginning 1)
451                                 (if (eq (aref string (match-beginning 1)) ?@)
452                                     (list (match-string 2 string) ?o)
453                                   (if (eq (aref string (match-beginning 1)) ?+)
454                                       (list (match-string 2 string) ?v)))
455                               (list (match-string 2 string)))
456                             users)))
457         (setq users (nreverse users))
458         (riece-naming-assert-channel-users users channel)
459         (riece-insert-info
460          buffer
461          (concat (format "%d users: " (length users)) string "\n"))
462         (riece-insert-info
463          (if (and riece-channel-buffer-mode
464                   (not (eq buffer riece-channel-buffer)))
465              (list riece-dialogue-buffer riece-others-buffer)
466            riece-dialogue-buffer)
467          (concat
468           (riece-concat-server-name
469            (concat (format "%d users on %s: "
470                            (length users)
471                            (riece-format-identity channel-identity t))
472                    string))
473           "\n")))))
474
475 (provide 'riece-300)
476
477 ;;; riece-300.el ends here