a
This commit is contained in:
109
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive.pl
vendored
Normal file
109
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive.pl
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/bin/perl
|
||||
|
||||
#(Message inbox:15)
|
||||
#Return-Path: Majordomo-Users-Owner@greatcircle.com
|
||||
#Message-Id: <m0oXmfl-0002wDC@hock.bolis.sf-bay.org>
|
||||
#From: Alan Millar <amillar@bolis.sf-bay.org>
|
||||
#Subject: Perl prog to create list archives
|
||||
#To: majordomo-users@greatcircle.com
|
||||
#Date: Wed, 1 Sep 1993 00:32:03 -0800 (PDT)
|
||||
#Cc: brent@greatcircle.com
|
||||
#Reply-To: Alan Millar <AMillar@bolis.sf-bay.org>
|
||||
#
|
||||
#
|
||||
#Hi-
|
||||
#
|
||||
#Here is a perl program I wrote to keep mailing list archives.
|
||||
#It is designed to produce list archive files similar to Revised
|
||||
#Listserv. Each message is separated by a line of "==="s and
|
||||
#most of the header "noise" is gone. Instead of being stored
|
||||
#in one big file, they are split into one file per month with
|
||||
#the name logYYMM where YY and MM are the numeric year and
|
||||
#month.
|
||||
#
|
||||
#I call it from /usr/lib/aliases using:
|
||||
#
|
||||
# listname-archive: "|/usr/local/mail/majordomo/wrapper archive.pl \
|
||||
# /usr/local/mail/lists/listname.archive"
|
||||
#
|
||||
#Where the last parameter is the directory name to put the
|
||||
#log files into.
|
||||
#
|
||||
#Give it a try and let me know what you think.
|
||||
#
|
||||
#- Alan
|
||||
#
|
||||
#---- ,,,,
|
||||
#Alan Millar amillar@bolis.SF-Bay.org __oo \
|
||||
#System Administrator =___/
|
||||
#The skill of accurate perception is called cynicism by those who don't
|
||||
#possess it.
|
||||
#----
|
||||
|
||||
|
||||
# archive.pl
|
||||
# Mailing list archiver. Specify the directory (not the file)
|
||||
# on the command line. Messages are written to a file
|
||||
# called 'logYYMM' in that directory, where YY is the two digit
|
||||
# year and MM is the two-digit month.
|
||||
|
||||
# Written by Alan Millar August 25 1993.
|
||||
|
||||
# All these should be in the standard PERL library
|
||||
unshift(@INC, $homedir);
|
||||
require "majordomo.pl"; # all sorts of general-purpose Majordomo subs
|
||||
require "shlock.pl"; # NNTP-style file locking
|
||||
|
||||
# The headers we want to keep, in order:
|
||||
@keepHeaders =
|
||||
( "To", "cc"
|
||||
, "from", "reply-to", "organization"
|
||||
, "date", "subject"
|
||||
, "summary", "keywords"
|
||||
, "Content-Type"
|
||||
);
|
||||
|
||||
#-----------------------------------
|
||||
# Set up output file. See if directory is specified on command line.
|
||||
$outputDir = $ARGV[0];
|
||||
if (! -d $outputDir) {
|
||||
$outputDir = "/tmp";
|
||||
}
|
||||
$outputDir =~ s/\/$//; # drop trailing slash
|
||||
|
||||
#------------------------------------
|
||||
# Get date for log file name
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
||||
|
||||
# log file name is form "logYYMM"
|
||||
$logFile = sprintf("$outputDir/log%2.2d%2.2d",$year,$mon + 1);
|
||||
|
||||
# open output file
|
||||
&lopen(OUTPUT,">>",$logFile);
|
||||
|
||||
# Parse the mail header of the message, so we can figure out who to reply to
|
||||
&ParseMailHeader(STDIN, *hdrs);
|
||||
|
||||
# Print the headers we want
|
||||
|
||||
print OUTPUT "========================================";
|
||||
print OUTPUT "======================================\n";
|
||||
|
||||
foreach $key (@keepHeaders) {
|
||||
$key =~ tr[A-Z][a-z];
|
||||
if (defined($hdrs{$key})) {
|
||||
$newKey = $key; substr($newKey,0,1) =~ tr/a-z/A-Z/;
|
||||
printf OUTPUT "%-15s%s\n", "$newKey: ", $hdrs{$key};
|
||||
} # if non-blank
|
||||
} # foreach
|
||||
|
||||
print OUTPUT "\n";
|
||||
|
||||
# copy the rest of the message
|
||||
|
||||
while (<STDIN>) {
|
||||
print OUTPUT $_;
|
||||
}
|
||||
print OUTPUT "\n";
|
||||
|
||||
&lclose(OUTPUT);
|
||||
34
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl
vendored
Normal file
34
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/archive_mh.pl
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/bin/perl
|
||||
|
||||
# archive: A hack to use mh to handle the archives
|
||||
#
|
||||
# You may redistribute this file, or inlcude it into the offical majordomo
|
||||
# package
|
||||
#
|
||||
# $Source: /sources/cvsrepos/majordomo/contrib/archive_mh.pl,v $
|
||||
# $Revision: 1.4 $
|
||||
# $Date: 1997/03/10 15:40:41 $
|
||||
# $Author: cwilson $
|
||||
# $State: Exp $
|
||||
#
|
||||
# $Locker: $
|
||||
|
||||
# set our path explicitly
|
||||
$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb";
|
||||
|
||||
# Read and execute the .cf file
|
||||
$cf = $ENV{"MAJORDOMO_CF"} || "/tools/majordomo-1.56/majordomo.cf";
|
||||
if ($ARGV[0] eq "-C") {
|
||||
$cf = $ARGV[1];
|
||||
shift(@ARGV);
|
||||
shift(@ARGV);
|
||||
}
|
||||
if (! -r $cf) {
|
||||
die("$cf not readable; stopped");
|
||||
}
|
||||
require "$cf";
|
||||
|
||||
# Go to the home directory specified by the .cf file
|
||||
chdir("$homedir");
|
||||
|
||||
exec("/tools/mh-6.8/lib/mh/rcvstore +$filedir/$ARGV[0] -nocreate\n");
|
||||
348
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.diff
vendored
Normal file
348
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.diff
vendored
Normal file
@@ -0,0 +1,348 @@
|
||||
From: pdc@lunch.asd.sgi.com (Paul Close)
|
||||
Subject: Digest code diffs for 1.90
|
||||
Date: Thu, 21 Apr 1994 17:56:22 -0700 (PDT)
|
||||
|
||||
Here are my changes to digest which support config file settings for
|
||||
specifying the digest size in lines and/or the maximum age of the oldest
|
||||
article, in days. Also support a new flag, -p (for "push"), intended for
|
||||
use by cron jobs. It checks to see if a digest should be sent, and sends
|
||||
it if it should (pretty well because an article is too old, but you could
|
||||
use this to send all the time).
|
||||
|
||||
A few comments on the code. In &should_be_sent, I calculate how big the
|
||||
article would be if the headers were stripped, both in bytes and in lines.
|
||||
I add in a bit of a fudge factor for mail headers, just so we don't get too
|
||||
close to maxlength bytes before sending. Typically, the line count will
|
||||
cause a digest to be sent before the byte count would (I see the maxlength
|
||||
count as more of a mailer issue than a digest issue).
|
||||
|
||||
The old digest code had a strange construct: s/\n+$/\n/; I assumed that
|
||||
this was to trim newlines off the end of the string, but multi-line regexps
|
||||
don't work that way. The only way I could get this to work is:
|
||||
|
||||
$len = length($body) - 1;
|
||||
$len-- while (substr($body,$len,1) eq "\n");
|
||||
substr($body,$len+1) = "";
|
||||
|
||||
Any clever hacks appreciated. In the same area, I changed the code that
|
||||
reads the body of the message to read the whole thing at once (undef $/)
|
||||
rather than do multiple string concatenations. Seems more efficient. I
|
||||
also added a ^From escaper, using enough of a real "From " line pattern,
|
||||
that it shouldn't match just any line beginning with From.
|
||||
|
||||
Under the heading of random perl lore, to count the number of newlines in a
|
||||
multi-line string, I used:
|
||||
|
||||
$lines += ($body =~ s/\n/\n/g);
|
||||
|
||||
seems pretty straightforward, but I have the nagging suspicion there's an
|
||||
easier way.
|
||||
|
||||
Finally, I made digest safe past the year 2000, by printing $year+1900
|
||||
rather than 19$year. Whoopee!
|
||||
|
||||
Comments welcome! The code is based on 1.90b2, which is the latest I have.
|
||||
|
||||
Index: digest/digest
|
||||
*** digest/digest.old Sun Mar 6 14:47:06 1994
|
||||
--- digest/digest Thu Apr 21 17:35:33 1994
|
||||
***************
|
||||
*** 63,72 ****
|
||||
|
||||
if (defined($opt_r)) {
|
||||
&receive_message;
|
||||
} elsif (defined($opt_m)) {
|
||||
&make_digest;
|
||||
} else {
|
||||
! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped");
|
||||
}
|
||||
|
||||
&free_lock;
|
||||
--- 63,79 ----
|
||||
|
||||
if (defined($opt_r)) {
|
||||
&receive_message;
|
||||
+ if (&should_be_sent()) {
|
||||
+ &make_digest;
|
||||
+ }
|
||||
} elsif (defined($opt_m)) {
|
||||
&make_digest;
|
||||
+ } elsif (defined($opt_p)) {
|
||||
+ if (&should_be_sent()) {
|
||||
+ &make_digest;
|
||||
+ }
|
||||
} else {
|
||||
! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped");
|
||||
}
|
||||
|
||||
&free_lock;
|
||||
***************
|
||||
*** 73,97 ****
|
||||
|
||||
exit(0);
|
||||
|
||||
sub receive_message {
|
||||
- $sum = 0;
|
||||
$i = 0;
|
||||
do {
|
||||
! $i++;
|
||||
! $file = sprintf("%s/%03d", $V{'INCOMING'}, $i);
|
||||
! $sum += (-s $file);
|
||||
} until (! -e $file);
|
||||
print STDERR "Receiving $i\n";
|
||||
open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!");
|
||||
while (<STDIN>) {
|
||||
print MSG $_;
|
||||
}
|
||||
close(MSG);
|
||||
- $sum += (-s $file);
|
||||
- if ($sum > $V{'DIGEST_SIZE'}) {
|
||||
- &make_digest;
|
||||
- }
|
||||
- return(1);
|
||||
}
|
||||
|
||||
|
||||
--- 80,146 ----
|
||||
|
||||
exit(0);
|
||||
|
||||
+ sub should_be_sent {
|
||||
+ # fudge factors for headers and footers
|
||||
+ $sum = 600 + length($HEADER) + length($HEADERS) + length($TRAILER);
|
||||
+ $lines = 25;
|
||||
+ $i = 0;
|
||||
+ while (1) {
|
||||
+ $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i);
|
||||
+ last unless (-e $file);
|
||||
+ open(COUNT, "<$file") || &abort("open(COUNT, \"<$file\"): $!");
|
||||
+
|
||||
+ $/ = ''; # grab the header
|
||||
+ $head = <COUNT>;
|
||||
+
|
||||
+ # only count From/Date/Subject header fields to get a
|
||||
+ # more accurate size and line count.
|
||||
+ $head =~ s/\n\s+/ /g;
|
||||
+ $head =~ /^(From:\s+.*)/i && ($sum += length($1)+1, $lines++);
|
||||
+ $head =~ /^(Subject:\s+.*)/i && ($sum += length($1)+1, $lines++);
|
||||
+ $head =~ /^(Date:\s+.*)/i && ($sum += length($1)+1, $lines++);
|
||||
+ $sum++, $lines++;
|
||||
+
|
||||
+ # count the body of the message
|
||||
+ undef $/;
|
||||
+ $body = <COUNT>;
|
||||
+ $sum += length($body);
|
||||
+ $lines += ($body =~ s/\n/\n/g); # count newlines
|
||||
+
|
||||
+ $/ = "\n";
|
||||
+ close(COUNT);
|
||||
+ $sum += length($EB) + 2, $lines += 2; # account for message delimiter
|
||||
+
|
||||
+ if ($V{'DIGEST_SIZE'} && $sum > $V{'DIGEST_SIZE'}) {
|
||||
+ return(1);
|
||||
+ }
|
||||
+ if ($V{'DIGEST_LINES'} && $lines > $V{'DIGEST_LINES'}) {
|
||||
+ return(1);
|
||||
+ }
|
||||
+ if ($V{'MAX_AGE'} && (-M $file) > $V{'MAX_AGE'}) {
|
||||
+ return(1);
|
||||
+ }
|
||||
+ }
|
||||
+ print "don't send. sum = $sum, lines = $lines\n";
|
||||
+
|
||||
+ return(0);
|
||||
+ }
|
||||
+
|
||||
sub receive_message {
|
||||
$i = 0;
|
||||
do {
|
||||
! $file = sprintf("%s/%03d", $V{'INCOMING'}, ++$i);
|
||||
} until (! -e $file);
|
||||
+
|
||||
print STDERR "Receiving $i\n";
|
||||
open(MSG, ">$file") || &abort("open(MSG, \">$file\"): $!");
|
||||
+
|
||||
+ # copy the message
|
||||
while (<STDIN>) {
|
||||
print MSG $_;
|
||||
}
|
||||
+
|
||||
close(MSG);
|
||||
}
|
||||
|
||||
|
||||
***************
|
||||
*** 111,129 ****
|
||||
$head = <message>;
|
||||
$head =~ s/\n\s+/ /g;
|
||||
$body = "";
|
||||
! ($subj) = ($head =~ /^subject:\s+(.*)/i);
|
||||
! $subj = "[none]" unless $subj;
|
||||
! ($from) = ($head =~ /^from:\s+(.*)/i);
|
||||
! ($date) = ($head =~ /^date:\s+(.*)/i);
|
||||
|
||||
! $/ = "\n";
|
||||
! while (<message>) {
|
||||
! s/^-/- -/; #escape encapsulation boundaries in message
|
||||
! $body .= $_;
|
||||
! }
|
||||
close(message);
|
||||
! $body =~ s/\n+$/\n/;
|
||||
|
||||
push(@subj,$subj);
|
||||
print TEMP <<EOF;
|
||||
From: $from
|
||||
--- 160,184 ----
|
||||
$head = <message>;
|
||||
$head =~ s/\n\s+/ /g;
|
||||
$body = "";
|
||||
! $subj = ($head =~ /^Subject:\s+(.*)/i)? $1: "[none]";
|
||||
! ($from) = $head =~ /^From:\s+(.*)/i;
|
||||
! ($date) = $head =~ /^Date:\s+(.*)/i;
|
||||
|
||||
! undef $/;
|
||||
! $body = <message>;
|
||||
close(message);
|
||||
!
|
||||
! # escape ^From <user> <weekday> <month> <day> <hr:min:sec> ...
|
||||
! $body =~
|
||||
! s/^From (\S+\s+\w{3}\s+\w{3}\s+\d+\s+\d+:\d+:\d+)/>From $1/g;
|
||||
! $body =~ s/^-/- -/g; # escape encapsulation boundaries in message
|
||||
! # trim trailing \n's
|
||||
! $len = length($body) - 1;
|
||||
! $len-- while (substr($body,$len,1) eq "\n");
|
||||
! substr($body,$len+1) = "";
|
||||
|
||||
+ $/ = "\n";
|
||||
+
|
||||
push(@subj,$subj);
|
||||
print TEMP <<EOF;
|
||||
From: $from
|
||||
***************
|
||||
*** 131,136 ****
|
||||
--- 186,192 ----
|
||||
Subject: $subj
|
||||
|
||||
$body
|
||||
+
|
||||
$EB
|
||||
|
||||
EOF
|
||||
***************
|
||||
*** 204,211 ****
|
||||
$* = 1;
|
||||
$HOME = $ENV{"HOME"} || (getpwuid($>))[7];
|
||||
chdir($HOME);
|
||||
! &getopt("rmc:Cl:") ||
|
||||
! &abort("Usage: digest {-r|-m} [-c config|(-C -l list)]\nStopped");
|
||||
$config = $opt_c || "$HOME/.digestrc";
|
||||
$TEMP = "/tmp/digest.$$";
|
||||
$SIG{'INT'} = 'cleanup';
|
||||
--- 260,267 ----
|
||||
$* = 1;
|
||||
$HOME = $ENV{"HOME"} || (getpwuid($>))[7];
|
||||
chdir($HOME);
|
||||
! &getopt("rmpc:Cl:") ||
|
||||
! &abort("Usage: digest {-r|-m|-p} [-c config|(-C -l list)]\nStopped");
|
||||
$config = $opt_c || "$HOME/.digestrc";
|
||||
$TEMP = "/tmp/digest.$$";
|
||||
$SIG{'INT'} = 'cleanup';
|
||||
***************
|
||||
*** 245,252 ****
|
||||
$NUMBER = $config_opts{$opt_l,"digest_issue"};
|
||||
$Precedence = $config_opts{$opt_l,"precedence"};
|
||||
$Precedence = "bulk" if ($Precedence eq "");
|
||||
! $V{'ARCHIVE'} = "$filedir/$opt_l$filedirsuffix";
|
||||
$V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"};
|
||||
$V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"};
|
||||
$V{'FROM'} = $config_opts{$opt_l, "sender"};
|
||||
$V{'INCOMING'} = "$digest_work_dir/$opt_l";
|
||||
--- 301,310 ----
|
||||
$NUMBER = $config_opts{$opt_l,"digest_issue"};
|
||||
$Precedence = $config_opts{$opt_l,"precedence"};
|
||||
$Precedence = "bulk" if ($Precedence eq "");
|
||||
! $V{'ARCHIVE'} = "$filedir/$opt_l$filedir_suffix";
|
||||
$V{'DIGEST_SIZE'} = $config_opts{$opt_l, "maxlength"};
|
||||
+ $V{'DIGEST_LINES'} = $config_opts{$opt_l, "digest_maxlines"};
|
||||
+ $V{'MAX_AGE'} = $config_opts{$opt_l, "digest_maxdays"};
|
||||
$V{'ERRORS-TO'} = $config_opts{$opt_l,"sender"};
|
||||
$V{'FROM'} = $config_opts{$opt_l, "sender"};
|
||||
$V{'INCOMING'} = "$digest_work_dir/$opt_l";
|
||||
***************
|
||||
*** 327,333 ****
|
||||
|
||||
sub getdate {
|
||||
local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
||||
! return($DAYS[$wday] . ", $mday " . $MONTHS[$mon] . " 19$year");
|
||||
}
|
||||
|
||||
sub set_lock {
|
||||
--- 385,392 ----
|
||||
|
||||
sub getdate {
|
||||
local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
||||
! $year += 1900;
|
||||
! return("$DAYS[$wday], $mday $MONTHS[$mon] $year");
|
||||
}
|
||||
|
||||
sub set_lock {
|
||||
|
||||
Index: config_parse.pl
|
||||
*** config_parse.pl.old Thu Apr 21 07:32:50 1994
|
||||
--- config_parse.pl Thu Apr 21 07:41:33 1994
|
||||
***************
|
||||
*** 128,133 ****
|
||||
--- 128,135 ----
|
||||
'digest_archive', '',
|
||||
'digest_rm_footer', '',
|
||||
'digest_rm_fronter', '',
|
||||
+ 'digest_maxlines', '',
|
||||
+ 'digest_maxdays', '',
|
||||
# general stuff below
|
||||
'comments', '', # comments about config file
|
||||
);
|
||||
***************
|
||||
*** 331,336 ****
|
||||
--- 333,346 ----
|
||||
Just like digest_rm_footer, it is also non-operative.',
|
||||
);
|
||||
|
||||
+ 'digest_maxlines',
|
||||
+ "automatically generate a new digest when the size of the digest exceeds
|
||||
+ this number of lines.",
|
||||
+
|
||||
+ 'digest_maxdays',
|
||||
+ "automatically generate a new digest when the age of the oldest article in
|
||||
+ the queue exceeds this number of days.",
|
||||
+
|
||||
# match commands to their subsystem, by default only 4 subsystems
|
||||
# exist, majordomo, resend, digest and config.
|
||||
%subsystem = (
|
||||
***************
|
||||
*** 372,377 ****
|
||||
--- 382,389 ----
|
||||
'digest_archive', 'digest',
|
||||
'digest_rm_footer', 'digest',
|
||||
'digest_rm_fronter', 'digest',
|
||||
+ 'digest_maxlines', 'digest',
|
||||
+ 'digest_maxdays', 'digest',
|
||||
# general stuff here
|
||||
'comments', 'config',
|
||||
);
|
||||
***************
|
||||
*** 418,423 ****
|
||||
--- 430,437 ----
|
||||
'digest_archive', 'grab_absolute_dir',
|
||||
'digest_rm_footer', 'grab_word',
|
||||
'digest_rm_fronter', 'grab_word',
|
||||
+ 'digest_maxlines', 'grab_integer',
|
||||
+ 'digest_maxdays', 'grab_integer',
|
||||
# general stuff below
|
||||
'comments', 'grab_string_array',
|
||||
);
|
||||
|
||||
--
|
||||
Paul Close pdc@sgi.com ...!{ames, decwrl, uunet}!sgi!pdc
|
||||
|
||||
No fate but what we make
|
||||
|
||||
45
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.num
vendored
Normal file
45
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.num
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
# Program name digest.num -- Digest numbering.
|
||||
#
|
||||
# Lindsay Haisley, FMP Computer Serivces (fmouse@fmp.com)
|
||||
#
|
||||
# Usage: digest.num -l list_name [-i issue_num] [-v volume_num]
|
||||
#
|
||||
# Sets number for next digest issue and volume number in the config file
|
||||
# for list list_name. If issue_num and volume_num are not supplied, they
|
||||
# are set to 0.
|
||||
|
||||
$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf";
|
||||
require "$cf";
|
||||
# chdir("$homedir");
|
||||
|
||||
require "shlock.pl";
|
||||
require "config_parse.pl";
|
||||
require "getopt.pl";
|
||||
|
||||
&Getopt('liv');
|
||||
die "No list config specified\n" if !defined($opt_l);
|
||||
die "List config file $opt_l.config does not exist\n" unless -e "$listdir/$opt_l.config";
|
||||
&get_config($listdir, $opt_l);
|
||||
|
||||
if (defined($opt_v)) {
|
||||
$volume = $opt_v;
|
||||
} else {
|
||||
$volume = 0;
|
||||
}
|
||||
|
||||
if (defined($opt_i)) {
|
||||
$issue = $opt_i;
|
||||
} else {
|
||||
$issue = 0;
|
||||
}
|
||||
|
||||
$config_opts{$opt_l, "digest_volume"} = $volume;
|
||||
$config_opts{$opt_l, "digest_issue"} = $issue;
|
||||
|
||||
&set_lock("$listdir/$opt_l.config.LOCK");
|
||||
&config'writeconfig($listdir, $opt_l);
|
||||
&free_lock("$listdir/$opt_l.config.LOCK");
|
||||
print STDERR "Config for list $opt_l set to volume $volume, issue $issue\n";
|
||||
|
||||
28
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.send
vendored
Normal file
28
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/digest.send
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#! /bin/sh
|
||||
# This script was contributed by "Paul Pomes" <P-Pomes@uiuc.edu>
|
||||
#
|
||||
# It only works with versions of "digest" that have been modified
|
||||
# to work with the config file moddifications in majordomo 1.90 and above.
|
||||
# This script can be called from cron to automatically generate
|
||||
# digests for all of the lists in DIGESTDIR. E.G.
|
||||
#
|
||||
# daily
|
||||
# 0 2 * * * /path/to/digest.send
|
||||
#
|
||||
# weekly (on monday)
|
||||
# 0 2 * * 1 /path/to/digest.send
|
||||
#
|
||||
# monthly (first of the month)
|
||||
# 0 2 1 * * /path/to/digest.send
|
||||
#
|
||||
DIGESTDIR=/usr/spool/digests
|
||||
cd $DIGESTDIR
|
||||
|
||||
for i in *
|
||||
do
|
||||
if [ -f $i/001 ];
|
||||
then
|
||||
/path/to/majordomo/wrapper digest -m -C -l $i ${i}-outgoing
|
||||
fi
|
||||
done
|
||||
|
||||
156
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl
vendored
Normal file
156
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/logsummary.pl
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/bin/perl
|
||||
#
|
||||
# Print various statistics about the Log file
|
||||
#
|
||||
# Todo: summarize admin commands
|
||||
#
|
||||
# Paul Close, April 1994
|
||||
#
|
||||
|
||||
while (<>) {
|
||||
if (($mon,$day,$time,$who,$cmd) =
|
||||
/([A-Za-z]+) (\d+) ([\d:]+)\s+.*majordomo\[\d+\]\s+{(.*)} (.*)/)
|
||||
{
|
||||
@f = split(' ',$cmd);
|
||||
$cmd = $f[0];
|
||||
$f[1] =~ s/[<>]//g;
|
||||
$f[2] =~ s/[<>]//g;
|
||||
$count{$cmd}++;
|
||||
|
||||
# help
|
||||
# lists
|
||||
# which [address]
|
||||
# approve PASSWD ...
|
||||
if ($cmd eq "approve" ||
|
||||
$cmd eq "help" ||
|
||||
$cmd eq "lists" ||
|
||||
$cmd eq "which")
|
||||
{
|
||||
${$cmd}++;
|
||||
}
|
||||
|
||||
# index list
|
||||
# info list
|
||||
# who list
|
||||
elsif ($cmd eq "index" ||
|
||||
$cmd eq "info" ||
|
||||
$cmd eq "who")
|
||||
{
|
||||
if ($#f == 1) {
|
||||
$lists{$f[1]}++;
|
||||
$f[1] =~ s/-//g;
|
||||
${$f[1]}{$cmd}++;
|
||||
} else {
|
||||
$bad{$cmd}++;
|
||||
}
|
||||
}
|
||||
|
||||
# get list file
|
||||
# newinfo list passwd
|
||||
elsif ($cmd eq "get" ||
|
||||
$cmd eq "newinfo")
|
||||
{
|
||||
if ($#f == 2) {
|
||||
$lists{$f[1]}++;
|
||||
$f[1] =~ s/-//g;
|
||||
${$f[1]}{$cmd}++;
|
||||
if ($cmd eq "get") {
|
||||
$req = &ParseAddrs($who);
|
||||
$long{$req} = $who;
|
||||
$getcount{$req}++;
|
||||
}
|
||||
} else {
|
||||
$bad{$cmd}++;
|
||||
}
|
||||
}
|
||||
|
||||
# subscribe list [address]
|
||||
# unsubscribe list [address]
|
||||
elsif ($cmd eq "subscribe" ||
|
||||
$cmd eq "unsubscribe")
|
||||
{
|
||||
if ($#f >= 1) {
|
||||
$lists{$f[1]}++;
|
||||
$f[1] =~ s/-//g;
|
||||
${$f[1]}{$cmd}++;
|
||||
} else {
|
||||
$bad{$cmd}++;
|
||||
}
|
||||
}
|
||||
|
||||
# request cmd list subscribe (for approval)
|
||||
elsif ($cmd eq "request") {
|
||||
if ($#f >= 2) {
|
||||
$lists{$f[2]}++;
|
||||
$f[2] =~ s/-//g;
|
||||
${$f[2]}{$cmd}++;
|
||||
} else {
|
||||
$bad{$cmd}++;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$unrecognized{$cmd}++;
|
||||
}
|
||||
} else {
|
||||
warn "line $. didn't match!\n" if !/^$/;
|
||||
}
|
||||
}
|
||||
|
||||
#print "Command summary:\n";
|
||||
#foreach $cmd (sort keys %count) {
|
||||
# printf " %-20s %4d\n", $cmd, $count{$cmd};
|
||||
#}
|
||||
|
||||
print "Global commands:\n";
|
||||
printf(" %-15s %4d\n", "help", $help) if defined($help);
|
||||
printf(" %-15s %4d\n", "lists", $lists) if defined($lists);
|
||||
printf(" %-15s %4d\n", "which", $which) if defined($which);
|
||||
print "\n";
|
||||
|
||||
#print "Unrecognized commands:\n";
|
||||
#foreach $cmd (sort keys %unrecognized) {
|
||||
# printf " %-15s %4d\n", $cmd, $unrecognized{$cmd};
|
||||
#}
|
||||
#print "\n";
|
||||
|
||||
if (defined(%bad)) {
|
||||
print "Incomplete commands:\n";
|
||||
foreach $cmd (sort keys %bad) {
|
||||
printf " %-15s %4d\n", $cmd, $bad{$cmd};
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
# skip request and newinfo
|
||||
print "List subscr unsub index get info who config approve\n";
|
||||
foreach $list (sort keys %lists) {
|
||||
printf "%-20s", substr($list,0,20);
|
||||
$list =~ s/-//g;
|
||||
%l = %{$list};
|
||||
printf " %6d %6d %6d %6d %6d %6d %6d %6d\n", $l{subscribe}, $l{unsubscribe},
|
||||
$l{index}, $l{get}, $l{info}, $l{who}, $l{config}, $l{approve};
|
||||
}
|
||||
print "\n";
|
||||
|
||||
@reqs = sort {$getcount{$b}<=>$getcount{$a};} keys %getcount;
|
||||
if ($#reqs >= 0) {
|
||||
print "Top requestors (get command):\n";
|
||||
for ($i=0; $i < 5; $i++) {
|
||||
printf " %5d %s\n", $getcount{$reqs[$i]}, $long{$reqs[$i]};
|
||||
last if ($i == $#reqs);
|
||||
}
|
||||
}
|
||||
|
||||
# from majordomo.pl, modified to work on a single address
|
||||
# $addrs = &ParseAddrs($addr_list)
|
||||
sub ParseAddrs {
|
||||
local($_) = shift;
|
||||
1 while s/\([^\(\)]*\)//g; # strip comments
|
||||
1 while s/"[^"]*"//g; # strip comments
|
||||
1 while s/.*<(.*)>.*/\1/;
|
||||
s/^\s+//;
|
||||
s/\s+$//;
|
||||
$_;
|
||||
}
|
||||
|
||||
98
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl
vendored
Normal file
98
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/makeindex.pl
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
#!/bin/perl
|
||||
#
|
||||
# Given an archive directory, create a table of contents file and a topics
|
||||
# file. The table of contents file simply lists each subject that appears
|
||||
# in each archive file, while the topics file is a list of each unique
|
||||
# subject and the files that subject appears in.
|
||||
#
|
||||
# I run this from cron every night....
|
||||
#
|
||||
# Paul Close, April 1994
|
||||
#
|
||||
|
||||
if ($#ARGV != -1) {
|
||||
$dir = $ARGV[0];
|
||||
shift;
|
||||
}
|
||||
else {
|
||||
die "usage: $0 archive_directory\n";
|
||||
}
|
||||
|
||||
opendir(FILES, $dir) || die "Can't open directory $dir: $!\n";
|
||||
@files = readdir(FILES); # get all files in archive directory
|
||||
closedir(FILES);
|
||||
|
||||
open(INDEX,">$dir/CONTENTS") || die "Can't open $dir/CONTENTS: $!\n";
|
||||
open(TOPICS,">$dir/TOPICS") || die "Can't open $dir/TOPICS: $!\n";
|
||||
|
||||
foreach $basename (@files) {
|
||||
next if $basename eq '.';
|
||||
next if $basename eq '..';
|
||||
next if $basename eq "CONTENTS";
|
||||
next if $basename eq "TOPICS";
|
||||
print INDEX "\n$basename:\n";
|
||||
open(FILE, "$dir/$basename") || next;
|
||||
while (<FILE>) {
|
||||
if (/^Subject:\s+(.*)/i) {
|
||||
($subj = $1) =~ s/\s*$//;
|
||||
next if $subj eq "";
|
||||
#
|
||||
# for index file, just print the subject
|
||||
#
|
||||
print INDEX " $subj\n";
|
||||
#
|
||||
# for topics file, strip Re:'s, remove digest postings,
|
||||
# and trim the length to 40 chars for pretty-printing.
|
||||
#
|
||||
1 while ($subj =~ s/^Re(\[\d+\]|2?):\s*//i); # trim all Re:'s
|
||||
next if $subj eq "";
|
||||
next if $subj =~ /[A-Za-z]+ Digest, Volume \d+,/i;
|
||||
next if $subj =~ /[A-Za-z]+ Digest V\d+ #\d+/i;
|
||||
if (length($subj) > 40) {
|
||||
$subj = substr($subj, 0, 37) . "...";
|
||||
}
|
||||
#
|
||||
# Make a key that's all lower case, and no whitespace to
|
||||
# reduce duplicate topics that differ only by those. This
|
||||
# also results in a list of topics sorted case-independent.
|
||||
#
|
||||
($key = $subj) =~ tr/A-Z/a-z/;
|
||||
$key =~ s/\s+//g;
|
||||
$subjlist{$key} .= "$basename,";
|
||||
if (!defined($realsubj{$key})) {
|
||||
$realsubj{$key} = $subj;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(FILE);
|
||||
}
|
||||
close(INDEX);
|
||||
|
||||
foreach $subj (sort keys %subjlist) {
|
||||
#
|
||||
# for each subject, record each file it was found in
|
||||
#
|
||||
undef %found;
|
||||
undef @names;
|
||||
for (split(",", $subjlist{$subj})) {
|
||||
$found{$_} = 1;
|
||||
}
|
||||
#
|
||||
# make list of 'found' names and wrap at 80 columns
|
||||
#
|
||||
$names = join(", ", sort keys %found);
|
||||
undef @namelist;
|
||||
while (length($names) > 40) {
|
||||
$index = 40;
|
||||
$index-- until (substr($names, $index, 1) eq " " || $index < 0);
|
||||
push(@namelist,substr($names,0,$index));
|
||||
$names = substr($names,$index+1);
|
||||
}
|
||||
push(@namelist,$names);
|
||||
printf TOPICS "%-40s %s\n", $realsubj{$subj}, $namelist[0];
|
||||
for ($i=1; $i <= $#namelist; $i++) {
|
||||
print TOPICS " " x 41, $namelist[$i], "\n";
|
||||
}
|
||||
}
|
||||
close(TOPICS);
|
||||
|
||||
103
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/new-list
vendored
Normal file
103
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/new-list
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
#!/bin/perl
|
||||
|
||||
|
||||
# $Source: /sources/cvsrepos/majordomo/contrib/new-list,v $
|
||||
# $Revision: 1.14 $
|
||||
# $Date: 1996/12/09 16:50:45 $
|
||||
# $Author: cwilson $
|
||||
# $State: Exp $
|
||||
#
|
||||
# $Locker: $
|
||||
|
||||
# set our path explicitly
|
||||
$ENV{'PATH'} = "/bin:/usr/bin:/usr/ucb";
|
||||
|
||||
# Read and execute the .cf file
|
||||
$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf";
|
||||
if ($ARGV[0] eq "-C") {
|
||||
$cf = $ARGV[1];
|
||||
shift(@ARGV);
|
||||
shift(@ARGV);
|
||||
}
|
||||
if (! -r $cf) {
|
||||
die("$cf not readable; stopped");
|
||||
}
|
||||
require "$cf";
|
||||
|
||||
chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");
|
||||
unshift(@INC, $homedir);
|
||||
require "majordomo.pl";
|
||||
require "shlock.pl";
|
||||
|
||||
&ParseMailHeader(STDIN, *hdrs);
|
||||
$reply_to = &RetMailAddr(*hdrs);
|
||||
$reply_to = join(", ", &ParseAddrs($reply_to));
|
||||
die("new-list: $reply_to is not a valid return address.\n")
|
||||
if (! &valid_addr($reply_to));
|
||||
|
||||
$in_reply_to = $hdrs{"message-id"} . ", from " . $hdrs{"from"};
|
||||
$list = $ARGV[0];
|
||||
|
||||
# Define all of the mailer properties:
|
||||
# It is possible that one or both of $sendmail_command and $bounce_mailer
|
||||
# are not defined, so we provide reasonable defaults.
|
||||
$sendmail_command = "/usr/lib/sendmail"
|
||||
unless defined $sendmail_command;
|
||||
$bounce_mailer = "$sendmail_command -f\$sender -t"
|
||||
unless defined $bounce_mailer;
|
||||
|
||||
$sender = "$list-approval";
|
||||
|
||||
$mailcmd = eval qq/"$bounce_mailer"/;
|
||||
|
||||
if (defined($isParent = open(MAIL, "|-"))) {
|
||||
&do_exec_sendmail(split(' ', $mailcmd))
|
||||
unless $isParent;
|
||||
} else {
|
||||
&abort("Failed to fork prior to mailer exec");
|
||||
}
|
||||
|
||||
|
||||
print MAIL <<"EOM";
|
||||
To: $reply_to
|
||||
Cc: $list-approval
|
||||
From: $list-approval
|
||||
Subject: Your mail to $list\@$whereami
|
||||
In-Reply-To: $in_reply_to
|
||||
Reply-To: $list-approval\@$whereami
|
||||
|
||||
This pre-recorded message is being sent in response to your recent
|
||||
email to $list\@$whereami.
|
||||
|
||||
If you were trying to subscribe to the list, please send your request
|
||||
to $whoami, not to $list\@$whereami.
|
||||
|
||||
This is a new list. Your message is being returned unsent, but please
|
||||
hold on to it. After a few days, when the flood of subscription
|
||||
requests has died down somewhat, the owner of the list will announce
|
||||
that the list is "open for business"; you should resubmit your posting
|
||||
then. This way, everybody who joins the list within the first few days
|
||||
of its existence starts out on an even footing, and we don't end up
|
||||
with every other message asking "what did I miss?".
|
||||
|
||||
Here's your original, unsent message:
|
||||
|
||||
EOM
|
||||
;
|
||||
|
||||
foreach ("From", "To", "Cc", "Subject", "Date", "Message-ID") {
|
||||
($hdr = $_) =~ tr/A-Z/a-z/;
|
||||
if (defined($hdrs{$hdr})) {
|
||||
print MAIL $_, ": ", $hdrs{$hdr}, "\n";
|
||||
}
|
||||
}
|
||||
|
||||
print MAIL "\n";
|
||||
|
||||
while (<STDIN>) {
|
||||
print MAIL $_;
|
||||
}
|
||||
|
||||
close(MAIL);
|
||||
|
||||
exit 0;
|
||||
559
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/sequencer
vendored
Normal file
559
directadmin-1.62.4/scripts/packages/majordomo-1.94.5/contrib/sequencer
vendored
Normal file
@@ -0,0 +1,559 @@
|
||||
#!/usr/bin/perl -U
|
||||
|
||||
# Copyright 1996 MACS, Inc.
|
||||
# Copyright 1992, D. Brent Chapman. See the Majordomo license agreement
|
||||
# for usage rights.
|
||||
#
|
||||
# $Source: /sources/cvsrepos/majordomo/contrib/sequencer,v $
|
||||
# $Revision: 1.2 $
|
||||
# $Date: 1996/12/09 16:50:48 $
|
||||
# $Author: cwilson $
|
||||
# $State: Exp $
|
||||
#
|
||||
# $Locker: $
|
||||
#
|
||||
|
||||
# sequence - a program for sequencing and archiving e-mail messages
|
||||
# from majordomo
|
||||
#
|
||||
# Based heavily upon the resend script included in the majordomo distribution
|
||||
|
||||
# set our path explicitly
|
||||
$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin";
|
||||
|
||||
# What shall we use for temporary files?
|
||||
$tmp = "/tmp/majordomo.$$";
|
||||
|
||||
# Before doing anything else tell the world I am sequencer
|
||||
# The mj_ prefix is reserved for tools that are part of majordomo proper.
|
||||
$main'program_name = 'sequencer';
|
||||
|
||||
|
||||
# If the first argument is "@filename", read the real arguments
|
||||
# from "filename", and shove them onto the ARGV for later processing
|
||||
# by &Getopts()
|
||||
|
||||
if ($ARGV[0] =~ /^@/) {
|
||||
$fn = shift(@ARGV);
|
||||
$fn =~ s/^@//;
|
||||
open(AV, $fn) || die("open(AV, \"$fn\"): $!\nStopped");
|
||||
undef($/); # set input field separator
|
||||
$av = <AV>; # read whole file into string
|
||||
close(AV);
|
||||
@av = split(/\s+/, $av);
|
||||
unshift(@ARGV, @av);
|
||||
$/ = "\n";
|
||||
}
|
||||
|
||||
# Read and execute the .cf file
|
||||
$cf = $ENV{"MAJORDOMO_CF"} || "/etc/majordomo.cf";
|
||||
if ($ARGV[0] eq "-C") {
|
||||
$cf = $ARGV[1];
|
||||
shift(@ARGV);
|
||||
shift(@ARGV);
|
||||
}
|
||||
if (! -r $cf) {
|
||||
die("$cf not readable; stopped");
|
||||
}
|
||||
require "$cf";
|
||||
|
||||
chdir($homedir) || die("Can't chdir(\"$homedir\"): $!");
|
||||
unshift(@INC, $homedir);
|
||||
use Getopt::Std;
|
||||
require "majordomo.pl";
|
||||
require "majordomo_version.pl";
|
||||
require "config_parse.pl";
|
||||
require "shlock.pl";
|
||||
|
||||
getopts("Aa:df:h:I:l:m:M:nNp:Rr:s") || die("sequencer: Getopts() failed: $!");
|
||||
|
||||
if (! defined($opt_l) || ! defined($opt_h)) {
|
||||
die("sequencer: must specify both '-l list' and '-h host' arguments");
|
||||
}
|
||||
|
||||
# smash case for the list name
|
||||
$opt_l =~ tr/A-Z/a-z/;
|
||||
|
||||
if ( ! @ARGV) {
|
||||
die("sequencer: must specify outgoing list as last arg(s)");
|
||||
}
|
||||
|
||||
$opt_r = "$opt_r@$opt_h" if ( defined($opt_r) );
|
||||
|
||||
&get_config($listdir, $opt_l);
|
||||
|
||||
$opt_A = &cf_ck_bool($opt_l,"moderate") if &cf_ck_bool($opt_l,"moderate");
|
||||
$opt_h = $config_opts{$opt_l,"resend_host"}
|
||||
if($config_opts{$opt_l,"resend_host"} ne '');
|
||||
$opt_a = $config_opts{$opt_l,"approve_passwd"}
|
||||
if ($config_opts{$opt_l,"approve_passwd"} ne '');
|
||||
$opt_M = $config_opts{$opt_l,"maxlength"}
|
||||
if ($config_opts{$opt_l,"maxlength"} ne '');
|
||||
|
||||
$opt_f = $config_opts{$opt_l,"sender"}
|
||||
if ($config_opts{$opt_l,"sender"} ne '');
|
||||
$opt_p = $config_opts{$opt_l,"precedence"}
|
||||
if ($config_opts{$opt_l,"precedence"} ne '');
|
||||
$opt_r = $config_opts{$opt_l,"reply_to"}
|
||||
if ($config_opts{$opt_l,"reply_to"} ne '');
|
||||
$opt_I = $config_opts{$opt_l,"restrict_post"}
|
||||
if ($config_opts{$opt_l,"restrict_post"} ne '');
|
||||
$opt_R = &cf_ck_bool($opt_l,"purge_received")
|
||||
if &cf_ck_bool($opt_l,"purge_received");
|
||||
$opt_s = &cf_ck_bool($opt_l,"administrivia")
|
||||
if &cf_ck_bool($opt_l,"administrivia");
|
||||
$opt_d = &cf_ck_bool($opt_l,"debug")
|
||||
if &cf_ck_bool($opt_l,"debug");
|
||||
|
||||
if (defined($opt_f)) {
|
||||
$sendmail_sender = $opt_f;
|
||||
} else {
|
||||
$sendmail_sender = "$opt_l-request";
|
||||
}
|
||||
|
||||
if (defined($opt_a)) {
|
||||
if ($opt_a =~ /^\//) {
|
||||
open(PWD, $opt_a) || die("sequencer: open(PWD, \"$opt_a\"): $!");
|
||||
$opt_a = &chop_nl(<PWD>);
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($opt_A) && ! defined($opt_a)) {
|
||||
die("sequencer: must also specify '-a passwd' if using '-A' flag");
|
||||
}
|
||||
|
||||
# code added for getting new sequence number
|
||||
|
||||
if (defined($opt_N)) {
|
||||
$opt_n = $opt_N;
|
||||
}
|
||||
|
||||
if (defined($opt_n)) {
|
||||
$seqfile = "$listdir/$opt_l.seq";
|
||||
if (! -r $seqfile) { # if there is no sequence file, make one
|
||||
open(SEQ, ">$seqfile") || die("sequencer: open of $seqfile failed: $!");
|
||||
print SEQ "1\n";
|
||||
close SEQ;
|
||||
}
|
||||
&main'lopen(SEQ, "<", "$seqfile") || die("sequencer: locked open of $seqfile failed: $!");
|
||||
chop($seqnum = <SEQ>);
|
||||
|
||||
# note that the sequence file is opened and locked from here until
|
||||
# the message is sent
|
||||
|
||||
}
|
||||
|
||||
|
||||
$sender = "$sendmail_sender@$opt_h";
|
||||
|
||||
&open_temp(OUT, "/tmp/sequencer.$$.out") ||
|
||||
&abort("sequencer:1 Can't open /tmp/sequencer.$$.out: $!");
|
||||
|
||||
&open_temp(IN, "/tmp/sequencer.$$.in") ||
|
||||
&abort("sequencer: Can't open /tmp/sequencer.$$.in: $!");
|
||||
|
||||
while (<STDIN>) {
|
||||
print IN $_;
|
||||
}
|
||||
|
||||
close(IN);
|
||||
|
||||
open(IN, "/tmp/sequencer.$$.in") ||
|
||||
die("sequencer: Can't open /tmp/sequencer.$$.tmp: $!");
|
||||
|
||||
do {
|
||||
$restart = 0;
|
||||
$pre_hdr = 1;
|
||||
while (<IN>) {
|
||||
if ($pre_hdr) {
|
||||
if (/^\s*$/) {
|
||||
# skip leading blank lines; usually only there if this is a
|
||||
# restart after an in-body "Approved:" line
|
||||
next;
|
||||
} else {
|
||||
$pre_hdr = 0;
|
||||
$in_hdr = 1;
|
||||
$kept_last = 0;
|
||||
}
|
||||
}
|
||||
if ($in_hdr) {
|
||||
if (/^\s*$/) {
|
||||
# end of header; add new header fields
|
||||
# if there is no subject, create one
|
||||
if (!defined($subject)) {
|
||||
local($foo);
|
||||
if ($config_opts{$opt_l,"subject_prefix"} ne '') {
|
||||
$foo = &config'substitute_values(
|
||||
$config_opts{$opt_l,"subject_prefix"}, $opt_l);
|
||||
# for sequencing we add a special keyword!
|
||||
if (defined($opt_n)) {
|
||||
$foo =~ s/\$SEQNUM/$seqnum/;
|
||||
}
|
||||
local($foo_pat) = $foo;
|
||||
$foo_pat =~ s/(\W)/\\$1/g;
|
||||
if (!/$foo_pat/) {
|
||||
$foo = $foo . " ";
|
||||
}
|
||||
}
|
||||
$subject = $foo . "Message for " . $opt_l;
|
||||
print OUT $subject, "\n";
|
||||
}
|
||||
|
||||
print OUT "Sender: $sender\n";
|
||||
if (defined($opt_p)) {
|
||||
print OUT "Precedence: $opt_p\n";
|
||||
}
|
||||
if (defined($opt_r)) {
|
||||
print OUT "Reply-To: ", &config'substitute_values($opt_r),
|
||||
"\n";
|
||||
}
|
||||
|
||||
# print out additonal headers
|
||||
if ( $config_opts{$opt_l,"message_headers"} ne '' ) {
|
||||
local($headers) = &config'substitute_values (
|
||||
$config_opts{$opt_l,"message_headers"}, $opt_l);
|
||||
$headers =~ s/\001/\n/g;
|
||||
print OUT $headers;
|
||||
}
|
||||
|
||||
$in_hdr = 0;
|
||||
print OUT $_;
|
||||
|
||||
# print out front matter
|
||||
if ( $config_opts{$opt_l,"message_fronter"} ne '' ) {
|
||||
local($fronter) = &config'substitute_values (
|
||||
$config_opts{$opt_l,"message_fronter"}, $opt_l);
|
||||
$fronter =~ s/\001|$/\n/g;
|
||||
print OUT $fronter;
|
||||
}
|
||||
} elsif (/^approved:\s*(.*)/i && defined($opt_a)) {
|
||||
$approved = &chop_nl($1);
|
||||
if ($approved ne $opt_a &&
|
||||
!(&main'valid_passwd($listdir, $opt_l, $approved))) {
|
||||
&bounce("Invalid 'Approved:' header");
|
||||
}
|
||||
} elsif (/^from /i # skip all these headers
|
||||
|| /^sender:/i
|
||||
|| /^return-receipt-to:/i
|
||||
|| /^errors-to:/i
|
||||
|| /^return-path:/i
|
||||
|| (/^reply-to:/i && defined($opt_r)) # skip only if "-r" set
|
||||
|| (/^precedence:/i && defined($opt_p)) # skip only if "-p" set
|
||||
|| (/^received:/i && defined($opt_R)) # skip only if "-R" set
|
||||
|| (/^\s/ && ! $kept_last) # skip if skipped last
|
||||
) {
|
||||
# reset $kept_last in case next line is continuation
|
||||
$kept_last = 0;
|
||||
} else {
|
||||
# check for administrivia requests
|
||||
if (defined($opt_s) && ! defined($approved)
|
||||
&& (/^subject:\s*subscribe\b/i ||
|
||||
/^subject:\s*unsubscribe\b/i ||
|
||||
/^subject:\s*help\b/i ||
|
||||
/^subject:\s*RCPT:\b/ ||
|
||||
/^subject:\s*Delivery Confirmation\b/ ||
|
||||
/^subject:\s*NON-DELIVERY of:/ ||
|
||||
/^subject:\s*Undeliverable Message\b/ ||
|
||||
/^subject:\s*Receipt Confirmation\b/ ||
|
||||
/^subject:\s*Failed mail\b/ ||
|
||||
/^subject:\s.*\bchange\b.*\baddress\b/ ||
|
||||
/^subject:\s*request\b.*\baddition\b/i)) {
|
||||
&bounce("Admin request");
|
||||
}
|
||||
|
||||
# prepend subject prefix
|
||||
if ( (/^subject:\s*/i) &&
|
||||
($config_opts{$opt_l,"subject_prefix"} ne '')
|
||||
) {
|
||||
local($foo) = &config'substitute_values(
|
||||
$config_opts{$opt_l,"subject_prefix"}, $opt_l);
|
||||
# for sequencing we add a special keyword!
|
||||
if (defined($opt_n)) {
|
||||
$foo =~ s/\$SEQNUM/$seqnum/;
|
||||
}
|
||||
$subject = $_;
|
||||
$subject =~ s/^subject:\s*(.*)/$1/i;
|
||||
$subject = &chop_nl($foo . " " . $subject);
|
||||
local($foo_pat) = $foo;
|
||||
$foo_pat =~ s/(\W)/\\$1/g;
|
||||
s/^subject:\s*/Subject: $foo /i if !/$foo_pat/;
|
||||
}
|
||||
|
||||
if ( /^from:\s*(.+)/i )
|
||||
{
|
||||
$from = $1;
|
||||
$from_last = 1;
|
||||
}
|
||||
elsif ( defined($from_last) )
|
||||
{
|
||||
if ( /^\s+(.+)/ )
|
||||
{
|
||||
$from .= " $1";
|
||||
}
|
||||
else
|
||||
{
|
||||
undef($from_last);
|
||||
}
|
||||
}
|
||||
&check_hdr_line($_); # check for length & balance
|
||||
$kept_last = 1;
|
||||
print OUT $_;
|
||||
}
|
||||
} else {
|
||||
# this isn't a header line, so print it (maybe)
|
||||
# first, though, is the first line of the body an "Approved:" line?
|
||||
if (($body_len == 0) && /^approved:\s*(.*)/i && defined($opt_a)) {
|
||||
# OK, is it a valid "Approved:" line?
|
||||
$approved = &chop_nl($1);
|
||||
if ($approved ne $opt_a &&
|
||||
!(&main'valid_passwd($listdir, $opt_l, $approved))) {
|
||||
&bounce("Invalid 'Approved:' header");
|
||||
} else {
|
||||
# Yes, it's a valid "Approved:" line...
|
||||
# So, we start over
|
||||
$restart = 1;
|
||||
close(OUT);
|
||||
unlink("/tmp/sequencer.$$.out");
|
||||
&open_temp(OUT, "/tmp/sequencer.$$.out") ||
|
||||
&abort("sequencer:2 Can't open /tmp/sequencer.$$.out: $!");
|
||||
last;
|
||||
}
|
||||
}
|
||||
$body_len += length($_);
|
||||
# make sure it doesn't make the message too long
|
||||
if (defined($opt_M) && ! defined($approved)
|
||||
&& ($body_len > $opt_M)) {
|
||||
&bounce("Message too long (>$opt_M)");
|
||||
}
|
||||
# add admin-request recognition heuristics here... (body)
|
||||
if (defined($opt_s) && ! defined($approved) && ($body_line++ < 5) && (
|
||||
/\badd me\b/i
|
||||
|| /\bdelete me\b/i || /\bremove\s+me\b/i
|
||||
|| /\bchange\b.*\baddress\b/
|
||||
|| /\bsubscribe\b/i || /^sub\b/i
|
||||
|| /\bunsubscribe\b/i || /^unsub\b/i
|
||||
|| /^\s*help\s*$/i # help
|
||||
|| /^\s*info\s*$/i # info
|
||||
|| /^\s*info\s+\S+\s*$/i # info list
|
||||
|| /^\s*lists\s*$/i # lists
|
||||
|| /^\s*which\s*$/i # which
|
||||
|| /^\s*which\s+\S+\s*$/i # which address
|
||||
|| /^\s*index\s*$/i # index
|
||||
|| /^\s*index\s+\S+\s*$/i # index list
|
||||
|| /^\s*who\s*$/i # who
|
||||
|| /^\s*who\s+\S+\s*$/i # who list
|
||||
|| /^\s*get\s+\S+\s*$/i # get file
|
||||
|| /^\s*get\s+\S+\s+\S+\s*$/i # get list file
|
||||
|| /^\s*approve\b/i
|
||||
|| /^\s*passwd\b/i
|
||||
|| /^\s*newinfo\b/i
|
||||
|| /^\s*config\b/i
|
||||
|| /^\s*newconfig\b/i
|
||||
|| /^\s*writeconfig\b/i
|
||||
|| /^\s*mkdigest\b/i
|
||||
)) {
|
||||
&bounce("Admin request");
|
||||
}
|
||||
print OUT $_;
|
||||
}
|
||||
}
|
||||
} while ($restart);
|
||||
|
||||
if ( $config_opts{$opt_l,"message_footer"} ne '' ) {
|
||||
local($footer) = &config'substitute_values(
|
||||
$config_opts{$opt_l,"message_footer"}, $opt_l);
|
||||
$footer =~ s/\001/\n/g;
|
||||
print OUT $footer;
|
||||
}
|
||||
|
||||
close(OUT);
|
||||
|
||||
if ( defined($opt_I) && defined($from) && ! defined($approved) ) {
|
||||
local($infile) = 0;
|
||||
|
||||
@files = split (/[:\t\n]+/, $opt_I);
|
||||
|
||||
foreach $file (@files) {
|
||||
if ($file !~ /^\//) {
|
||||
$file = "$listdir/$file";
|
||||
}
|
||||
if ( open (LISTFD, "<${file}") != 0 ) {
|
||||
@output = grep (&addr_match($from, $_), <LISTFD>);
|
||||
close (LISTFD);
|
||||
|
||||
if ( $#output != -1 ) {
|
||||
$infile = 1;
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
die("sequencer:Can't open $file: $!");
|
||||
}
|
||||
}
|
||||
|
||||
if ( $infile == 0 ) {
|
||||
&bounce ("Non-member submission from [$from]");
|
||||
}
|
||||
}
|
||||
|
||||
if (defined($opt_A) && ! defined($approved)) {
|
||||
&bounce("Approval required");
|
||||
}
|
||||
|
||||
$sendmail_cmd = "/usr/lib/sendmail $opt_m -f$sendmail_sender " .
|
||||
join(" ", @ARGV);
|
||||
|
||||
if (defined($opt_d)) {
|
||||
$| = 1;
|
||||
print "Command: $sendmail_cmd\n";
|
||||
$status = (system("cat /tmp/sequencer.$$.out") >> 8);
|
||||
unlink(</tmp/sequencer.$$.*>);
|
||||
|
||||
#remember to unlock the sequence file here!
|
||||
if (defined($opt_n)) {
|
||||
&main'lclose(SEQ);
|
||||
}
|
||||
exit($status);
|
||||
} else {
|
||||
local(*MAILOUT, *MAILIN, @mailer);
|
||||
@mailer = split(' ', "$sendmail_cmd");
|
||||
open(MAILOUT, "|-") || &do_exec_sendmail(@mailer);
|
||||
# create archival copy
|
||||
if (defined($opt_N)) {
|
||||
if (open (INDEX, ">>$filedir/$opt_l$filedir_suffix/INDEX")) {
|
||||
$timenow = localtime(time);
|
||||
printf(INDEX "%s\n\tFrom %s on %s\n", $subject, $from, $timenow);
|
||||
close (INDEX);
|
||||
}
|
||||
open (ARCHIVE, ">$filedir/$opt_l$filedir_suffix/$seqnum");
|
||||
}
|
||||
open(MAILIN, "/tmp/sequencer.$$.out");
|
||||
while (<MAILIN>) {
|
||||
print MAILOUT $_;
|
||||
if (defined($opt_N)) {
|
||||
print ARCHIVE $_;
|
||||
}
|
||||
}
|
||||
close(MAILOUT);
|
||||
if (defined($opt_N)) {
|
||||
close(ARCHIVE);
|
||||
}
|
||||
if (defined($opt_n)) {
|
||||
$seqnum++;
|
||||
&main'lreopen(SEQ, ">", "$seqfile");
|
||||
print SEQ $seqnum, "\n";
|
||||
&main'lclose(SEQ);
|
||||
}
|
||||
close(MAILIN);
|
||||
unlink(</tmp/sequencer.$$.*>);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sub check_balance {
|
||||
# set a temporary variable
|
||||
local($t) = shift;
|
||||
# strip out all nested parentheses
|
||||
1 while $t =~ s/\([^\(\)]*\)//g;
|
||||
# strip out all nested angle brackets
|
||||
1 while $t =~ s/\<[^\<\>]*\>//g;
|
||||
# if any parentheses or angle brackets remain, were imbalanced
|
||||
if ($t =~ /[\(\)\<\>]/ && ! defined($approved)) {
|
||||
&bounce("Imbalanced parentheses or angle brackets");
|
||||
return(undef);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
sub check_hdr_line {
|
||||
|
||||
local($_) = shift;
|
||||
|
||||
if (! /^\s/) { # is this a continuation line?
|
||||
# Not a continuation line.
|
||||
# If $balanced_fld is defined, it means the last field was one
|
||||
# that needed to have balanced "()" and "<>" (i.e., "To:", "From:",
|
||||
# and "Cc:", so check it. We do it here in case the last field was
|
||||
# multi-line.
|
||||
|
||||
if (defined($balanced_fld)) {
|
||||
&check_balance($balanced_fld);
|
||||
}
|
||||
|
||||
# we undefine $balanced_fld and reset $field_len; these may be set below
|
||||
|
||||
undef($balanced_fld);
|
||||
$field_len = 0;
|
||||
}
|
||||
|
||||
# is this a field that must be checked for balanced "()" and "<>"?
|
||||
if (defined($balanced_fld) || /^from:/i || /^cc:/i || /^to:/i) {
|
||||
# yes it is, but we can't check it yet because there might be
|
||||
# continuation lines. Buffer it to be checked at the beginning
|
||||
# of the next non-continuation line.
|
||||
|
||||
# is this line too long?
|
||||
if ((length($_) > 128) && ! defined($approved)) {
|
||||
&bounce("Header line too long (>128)");
|
||||
return(undef);
|
||||
}
|
||||
|
||||
# is this field too long?
|
||||
if ((($field_len += length($_)) > 1024) && ! defined($approved)) {
|
||||
&bounce("Header field too long (>1024)");
|
||||
return(undef);
|
||||
}
|
||||
|
||||
$balanced_fld .= $_;
|
||||
chop($balanced_fld);
|
||||
}
|
||||
|
||||
# if we get here, everything was OK.
|
||||
return(1);
|
||||
}
|
||||
|
||||
sub bounce {
|
||||
local($reason) = shift;
|
||||
local($_);
|
||||
|
||||
&resend_sendmail(BOUNCE, $sender, "BOUNCE $opt_l@$opt_h: $reason");
|
||||
|
||||
seek(IN, 0, 0);
|
||||
while (<IN>) {
|
||||
print BOUNCE $_;
|
||||
}
|
||||
close(BOUNCE);
|
||||
unlink(</tmp/sequencer.$$.*>);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sub resend_sendmail {
|
||||
local(*MAIL) = shift;
|
||||
local($to) = shift;
|
||||
local($subject) = shift;
|
||||
|
||||
# clean up the addresses, for use on the sendmail command line
|
||||
local(@to) = &ParseAddrs($to);
|
||||
for (@to) {
|
||||
$_ = join(", ", &ParseAddrs($_));
|
||||
}
|
||||
$to = join(", ", @to);
|
||||
|
||||
# open the process
|
||||
if (defined($opt_d)) {
|
||||
# debugging, so just say it, don't do it
|
||||
open(MAIL, ">-");
|
||||
print MAIL ">>> /usr/lib/sendmail -f$sendmail_sender -t\n";
|
||||
} else {
|
||||
local(@mailer) = split(' ',"/usr/lib/sendmail -f$sendmail_sender -t");
|
||||
open(MAIL, "|-") || &do_exec_sendmail(@mailer);
|
||||
}
|
||||
|
||||
# generate the header
|
||||
print MAIL <<"EOM";
|
||||
To: $to
|
||||
From: $sender
|
||||
Subject: $subject
|
||||
|
||||
EOM
|
||||
|
||||
return;
|
||||
}
|
||||
Reference in New Issue
Block a user