~msapiro/mailman/topics

« back to all changes in this revision

Viewing changes to contrib/courier-to-mailman.py

  • Committer: Mark Sapiro
  • Date: 2009-02-06 21:45:27 UTC
  • mfrom: (984.1.184 2.1)
  • mto: (1006.1.110 2.2)
  • mto: This revision was merged to the branch mainline in revision 1012.
  • Revision ID: mark@msapiro.net-20090206214527-ijyq7famejh0auwl
Merged changes from 2.1 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python
 
2
 
 
3
# Configuration variables - Change these for your site if necessary.
 
4
#
 
5
MailmanHome = "@prefix@"; # Mailman home directory.
 
6
MailmanVar = "@VAR_PREFIX@"; # Mailman directory for mutable data.
 
7
MailmanOwner = "postmaster@localhost"; # Postmaster and abuse mail recepient.
 
8
#
 
9
# End of configuration variables.
 
10
 
 
11
# courier-to-mailman.py
 
12
#
 
13
# Interface mailman to a Courier virtual domain. Does not require the creation
 
14
# of _any_ list-specific aliases to connect lists to your mail system.
 
15
#
 
16
# Adapted March 29, 2004 by Lindsay Haisley, fmouse@fmp.com from
 
17
# qmail-to-mailman.py by Bruce Perens, bruce@perens.com, March 1999.
 
18
#
 
19
# This is free software under the GNU General Public License.
 
20
#
 
21
# This script is meant to be called from
 
22
# <domain_home>/alias/.courier-default. It catches all mail to any address
 
23
# at a virtual domain not otherwise handled by an explicit account or a
 
24
# .courier file.  It looks at the recepient for each mail message not
 
25
# otherwise handled and decides if the mail is addressed to a valid list or
 
26
# not, and bounces the message with a helpful suggestion if it's not
 
27
# addressed to a list.  It decides if it is a posting, a list command, or
 
28
# mail to the list administrator by checking for the various address tags as
 
29
# defined in manual Mailman list creation output (~mailman/bin/newlist).  It
 
30
# will recognize a list as soon as the list is created.  Above and beyond
 
31
# setting up a proper locally-hosted domain in Courier (the use of webadmin
 
32
# is highly recommended!), no other configuration should be required. This
 
33
# program recognizes mail to postmaster, mailman-owner, abuse,
 
34
# mailer-daemon, root, and owner, and routes those mails to MailmanOwner as
 
35
# defined in the configuration variables, above.
 
36
#
 
37
# INSTALLATION:
 
38
#
 
39
# Install this file as @prefix@/bin/courier-to-mailman.py
 
40
#
 
41
# To configure a virtual domain to connect to mailman, create these files:
 
42
#
 
43
# <domain_home>/alias/.courier-listname
 
44
# ... containing ...
 
45
# |/usr/bin/preline @prefix@/bin/courier-to-mailman.py
 
46
#
 
47
# Symlink <domain_home>/alias/.courier-listname-default to this file
 
48
#
 
49
# "listname" is the name of your list.
 
50
#
 
51
# Paths must, of course, be set correctly for the Courier and Mailman
 
52
# installations on your system.
 
53
#
 
54
# Note: "preline" is a Courier program which ensures a Unix "From " header
 
55
# is on the message.  Archiving will break without this.
 
56
 
 
57
import sys, os, re, string
 
58
 
 
59
def main():
 
60
        os.nice(5)  # Handle mailing lists at non-interactive priority.
 
61
 
 
62
        os.chdir(MailmanVar + "/lists")
 
63
 
 
64
        try:
 
65
                local = string.lower(os.environ["LOCAL"])
 
66
        except:
 
67
                # This might happen if we're not using qmail.
 
68
                sys.stderr.write("LOCAL not set in environment?\n")
 
69
                sys.exit(112)
 
70
 
 
71
        names = ("root", "postmaster", "mailer-daemon", "mailman-owner", "owner",
 
72
                         "abuse")
 
73
        for i in names:
 
74
                if i == local:
 
75
                        os.execv("/usr/bin/sendmail",
 
76
                                         ("/usr/bin/sendmail", MailmanOwner))
 
77
                        sys.exit(0)
 
78
 
 
79
        type = "post"
 
80
        listname = string.lower(local)
 
81
        types = (("-admin$", "admin"),
 
82
                         ("-bounces$", "bounces"),
 
83
                         ("-bounces\+.*$", "bounces"),          # for VERP
 
84
                         ("-confirm$", "confirm"),
 
85
                         ("-confirm\+.*$", "confirm"),
 
86
                         ("-join$", "join"),
 
87
                         ("-leave$", "leave"),
 
88
                         ("-owner$", "owner"),
 
89
                         ("-request$", "request"),
 
90
                         ("-subscribe$", "subscribe"),
 
91
                         ("-unsubscribe$", "unsubscribe"))
 
92
 
 
93
        for i in types:
 
94
                if re.search(i[0],local):
 
95
                        type = i[1]
 
96
                        listname = re.sub(i[0],"",local)
 
97
 
 
98
        if os.path.exists(listname):
 
99
                os.execv(MailmanHome + "/mail/mailman",
 
100
                                 (MailmanHome + "/mail/mailman", type, listname))
 
101
        else:
 
102
                bounce()
 
103
 
 
104
        sys.exit(111)
 
105
 
 
106
def bounce():
 
107
        bounce_message = """\
 
108
TO ACCESS THE MAILING LIST SYSTEM: Start your web browser on
 
109
http://%s/
 
110
That web page will help you subscribe or unsubscribe, and will
 
111
give you directions on how to post to each mailing list.\n"""
 
112
        sys.stderr.write(bounce_message % (os.environ["HOST"]))
 
113
        sys.exit(100)
 
114
 
 
115
try:
 
116
        sys.exit(main())
 
117
except SystemExit, argument:
 
118
        sys.exit(argument)
 
119
 
 
120
except Exception, argument:
 
121
        info = sys.exc_info()
 
122
        trace = info[2]
 
123
        sys.stderr.write("%s %s\n" % (sys.exc_type, argument))
 
124
        sys.stderr.write("LINE %d\n" % (trace.tb_lineno))
 
125
        sys.exit(111) # Soft failure, try again later.