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.
|