summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw1999-03-23 00:03:18 +0000
committerbwarsaw1999-03-23 00:03:18 +0000
commit7c052955153a9bb58ef65d22ecc89536caf88ee6 (patch)
treef175929e8eb785b88f2b58102333078d9ed74428
parent449477a158b7ec7fd3bd0f1cb9efa65c98d6dffe (diff)
downloadmailman-7c052955153a9bb58ef65d22ecc89536caf88ee6.tar.gz
mailman-7c052955153a9bb58ef65d22ecc89536caf88ee6.tar.zst
mailman-7c052955153a9bb58ef65d22ecc89536caf88ee6.zip
Script to synchronize memberships
-rw-r--r--bin/Makefile72
-rwxr-xr-xbin/sync_members193
2 files changed, 265 insertions, 0 deletions
diff --git a/bin/Makefile b/bin/Makefile
new file mode 100644
index 000000000..d85a26b93
--- /dev/null
+++ b/bin/Makefile
@@ -0,0 +1,72 @@
+# Generated automatically from Makefile.in by configure.
+# Copyright (C) 1998 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# NOTE: Makefile.in is converted into Makefile by the configure script
+# in the parent directory. Once configure has run, you can recreate
+# the Makefile by running just config.status.
+
+# Variables set by configure
+
+srcdir= .
+bindir= ${exec_prefix}/bin
+prefix= /export/home/mailman
+exec_prefix= ${prefix}
+
+CC= gcc
+CHMOD= @CHMOD@
+INSTALL= .././install-sh -c
+
+DEFS= -DHAVE_STRERROR=1 -DHAVE_SETREGID=1 -DSTDC_HEADERS=1 -DHAVE_SYSLOG_H=1 -DGETGROUPS_T=gid_t -DHAVE_VPRINTF=1
+
+# Customizable but not set by configure
+
+OPT= -g -O2
+CFLAGS= $(OPT) $(DEFS)
+MAILDIR= $(exec_prefix)/mail
+SCRIPTSDIR= $(prefix)/bin
+
+SHELL= /bin/sh
+
+SCRIPTS= digest_arch mmsitepass newlist rmlist add_members \
+ list_members remove_members clone_member update arch \
+ sync_members check_db
+
+# Modes for directories and executables created by the install
+# process. Default to group-writable directories but
+# user-only-writable for executables.
+DIRMODE= 775
+EXEMODE= 755
+FILEMODE= 644
+INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
+
+
+# Rules
+
+all:
+
+install:
+ for f in $(SCRIPTS); \
+ do \
+ $(INSTALL) -m $(EXEMODE) $$f $(SCRIPTSDIR); \
+ done
+
+finish:
+
+clean:
+
+distclean:
+ -rm Makefile
diff --git a/bin/sync_members b/bin/sync_members
new file mode 100755
index 000000000..20ca0f68e
--- /dev/null
+++ b/bin/sync_members
@@ -0,0 +1,193 @@
+#! /usr/bin/env python
+#
+# Copyright (C) 1998 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Synchronize a mailing list's membership with a flat file.
+
+This script is useful if you have a Mailman mailing list and a sendmail
+:include: style list of addresses (also as is used in Majordomo). For every
+address in the file that does not appear in the mailing list, the address is
+added. For every address in the mailing list that does not appear in the
+file, the address is removed. Other options control what happens when an
+address is added or removed.
+
+Usage: %(program)s [-n] [-w[=<yes|no>]] [-d[=<yes|no>]] [-h] -f file listname
+
+Where:
+
+ --no-change
+ -n
+ Don't actually make the changes. Instead, print out what would be
+ done to the list.
+
+ --welcome-msg[=<yes|no>]
+ -w[=<yes|no>]
+ Sets whether or not to send the newly added members a welcome
+ message, overriding whatever the list's `send_welcome_msg' setting
+ is. With -w=yes or -w, the welcome message is sent. With -w=no, no
+ message is sent.
+
+ --digest[=<yes|no>]
+ -d[=<yes|no>]
+ Selects whether to make newly added members receive messages in
+ digests. With -d=yes or -d, they become digest members. With -d=no
+ (or if no -d option given) they are added as regular members.
+
+ --help
+ -h
+ Print this message.
+
+ --file <filename | ->
+ -f <filename | ->
+ This option is required. It specifies the flat file to synchronize
+ against. If filename is `-' then stdin is used.
+
+ listname
+ Required. This specifies the list to synchronize.
+"""
+
+import sys
+import string
+import paths
+from Mailman import MailList
+from Mailman import Errors
+
+program = sys.argv[0]
+
+def usage(status, msg=''):
+ print __doc__ % globals()
+ if msg:
+ print msg
+ sys.exit(status)
+
+
+
+def startswith(s, prefix):
+ return s[:len(prefix)] == prefix
+
+def endswith(s, suffix):
+ return s[-len(suffix):] == suffix
+
+
+
+def yesno(opt):
+ i = string.find(opt, '=')
+ yesno = string.lower(opt[i+1:])
+ if yesno in ('y', 'yes'):
+ return 1
+ elif yesno in ('n', 'no'):
+ return 0
+ else:
+ usage(0)
+ # no return
+
+
+def main():
+ dryrun = 1
+ digest = 0
+ welcome = None
+ filename = None
+ listname = None
+
+ i = 1
+ while i < len(sys.argv):
+ opt = sys.argv[i]
+ if opt in ('-h', '--help'):
+ usage(0)
+ elif opt in ('-n', '--no-change'):
+ dryrun = 1
+ i = i + 1
+ elif opt in ('-d', '--digest'):
+ digest = 1
+ i = i + 1
+ elif startswith(opt, '-d=') or startswith(opt, '-digest='):
+ digest = yesno(opt)
+ i = i + 1
+ elif opt in ('-w', '--welcome-msg'):
+ welcome = 1
+ i = i + 1
+ elif startswith(opt, '-w=') or startswith(opt, '-welcome-msg='):
+ welcome = yesno(opt)
+ i = i + 1
+ elif opt in ('-f', '--file'):
+ if filename is not None:
+ usage(1)
+ try:
+ filename = sys.argv[i+1]
+ except IndexError:
+ usage(1)
+ i = i + 2
+ elif opt[0] == '-':
+ usage(1, 'Illegal option: ' + opt)
+ else:
+ try:
+ listname = sys.argv[i+1]
+ i = i + 2
+ except IndexError:
+ usage(1)
+ break
+
+ if listname is None or filename is None:
+ usage(1)
+
+ # read the list of addresses to sync to from the file
+ if filename == '-':
+ filemembers = sys.argv[i:]
+ else:
+ try:
+ fp = open(filename)
+ except IOError, (code, msg):
+ print 'Cannot read address file:', filename, msg
+ sys.exit(1)
+ filemembers = fp.readlines()
+ fp.close()
+
+ try:
+ mlist = MailList.MailList(listname)
+ except Errors.MMUnknownListError:
+ print 'No list:', listname
+ sys.exit(1)
+
+ # get the list of addresses currently subscribed
+ addrs = {}
+ needsadding = {}
+ for addr in mlist.GetDeliveryMembers() + mlist.GetDigestDeliveryMembers():
+ addrs[string.lower(addr)] = addr
+
+ for addr in filemembers:
+ # any address found in the file that is also in the list can be
+ # ignored. if not found in the list, it must be added later
+ laddr = string.lower(addr)
+ if addrs.has_key(laddr):
+ del addrs[laddr]
+ else:
+ needsadding[laddr] = addr
+
+ # addrs contains now all the addresses that need removing
+ for laddr, addr in needsadding.items():
+ print 'Adding %30s (%30s)' % (laddr, addr)
+ if dryrun:
+ continue
+
+ for laddr, addr in addrs.items():
+ print 'Removing %30s (%30s)' % (laddr, addr)
+ if dryrun:
+ continue
+
+
+if __name__ == '__main__':
+ main()