#!/usr/bin/perl -w # ==================================================================== # Copyright (c) 1999, MeepZor Consulting. # All rights reserved. # # The use and distribution of this code or document is # governed by the latest version of the MeepZor Consulting # Licence (MCL), which may be found on the Internet at # . # # # mklist: Majordomo utility to make a new list # # $Id: mklist,v 1.13 2001/04/19 12:45:47 coar Exp $ # # See the MANIFEST file for package information. # # A required file is "template-list.config", which is a Majordomo # list configuration file with special placeholders in it. The # placeholders, and with what they're replaced when the real .config file # is created, are: # # @@PASSWORD@@ # The password for list management, specified with -p # # @@OWNER@@ # The email address of the list owner, specified with -o # # @@HOST@@ # The name of the mailing-list host (used in From addresses and # administrative notices). Specified manually with -H or derived # from the current hostname. # # @@LNAME-H@@ # The listname as consumable by humans (i.e., with case preserved), # specified by -n # # @@LNAME-M@@ # The listname as consumable by Majordomo (i.e., converted to all # lowercase). Derived from @@LNAME-H@@ # # @@DNAME-H@@ # The human-consumable name of the digest list, formed from the value # of the -n option with "-Digest" appended # # @@DNAME-M@@ # The Majordomo-usable name of the digest list; @@DNAME-H@@ lowercased # # If digesting is going to be done, "template-digest.config" is also # required. The placeholders have the same meanings. The -T switch # tells mklist where the template files can be found. # # All lists are archived with -M by default, in the .archive # subdirectory under the lists directory. # # See the usage() function at the end of this script for a description of # all of the switches and their meanings. # use Getopt::Long; use Sys::Hostname; Getopt::Long::Configure("bundling"); # # Pre-set the option scalars so Perl won't gritch about them only being # used once. # %opt = (); $opts = join("", @ARGV); foreach (split(//, "dhnopDFHLMNPSTvVW")) { $opt{$_} = ""; } GetOptions(\%opt, "description|d=s" => \$opt{'d'}, "help|h" => \$opt{'h'}, "list-name|n=s" => \$opt{'n'}, "owner|o=s" => \$opt{'o'}, "password|p=s" => \$opt{'p'}, "verbose|v" => \$opt{'v'}, "config-file|C=s" => \$opt{'C'}, "digest|D" => \$opt{'D'}, "force|F" => \$opt{'F'}, "host|H=s" => \$opt{'H'}, "list-directory|L=s" => \$opt{'L'}, "majordomo-home|M=s" => \$opt{'M'}, "no-action|N" => \$opt{'N'}, "alias-prefix|P=s" => \$opt{'P'}, "save|S" => \$opt{'S'}, "template-directory|T=s" => \$opt{'T'}, "very-verbose|V" => \$opt{'V'}, "digest-work|W=s" => \$opt{'W'} ); $opt{'h'} = $opt{'h'} || ($opts eq "") || (join("", %opt) eq ""); if ($opt{'h'}) { &usage(); exit 0; } # # Check to see if we have a saved-settings file, and load the values # if so. # %sticky_settings = ('-H' => &hostname(), '-L' => '/usr/local/mail/lists', '-M' => '/usr/local/mail/majordomo', '-P' => '', '-T' => '/usr/local/mail', '-W' => '/usr/local/mail/digests' ); $HOME = $ENV{'HOME'}; print "$0: checking for a .mklistrc file\n" if ($opt{'V'}); $file = (-f "./.mklistrc") ? "./.mklistrc" : "$HOME/.mklistrc"; if (open(RC, $file)) { print "$0: loading saved settings: " if ($opt{'v'} || $opt{'V'}); my(@opts) = ; close(RC); foreach (@opts) { chomp; if ($_ =~ m:^\s*-([A-Z])\s+(.*):) { $sticky_settings{"-$1"} = $2; } } print "done.\n" if ($opt{'v'} || $opt{'V'}); if ($opt{'V'}) { print "$0: current sticky settings:\n"; foreach (sort(keys(%sticky_settings))) { print " $_ = " . $sticky_settings{$_} . "\n"; } } } @errors = (); $sticky_settings{'-H'} = $HOST = $opt{'H'} || $sticky_settings{'-H'}; $sticky_settings{'-L'} = $LDIR = $opt{'L'} || $sticky_settings{'-L'}; $sticky_settings{'-M'} = $MDIR = $opt{'M'} || $sticky_settings{'-M'}; $sticky_settings{'-P'} = $PFIX = $opt{'P'} || $sticky_settings{'-P'}; $sticky_settings{'-T'} = $TDIR = $opt{'T'} || $sticky_settings{'-T'}; $sticky_settings{'-W'} = $DDIR = $opt{'W'} || $sticky_settings{'-W'}; $list_has_digest = $opt{'D'}; # # Deal with the name of the list. If it's a digest, the user should # specify the name of the actual list, not the digest name. # if ($opt{'S'} && ($opt{'d'} || $opt{'n'} || $opt{'o'} || $opt{'p'})) { push(@errors, "-S may not be combined with -d, -n, -o, or -p"); } elsif ($opt{'S'}) { print "$0: saving sticky settings: " if ($opt{'v'} || $opt{'V'}); open(RC, ">$HOME/.mklistrc") || die("Can't create $HOME/.mklistrc"); print RC "#\n# .mklistrc -- settings for mklist's sticky options\n#\n"; foreach (sort(keys(%sticky_settings))) { print RC "$_ " . $sticky_settings{$_} . "\n"; } print "done.\n" if ($opt{'v'} || $opt{'V'}); exit(0); } if ((! $opt{'n'}) && (! $opt{'S'})) { push(@errors, "-n must specify the name of the list"); } elsif ($opt{'n'}) { $lname_h = $dname_h = $opt{'n'}; $dname_h .= ($lname_h =~ /[A-Z]/) ? "-Digest" : "-digest"; $lname_m = lc($lname_h); $dname_m = lc($dname_h); chdir("$LDIR"); if (! $opt{'F'}) { push(@errors, "subscriber file $lname_m exists") if (-e "$lname_m"); push(@errors, "config file ${lname_m}.config exists") if (-e "${lname_m}.config"); push(@errors, "introduction file ${lname_m}.intro exists") if (-e "${lname_m}.intro"); push(@errors, "information file ${lname_m}.config exists") if (-e "${lname_m}.info"); push(@errors, "archive directory ${lname_m}.archive exists") if (-e "${lname_m}.archive"); } } $description = $opt{'d'}; if ((! $description) && (! $opt{'S'})){ push(@errors, "-d must specify up to 50 characters of description"); } if (length($description) > 50) { push(@errors, "-d is too long; no more than 50 characters"); } $password = $opt{'p'}; if ((! $password) && (! $opt{'S'})) { push(@errors, "-p must specify a password"); } $owner = $opt{'o'}; if ((! $owner) && (! $opt{'S'})) { push(@errors, "-o must specify a (possibly local) email address for " . "the list owner"); } if ($#errors >= 0) { print STDERR "$0: ", join("\n$0: ", @errors), "\n"; exit 1; } # # Right; if we've gotten this far, we're ready to go. We have at least one # list to set up, so let's do it. # $list_type = "list"; $dname_h = $lname_h; $dname_h .= ($lname_h =~ /[A-Z]/) ? "-Digest" : "-digest"; $dname_m = lc($dname_h); # # Create the 'welcome to the list' and 'here's what the list is about # in case you want to join' description files. # &mkintro(0); &mkinfo(0); # # Create a blank subscriber file (do nothing if it already exists, since that # means we're just normalising the control files). # system("touch $LDIR/$lname_m"); # # Create the list's configuration file from the template and our # settings. # &mkconfig("$TDIR/template-list.config", "$LDIR/${lname_m}.config"); # # Create the list's archive directory. # mkdir("$LDIR/${lname_m}.archive", 0755); # # Create a file containing the various alias entries for easy addition # to the /etc/aliases file. # &mkalii(0); # # Now, if this list doesn't have a digest, we're all done. Otherwise # we need to adjust our variables and create the digest-list info too. # exit 0 if (! $list_has_digest); # # Heigh-ho, time to make the digest. # $list_type = "digest"; $tmp = $dname_h; $dname_h = $lname_h; $lname_h = $tmp; $tmp = $dname_m; $dname_m = $lname_m; $lname_m = $tmp; $description = "Digests of the $dname_h list"; # # Make the blurb files. # &mkintro(1); &mkinfo(1); # # Now the subscriber list. # system("touch $LDIR/$lname_m"); # # Now create the config file from the digest template. # &mkconfig("$TDIR/template-digest.config", "$LDIR/${lname_m}.config"); # # Create the digest working directory. # mkdir("$DDIR/${lname_m}", 0755); # # Create the list's archive directory. This is where the digests are # archived for later retrieval. # mkdir("$LDIR/${lname_m}.archive", 0755); # # Create a file containing the various alias entries for easy addition # to the /etc/aliases file. # &mkalii(1); # # Create a file containing the cron definition for the digestification. # open CRON, ">$LDIR/${lname_m}.cron"; print CRON "0 21 * * * ", "echo \"mkdigest $lname_m ${lname_h}-Subscribers $password\" ", "| mail Majordomo\@Localhost\n"; close CRON; # # All done! # exit 0; # # Create a file containing the various alii needed for Majordomo # to manage this mailing list. The user has to add these to the # appropriate system alias file, but this is to make it easy. # sub mkalii { my($digest) = @_; my($cfgfile) = $opt{'C'} ? " -C $opt{'C'}" : ""; printf STDERR ("$0: creating ${lname_m}.alii:") if ($opt{'V'}); open ALII, ">${lname_m}.alii"; print ALII <${lname_m}.virtuser"; print VIRTUSER <$CONFIG") or die("$0: Can't open new config file '$CONFIG'"); while (