Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymilter
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
misc
pymilter
Commits
b9467598
Commit
b9467598
authored
14 years ago
by
Stuart Gathman
Browse files
Options
Downloads
Patches
Plain Diff
Document threading limitations and show multiprocessing example.
parent
f6702e39
No related branches found
No related tags found
No related merge requests found
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
Milter/__init__.py
+9
-6
9 additions, 6 deletions
Milter/__init__.py
README
+1
-2
1 addition, 2 deletions
README
doc/mainpage.py
+18
-1
18 additions, 1 deletion
doc/mainpage.py
milter-template.py
+20
-4
20 additions, 4 deletions
milter-template.py
pymilter.spec
+4
-2
4 additions, 2 deletions
pymilter.spec
with
52 additions
and
15 deletions
Milter/__init__.py
+
9
−
6
View file @
b9467598
...
...
@@ -28,6 +28,7 @@ def uniqueID():
_seq_lock
.
release
()
return
seqno
## @private
OPTIONAL_CALLBACKS
=
{
'
connect
'
:(
P_NR_CONN
,
P_NOCONNECT
),
'
hello
'
:(
P_NR_HELO
,
P_NOHELO
),
...
...
@@ -40,6 +41,7 @@ OPTIONAL_CALLBACKS = {
'
header
'
:(
P_NR_HDR
,
P_NOHDRS
)
}
## @private
def
decode_mask
(
bits
,
names
):
t
=
[
(
s
,
getattr
(
milter
,
s
))
for
s
in
names
]
nms
=
[
s
for
s
,
m
in
t
if
bits
&
m
]
...
...
@@ -47,6 +49,13 @@ def decode_mask(bits,names):
if
bits
:
nms
+=
hex
(
bits
)
return
nms
## @fn set_flags(flags)
# @brief Enable optional %milter actions.
# Certain %milter actions need to be enabled before calling milter.runmilter()
# or they throw an exception.
# @param flags Bit ored mask of optional actions to enable
## Class decorator to enable optional protocol steps.
# P_SKIP is enabled by default when supported, but
# applications may wish to enable P_HDR_LEADSPC
...
...
@@ -538,12 +547,6 @@ class Milter(Base):
# change in configuration.
factory
=
Milter
## @fn set_flags(flags)
# @brief Enable optional %milter actions.
# Certain %milter actions need to be enabled before calling milter.runmilter()
# or they throw an exception.
# @param flags Bit ored mask of optional actions to enable
## @private
# @brief Connect context to connection instance and return enabled callbacks.
def
negotiate_callback
(
ctx
,
opts
):
...
...
This diff is collapsed.
Click to expand it.
README
+
1
−
2
View file @
b9467598
...
...
@@ -69,8 +69,7 @@ Not-so-quick Installation
First install Sendmail. Make sure you read libmilter/README in the Sendmail
source directory, and make sure you enable libmilter before you build. The
8.11 series had libmilter marked as FFR (For Future Release); 8.12
officially
supports libmilter, but it's still not built by default.
officially supports libmilter, but it's still not built by default.
Install Python, and enable threading in Modules/Setup.
...
...
This diff is collapsed.
Click to expand it.
doc/mainpage.py
+
18
−
1
View file @
b9467598
## @mainpage Writing Milters in Python
#
#
# At the lowest level, the <code>milter</code> module provides a thin wrapper
# around the <a href="https://www.milter.org/developers/api/index"> sendmail
# libmilter API</a>. This API lets you register callbacks for a number of
...
...
@@ -34,3 +33,21 @@
# The <code>mime</code> module provides a wrapper for the Python email package
# that fixes some bugs, and simplifies modifying selected parts of a MIME
# message.
#
# @section threading
#
# The libmilter library which pymilter wraps
# <a href="https://www.milter.org/developers/overview#SignalHandling">handles
# all signals</a> itself, and expects to be called from a single main thread.
# It handles SIGTERM, SIGHUP, and SIGINT, mapping the first two to
# <a href="https://www.milter.org/developers/api/smfi_stop">smfi_stop</a>
# and the last to an internal ABORT.
#
# If you use python threads or threading modules, then signal handling gets
# confused. Threads may still be useful, but you may need to provide an
# alternate means of causing graceful shutdown.
#
# You may find the
# <a href="http://docs.python.org/release/2.6.6/library/multiprocessing.html">
# multiprocessing</a> module useful. It can be a drop-in
# replacement for threading as illustrated in @ref milter-template.py.
This diff is collapsed.
Click to expand it.
milter-template.py
+
20
−
4
View file @
b9467598
...
...
@@ -14,7 +14,13 @@ import email
import
sys
from
socket
import
AF_INET
,
AF_INET6
from
Milter.utils
import
parse_addr
if
True
:
from
multiprocessing
import
Process
as
Thread
,
Queue
else
:
from
threading
import
Thread
from
Queue
import
Queue
logq
=
Queue
(
maxsize
=
4
)
class
myMilter
(
Milter
.
Base
):
...
...
@@ -117,16 +123,24 @@ class myMilter(Milter.Base):
## === Support Functions ===
def
log
(
self
,
*
msg
):
print
"
%s [%d]
"
%
(
time
.
strftime
(
'
%Y%b%d %H:%M:%S
'
),
self
.
id
),
logq
.
put
((
msg
,
self
.
id
,
time
.
time
()))
def
background
():
while
True
:
t
=
logq
.
get
()
if
not
t
:
break
msg
,
id
,
ts
=
t
print
"
%s [%d]
"
%
(
time
.
strftime
(
'
%Y%b%d %H:%M:%S
'
,
time
.
localtime
(
ts
)),
id
),
# 2005Oct13 02:34:11 [1] msg1 msg2 msg3 ...
for
i
in
msg
:
print
i
,
print
## ===
def
main
():
socketname
=
"
/tmp/pythonsock
"
bt
=
Thread
(
target
=
background
)
bt
.
start
()
socketname
=
"
/home/stuart/pythonsock
"
timeout
=
600
# Register to have the Milter factory create instances of your class:
Milter
.
factory
=
myMilter
...
...
@@ -136,7 +150,9 @@ def main():
Milter
.
set_flags
(
flags
)
# tell Sendmail which features we use
print
"
%s milter startup
"
%
time
.
strftime
(
'
%Y%b%d %H:%M:%S
'
)
sys
.
stdout
.
flush
()
Milter
.
runmilter
(
"
test
"
,
socketname
,
timeout
)
Milter
.
runmilter
(
"
pythonfilter
"
,
socketname
,
timeout
)
logq
.
put
(
None
)
bt
.
join
()
print
"
%s bms milter shutdown
"
%
time
.
strftime
(
'
%Y%b%d %H:%M:%S
'
)
if
__name__
==
"
__main__
"
:
...
...
This diff is collapsed.
Click to expand it.
pymilter.spec
+
4
−
2
View file @
b9467598
...
...
@@ -13,8 +13,9 @@ License: GPLv2+
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Url: http://www.bmsi.com/python/milter.html
Requires: %{pythonbase}, sendmail >= 8.13
# Need python2.4 specific pydns, not the version for system python
# python-2.6.4 gets RuntimeError: not holding the import lock
Requires: %{pythonbase} >= 2.6.5, sendmail >= 8.13
# Need python2.6 specific pydns, not the version for system python
Requires: %{pythonbase}-pydns
# Needed for callbacks, not a core function but highly useful for milters
BuildRequires: ed, %{pythonbase}-devel, sendmail-devel >= 8.13
...
...
@@ -77,6 +78,7 @@ rm -rf $RPM_BUILD_ROOT
* Wed Mar 02 2010 Stuart Gathman <stuart@bmsi.com> 0.9.5-1
- Print milter.error for invalid callback return type.
(Since stacktrace is empty, the TypeError exception is confusing.)
- Fix milter-template.py
* Wed Mar 02 2010 Stuart Gathman <stuart@bmsi.com> 0.9.4-1
- Handle IP6 in Milter.utils.iniplist()
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment