;; -*- emacs-lisp -*- ;;; erc-mst-banlist.el --- list bans ;; Copyright (C) 2003 Free Software Foundation, Inc. ;; Author: Mark Triggs ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; store ban lists (add-hook 'erc-server-367-hook 'erc-store-banlist) (add-hook 'erc-server-MODE-hook 'erc-parse-bans) (add-hook 'erc-server-JOIN-hook (lambda (proc parsed) (let* ((chnl (aref parsed 2)) (sndr (erc-parse-user (aref parsed 1))) (nick (nth 0 sndr))) (when (string= (erc-current-nick) nick) (erc-send-command (format "MODE %s b" chnl))))) t nil) (defvar channel-ban-list nil "A list of bans seen for the current channel. Each ban is represented by a dotted pair whose car is the nickname who set the ban, and whose cdr is the ban mask.") (make-variable-buffer-local 'channel-ban-list) (defun erc-store-banlist (proc parsed) "Record the ban list for a channel" (let ((whoset (car (erc-parse-user (aref parsed 5)))) (channel (aref parsed 3)) (mask (aref parsed 4))) ;; Determine to which buffer the message corresponds (let ((buffer (erc-get-buffer channel proc))) (save-excursion (set-buffer buffer) (when (not (member `(,whoset . ,mask) channel-ban-list)) (push `(,whoset . ,mask) channel-ban-list)))))) ;; Keep track of bans as they are added and removed (defun erc-parse-bans (proc parsed) "Check MODE commands for ban references and record them as appropriate" (let* ((tgt (aref parsed 2)) (mode (mapconcat 'identity (delete* nil (subseq parsed 3)) " ")) (sndr (erc-parse-user (aref parsed 1))) (nick (nth 0 sndr)) (buffer (erc-get-buffer tgt proc))) (when buffer (save-excursion (set-buffer buffer) (when (string-match "^\\([+-]\\)b" mode) ;; This is a ban (cond ((string-match "^-" mode) ;; Remove the unbanned masks from the ban list (setq channel-ban-list (remove-if (lambda (y) (member (upcase (cdr y)) (mapcar #'upcase (cdr (split-string mode))))) channel-ban-list))) ((string-match "^+" mode) ;; Add the banned mask(s) to the ban list (mapc (lambda (mask) (when (not (member `(,nick . ,mask) channel-ban-list)) (push `(,nick . ,mask) channel-ban-list))) (cdr (split-string mode)))) (t nil))) nil)))) (defun erc-cmd-LISTBANS () "list all bans for the current channel" (cond ((not (erc-channel-p (erc-default-target))) t) ((null channel-ban-list) (erc-display-line (erc-make-notice (format "No bans for channel: %s\n" (erc-default-target))) 'active)) (t (let ((separator (do ((i 0 (1+ i)) (j nil (concat j "="))) ((> i fill-column) j)))) (erc-display-line (erc-make-notice (format "Ban list for channel: %s\n" (erc-default-target))) 'active) (erc-display-line (format "%s" separator) 'active) (erc-display-line (format (concat "%-" (number-to-string (/ fill-column 2)) "s " "%" (number-to-string (/ fill-column 2)) "s") "Ban Mask" "Banned By") 'active) (erc-display-line (format "%s" separator) 'active) (mapc (lambda (x) (erc-display-line (format (concat "%-" (number-to-string (/ fill-column 2)) "s" "%" (number-to-string (/ fill-column 2)) "s") (truncate-string (cdr x) (/ fill-column 2)) (truncate-string (car x) (/ fill-column 2))) 'active)) channel-ban-list) (erc-display-line (erc-make-notice "End of Ban List") 'active)))) t) (defun group-list (lst num) "Group 'lst' into sublists of length 'num'" (cond ((null lst) nil) ((null (nthcdr num lst)) (list lst)) (t (cons (subseq lst 0 num) (group-list (nthcdr num lst) num))))) (defun erc-cmd-MUB () "Mass Unban" (let ((bans (mapcar (lambda (x) (cdr x)) channel-ban-list))) (when bans ;; Glob the bans into groups of three, and carry out the unban. ;; eg. /mode #foo -bbb a*!*@* b*!*@* c*!*@* (mapc (lambda (x) (erc-send-command (format "MODE %s -%s %s" (erc-default-target) (make-string (length x) (string-to-char "b")) (reduce (lambda (a &optional b) (concat a (if (boundp 'b) (concat " " b)))) x)))) (group-list bans 3)))) t) (provide 'erc-mst-banlist) ;;; erc-mst-banlist.el ends here