* rubyserv.rb: New file.
[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 (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 "^\\([^ ]+\\) :?") 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 "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\* :?")
131        string)
132       (let ((user (match-string 1 string))
133             (name (substring string (match-end 0)))
134             (user-at-host (concat (match-string 2 string) "@"
135                                   (match-string 3 string))))
136         (riece-insert-info
137          (list riece-dialogue-buffer riece-others-buffer)
138          (concat
139           (riece-concat-server-name
140            (format "%s is %s (%s)"
141                    (riece-format-identity
142                     (riece-make-identity user riece-server-name)
143                     t)
144                    name
145                    user-at-host))
146           "\n")))))
147
148 (defun riece-handle-312-message (prefix number name string)
149   (if (string-match
150        (concat "^\\([^ ]+\\) \\([^ ]+\\) :?")
151        string)
152       (riece-insert-info
153        (list riece-dialogue-buffer riece-others-buffer)
154        (concat
155         (riece-concat-server-name
156          (format "on via server %s: %s"
157                  (match-string 2 string)
158                  (substring string (match-end 0))))
159         "\n"))))
160
161 (defun riece-handle-313-message (prefix number name string)
162   (if (string-match (concat "^" riece-user-regexp) string)
163       (let ((user (match-string 0 string)))
164         (riece-insert-info
165          (list riece-dialogue-buffer riece-others-buffer)
166          (concat
167           (riece-concat-server-name
168            (concat (riece-format-identity
169                     (riece-make-identity user riece-server-name)
170                     t)
171                    " is an IRC operator"))
172           "\n")))))
173
174 (defun riece-handle-317-message (prefix number name string)
175   (if (string-match
176        (concat "^\\([^ ]+\\) \\([0-9]+\\) ")
177        string)
178       (let* ((user (match-string 1 string))
179              (seconds (string-to-number (match-string 2 string)))
180              (units (list (cons (/ seconds 60 60 24) "days")
181                           (cons (mod (/ seconds 60 60) 24) "hours")
182                           (cons (mod (/ seconds 60) 60) "minutes")
183                           (cons (mod seconds 60) "seconds"))))
184         (riece-insert-info
185          (list riece-dialogue-buffer riece-others-buffer)
186          (concat
187           (riece-concat-server-name
188            (format "%s is %s idle"
189                    (riece-format-identity
190                     (riece-make-identity user riece-server-name)
191                     t)
192                    (mapconcat #'identity
193                               (delq nil
194                                     (mapcar
195                                      (lambda (unit)
196                                        (if (/= (car unit) 0)
197                                            (format "%d %s"
198                                                    (car unit) (cdr unit))))
199                                      units))
200                               " ")))
201           "\n")))))
202
203 (defun riece-handle-319-message (prefix number name string)
204   (if (string-match (concat "^\\([^ ]+\\) :?") string)
205       (let ((user (match-string 1 string))
206             (channels
207              (mapconcat
208               (lambda (channel)
209                 (if (string-match
210                      (concat "^\\([@+]?\\)\\(" riece-channel-regexp "\\)")
211                      channel)
212                     (concat
213                      (match-string 1 channel)
214                      (riece-format-identity
215                       (riece-make-identity (match-string 2 channel)
216                                            riece-server-name)
217                       t))))
218               (split-string (substring string (match-end 0)) " ")
219               " ")))
220         (riece-insert-info
221          (list riece-dialogue-buffer riece-others-buffer)
222          (concat
223           (riece-concat-server-name
224            (format "%s: %s"
225                    (riece-format-identity
226                     (riece-make-identity user riece-server-name)
227                     t)
228                    channels))
229           "\n")))))
230
231 (defun riece-handle-351-message (prefix number name string)
232   (if (string-match "\\([^ ]+\\.[^ ]+\\) \\([^ ]+\\) :?" string)
233       (riece-insert-info
234        (list riece-dialogue-buffer riece-others-buffer)
235        (concat
236         (riece-concat-server-name
237          (format "%s is running on %s: %s"
238                  (match-string 1 string)
239                  (match-string 2 string)
240                  (substring string (match-end 0))))
241         "\n"))))
242
243 (defvar riece-353-message-alist nil)
244 (defun riece-handle-353-message (prefix number name string)
245   "RPL_NAMREPLY \"[=\*@] <channel> :[[@|+]<nick> [[@|+]<nick> [...]]]\"."
246   (make-local-variable 'riece-353-message-alist)      
247   (if (string-match "^[=\*@] *\\([^ ]+\\) +:?" string)
248       (let* ((channel (match-string 1 string))
249              (entry (riece-identity-assoc channel riece-353-message-alist t)))
250         (if entry
251             (setcdr entry
252                     (concat (cdr entry)
253                             (substring string (match-end 0))))
254           (setq riece-353-message-alist
255                 (cons (cons channel (substring string (match-end 0)))
256                       riece-353-message-alist))))))
257
258 (defun riece-handle-322-message (prefix number name string)
259   (if (string-match "^\\([^ ]+\\) \\([0-9]+\\) :?" string)
260       (let* ((channel (match-string 1 string))
261              (visible (match-string 2 string))
262              (topic (substring string (match-end 0))))
263         (riece-channel-set-topic (riece-get-channel channel) topic)
264         (let* ((channel-identity (riece-make-identity channel
265                                                       riece-server-name))
266                (buffer (riece-channel-buffer channel-identity)))
267           (riece-insert-info buffer (concat visible " users, topic: "
268                                             topic "\n"))
269           (riece-insert-info
270            (if (and riece-channel-buffer-mode
271                     (not (eq buffer riece-channel-buffer)))
272                (list riece-dialogue-buffer riece-others-buffer)
273              riece-dialogue-buffer)
274            (concat
275             (riece-concat-server-name
276              (format "%s: %s users, topic: %s"
277                      (riece-format-identity channel-identity t) visible topic))
278             "\n"))))))
279
280 (defun riece-handle-324-message (prefix number name string)
281   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) " string)
282       (let* ((channel (match-string 1 string))
283              (mode-string (match-string 2 string)))
284         (riece-naming-assert-channel-modes channel
285                                            (riece-parse-modes mode-string))
286         (let* ((channel-identity (riece-make-identity channel
287                                                       riece-server-name))
288                (buffer (riece-channel-buffer channel-identity)))
289           (riece-insert-info buffer (concat "Mode: " mode-string "\n"))
290           (riece-insert-info
291            (if (and riece-channel-buffer-mode
292                     (not (eq buffer riece-channel-buffer)))
293                (list riece-dialogue-buffer riece-others-buffer)
294              riece-dialogue-buffer)
295            (concat
296             (riece-concat-server-name
297              (format "Mode for %s: %s"
298                      (riece-format-identity channel-identity t)
299                      mode-string))
300             "\n"))))))
301
302 (defun riece-handle-set-topic (prefix number name string remove)
303   (if (string-match "^\\([^ ]+\\) :?" string)
304       (let* ((channel (match-string 1 string))
305              (message (substring string (match-end 0)))
306              (channel-identity (riece-make-identity channel riece-server-name))
307              (buffer (riece-channel-buffer channel-identity)))
308         (if remove
309             (riece-channel-set-topic (riece-get-channel channel) nil)
310           (riece-channel-set-topic (riece-get-channel channel) message)
311           (riece-insert-info buffer (concat "Topic: " message "\n"))
312           (riece-insert-info
313            (if (and riece-channel-buffer-mode
314                     (not (eq buffer riece-channel-buffer)))
315                (list riece-dialogue-buffer riece-others-buffer)
316              riece-dialogue-buffer)
317            (concat
318             (riece-concat-server-name
319              (format "Topic for %s: %s"
320                      (riece-format-identity channel-identity t)
321                      message))
322             "\n")))
323         (riece-emit-signal 'channel-topic-changed
324                             channel-identity
325                             (unless remove
326                               message)))))
327
328 (defun riece-handle-331-message (prefix number name string)
329   (riece-handle-set-topic prefix number name string t))
330
331 (defun riece-handle-332-message (prefix number name string)
332   (riece-handle-set-topic prefix number name string nil))
333
334 (defun riece-handle-341-message (prefix number name string)
335   (if (string-match "^\\([^ ]+\\) " string)
336       (let* ((channel (match-string 1 string))
337              (user (substring string (match-end 0)))
338              (channel-identity (riece-make-identity channel riece-server-name))
339              (buffer (riece-channel-buffer channel-identity)))
340         (riece-insert-info buffer (concat "Inviting " user "\n"))
341         (riece-insert-info
342          (if (and riece-channel-buffer-mode
343                   (not (eq buffer riece-channel-buffer)))
344              (list riece-dialogue-buffer riece-others-buffer)
345            riece-dialogue-buffer)
346          (concat
347           (riece-concat-server-name
348            (format "Inviting %s to %s" user
349                    (riece-format-identity channel-identity t)))
350           "\n")))))
351
352 (defun riece-handle-352-message (prefix number name string)
353   (if (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([^ ]+\\) \\([HG]\\)\\(\\*\\)?\\([@+]\\)? :\\([0-9]+\\) " string)
354       (let* ((channel (match-string 1 string))
355              (user (match-string 2 string))
356              (host (match-string 3 string))
357              (server (match-string 4 string))
358              (nick (match-string 5 string))
359              (away (equal (match-string 6 string) "G"))
360              (operator (not (null (match-beginning 7))))
361              (flag (match-string 8 string))
362              (hops (match-string 9 string))
363              (name (substring string (match-end 0)))
364              (buffer (riece-channel-buffer (riece-make-identity
365                                             channel riece-server-name)))
366              (info (format "%10s = %s (%s)"
367                            (concat
368                             (if (memq flag '(?@ ?+))
369                                 (char-to-string flag)
370                               " ")
371                             (riece-format-identity
372                              (riece-make-identity nick riece-server-name)
373                              t))
374                            name
375                            (riece-strip-user-at-host
376                             (concat user "@" host))))
377              status)
378         (if operator
379             (setq status (cons "operator" status)))
380         (if away
381             (setq status (cons "away" status)))
382         (unless (equal hops "0")
383           (setq status (cons (concat "on " server)
384                              (cons (concat hops " hops")
385                                    status))))
386         (if status
387             (setq status (nreverse status)))
388         (riece-naming-assert-join nick channel)
389         (riece-user-toggle-away user away)
390         (riece-emit-signal 'user-away-changed
391                            (riece-make-identity user riece-server-name)
392                            away)
393         (riece-user-toggle-operator user operator)
394         (riece-emit-signal 'user-operator-changed
395                            (riece-make-identity user riece-server-name)
396                            operator)
397         (riece-insert-info buffer (concat (riece-concat-user-status
398                                            status info)
399                                           "\n"))
400         (riece-insert-info
401          (if (and riece-channel-buffer-mode
402                   (not (eq buffer riece-channel-buffer)))
403              (list riece-dialogue-buffer riece-others-buffer)
404            riece-dialogue-buffer)
405          (concat
406           (riece-concat-server-name
407            (riece-concat-user-status
408             status
409             (concat
410              (riece-format-identity
411               (riece-make-identity channel riece-server-name)
412               t)
413              " "
414              info)))
415           "\n")))))
416
417 (defun riece-handle-315-message (prefix number name string))
418 (defun riece-handle-318-message (prefix number name string))
419 (defun riece-handle-323-message (prefix number name string))
420
421 (defun riece-handle-366-message (prefix number name string)
422   "RPL_ENDOFNAMES \"<channel> :End of NAMES list\""
423   (if (string-match "^\\([^ ]+\\) " string)
424       (let* ((channel (match-string 1 string))
425              (channel-identity (riece-make-identity channel
426                                                     riece-server-name))
427              (buffer (riece-channel-buffer channel-identity))
428              (entry (riece-identity-assoc channel riece-353-message-alist t))
429              (string (cdr entry))
430              (start 0)
431              users)
432         (if entry
433             (setq riece-353-message-alist
434                   (delq entry riece-353-message-alist)))
435         (while (string-match
436                 (concat "\\([@+]\\)?\\(" riece-user-regexp "\\) *")
437                 string start)
438           (put-text-property (match-beginning 2) (match-end 2)
439                              'riece-identity
440                              (riece-make-identity (match-string 2 string)
441                                                   riece-server-name)
442                              string)
443           (setq start (match-end 0)
444                 users (cons (if (match-beginning 1)
445                                 (if (eq (aref string (match-beginning 1)) ?@)
446                                     (list (match-string 2 string) ?o)
447                                   (if (eq (aref string (match-beginning 1)) ?+)
448                                       (list (match-string 2 string) ?v)))
449                               (list (match-string 2 string)))
450                             users)))
451         (setq users (nreverse users))
452         (riece-naming-assert-channel-users users channel)
453         (riece-insert-info
454          buffer
455          (concat (format "%d users: " (length users)) string "\n"))
456         (riece-insert-info
457          (if (and riece-channel-buffer-mode
458                   (not (eq buffer riece-channel-buffer)))
459              (list riece-dialogue-buffer riece-others-buffer)
460            riece-dialogue-buffer)
461          (concat
462           (riece-concat-server-name
463            (concat (format "%d users on %s: "
464                            (length users)
465                            (riece-format-identity channel-identity t))
466                    string))
467           "\n")))))
468
469 (provide 'riece-300)
470
471 ;;; riece-300.el ends here