253 lines
6.4 KiB
Perl
253 lines
6.4 KiB
Perl
#!/bin/perl
|
|
|
|
# Approve Majordomo requests or "resend" bounces.
|
|
#
|
|
# Given arguments, approves the requests in those files;
|
|
# given no arguments, reads standard input.
|
|
#
|
|
# If the "Subject: " line is "APPROVE <list>", the message is treated as
|
|
# a request for approval from Majordomo. An appropriate command is generated
|
|
# and mailed to Majordomo to approve the request.
|
|
#
|
|
# If the "Subject: " line is "BOUNCE <list>: <reason>", the message is treated
|
|
# as a posting rejected by "resend" for some reason, and is reformatted with
|
|
# appropriate "Approved:" headers to cause it to succeed, then resubmitted
|
|
# for posting.
|
|
#
|
|
# Assumes that the "approve" password for each list is the same as the
|
|
# "approval" password used by "resend", and that this password is stored
|
|
# in a file called ".majordomo" in the user's home directory, in the
|
|
# following format:
|
|
#
|
|
# List Password Majordomo-Address
|
|
#
|
|
# Assumes that the "Majordomo-Address" field is an Internet-style
|
|
# "something@somewhere" address, and that postings for "List" should
|
|
# be sent to "List@somewhere".
|
|
#
|
|
# Here's an example of what a .majordomo file should look like:
|
|
#
|
|
# this-list passwd1 Majordomo@This.COM
|
|
# other-list passwd2 Majordomo@Other.GOV
|
|
#
|
|
# If, for instance, /tmp/request contains a standard request from Majordomo
|
|
# to a list manager, such as:
|
|
#
|
|
# From: Majordomo@This.COM
|
|
# To: this-list-approval@This.COM
|
|
#
|
|
# User@Fubar.COM (Joe User) requests you approve the following:
|
|
#
|
|
# subscribe this-list User@Fubar.COM (Joe User)
|
|
#
|
|
# If you approve, send a line such as the following to Majordomo@This.COM:
|
|
#
|
|
# approve PASSWD subscribe this-list User@Fubar.COM (Joe User)
|
|
#
|
|
# Then, if you run "approve /tmp/request" or "approve < /tmp/request", the
|
|
# following message will be sent to Majordomo@This.COM:
|
|
#
|
|
# To: Majordomo@This.COM
|
|
#
|
|
# approve passwd1 subscribe this-list User@Fubar.COM (Joe User)
|
|
#
|
|
# Brent Chapman Great Circle Associates
|
|
# Brent@GreatCircle.COM 1057 West Dana Street
|
|
# +1 415 962 0841 Mountain View, CA 94041
|
|
|
|
# $Source: /sources/cvsrepos/majordomo/approve,v $
|
|
# $Revision: 1.15 $
|
|
# $Date: 1997/04/05 19:18:36 $
|
|
# $Author: cwilson $
|
|
# $State: Exp $
|
|
#
|
|
# $Locker: $
|
|
|
|
$MAILER = '/usr/lib/sendmail' if -x '/usr/lib/sendmail';
|
|
$MAILER = '/usr/sbin/sendmail' if -x '/usr/sbin/sendmail';
|
|
|
|
die "Couldn't find a sendmail to invoke, please define!"
|
|
if !$MAILER;
|
|
|
|
|
|
use Getopt::Std;
|
|
|
|
getopts("df:") ||
|
|
die("USAGE: approve [-f <config-file>] [-d] [<file> ...]\nStopped");
|
|
|
|
if (!defined($opt_f)) {
|
|
$opt_f = "$ENV{HOME}/.majordomo";
|
|
}
|
|
|
|
&read_config();
|
|
|
|
# Read the headers. Look at the "Reply-To:" header to figure out where to
|
|
# respond to. Look at the "Subject:" header to figure out if this is an
|
|
# APPROVE or a BOUNCE request.
|
|
|
|
if (@ARGV) {
|
|
foreach $file (@ARGV) {
|
|
open(FILE, $file) || (warn("can't open \"$file\"; skipping"), next);
|
|
&process_file(FILE);
|
|
close(FILE);
|
|
}
|
|
} else {
|
|
&process_file(STDIN);
|
|
}
|
|
|
|
exit(0);
|
|
|
|
sub process_file {
|
|
local($FILE) = shift;
|
|
local($reply_to);
|
|
local($subject);
|
|
local($request);
|
|
local($list);
|
|
|
|
while (<$FILE>) {
|
|
s/\n$//;
|
|
if (/^reply-to:/i) {
|
|
s/^\S*:\s+//;
|
|
$reply_to = $_;
|
|
$reply_to =~ tr/A-Z/a-z/;
|
|
next;
|
|
}
|
|
if (/^subject:/i) {
|
|
s/^\S*:\s+//;
|
|
$subject = $_;
|
|
$subject =~ tr/A-Z/a-z/;
|
|
($request, $list) = split(/\s/, $subject, 2);
|
|
$list =~ s/:.*//;
|
|
next;
|
|
}
|
|
if (/^$/) {
|
|
last;
|
|
}
|
|
}
|
|
|
|
# we've read the headers, so we should know now if this is an "APPROVE"
|
|
# or a "BOUNCE" that we're processing.
|
|
|
|
if ($request eq "approve") { &process_approve($FILE); }
|
|
elsif ($request eq "bounce") { &process_bounce($FILE); }
|
|
else {
|
|
warn("unknown request type '$request' in file '$file'; skipping");
|
|
}
|
|
}
|
|
|
|
sub process_approve {
|
|
local($FILE) = shift;
|
|
while (<$FILE>) {
|
|
if ((/^\tsubscribe\s/) || (/^\tunsubscribe\s/)) {
|
|
if (!defined($reply_to)) {
|
|
warn("No \"Reply-To:\"; exiting");
|
|
exit(1);
|
|
}
|
|
s/^\t//;
|
|
split;
|
|
$list = $_[1];
|
|
$list =~ tr/A-Z/a-z/;
|
|
$passwd = $passwd{"$list\@$reply_to"};
|
|
if (! $passwd) {
|
|
warn("no password for list $list; skipping \"$_\"");
|
|
next;
|
|
}
|
|
if (defined($opt_d)) {
|
|
open(MAIL, ">&STDOUT");
|
|
print MAIL "-" x 20, "\n";
|
|
} else {
|
|
open(MAIL, "|$MAILER $reply_to") ||
|
|
die ("open(\"|$MAILER ...\"): $!");
|
|
}
|
|
|
|
print MAIL "To: $reply_to\n\n";
|
|
print MAIL "approve $passwd $_";
|
|
close(MAIL);
|
|
last;
|
|
}
|
|
}
|
|
print STDERR "Mailed approved command to $list list.\n"
|
|
unless defined $opt_d;
|
|
}
|
|
|
|
sub process_bounce {
|
|
local($FILE) = shift;
|
|
local ($from_skipped);
|
|
|
|
# we've already skipped the header, so set up to approve the message
|
|
|
|
# first, figure out where to send it
|
|
if (defined($reply_to)) {
|
|
# if there's a "Reply-To:" field set, use it.
|
|
$post_to = $reply_to;
|
|
} elsif ($list =~ /\@/) {
|
|
# if the list name already appears fully qualified, use it
|
|
$post_to = $list;
|
|
} else {
|
|
# Well, can we figure it out?
|
|
if ($site{$list} eq "MULTIPLE") {
|
|
warn("Can't distinguish between multiple lists named '$list'\nSkipping '$file'");
|
|
return;
|
|
} else {
|
|
$post_to = $list . "\@" . $site{$list};
|
|
}
|
|
}
|
|
|
|
if (!defined($passwd{$list})) {
|
|
warn "Can't find password for list $list, Stopped";
|
|
return;
|
|
}
|
|
|
|
if (defined($opt_d)) {
|
|
open(MAIL, ">&STDOUT");
|
|
print MAIL "-" x 20, "\n";
|
|
print MAIL "To: $post_to\n\n";
|
|
} else {
|
|
open(MAIL, "|$MAILER $post_to") || die("open(\"|$MAILER...\"): $!");
|
|
}
|
|
|
|
print MAIL "Approved: $passwd{$list}\n";
|
|
|
|
while (<$FILE>) {
|
|
if (/^>?From / && ! defined($from_skipped)) {
|
|
# Skip any initial "From " or ">From " line
|
|
$from_skipped = 1;
|
|
next;
|
|
}
|
|
s/^~/~~/;
|
|
print MAIL $_;
|
|
}
|
|
close(MAIL);
|
|
print STDERR "Mailed approved message to $list list.\n";
|
|
}
|
|
|
|
sub read_config {
|
|
local($l);
|
|
local($p);
|
|
local($m);
|
|
local($s);
|
|
open(CONF, $opt_f) || die("open(CONF, \"$opt_f\"): $!");
|
|
while (<CONF>) {
|
|
s/\n$//;
|
|
s/#.*//;
|
|
if (/^$/) { next; }
|
|
split;
|
|
$l = $_[0]; $l =~ tr/A-Z/a-z/; # list
|
|
$p = $_[1]; # password
|
|
$m = $_[2]; $m =~ tr/A-Z/a-z/; # majordomo@site
|
|
split(/\@/, $m);
|
|
$s = $_[1]; $s =~ tr/A-Z/a-z/; # site
|
|
|
|
$passwd{$l} = $p;
|
|
$passwd{"$l\@$m"} = $p;
|
|
$passwd{"$l\@$s"} = $p;
|
|
if (defined($site{$l})) {
|
|
# if it's already defined, there's more than one list by this name
|
|
$site{$l} = "MULTIPLE";
|
|
} else {
|
|
$site{$l} = $s;
|
|
}
|
|
}
|
|
close(CONF);
|
|
}
|