aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/courier-to-mailman.py
blob: 922401fb43614e9187dc3bb67ccd1a0f81082fa2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#! /usr/bin/python

# Configuration variables - Change these for your site if necessary.
#
MailmanHome = "@prefix@"; # Mailman home directory.
MailmanVar = "@VAR_PREFIX@"; # Mailman directory for mutable data.
MailmanOwner = "postmaster@localhost"; # Postmaster and abuse mail recepient.
#
# End of configuration variables.

# courier-to-mailman.py
#
# Interface mailman to a Courier virtual domain. Does not require the creation
# of _any_ list-specific aliases to connect lists to your mail system.
#
# Adapted March 29, 2004 by Lindsay Haisley, fmouse@fmp.com from
# qmail-to-mailman.py by Bruce Perens, bruce@perens.com, March 1999.
#
# This is free software under the GNU General Public License.
#
# This script is meant to be called from
# <domain_home>/alias/.courier-default. It catches all mail to any address
# at a virtual domain not otherwise handled by an explicit account or a
# .courier file.  It looks at the recepient for each mail message not
# otherwise handled and decides if the mail is addressed to a valid list or
# not, and bounces the message with a helpful suggestion if it's not
# addressed to a list.  It decides if it is a posting, a list command, or
# mail to the list administrator by checking for the various address tags as
# defined in manual Mailman list creation output (~mailman/bin/newlist).  It
# will recognize a list as soon as the list is created.  Above and beyond
# setting up a proper locally-hosted domain in Courier (the use of webadmin
# is highly recommended!), no other configuration should be required. This
# program recognizes mail to postmaster, mailman-owner, abuse,
# mailer-daemon, root, and owner, and routes those mails to MailmanOwner as
# defined in the configuration variables, above.
#
# INSTALLATION:
#
# Install this file as @prefix@/bin/courier-to-mailman.py
#
# To configure a virtual domain to connect to mailman, create these files:
#
# <domain_home>/alias/.courier-listname
# ... containing ...
# |/usr/bin/preline @prefix@/bin/courier-to-mailman.py
#
# Symlink <domain_home>/alias/.courier-listname-default to this file
#
# "listname" is the name of your list.
#
# Paths must, of course, be set correctly for the Courier and Mailman
# installations on your system.
#
# Note: "preline" is a Courier program which ensures a Unix "From " header
# is on the message.  Archiving will break without this.

import sys, os, re, string

def main():
	os.nice(5)  # Handle mailing lists at non-interactive priority.

	os.chdir(MailmanVar + "/lists")

	try:
		local = string.lower(os.environ["LOCAL"])
	except:
		# This might happen if we're not using qmail.
		sys.stderr.write("LOCAL not set in environment?\n")
		sys.exit(112)

	names = ("root", "postmaster", "mailer-daemon", "mailman-owner", "owner",
			 "abuse")
	for i in names:
		if i == local:
			os.execv("/usr/bin/sendmail",
					 ("/usr/bin/sendmail", MailmanOwner))
			sys.exit(0)

	type = "post"
	listname = string.lower(local)
	types = (("-admin$", "admin"),
			 ("-bounces$", "bounces"),
			 ("-bounces\+.*$", "bounces"),		# for VERP
			 ("-confirm$", "confirm"),
			 ("-confirm\+.*$", "confirm"),
			 ("-join$", "join"),
			 ("-leave$", "leave"),
			 ("-owner$", "owner"),
			 ("-request$", "request"),
			 ("-subscribe$", "subscribe"),
			 ("-unsubscribe$", "unsubscribe"))

	for i in types:
		if re.search(i[0],local):
			type = i[1]
			listname = re.sub(i[0],"",local)

	if os.path.exists(listname):
		os.execv(MailmanHome + "/mail/mailman",
				 (MailmanHome + "/mail/mailman", type, listname))
	else:
		bounce()

	sys.exit(111)

def bounce():
	bounce_message = """\
TO ACCESS THE MAILING LIST SYSTEM: Start your web browser on
http://%s/
That web page will help you subscribe or unsubscribe, and will
give you directions on how to post to each mailing list.\n"""
	sys.stderr.write(bounce_message % (os.environ["HOST"]))
	sys.exit(100)

try:
	sys.exit(main())
except SystemExit, argument:
	sys.exit(argument)

except Exception, argument:
	info = sys.exc_info()
	trace = info[2]
	sys.stderr.write("%s %s\n" % (sys.exc_type, argument))
	sys.stderr.write("LINE %d\n" % (trace.tb_lineno))
	sys.exit(111) # Soft failure, try again later.