| 1 | #!/usr/bin/perl -w |
|---|
| 2 | |
|---|
| 3 | =head1 NAME |
|---|
| 4 | |
|---|
| 5 | pl-init - Initialise a Lancelot mailing list |
|---|
| 6 | |
|---|
| 7 | =head1 SYNOPSIS |
|---|
| 8 | |
|---|
| 9 | pl-init [-v?] [--clone=otherlist] [--config=FILE] ... |
|---|
| 10 | [--[no]mailfilter] [--our-isp] [--verbose] |
|---|
| 11 | list@domain owner-address key=value ... |
|---|
| 12 | |
|---|
| 13 | =head1 OVERVIEW |
|---|
| 14 | |
|---|
| 15 | The B<pl-init> command creates a new Lancelot mailing list with |
|---|
| 16 | a sensible (if basic) configuration. |
|---|
| 17 | |
|---|
| 18 | =head1 DESCRIPTION |
|---|
| 19 | |
|---|
| 20 | The B<pl-init> command creates a new Lancelot mailing list with no |
|---|
| 21 | subscribers. It installs a basic configuration (which should be |
|---|
| 22 | sensible) and allows the list owner to change individual configuration |
|---|
| 23 | settings and/or clone the configuration of another list. |
|---|
| 24 | |
|---|
| 25 | The initial configuration is derived from (1) hard-coded defaults, (2) |
|---|
| 26 | the content of a system-wide defaults file (if available), (3) the |
|---|
| 27 | content of the user-specific defaults file F<$HOME/.pl/defaults.conf> |
|---|
| 28 | (if available), (4) any files whose names are passed on the command line |
|---|
| 29 | by means of the B<--config> option, and (5) any configuration parameter |
|---|
| 30 | assignments given on the command line, in that order. Later settings |
|---|
| 31 | override earlier ones. Between (3) and (4), the B<list.address> parameter |
|---|
| 32 | is set to I<list@domain>, the B<list.owneraddress> parameter is set to |
|---|
| 33 | I<owner-address>, the B<list.ownername> parameter is set to the list |
|---|
| 34 | owner's name if one is passed as part of I<owner-address>, and the |
|---|
| 35 | B<list.name> parameter is set to the local part of I<list@domain>, |
|---|
| 36 | capitalised. |
|---|
| 37 | |
|---|
| 38 | Any command-line parameters passed after I<owner-address> will be |
|---|
| 39 | considered configuration parameter assignments in the sense of (5) above. |
|---|
| 40 | Note that these are pre-parsed by the shell, and USE QUOTES IF YOUR |
|---|
| 41 | CONFIGURATION PARAMETER ASSIGNMENTS CONTAIN WHITESPACE. |
|---|
| 42 | |
|---|
| 43 | If a list configuration is "cloned" from that of another list, that |
|---|
| 44 | list's configuration is copied to the new list after the defaults |
|---|
| 45 | files have been processed but before the configuration files and |
|---|
| 46 | parameter assignments given on the command line take effect. |
|---|
| 47 | This makes it possible to copy a list's configuration "except for" |
|---|
| 48 | some specific settings. The list and owner addresses are set immediately |
|---|
| 49 | before the command-line parameter assignments are processed, so they will |
|---|
| 50 | be correct for a "cloned" list; you overwrite them from the command line |
|---|
| 51 | at your own peril. |
|---|
| 52 | |
|---|
| 53 | The I<owner-address> will also be subscribed to the list as an |
|---|
| 54 | administrator. If you'd rather not have this, add the configuration |
|---|
| 55 | parameter |
|---|
| 56 | |
|---|
| 57 | list.subscribeowner = 0 |
|---|
| 58 | |
|---|
| 59 | to one of the default files or invoke B<pl-init> like |
|---|
| 60 | |
|---|
| 61 | pl-init list@domain owner@domain list.subscribeowner=0 |
|---|
| 62 | |
|---|
| 63 | |
|---|
| 64 | =head1 OPTIONS |
|---|
| 65 | |
|---|
| 66 | =over 4 |
|---|
| 67 | |
|---|
| 68 | =item B<--clone>=I<otherlist@otherlistdomain> |
|---|
| 69 | |
|---|
| 70 | Copies I<otherlist@otherlistdomain>'s configuration as far as |
|---|
| 71 | possible. I<otherlist@otherlistdomain> must belong to the same user |
|---|
| 72 | as the new list. |
|---|
| 73 | |
|---|
| 74 | =item B<--config>=I<file> |
|---|
| 75 | |
|---|
| 76 | Reads configuration parameter assignments from I<file>. Empty lines |
|---|
| 77 | and comment lines (starting with "#") in I<file> will be ignored. |
|---|
| 78 | |
|---|
| 79 | If B<--config> is used together with B<--clone>, the changes take |
|---|
| 80 | place after the configuration has been cloned. There may be multiple |
|---|
| 81 | B<--config> options on the same command line. Configuration parameters |
|---|
| 82 | may be changed later using the B<pl-conf> command. |
|---|
| 83 | |
|---|
| 84 | =item B<--mailfilter> |
|---|
| 85 | |
|---|
| 86 | For Our-ISP style lists, generates a F<.mailfilter> file |
|---|
| 87 | in the list directory which redirects the various list addresses to the |
|---|
| 88 | pl-incoming(1) program. |
|---|
| 89 | |
|---|
| 90 | =item B<--nomailfilter> |
|---|
| 91 | |
|---|
| 92 | Causes the program to not generate a F<.mailfilter> file for an |
|---|
| 93 | Our-ISP-style Lancelot list. |
|---|
| 94 | |
|---|
| 95 | =item B<--our-isp> |
|---|
| 96 | |
|---|
| 97 | Creates the mailing list according to the conventions of Our-ISP. In |
|---|
| 98 | particular, this means that the list database will be created in |
|---|
| 99 | F<$HOME/domains/>I<domain>F</>I<list>F</list.db> rather than |
|---|
| 100 | F<$HOME/.pl/>I<list>F<@>I<domain>F</list.db>. Implies B<--mailfilter>. |
|---|
| 101 | |
|---|
| 102 | =back |
|---|
| 103 | |
|---|
| 104 | =head1 SEE ALSO |
|---|
| 105 | |
|---|
| 106 | pl-conf(1), pl-init(1), pl-incoming(1), pl-list(1), pl-subchange(1), pl-subscribe(1) |
|---|
| 107 | |
|---|
| 108 | =head1 AUTHOR |
|---|
| 109 | |
|---|
| 110 | Anselm Lingnau <anselm@anselms.net> |
|---|
| 111 | |
|---|
| 112 | =head1 COPYRIGHT AND LICENSE |
|---|
| 113 | |
|---|
| 114 | Copyright 2004-11 by Anselm Lingnau. This program is free software; you |
|---|
| 115 | may redistribute it and/or modify it under the terms of the GNU |
|---|
| 116 | General Public License as published by the Free Software Foundation; |
|---|
| 117 | either version 2 of the License, or (at your option) any later version. |
|---|
| 118 | |
|---|
| 119 | This program is distributed in the hope that it will be useful, but |
|---|
| 120 | WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 121 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 122 | General Public License for more details. |
|---|
| 123 | |
|---|
| 124 | You should have received a copy of the GNU General Public License |
|---|
| 125 | along with this program; if not, refer to |
|---|
| 126 | <URL:http://www.gnu.org/copyleft/gpl.html>. You may also obtain it by |
|---|
| 127 | writing to the Free Software Foundation, Inc., 59 Temple Place - Suite |
|---|
| 128 | 330, Boston, MA 02111-1307, USA. |
|---|
| 129 | |
|---|
| 130 | =cut |
|---|
| 131 | |
|---|
| 132 | use strict; |
|---|
| 133 | |
|---|
| 134 | # Make Binary find it's libraries for non standard installations ... |
|---|
| 135 | use Config; |
|---|
| 136 | use File::Basename; |
|---|
| 137 | use vars qw($g_base_dir); |
|---|
| 138 | BEGIN { |
|---|
| 139 | use FindBin qw($Bin); |
|---|
| 140 | $g_base_dir = dirname ($Bin); |
|---|
| 141 | } |
|---|
| 142 | use lib "$g_base_dir/lib"; |
|---|
| 143 | use lib "$g_base_dir/lib/perl5/$Config{version}"; |
|---|
| 144 | use lib "$g_base_dir/lib/perl5/site_perl/$Config{version}"; |
|---|
| 145 | |
|---|
| 146 | use Lancelot::GetOpt qw/GetOptions/; |
|---|
| 147 | |
|---|
| 148 | use Lancelot::DB; |
|---|
| 149 | use Lancelot::Log qw/log/; |
|---|
| 150 | |
|---|
| 151 | my %opts; |
|---|
| 152 | |
|---|
| 153 | GetOptions(\%opts, -defaults, |
|---|
| 154 | -argvmin => 2, "need list and owner address", |
|---|
| 155 | "our-isp?", "clone=", "config@", "mailfilter!"); |
|---|
| 156 | |
|---|
| 157 | my $listaddr = shift; |
|---|
| 158 | my $owneraddr = (Email::Address->parse(shift))[0]; |
|---|
| 159 | my $ownername = $owneraddr->phrase || $owneraddr->comment; |
|---|
| 160 | |
|---|
| 161 | my %options = ( create => 1, ourisp => $opts{"our-isp"} ); |
|---|
| 162 | |
|---|
| 163 | my $db = new Lancelot::DB $listaddr, \%options |
|---|
| 164 | or die "$0: error creating list $listaddr\n"; |
|---|
| 165 | |
|---|
| 166 | clone_list($db, $opts{clone}) if $opts{clone}; |
|---|
| 167 | |
|---|
| 168 | $db->set_config("list.address", $listaddr); |
|---|
| 169 | $db->set_config("list.owneraddress", $owneraddr->address); |
|---|
| 170 | $db->set_config("list.ownername", $ownername) if $ownername; |
|---|
| 171 | my $listname = $listaddr; |
|---|
| 172 | $listname =~ s/\@.*$//; |
|---|
| 173 | $db->set_config("list.name", ucfirst($listname)); |
|---|
| 174 | |
|---|
| 175 | $db->set_configs_from_file($_, 0) foreach @{$opts{config}}; |
|---|
| 176 | $db->set_configs(@ARGV) if @ARGV; |
|---|
| 177 | |
|---|
| 178 | if ($opts{"our-isp"} && !($opts{mailfilter} == 0)) { |
|---|
| 179 | my ($mfname) = File::Spec->join($db->get_listdir, ".mailfilter"); |
|---|
| 180 | log "info", "creating mailfilter file $mfname"; |
|---|
| 181 | my ($mfh) = IO::File->new("> $mfname"); |
|---|
| 182 | |
|---|
| 183 | if ($mfh) { |
|---|
| 184 | print $mfh qq{to "|$Bin/pl-incoming $listaddr"\n}; |
|---|
| 185 | $mfh->close; |
|---|
| 186 | chmod 0600, $mfname; |
|---|
| 187 | } else { |
|---|
| 188 | die "$0: couldn't create $mfname: $!\n"; |
|---|
| 189 | } |
|---|
| 190 | } else { |
|---|
| 191 | my $xlistaddr = $listaddr; |
|---|
| 192 | my $delim = $db->get_config("mail.delimiter"); |
|---|
| 193 | $xlistaddr =~ s/\@/${delim}ANYTHING\@/; |
|---|
| 194 | my $user = getpwuid($<); |
|---|
| 195 | |
|---|
| 196 | print "Make sure that within your MTA setup, messages to\n\n"; |
|---|
| 197 | print " $listaddr as well as\n"; |
|---|
| 198 | print " $xlistaddr\n\n"; |
|---|
| 199 | print "are piped into\n\n"; |
|---|
| 200 | print " $Bin/pl-incoming --user $user $listaddr\n\n"; |
|---|
| 201 | print "Consult Project Lancelot's Deployment-HOWTO for details.\n"; |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | my $subscribe_owner = $db->get_config("list.subscribeowner"); |
|---|
| 205 | if ($subscribe_owner) { |
|---|
| 206 | log "info", "subscribing owner address as list administrator"; |
|---|
| 207 | unless ($db->add_address($owneraddr, { admin => 1 })) { |
|---|
| 208 | log "err", "error subscribing $owneraddr\n"; |
|---|
| 209 | } |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | sub clone_list { |
|---|
| 213 | my ($db, $clonelist) = @_; |
|---|
| 214 | |
|---|
| 215 | log "info", "cloning list $clonelist"; |
|---|
| 216 | my ($db1) = new Lancelot::DB $clonelist |
|---|
| 217 | or die "$0: list $clonelist does not exist\n"; |
|---|
| 218 | foreach my $c ($db1->config_names) { |
|---|
| 219 | $db->set_config($c, $db1->get_config($c)); |
|---|
| 220 | } |
|---|
| 221 | } |
|---|