config root man

Current Path : /compat/linux/proc/68247/cwd/usr/local/majordomo/

FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64
Upload File :
Current File : //compat/linux/proc/68247/cwd/usr/local/majordomo/sequencer

#!/usr/bin/perl

use ADN::MIME;
use ADN::Utility;

$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin";

#$tmp = "/tmp/majordomo.$$";
#$main'program_name = 'sequencer';

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);

require "majordomo.pl";
require "majordomo_version.pl";
require "getopts.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";
    $sendmail_sender = "owner-$opt_m\@$opt_h";
}

$sendmail_path = "/usr/local/sbin/sendmail";
$sendmail_cmd = "$sendmail_path -f$sendmail_sender " . join(" ", @ARGV);

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>);
}

$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>) {
    if ((/^subject:/i) || (defined($subj_last))) {
        if ((/^subject:/i) || (/^\s+(.+)/)) {
            $_ = ADN::MIME::HeaderDecode($_, 'euc');
            $_ = ADN::MIME::HeaderEncode($_);

            s/R[eE]\:.*[\(\[].*\d+[\)\]]/Re\:/g;
            s/R[eE]\:\s+R[eE]\:/Re\:/g;
            $subj_last = 1;

        } else {
            undef($subj_last);
        }
    }
    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) {
            next if (/^\s*$/);

            $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 = "Subject: " . $foo; $subject =~ s/ $//;
                    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;
                }

                $ml = $opt_l;

                print OUT "X-Sequence: " . &config'substitute_values($config_opts{$opt_l,"sequence_prefix"}, $opt_l) . " $seqnum\n";

                $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)) {
                # 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);

#                    if ($config_opts{$opt_l,"subject_prefix"} ne '') {
                        # 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/;
                    $subject_last = 1;

                } elsif (defined($subject_last)) {
                    if (/^\s+(.+)/) {
                        $subject .= " $1";
                    } else {
                        undef($subject_last);
                    }
                }

                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");
}

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 = ADN::Utility::utime2date(time());
            $de_subject = ADN::MIME::HeaderDecode($subject, 'euc');
            $de_from    = ADN::MIME::HeaderDecode($from, 'euc');

            print INDEX "$de_subject\n\t$timenow\t$de_from\n\n";

            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)) {
        `chmod 664 $filedir/$opt_l$filedir_suffix/$seqnum`;
        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 routine

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($_) > $MAX_HEADER_LINE_LENGTH) && ! defined($approved)) {
            &bounce("Header line too long (>$MAX_HEADER_LINE_LENGTH)");
            return(undef);
        }

    # is this field too long?
        if ((($field_len += length($_)) > $MAX_TOTAL_HEADER_LENGTH) && ! defined($approved)) {
            &bounce("Header field too long (>$MAX_TOTAL_HEADER_LENGTH)");
            return(undef);
        }

        $balanced_fld .= $_;
        chop($balanced_fld);
    }

    # if we get here, everything was OK.
    return(1);
}

sub bounce {
    local($reason) = shift;
    local($_);

    my $maddr0 = "$opt_m\@$opt_h";
    my $maddr1 = "$opt_m-approval\@$opt_h";

    &resend_sendmail(BOUNCE,
                     (($config_opts{$opt_l, 'moderator'} ne "") ?
                      #$config_opts{$opt_l, 'moderator'} : "$opt_l-approval\@$opt_h"),
                      #"BOUNCE $opt_l\@$opt_h: $reason");
                      $config_opts{$opt_l, 'moderator'} : $maddr1),
                      "BOUNCE $maddr0: $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;
    local($isParent);
    local($mailcmd);

    $mailcmd = "$sendmail_path -f$sender -t";

    # clean up the addresses, for use on the sendmail command line
    local(@to) = &ParseAddrs($to);
    $to = join(", ", @to);

    # open the process
    if (defined($opt_d)) {
	# debugging, so just say it, don't do it
	open(MAIL, ">-");
	print MAIL ">>> $mailcmd\n";
    } else {
 	if (defined($isParent = open(MAIL, "|-"))) {
 	    &do_exec_sendmail(split(' ', $mailcmd))
 		unless $isParent;
 	} else {
 	    &abort("Failed to fork prior to mailer exec");
 	}
    }

    # generate the header
    print MAIL <<"EOM";
To: $to
From: $sender
Subject: $subject

EOM

    return;
}

Man Man