#! /bin/perl

#                             B L I T Z
#                 Blast Listserv Idiot Turkey Zeroes
#                     Version 1.3  --  March MIM

#                           by John Walker
#                      http://www.fourmilab.ch/

#   One of the great mysteries of the Internet is why it is that any
#   drooling moron can instantly subscribe to every mailing list he
#   hears word of, but can't seem to manage to unsubscribe without
#   posting something to every user on the list, or personally
#   involving the list manager, often soliciting this assistance with
#   abusive and obscene E-mail.

#   Genuinely solving this problem will probably require an upgrade
#   to the general intellectual calibre of Internet users, and it
#   appears the trend is heading in the opposite direction.  BLITZ
#   merely reduces the workload on the poor overworked list manager
#   by providing a cut-and-paste tool that allows blowing away these
#   idiots without invoking a text editor on a series of mailing list
#   files.

#   Note that users are actually unsubscribed by sending messages to
#   majordomo (or whatever manager user name is configured below)
#   rather than directly modifying the mailing list files.  This
#   automatically protects against race conditions since the list
#   manager contains locks to prevent multiple simultaneous updates
#   to its list files.

#   As an extra gimmick, entering a user name of "?" lists the
#   number of subscribers to each of the lists being managed.

#   Configuration

    # Directory where lists reside

    $dir = "/files/people/majordomo/lists";

    # Lists to be managed

    @lists = (
                "test-digest",
                "test"
             );

    # List manager (majordomo) request address

    $manager = "majordomo\@yoursite.net";

    # Majordomo approval password.  We currently assume the same
    # password is used for all lists.  This should be changed to
    # permit per-list passwords.  Since this is a one-list-manager
    # site, I haven't gotten around to doing this yet.

    $passwd = "YourPasswd";

#   End configuration.  You shouldn't have to change anything below this line.

#   Prompt user for next pattern

    while (1) {
        print("User: ");
        $u = <>;
        if (!$u || (chop($u), ($u =~ m/^\s*$/))) {
            exit(0);
        }

        #   If user name is "?", show number of users in each list

        if ($u eq '?') {
            foreach $f (@lists) {
                $n = `wc -l $dir/$f`;
                chop($n);
                $n =~ s/^\s*//;
                $n =~ s/\s.*$//;
                print("$f: $n subscribers.\n");
            }
            next;
        }

        #   Search for occurrences of pattern in lists.  Comparison
        #   is done without regard to case since the folks who
        #   motivated this utility are very fond of weird 
        #   capitalisation.

        $u =~ tr/A-Z/a-z/;
ditch:  foreach $f (@lists) {
            open(F, "$dir/$f") || die("Cannot open list file $dir/$f: $!");
            while ($l = <F>) {
                chop($l);
                $cl = $l;
                $cl =~ tr/A-Z/a-z/;
#   We originally used the user name as a regular expression, as follows
#               if ($cl =~ m/$u/) {
#   On further reflection, it seemed to make more sense to simply test
#   for a substring within the name, as that allows entering dotted
#   domain names without the need to quote them.
                if (index($cl, $u) >= 0) {
                    print("$f: $l  Delete [yNq]? ");
                    $yn = <>;
                    if (!$yn) {
                        exit(0);
                    }
                    $yn =~ tr/A-Z/a-z/;
                    if (substr($yn, 0, 1) eq 'y') {
                        system("echo \"\012approve $passwd unsubscribe $f $l\" | Mail -s Blitz $manager");
                    } elsif (substr($yn, 0, 1) eq 'q') {
                        last ditch;
                    }
                }
            }
            close(F);
        }

    }
