[Mailman-Users] Posting to a list while being a memeber form another list

Caleb Epstein cae at bklyn.org
Thu Jan 31 15:23:32 CET 2002

On Thu, Jan 31, 2002 at 08:44:36AM -0500, Lafleur Maurice wrote:

> I have the following situation: List A is a generic, plain ML to
> which members can post List B is an "announce" type list: only one
> person can post, members read only.  Members of B want to post to A
> without being members of A, but *have to* be members of B. In other
> words, they dont want the traffic from A but still need to post to
> it.  What set up should I use for this?  Thank you.  MGL

	Here is what I have done for a situation like this.  I have
	written a Perl script (sorry, my Python skills are
	non-existent at this point) called "setup-posters".  It
	takes a list of mailing list names, flat files or email
	addresses (or any combination thereof) and merges them all
	together into a list of unique email addresses.  It then sets
	up the "posters" variable for a target list to be this list of

	I run it like this, from cron:

	setup-posters.pl --source server --source siteops --target announce

	this says to take the membership of the mailing lists "server"
	and "siteops" and give them all posting privileges to the
	"announce" list.  I think in your case you'd use --source
	announce --target list-a

	The script is attached.  Please let me know if you have any
	questions about how to use it or how it works.  I'm pasting it
	below my sig in case this list strips MIME attachments like
	mine :)

Caleb Epstein |  bklyn . org  | Politics is not the art of the possible.
    cae at    | Brooklyn Dust | It consists in choosing between the disastrous
bklyn dot org |   Bunny Mfg.  | and the unpalatable.
              |               | 		-- John Kenneth Galbraith

#!/usr/bin/perl -w
# Setup the "posters" configuration for a "target" list based on a set
# of "sources", which can be Mailmn list names, flat files of email
# addresses, or email addresses passed on the command line.
# $Id$

use strict;
use POSIX qw(tmpnam);
use Getopt::Long;
use File::Basename;

my $progname = basename $0;
my $target;
my $mailman = (getpwnam("mailman"))[5] || "/usr/local/mailman";
my $verbose = 0;

sub usage {
   print <<EOF
$progname - Configure the 'posters' allowed on a Mailman list

Usage: $progname [options]

  -s | --source s    Specify a source for the email addresses.  May be an
                     absolute path which file contains email addresses, an
                     individual email address of the form user\@domain or a
                     Mailman list name, whose members will be used.
  -t | --target t    Must be a list known to Mailman.
  -m | --mailman m   Specify root of Mailman install.  It should be detected
                     automatically, but if this fails, you will need to supply
                     this option.
  -h | --help        Generate this usage message and exit.
  -v | --verbose     Print verbose progress messages.

You must specify one or more sources and one and only one target.

my $retval = GetOptions ("help!" => sub { usage; exit 0; },
			 "source=s@" => \@SOURCE,
			 "target=s" => \$target,
			 "verbose!" => \$verbose,
			 "mailman=s" => \$mailman);

if ($retval == 0) {
   exit 1;

die "Could not find Mailman root directory.\n"
  unless -d $mailman and -d "$mailman/bin";

die "No sources specified.\n" unless scalar @SOURCE;
die "No target specified.\n" unless defined $target;
die "Target $target is not a valid Mailman list.\n"
  unless -d "$mailman/lists/$target";


sub get_members {
   my $spec = shift;
   my %M;

   if (-f $spec) {
      print "Reading addresses from file $spec.\n" if $verbose;
      open (FILE, $spec)
	or warn "Couldn't open $spec: $!\n";
      while (<FILE>) {
	 next if /^\#/;
	 $M{lc $_} = 1;
   } elsif ($spec =~ m/^.+\@.+/) {
      $M{lc $spec} = 1;
   } elsif (-d "$mailman/lists/$spec") {
      print "Getting membership roster from Mailman list $spec.\n"
	if $verbose;
      open (MM, "$mailman/bin/list_members $spec|")
	or warn "Couldn't open pipe to $mailman/bin/list_members: $!\n";
      while (<MM>) {
	 next unless /^.+\@.+/;
	 $M{lc $_} = 1;
   } else {
      warn "Don't know how to turn '$spec' into a list of addresses.\n";

   print "Found " . (scalar keys %M) . " addresses in $spec.\n"
     if $verbose and scalar keys %M;

   sort keys %M;

print "Processing source(s):\n" if $verbose;

foreach my $source (@SOURCE) {
   my @M = get_members ($source);
   map { $MEMBERS{lc $_} = 1 } @M;

print "Found " . (scalar keys %MEMBERS) . " total unique addresses.\n"
  if $verbose;

die "No subscribers found in @SOURCE\n"
    unless scalar keys %MEMBERS;

my $tmpfile = tmpnam();

open (POSTERS, "> $tmpfile")
    or die "Couldn't open $tmpfile for writing: $!\n"; 

print POSTERS "posters = ['", join ("', '", sort keys %MEMBERS), "']\n";

close POSTERS;

my $cmd = "$mailman/bin/config_list -i $tmpfile $target";

print "Running $cmd\n" if $verbose;

$retval = system ("$mailman/bin/config_list -i $tmpfile $target");

unlink $tmpfile;

my $status = $retval >> 8;

if ($retval != 0 or $verbose) {
   my $signal = $retval & 127;
   my $cored = $retval & 128;

   warn "Mailman config_list command exited with status $status" .
     ($signal ? " from signal $signal" : "") .
       ($cored ? ", dumped core" : "") .

exit $status;

More information about the Mailman-Users mailing list